diff options
author | Daniil Yarancev <21169548+Yardanico@users.noreply.github.com> | 2018-01-07 21:02:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-07 21:02:00 +0300 |
commit | fb44c522e6173528efa8035ecc459c84887d0167 (patch) | |
tree | a2f5e98606be265981a5f72748896967033e23d7 | |
parent | ccf99fa5ce4fe992fb80dc89271faa51456c3fa5 (diff) | |
parent | e23ea64c41e101d4e1d933f0b015f51cc6c2f7de (diff) | |
download | Nim-fb44c522e6173528efa8035ecc459c84887d0167.tar.gz |
Merge pull request #1 from nim-lang/devel
upstream
819 files changed, 89233 insertions, 41878 deletions
diff --git a/.gitignore b/.gitignore index 5476e173f..fc090130b 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,7 @@ dist/ # Private directories and files (IDEs) .*/ ~* + +# testament cruft +testresults/ +test.txt diff --git a/.travis.yml b/.travis.yml index 3d9fc49e8..6b8cdbe03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,3 +46,7 @@ script: - tests/testament/tester --pedantic all -d:nimCoroutines - ./koch web - ./koch csource + - ./koch nimsuggest +# - nim c -r nimsuggest/tester + - ( ! grep -F '.. code-block' -l -r --include '*.html' --exclude contributing.html --exclude docgen.html --exclude tut2.html ) + - ( ! grep -F '..code-block' -l -r --include '*.html' --exclude contributing.html --exclude docgen.html --exclude tut2.html ) diff --git a/changelog.md b/changelog.md index a4161f504..21ab2b87a 100644 --- a/changelog.md +++ b/changelog.md @@ -2,11 +2,191 @@ ### Changes affecting backwards compatibility -- Removed basic2d/basic3d out of the stdlib and into Nimble packages. - These packages deprecated however, use the ``glm``, ``arraymancer``, ``neo`` - or another package. + - Arrays of char cannot be converted to ``cstring`` anymore, pointers to arrays of char can! This means ``$`` for arrays can finally exist in ``system.nim`` and do the right thing. -- JSON: Deprecated `getBVal`, `getFNum`, and `getNum` in favour to - `getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added. \ No newline at end of file +- ``echo`` now works with strings that contain ``\0`` (the binary zero is not + shown) and ``nil`` strings are equal to empty strings. +- JSON: Deprecated `getBVal`, `getFNum`, and `getNum` in favour to + `getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added. +- `reExtended` is no longer default for the `re` constructor in the `re` + module. +- The overloading rules changed slightly so that constrained generics are + preferred over unconstrained generics. (Bug #6526) +- It is now possible to forward declare object types so that mutually + recursive types can be created across module boundaries. See + [package level objects](https://nim-lang.org/docs/manual.html#package-level-objects) + for more information. +- The **unary** ``<`` is now deprecated, for ``.. <`` use ``..<`` for other usages + use the ``pred`` proc. +- We changed how array accesses "from backwards" like ``a[^1]`` or ``a[0..^1]`` are + implemented. These are now implemented purely in ``system.nim`` without compiler + support. There is a new "heterogenous" slice type ``system.HSlice`` that takes 2 + generic parameters which can be ``BackwardsIndex`` indices. ``BackwardsIndex`` is + produced by ``system.^``. + This means if you overload ``[]`` or ``[]=`` you need to ensure they also work + with ``system.BackwardsIndex`` (if applicable for the accessors). +- ``mod`` and bitwise ``and`` do not produce ``range`` subtypes anymore. This + turned out to be more harmful than helpful and the language is simpler + without this special typing rule. +- Added ``algorithm.rotateLeft``. +- ``rationals.toRational`` now uses an algorithm based on continued fractions. + This means its results are more precise and it can't run into an infinite loop + anymore. +- Added ``typetraits.$`` as an alias for ``typetraits.name``. +- ``os.getEnv`` now takes an optional ``default`` parameter that tells ``getEnv`` + what to return if the environment variable does not exist. +- Bodies of ``for`` loops now get their own scope: + +```nim + # now compiles: + for i in 0..4: + let i = i + 1 + echo i +``` + +- The parsing rules of ``if`` expressions were changed so that multiple + statements are allowed in the branches. We found few code examples that + now fail because of this change, but here is one: + +```nim + t[ti] = if exp_negative: '-' else: '+'; inc(ti) +``` + +This now needs to be written as: + +```nim + t[ti] = (if exp_negative: '-' else: '+'); inc(ti) +``` + +- To make Nim even more robust the system iterators ``..`` and ``countup`` + now only accept a single generic type ``T``. This means the following code + doesn't die with an "out of range" error anymore: + +```nim + var b = 5.Natural + var a = -5 + for i in a..b: + echo i +``` + +- ``formatFloat``/``formatBiggestFloat`` now support formatting floats with zero + precision digits. The previous ``precision = 0`` behavior (default formatting) + is now available via ``precision = -1``. +- The ``nim doc`` command is now an alias for ``nim doc2``, the second version of + the documentation generator. The old version 1 can still be accessed + via the new ``nim doc0`` command. +- Added ``system.getStackTraceEntries`` that allows you to access the stack + trace in a structured manner without string parsing. +- Added ``sequtils.mapLiterals`` for easier construction of array and tuple + literals. +- Added ``parseutils.parseSaturatedNatural``. +- ``atomic`` and ``generic`` are no longer keywords in Nim. ``generic`` used to be + an alias for ``concept``, ``atomic`` was not used for anything. +- Moved from stdlib into Nimble packages: + - [``basic2d``](https://github.com/nim-lang/basic2d) + _deprecated: use ``glm``, ``arraymancer``, ``neo``, or another package instead_ + - [``basic3d``](https://github.com/nim-lang/basic3d) + _deprecated: use ``glm``, ``arraymancer``, ``neo``, or another package instead_ + - [``gentabs``](https://github.com/lcrees/gentabs) + - [``libuv``](https://github.com/lcrees/libuv) + - [``numeric``](https://github.com/lcrees/polynumeric) + - [``poly``](https://github.com/lcrees/polynumeric) + - [``pdcurses``](https://github.com/lcrees/pdcurses) + - [``romans``](https://github.com/lcrees/romans) + +- Added ``system.runnableExamples`` to make examples in Nim's documentation easier + to write and test. The examples are tested as the last step of + ``nim doc``. +- Nim's ``rst2html`` command now supports the testing of code snippets via an RST + extension that we called ``:test:``:: + + ```rst + .. code-block:: nim + :test: + # shows how the 'if' statement works + if true: echo "yes" + ``` +- The ``[]`` proc for strings now raises an ``IndexError`` exception when + the specified slice is out of bounds. See issue + [#6223](https://github.com/nim-lang/Nim/issues/6223) for more details. + You can use ``substr(str, start, finish)`` to get the old behaviour back, + see [this commit](https://github.com/nim-lang/nimbot/commit/98cc031a27ea89947daa7f0bb536bcf86462941f) for an example. +- ``strutils.split`` and ``strutils.rsplit`` with an empty string and a + separator now returns that empty string. + See issue [#4377](https://github.com/nim-lang/Nim/issues/4377). +- The experimental overloading of the dot ``.`` operators now take + an ``untyped``` parameter as the field name, it used to be + a ``static[string]``. You can use ``when defined(nimNewDot)`` to make + your code work with both old and new Nim versions. + See [special-operators](https://nim-lang.org/docs/manual.html#special-operators) + for more information. +- Added ``macros.unpackVarargs``. +- The memory manager now uses a variant of the TLSF algorithm that has much + better memory fragmentation behaviour. According + to [http://www.gii.upv.es/tlsf/](http://www.gii.upv.es/tlsf/) the maximum + fragmentation measured is lower than 25%. As a nice bonus ``alloc`` and + ``dealloc`` became O(1) operations. +- The behavior of ``$`` has been changed for all standard library collections. The + collection-to-string implementations now perform proper quoting and escaping of + strings and chars. +- The ``random`` procs in ``random.nim`` have all been deprecated. Instead use + the new ``rand`` procs. The module now exports the state of the random + number generator as type ``Rand`` so multiple threads can easily use their + own random number generators that do not require locking. For more information + about this rename see issue [#6934](https://github.com/nim-lang/Nim/issues/6934) +- The compiler is now more consistent in its treatment of ambiguous symbols: + Types that shadow procs and vice versa are marked as ambiguous (bug #6693). +- ``yield`` (or ``await`` which is mapped to ``yield``) never worked reliably + in an array, seq or object constructor and is now prevented at compile-time. +- For string formatting / interpolation a new module + called [strformat](https://nim-lang.org/docs/strformat.html) has been added + to the stdlib. +- codegenDecl pragma now works for the JavaScript backend. It returns an empty string for + function return type placeholders. +- Asynchronous programming for the JavaScript backend using the `asyncjs` module. +- Extra semantic checks for procs with noreturn pragma: return type is not allowed, + statements after call to noreturn procs are no longer allowed. +- Noreturn proc calls and raising exceptions branches are now skipped during common type + deduction in if and case expressions. The following code snippets now compile: +```nim +import strutils +let str = "Y" +let a = case str: + of "Y": true + of "N": false + else: raise newException(ValueError, "Invalid boolean") +let b = case str: + of nil, "": raise newException(ValueError, "Invalid boolean") + elif str.startsWith("Y"): true + elif str.startsWith("N"): false + else: false +let c = if str == "Y": true + elif str == "N": false + else: + echo "invalid bool" + quit("this is the end") +``` +- Proc [toCountTable](https://nim-lang.org/docs/tables.html#toCountTable,openArray[A]) now produces a `CountTable` with values correspoding to the number of occurrences of the key in the input. It used to produce a table with all values set to `1`. + +Counting occurrences in a sequence used to be: + +```nim +let mySeq = @[1, 2, 1, 3, 1, 4] +var myCounter = initCountTable[int]() + +for item in mySeq: + myCounter.inc item +``` + +Now, you can simply do: + +```nim +let + mySeq = @[1, 2, 1, 3, 1, 4] + myCounter = mySeq.toCountTable() +``` + +- Added support for casting between integers of same bitsize in VM (compile time and nimscript). + This allow to among other things to reinterpret signed integers as unsigned. diff --git a/compiler/aliases.nim b/compiler/aliases.nim index c0371e159..cd7e7f19a 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -179,5 +179,11 @@ proc isPartOf*(a, b: PNode): TAnalysisResult = result = isPartOf(a[0], b) if result == arNo: result = arMaybe else: discard + of nkObjConstr: + result = arNo + for i in 1..<b.len: + let res = isPartOf(a, b[i][1]) + if res != arNo: + result = res + if res == arYes: break else: discard - diff --git a/compiler/ast.nim b/compiler/ast.nim index 6519b698a..27a44c6c2 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -62,8 +62,8 @@ type nkTripleStrLit, # a triple string literal """ nkNilLit, # the nil literal # end of atoms - nkMetaNode_Obsolete, # difficult to explain; represents itself - # (used for macros) + nkComesFrom, # "comes from" template/macro information for + # better stack trace generation nkDotCall, # used to temporarily flag a nkCall node; # this is used # for transforming ``s.len`` to ``len(s)`` @@ -639,7 +639,8 @@ type mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl, mNHint, mNWarning, mNError, mInstantiationInfo, mGetTypeInfo, mNGenSym, - mNimvm, mIntDefine, mStrDefine + mNimvm, mIntDefine, mStrDefine, mRunnableExamples, + mException # things that we can evaluate safely at compile time, even if not asked for it: const @@ -744,6 +745,8 @@ type OnUnknown, # location is unknown (stack, heap or static) OnStatic, # in a static section OnStack, # location is on hardware stack + OnStackShadowDup, # location is on the stack but also replicated + # on the shadow stack OnHeap # location is on heap or global # (reference counting needed) TLocFlags* = set[TLocFlag] @@ -753,6 +756,7 @@ type flags*: TLocFlags # location's flags lode*: PNode # Node where the location came from; can be faked r*: Rope # rope value of location (code generators) + dup*: Rope # duplicated location for precise stack scans # ---------------- end of backend information ------------------------------ @@ -1017,16 +1021,11 @@ proc add*(father, son: PNode) = type Indexable = PNode | PType -template `[]`*(n: Indexable, i: int): Indexable = - n.sons[i] +template `[]`*(n: Indexable, i: int): Indexable = n.sons[i] +template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x -template `-|`*(b, s: untyped): untyped = - (if b >= 0: b else: s.len + b) - -# son access operators with support for negative indices -template `{}`*(n: Indexable, i: int): untyped = n[i -| n] -template `{}=`*(n: Indexable, i: int, s: Indexable) = - n.sons[i -| n] = s +template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int] +template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x when defined(useNodeIds): const nodeIdToDebug* = -1 # 299750 # 300761 #300863 # 300879 @@ -1036,9 +1035,9 @@ proc newNode*(kind: TNodeKind): PNode = new(result) result.kind = kind #result.info = UnknownLineInfo() inlined: - result.info.fileIndex = int32(- 1) - result.info.col = int16(- 1) - result.info.line = int16(- 1) + result.info.fileIndex = int32(-1) + result.info.col = int16(-1) + result.info.line = int16(-1) when defined(useNodeIds): result.id = gNodeId if result.id == nodeIdToDebug: @@ -1392,6 +1391,14 @@ proc skipTypes*(t: PType, kinds: TTypeKinds): PType = result = t while result.kind in kinds: result = lastSon(result) +proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType = + result = t + var i = maxIters + while result.kind in kinds: + result = lastSon(result) + dec i + if i == 0: return nil + proc skipTypesOrNil*(t: PType, kinds: TTypeKinds): PType = ## same as skipTypes but handles 'nil' result = t @@ -1405,7 +1412,7 @@ proc isGCedMem*(t: PType): bool {.inline.} = proc propagateToOwner*(owner, elem: PType) = const HaveTheirOwnEmpty = {tySequence, tyOpt, tySet, tyPtr, tyRef, tyProc} - owner.flags = owner.flags + (elem.flags * {tfHasMeta}) + owner.flags = owner.flags + (elem.flags * {tfHasMeta, tfTriggersCompileTime}) if tfNotNil in elem.flags: if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvocation}: owner.flags.incl tfNotNil @@ -1420,15 +1427,12 @@ proc propagateToOwner*(owner, elem: PType) = owner.flags.incl tfHasMeta if tfHasAsgn in elem.flags: - let o2 = elem.skipTypes({tyGenericInst, tyAlias}) + let o2 = owner.skipTypes({tyGenericInst, tyAlias}) if o2.kind in {tyTuple, tyObject, tyArray, tySequence, tyOpt, tySet, tyDistinct}: o2.flags.incl tfHasAsgn owner.flags.incl tfHasAsgn - if tfTriggersCompileTime in elem.flags: - owner.flags.incl tfTriggersCompileTime - if owner.kind notin {tyProc, tyGenericInst, tyGenericBody, tyGenericInvocation, tyPtr}: let elemB = elem.skipTypes({tyGenericInst, tyAlias}) @@ -1442,6 +1446,10 @@ proc rawAddSon*(father, son: PType) = add(father.sons, son) if not son.isNil: propagateToOwner(father, son) +proc rawAddSonNoPropagationOfTypeFlags*(father, son: PType) = + if isNil(father.sons): father.sons = @[] + add(father.sons, son) + proc addSonNilAllowed*(father, son: PNode) = if isNil(father.sons): father.sons = @[] add(father.sons, son) @@ -1604,10 +1612,10 @@ proc hasPattern*(s: PSym): bool {.inline.} = result = isRoutine(s) and s.ast.sons[patternPos].kind != nkEmpty iterator items*(n: PNode): PNode = - for i in 0.. <n.safeLen: yield n.sons[i] + for i in 0..<n.safeLen: yield n.sons[i] iterator pairs*(n: PNode): tuple[i: int, n: PNode] = - for i in 0.. <n.len: yield (i, n.sons[i]) + for i in 0..<n.len: yield (i, n.sons[i]) proc isAtom*(n: PNode): bool {.inline.} = result = n.kind >= nkNone and n.kind <= nkNilLit @@ -1663,3 +1671,10 @@ when false: if n.isNil: return true for i in 0 ..< n.safeLen: if n[i].containsNil: return true + +template hasDestructor*(t: PType): bool = tfHasAsgn in t.flags +template incompleteType*(t: PType): bool = + t.sym != nil and {sfForward, sfNoForward} * t.sym.flags == {sfForward} + +template typeCompleted*(s: PSym) = + incl s.flags, sfNoForward diff --git a/compiler/canonicalizer.nim b/compiler/canonicalizer.nim index 6972f5acf..d1669a06c 100644 --- a/compiler/canonicalizer.nim +++ b/compiler/canonicalizer.nim @@ -102,7 +102,7 @@ proc hashTree(c: var MD5Context, n: PNode) = of nkStrLit..nkTripleStrLit: c &= n.strVal else: - for i in 0.. <n.len: hashTree(c, n.sons[i]) + for i in 0..<n.len: hashTree(c, n.sons[i]) proc hashType(c: var MD5Context, t: PType) = # modelled after 'typeToString' @@ -151,13 +151,13 @@ proc hashType(c: var MD5Context, t: PType) = c.hashType(t.sons[0]) of tyProc: c &= (if tfIterator in t.flags: "iterator " else: "proc ") - for i in 0.. <t.len: c.hashType(t.sons[i]) + for i in 0..<t.len: c.hashType(t.sons[i]) md5Update(c, cast[cstring](addr(t.callConv)), 1) if tfNoSideEffect in t.flags: c &= ".noSideEffect" if tfThread in t.flags: c &= ".thread" else: - for i in 0.. <t.len: c.hashType(t.sons[i]) + for i in 0..<t.len: c.hashType(t.sons[i]) if tfNotNil in t.flags: c &= "not nil" proc canonConst(n: PNode): TUid = diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index a00e2bc77..d4fad041d 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -11,7 +11,7 @@ proc leftAppearsOnRightSide(le, ri: PNode): bool = if le != nil: - for i in 1 .. <ri.len: + for i in 1 ..< ri.len: let r = ri[i] if isPartOf(le, r) != arNo: return true @@ -364,7 +364,7 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope = of '@': if j < ri.len: result.add genOtherArg(p, ri, j, typ) - for k in j+1 .. < ri.len: + for k in j+1 ..< ri.len: result.add(~", ") result.add genOtherArg(p, ri, k, typ) inc i @@ -377,7 +377,7 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope = result.add(~"(") if 1 < ri.len: result.add genOtherArg(p, ri, 1, typ) - for k in j+1 .. < ri.len: + for k in j+1 ..< ri.len: result.add(~", ") result.add genOtherArg(p, ri, k, typ) result.add(~")") diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 88944aea6..5a25a9853 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -228,7 +228,7 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = else: flags let t = skipTypes(dest.t, abstractInst).getUniqueType() - for i in 0 .. <t.len: + for i in 0 ..< t.len: let t = t.sons[i] let field = "Field$1" % [i.rope] genAssignment(p, optAsgnLoc(dest, t, field), @@ -270,10 +270,10 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = addrLoc(dest), addrLoc(src), rdLoc(dest)) else: linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n", - addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) + addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t, dest.lode.info)) else: linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n", - addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) + addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t, dest.lode.info)) proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = # This function replaces all other methods for generating @@ -291,7 +291,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = genRefAssign(p, dest, src, flags) else: linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n", - addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t)) + addrLoc(dest), rdLoc(src), + genTypeInfo(p.module, dest.t, dest.lode.info)) of tyString: if (needToCopy notin flags and src.storage != OnStatic) or canMove(src.lode): genRefAssign(p, dest, src, flags) @@ -352,7 +353,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if needsComplexAssignment(dest.t): linefmt(p, cpsStmts, # XXX: is this correct for arrays? "#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n", - addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) + addrLoc(dest), addrLoc(src), + genTypeInfo(p.module, dest.t, dest.lode.info)) else: useStringh(p.module) linefmt(p, cpsStmts, @@ -393,14 +395,17 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) = of tyPtr, tyRef, tyProc, tyTuple, tyObject, tyArray: # XXX optimize this linefmt(p, cpsStmts, "#genericDeepCopy((void*)$1, (void*)$2, $3);$n", - addrLoc(dest), addrLocOrTemp(src), genTypeInfo(p.module, dest.t)) + addrLoc(dest), addrLocOrTemp(src), + genTypeInfo(p.module, dest.t, dest.lode.info)) of tySequence, tyString: linefmt(p, cpsStmts, "#genericSeqDeepCopy($1, $2, $3);$n", - addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t)) + addrLoc(dest), rdLoc(src), + genTypeInfo(p.module, dest.t, dest.lode.info)) of tyOpenArray, tyVarargs: linefmt(p, cpsStmts, "#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n", - addrLoc(dest), addrLocOrTemp(src), genTypeInfo(p.module, dest.t)) + addrLoc(dest), addrLocOrTemp(src), + genTypeInfo(p.module, dest.t, dest.lode.info)) of tySet: if mapType(ty) == ctArray: useStringh(p.module) @@ -678,9 +683,10 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) = d.storage = OnHeap else: var a: TLoc - var typ = skipTypes(e.sons[0].typ, abstractInst) + var typ = e.sons[0].typ if typ.kind in {tyUserTypeClass, tyUserTypeClassInst} and typ.isResolvedUserTypeClass: typ = typ.lastSon + typ = typ.skipTypes(abstractInst) if typ.kind == tyVar and tfVarIsPtr notin typ.flags and p.module.compileToCpp and e.sons[0].kind == nkHiddenAddr: initLocExprSingleUse(p, e[0][0], d) return @@ -793,8 +799,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) = proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) -proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym; - origTy: PType) = +proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) = var test, u, v: TLoc for i in countup(1, sonsLen(e) - 1): var it = e.sons[i] @@ -806,12 +811,10 @@ proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym; assert(disc.kind == nkSym) initLoc(test, locNone, it, OnStack) initLocExpr(p, it.sons[1], u) - var o = obj - let d = lookupFieldAgain(p, origTy, disc.sym, o) initLoc(v, locExpr, disc, OnUnknown) - v.r = o + v.r = obj v.r.add(".") - v.r.add(d.loc.r) + v.r.add(disc.sym.loc.r) genInExprAux(p, it, u, v, test) let id = nodeTableTestOrSet(p.module.dataCache, newStrNode(nkStrLit, field.name.s), p.module.labels) @@ -837,7 +840,7 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = if field.loc.r == nil: fillObjectFields(p.module, ty) if field.loc.r == nil: internalError(e.info, "genCheckedRecordField") # generate the checks: - genFieldCheck(p, e, r, field, ty) + genFieldCheck(p, e, r, field) add(r, rfmt(nil, ".$1", field.loc.r)) putIntoDest(p, d, e.sons[0], r, a.storage) else: @@ -847,7 +850,7 @@ proc genArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) = var a, b: TLoc initLocExpr(p, x, a) initLocExpr(p, y, b) - var ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs) + var ty = skipTypes(a.t, abstractVarRange + abstractPtrs + tyUserTypeClasses) var first = intLiteral(firstOrd(ty)) # emit range check: if optBoundsCheck in p.options and tfUncheckedArray notin ty.flags: @@ -965,23 +968,30 @@ proc genEcho(p: BProc, n: PNode) = # this unusal way of implementing it ensures that e.g. ``echo("hallo", 45)`` # is threadsafe. internalAssert n.kind == nkBracket - var args: Rope = nil - var a: TLoc - for i in countup(0, n.len-1): - if n.sons[i].skipConv.kind == nkNilLit: - add(args, ", \"nil\"") - else: - initLocExpr(p, n.sons[i], a) - addf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)]) if platform.targetOS == osGenode: # bypass libc and print directly to the Genode LOG session + var args: Rope = nil + var a: TLoc + for i in countup(0, n.len-1): + if n.sons[i].skipConv.kind == nkNilLit: + add(args, ", \"nil\"") + else: + initLocExpr(p, n.sons[i], a) + addf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)]) p.module.includeHeader("<base/log.h>") linefmt(p, cpsStmts, """Genode::log(""$1);$n""", args) else: - p.module.includeHeader("<stdio.h>") - linefmt(p, cpsStmts, "printf($1$2);$n", - makeCString(repeat("%s", n.len) & tnl), args) - linefmt(p, cpsStmts, "fflush(stdout);$n") + if n.len == 0: + linefmt(p, cpsStmts, "#echoBinSafe(NIM_NIL, $1);$n", n.len.rope) + else: + var a: TLoc + initLocExpr(p, n, a) + linefmt(p, cpsStmts, "#echoBinSafe($1, $2);$n", a.rdLoc, n.len.rope) + when false: + p.module.includeHeader("<stdio.h>") + linefmt(p, cpsStmts, "printf($1$2);$n", + makeCString(repeat("%s", n.len) & tnl), args) + linefmt(p, cpsStmts, "fflush(stdout);$n") proc gcUsage(n: PNode) = if gSelectedGC == gcNone: message(n.info, warnGcMem, n.renderTree) @@ -1094,7 +1104,8 @@ proc genReset(p: BProc, n: PNode) = var a: TLoc initLocExpr(p, n.sons[1], a) linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n", - addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, {tyVar}))) + addrLoc(a), + genTypeInfo(p.module, skipTypes(a.t, {tyVar}), n.info)) proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = var sizeExpr = sizeExpr @@ -1108,7 +1119,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = sizeExpr = "sizeof($1)" % [getTypeDesc(p.module, bt)] let args = [getTypeDesc(p.module, typ), - genTypeInfo(p.module, typ), + genTypeInfo(p.module, typ, a.lode.info), sizeExpr] if a.storage == OnHeap and usesNativeGC(): # use newObjRC1 as an optimization @@ -1138,7 +1149,7 @@ proc genNew(p: BProc, e: PNode) = proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope) = let seqtype = skipTypes(dest.t, abstractVarRange) let args = [getTypeDesc(p.module, seqtype), - genTypeInfo(p.module, seqtype), length] + genTypeInfo(p.module, seqtype, dest.lode.info), length] var call: TLoc initLoc(call, locExpr, dest.lode, OnHeap) if dest.storage == OnHeap and usesNativeGC(): @@ -1166,7 +1177,7 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) = putIntoDest(p, d, e, ropecg(p.module, "($1)#nimNewSeqOfCap($2, $3)", [ getTypeDesc(p.module, seqtype), - genTypeInfo(p.module, seqtype), a.rdLoc])) + genTypeInfo(p.module, seqtype, e.info), a.rdLoc])) gcUsage(e) proc genConstExpr(p: BProc, n: PNode): Rope @@ -1205,7 +1216,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = constructLoc(p, tmp) discard getTypeDesc(p.module, t) let ty = getUniqueType(t) - for i in 1 .. <e.len: + for i in 1 ..< e.len: let it = e.sons[i] var tmp2: TLoc tmp2.r = r @@ -1213,7 +1224,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = if field.loc.r == nil: fillObjectFields(p.module, ty) if field.loc.r == nil: internalError(e.info, "genObjConstr") if it.len == 3 and optFieldCheck in p.options: - genFieldCheck(p, it.sons[2], r, field, ty) + genFieldCheck(p, it.sons[2], r, field) add(tmp2.r, ".") add(tmp2.r, field.loc.r) tmp2.k = locTemp @@ -1226,18 +1237,32 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = else: genAssignment(p, d, tmp, {}) +proc lhsDoesAlias(a, b: PNode): bool = + for y in b: + if isPartOf(a, y) != arNo: return true + proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) = - var arr: TLoc - if d.k == locNone: + var arr, tmp: TLoc + # bug #668 + let doesAlias = lhsDoesAlias(d.lode, n) + let dest = if doesAlias: addr(tmp) else: addr(d) + if doesAlias: + getTemp(p, n.typ, tmp) + elif d.k == locNone: getTemp(p, n.typ, d) # generate call to newSeq before adding the elements per hand: - genNewSeqAux(p, d, intLiteral(sonsLen(n))) + genNewSeqAux(p, dest[], intLiteral(sonsLen(n))) for i in countup(0, sonsLen(n) - 1): initLoc(arr, locExpr, n[i], OnHeap) - arr.r = rfmt(nil, "$1->data[$2]", rdLoc(d), intLiteral(i)) + arr.r = rfmt(nil, "$1->data[$2]", rdLoc(dest[]), intLiteral(i)) arr.storage = OnHeap # we know that sequences are on the heap expr(p, n[i], arr) gcUsage(n) + if doesAlias: + if d.k == locNone: + d = tmp + else: + genAssignment(p, d, tmp, {}) proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) = var elem, a, arr: TLoc @@ -1248,17 +1273,31 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) = if d.k == locNone: getTemp(p, n.typ, d) # generate call to newSeq before adding the elements per hand: - var L = int(lengthOrd(n.sons[1].typ)) - + let L = int(lengthOrd(n.sons[1].typ)) genNewSeqAux(p, d, intLiteral(L)) initLocExpr(p, n.sons[1], a) - for i in countup(0, L - 1): + # bug #5007; do not produce excessive C source code: + if L < 10: + for i in countup(0, L - 1): + initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap) + elem.r = rfmt(nil, "$1->data[$2]", rdLoc(d), intLiteral(i)) + elem.storage = OnHeap # we know that sequences are on the heap + initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.sons[1].typ, abstractInst)), a.storage) + arr.r = rfmt(nil, "$1[$2]", rdLoc(a), intLiteral(i)) + genAssignment(p, elem, arr, {afDestIsNil, needToCopy}) + else: + var i: TLoc + getTemp(p, getSysType(tyInt), i) + let oldCode = p.s(cpsStmts) + linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n", i.r, L.rope) initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap) - elem.r = rfmt(nil, "$1->data[$2]", rdLoc(d), intLiteral(i)) + elem.r = rfmt(nil, "$1->data[$2]", rdLoc(d), rdLoc(i)) elem.storage = OnHeap # we know that sequences are on the heap initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.sons[1].typ, abstractInst)), a.storage) - arr.r = rfmt(nil, "$1[$2]", rdLoc(a), intLiteral(i)) + arr.r = rfmt(nil, "$1[$2]", rdLoc(a), rdLoc(i)) genAssignment(p, elem, arr, {afDestIsNil, needToCopy}) + lineF(p, cpsStmts, "}$n", []) + proc genNewFinalize(p: BProc, e: PNode) = var @@ -1269,7 +1308,7 @@ proc genNewFinalize(p: BProc, e: PNode) = initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], f) initLoc(b, locExpr, a.lode, OnHeap) - ti = genTypeInfo(p.module, refType) + ti = genTypeInfo(p.module, refType, e.info) addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)]) b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [ getTypeDesc(p.module, refType), @@ -1279,10 +1318,10 @@ proc genNewFinalize(p: BProc, e: PNode) = genObjectInit(p, cpsStmts, bt, a, false) gcUsage(e) -proc genOfHelper(p: BProc; dest: PType; a: Rope): Rope = +proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope = # unfortunately 'genTypeInfo' sets tfObjHasKids as a side effect, so we # have to call it here first: - let ti = genTypeInfo(p.module, dest) + let ti = genTypeInfo(p.module, dest, info) if tfFinal in dest.flags or (objHasKidsValid in p.module.flags and tfObjHasKids notin dest.flags): result = "$1.m_type == $2" % [a, ti] @@ -1295,7 +1334,7 @@ proc genOfHelper(p: BProc; dest: PType; a: Rope): Rope = when false: # former version: result = rfmt(p.module, "#isObj($1.m_type, $2)", - a, genTypeInfo(p.module, dest)) + a, genTypeInfo(p.module, dest, info)) proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) = var a: TLoc @@ -1317,9 +1356,9 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) = globalError(x.info, errGenerated, "no 'of' operator available for pure objects") if nilCheck != nil: - r = rfmt(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r)) + r = rfmt(p.module, "(($1) && ($2))", nilCheck, genOfHelper(p, dest, r, x.info)) else: - r = rfmt(p.module, "($1)", genOfHelper(p, dest, r)) + r = rfmt(p.module, "($1)", genOfHelper(p, dest, r, x.info)) putIntoDest(p, d, x, r, a.storage) proc genOf(p: BProc, n: PNode, d: var TLoc) = @@ -1342,12 +1381,12 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = of tyEnum, tyOrdinal: putIntoDest(p, d, e, ropecg(p.module, "#reprEnum((NI)$1, $2)", [ - rdLoc(a), genTypeInfo(p.module, t)]), a.storage) + rdLoc(a), genTypeInfo(p.module, t, e.info)]), a.storage) of tyString: putIntoDest(p, d, e, ropecg(p.module, "#reprStr($1)", [rdLoc(a)]), a.storage) of tySet: putIntoDest(p, d, e, ropecg(p.module, "#reprSet($1, $2)", [ - addrLoc(a), genTypeInfo(p.module, t)]), a.storage) + addrLoc(a), genTypeInfo(p.module, t, e.info)]), a.storage) of tyOpenArray, tyVarargs: var b: TLoc case a.t.kind @@ -1362,22 +1401,22 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) = else: internalError(e.sons[0].info, "genRepr()") putIntoDest(p, d, e, ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b), - genTypeInfo(p.module, elemType(t))]), a.storage) + genTypeInfo(p.module, elemType(t), e.info)]), a.storage) of tyCString, tyArray, tyRef, tyPtr, tyPointer, tyNil, tySequence: putIntoDest(p, d, e, ropecg(p.module, "#reprAny($1, $2)", [ - rdLoc(a), genTypeInfo(p.module, t)]), a.storage) + rdLoc(a), genTypeInfo(p.module, t, e.info)]), a.storage) of tyEmpty, tyVoid: localError(e.info, "'repr' doesn't support 'void' type") else: putIntoDest(p, d, e, ropecg(p.module, "#reprAny($1, $2)", - [addrLoc(a), genTypeInfo(p.module, t)]), + [addrLoc(a), genTypeInfo(p.module, t, e.info)]), a.storage) gcUsage(e) proc genGetTypeInfo(p: BProc, e: PNode, d: var TLoc) = let t = e.sons[1].typ - putIntoDest(p, d, e, genTypeInfo(p.module, t)) + putIntoDest(p, d, e, genTypeInfo(p.module, t, e.info)) proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) = var a: TLoc @@ -1618,8 +1657,14 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, d, e, "(($1) ($2))" % [getClosureType(p.module, etyp, clHalfWithEnv), rdCharLoc(a)], a.storage) else: - putIntoDest(p, d, e, "(($1) ($2))" % - [getTypeDesc(p.module, e.typ), rdCharLoc(a)], a.storage) + let srcTyp = skipTypes(e.sons[1].typ, abstractRange) + # C++ does not like direct casts from pointer to shorter integral types + if srcTyp.kind in {tyPtr, tyPointer} and etyp.kind in IntegralTypes: + putIntoDest(p, d, e, "(($1) (ptrdiff_t) ($2))" % + [getTypeDesc(p.module, e.typ), rdCharLoc(a)], a.storage) + else: + putIntoDest(p, d, e, "(($1) ($2))" % + [getTypeDesc(p.module, e.typ), rdCharLoc(a)], a.storage) proc genCast(p: BProc, e: PNode, d: var TLoc) = const ValueTypes = {tyFloat..tyFloat128, tyTuple, tyObject, tyArray} @@ -1663,7 +1708,7 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) = proc genConv(p: BProc, e: PNode, d: var TLoc) = let destType = e.typ.skipTypes({tyVar, tyGenericInst, tyAlias}) - if compareTypes(destType, e.sons[1].typ, dcEqIgnoreDistinct): + if sameBackendType(destType, e.sons[1].typ): expr(p, e.sons[1], d) else: genSomeCast(p, e, d) @@ -1830,7 +1875,10 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = initLocExpr(p, e.sons[2], b) genDeepCopy(p, a, b) of mDotDot, mEqCString: genCall(p, e, d) - else: internalError(e.info, "genMagicExpr: " & $op) + else: + when defined(debugMagics): + echo p.prc.name.s, " ", p.prc.id, " ", p.prc.flags, " ", p.prc.ast[genericParamsPos].kind + internalError(e.info, "genMagicExpr: " & $op) proc genSetConstr(p: BProc, e: PNode, d: var TLoc) = # example: { a..b, c, d, e, f..g } @@ -1935,10 +1983,35 @@ proc genComplexConst(p: BProc, sym: PSym, d: var TLoc) = assert((sym.loc.r != nil) and (sym.loc.t != nil)) putLocIntoDest(p, d, sym.loc) +template genStmtListExprImpl(exprOrStmt) {.dirty.} = + #let hasNimFrame = magicsys.getCompilerProc("nimFrame") != nil + let hasNimFrame = p.prc != nil and + sfSystemModule notin p.module.module.flags and + optStackTrace in p.prc.options + var frameName: Rope = nil + for i in 0 .. n.len - 2: + let it = n[i] + if it.kind == nkComesFrom: + if hasNimFrame and frameName == nil: + inc p.labels + frameName = "FR" & rope(p.labels) & "_" + let theMacro = it[0].sym + add p.s(cpsStmts), initFrameNoDebug(p, frameName, + makeCString theMacro.name.s, + theMacro.info.quotedFilename, it.info.line) + else: + genStmts(p, it) + if n.len > 0: exprOrStmt + if frameName != nil: + add p.s(cpsStmts), deinitFrameNoDebug(p, frameName) + proc genStmtListExpr(p: BProc, n: PNode, d: var TLoc) = - var length = sonsLen(n) - for i in countup(0, length - 2): genStmts(p, n.sons[i]) - if length > 0: expr(p, n.sons[length - 1], d) + genStmtListExprImpl: + expr(p, n[n.len - 1], d) + +proc genStmtList(p: BProc, n: PNode) = + genStmtListExprImpl: + genStmts(p, n[n.len - 1]) proc upConv(p: BProc, n: PNode, d: var TLoc) = var a: TLoc @@ -1959,10 +2032,10 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) = t = skipTypes(t.sons[0], skipPtrs) if nilCheck != nil: linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n", - nilCheck, r, genTypeInfo(p.module, dest)) + nilCheck, r, genTypeInfo(p.module, dest, n.info)) else: linefmt(p, cpsStmts, "#chckObj($1.m_type, $2);$n", - r, genTypeInfo(p.module, dest)) + r, genTypeInfo(p.module, dest, n.info)) if n.sons[0].typ.kind != tyObject: putIntoDest(p, d, n, "(($1) ($2))" % [getTypeDesc(p.module, n.typ), rdLoc(a)], a.storage) @@ -2137,8 +2210,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of nkCheckedFieldExpr: genCheckedRecordField(p, n, d) of nkBlockExpr, nkBlockStmt: genBlock(p, n, d) of nkStmtListExpr: genStmtListExpr(p, n, d) - of nkStmtList: - for i in countup(0, sonsLen(n) - 1): genStmts(p, n.sons[i]) + of nkStmtList: genStmtList(p, n) of nkIfExpr, nkIfStmt: genIf(p, n, d) of nkWhen: # This should be a "when nimvm" node. @@ -2245,10 +2317,16 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo): Rope = result = rope"{NIM_NIL, NIM_NIL}" of tyObject: if not isObjLackingTypeField(t) and not p.module.compileToCpp: - result = "{{$1}}" % [genTypeInfo(p.module, t)] + result = "{{$1}}" % [genTypeInfo(p.module, t, info)] else: result = rope"{}" - of tyArray, tyTuple: result = rope"{}" + of tyTuple: + result = rope"{" + for i in 0 ..< typ.len: + if i > 0: result.add ", " + result.add getDefaultValue(p, typ.sons[i], info) + result.add "}" + of tyArray: result = rope"{}" of tySet: if mapType(t) == ctArray: result = rope"{}" else: result = rope"0" @@ -2290,7 +2368,7 @@ proc getNullValueAuxT(p: BProc; orig, t: PType; obj, cons: PNode, result: var Ro base = skipTypes(base, skipPtrs) getNullValueAuxT(p, orig, base, base.n, cons, result, count) elif not isObjLackingTypeField(t) and not p.module.compileToCpp: - addf(result, "$1", [genTypeInfo(p.module, orig)]) + addf(result, "$1", [genTypeInfo(p.module, orig, obj.info)]) inc count getNullValueAux(p, t, obj, cons, result, count) # do not emit '{}' as that is not valid C: diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index 58a03ecd2..f667be70f 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -96,7 +96,7 @@ proc writeIntSet(a: IntSet, s: var string) = s.add('}') proc genMergeInfo*(m: BModule): Rope = - if optSymbolFiles notin gGlobalOptions: return nil + if not compilationCachePresent: return nil var s = "/*\tNIM_merge_INFO:" s.add(tnl) s.add("typeCache:{") diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 5434d87b2..36816cc2c 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -20,7 +20,7 @@ proc registerGcRoot(p: BProc, v: PSym) = containsGarbageCollectedRef(v.loc.t): # we register a specialized marked proc here; this has the advantage # that it works out of the box for thread local storage then :-) - let prc = genTraverseProcForGlobal(p.module, v) + let prc = genTraverseProcForGlobal(p.module, v, v.info) appcg(p.module, p.module.initProc.procSec(cpsInit), "#nimRegisterGlobalMarker($1);$n", [prc]) @@ -165,7 +165,7 @@ proc genGotoState(p: BProc, n: PNode) = statesCounter = n[1].intVal let prefix = if n.len == 3 and n[2].kind == nkStrLit: n[2].strVal.rope else: rope"STATE" - for i in 0 .. statesCounter: + for i in 0i64 .. statesCounter: lineF(p, cpsStmts, "case $2: goto $1$2;$n", [prefix, rope(i)]) lineF(p, cpsStmts, "}$n", []) @@ -235,7 +235,7 @@ proc genSingleVar(p: BProc, a: PNode) = var params: Rope let typ = skipTypes(value.sons[0].typ, abstractInst) assert(typ.kind == tyProc) - for i in 1.. <value.len: + for i in 1..<value.len: if params != nil: params.add(~", ") assert(sonsLen(typ) == sonsLen(typ.n)) add(params, genOtherArg(p, value, i, typ)) @@ -386,7 +386,7 @@ proc genReturnStmt(p: BProc, t: PNode) = lineF(p, cpsStmts, "goto BeforeRet_;$n", []) proc genGotoForCase(p: BProc; caseStmt: PNode) = - for i in 1 .. <caseStmt.len: + for i in 1 ..< caseStmt.len: startBlock(p) let it = caseStmt.sons[i] for j in 0 .. it.len-2: @@ -402,7 +402,7 @@ proc genComputedGoto(p: BProc; n: PNode) = # first pass: Generate array of computed labels: var casePos = -1 var arraySize: int - for i in 0 .. <n.len: + for i in 0 ..< n.len: let it = n.sons[i] if it.kind == nkCaseStmt: if lastSon(it).kind != nkOfBranch: @@ -432,7 +432,7 @@ proc genComputedGoto(p: BProc; n: PNode) = let oldBody = p.blocks[topBlock].sections[cpsStmts] p.blocks[topBlock].sections[cpsStmts] = nil - for j in casePos+1 .. <n.len: genStmts(p, n.sons[j]) + for j in casePos+1 ..< n.len: genStmts(p, n.sons[j]) let tailB = p.blocks[topBlock].sections[cpsStmts] p.blocks[topBlock].sections[cpsStmts] = nil @@ -447,7 +447,7 @@ proc genComputedGoto(p: BProc; n: PNode) = # first goto: lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc]) - for i in 1 .. <caseStmt.len: + for i in 1 ..< caseStmt.len: startBlock(p) let it = caseStmt.sons[i] for j in 0 .. it.len-2: @@ -457,7 +457,7 @@ proc genComputedGoto(p: BProc; n: PNode) = let val = getOrdValue(it.sons[j]) lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(val+id+1)]) genStmts(p, it.lastSon) - #for j in casePos+1 .. <n.len: genStmts(p, n.sons[j]) # tailB + #for j in casePos+1 ..< n.len: genStmts(p, n.sons[j]) # tailB #for j in 0 .. casePos-1: genStmts(p, n.sons[j]) # tailA add(p.s(cpsStmts), tailB) add(p.s(cpsStmts), tailA) @@ -564,9 +564,6 @@ proc genBreakStmt(p: BProc, t: PNode) = genLineDir(p, t) lineF(p, cpsStmts, "goto $1;$n", [label]) -proc getRaiseFrmt(p: BProc): string = - result = "#raiseException((#Exception*)$1, $2);$n" - proc genRaiseStmt(p: BProc, t: PNode) = if p.inExceptBlock > 0: # if the current try stmt have a finally block, @@ -580,7 +577,8 @@ proc genRaiseStmt(p: BProc, t: PNode) = var e = rdLoc(a) var typ = skipTypes(t.sons[0].typ, abstractPtrs) genLineDir(p, t) - lineCg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)]) + lineCg(p, cpsStmts, "#raiseException((#Exception*)$1, $2);$n", + [e, makeCString(typ.sym.name.s)]) else: genLineDir(p, t) # reraise the last exception: @@ -744,7 +742,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) = if splitPoint+1 < n.len: lineF(p, cpsStmts, "switch ($1) {$n", [rdCharLoc(a)]) var hasDefault = false - for i in splitPoint+1 .. < n.len: + for i in splitPoint+1 ..< n.len: # bug #4230: avoid false sharing between branches: if d.k == locTemp and isEmptyType(n.typ): d.k = locNone var branch = n[i] @@ -835,7 +833,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = if orExpr != nil: add(orExpr, "||") appcg(p.module, orExpr, "#isObj($1.exp->m_type, $2)", - [exc, genTypeInfo(p.module, t.sons[i].sons[j].typ)]) + [exc, genTypeInfo(p.module, t[i][j].typ, t[i][j].info)]) lineF(p, cpsStmts, "if ($1) ", [orExpr]) startBlock(p) expr(p, t.sons[i].sons[blen-1], d) @@ -944,7 +942,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = "#isObj(#getCurrentException()->Sup.m_type, $1)" else: "#isObj(#getCurrentException()->m_type, $1)" appcg(p.module, orExpr, isObjFormat, - [genTypeInfo(p.module, t.sons[i].sons[j].typ)]) + [genTypeInfo(p.module, t[i][j].typ, t[i][j].info)]) if i > 1: line(p, cpsStmts, "else ") startBlock(p, "if ($1) {$n", [orExpr]) linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint) @@ -1062,7 +1060,7 @@ proc genWatchpoint(p: BProc, n: PNode) = let typ = skipTypes(n.sons[1].typ, abstractVarRange) lineCg(p, cpsStmts, "#dbgRegisterWatchpoint($1, (NCSTRING)$2, $3);$n", [a.addrLoc, makeCString(renderTree(n.sons[1])), - genTypeInfo(p.module, typ)]) + genTypeInfo(p.module, typ, n.info)]) proc genPragma(p: BProc, n: PNode) = for i in countup(0, sonsLen(n) - 1): @@ -1092,7 +1090,7 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType, field: PSym) = var t = skipTypes(objtype, abstractVar) assert t.kind == tyObject - discard genTypeInfo(p.module, t) + discard genTypeInfo(p.module, t, a.lode.info) var L = lengthOrd(field.typ) if not containsOrIncl(p.module.declaredThings, field.id): appcg(p.module, cfsVars, "extern $1", @@ -1112,19 +1110,46 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) = genDiscriminantCheck(p, a, tmp, dotExpr.sons[0].typ, dotExpr.sons[1].sym) genAssignment(p, a, tmp, {}) +proc patchAsgnStmtListExpr(father, orig, n: PNode) = + case n.kind + of nkDerefExpr, nkHiddenDeref: + let asgn = copyNode(orig) + asgn.add orig[0] + asgn.add n + father.add asgn + of nkStmtList, nkStmtListExpr: + for x in n: + patchAsgnStmtListExpr(father, orig, x) + else: + father.add n + proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) = if e.sons[0].kind == nkSym and sfGoto in e.sons[0].sym.flags: genLineDir(p, e) genGotoVar(p, e.sons[1]) elif not fieldDiscriminantCheckNeeded(p, e): + # this fixes bug #6422 but we really need to change the representation of + # arrays in the backend... + let le = e[0] + let ri = e[1] + var needsRepair = false + var it = ri + while it.kind in {nkStmtList, nkStmtListExpr}: + it = it.lastSon + needsRepair = true + if it.kind in {nkDerefExpr, nkHiddenDeref} and needsRepair: + var patchedTree = newNodeI(nkStmtList, e.info) + patchAsgnStmtListExpr(patchedTree, e, ri) + genStmts(p, patchedTree) + return + var a: TLoc - if e[0].kind in {nkDerefExpr, nkHiddenDeref}: - genDeref(p, e[0], a, enforceDeref=true) + if le.kind in {nkDerefExpr, nkHiddenDeref}: + genDeref(p, le, a, enforceDeref=true) else: - initLocExpr(p, e.sons[0], a) + initLocExpr(p, le, a) if fastAsgn: incl(a.flags, lfNoDeepCopy) assert(a.t != nil) - let ri = e.sons[1] genLineDir(p, ri) loadInto(p, e.sons[0], ri, a) else: diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index 4215a84b1..275c2ddb6 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -66,7 +66,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType) = var p = c.p case typ.kind - of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct: + of tyGenericInst, tyGenericBody, tyTypeDesc, tyAlias, tyDistinct, tyInferred: genTraverseProc(c, accessor, lastSon(typ)) of tyArray: let arraySize = lengthOrd(typ.sons[0]) @@ -151,8 +151,8 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash; m.s[cfsProcHeaders].addf("$1;$n", [header]) m.s[cfsProcs].add(generatedProc) -proc genTraverseProcForGlobal(m: BModule, s: PSym): Rope = - discard genTypeInfo(m, s.loc.t) +proc genTraverseProcForGlobal(m: BModule, s: PSym; info: TLineInfo): Rope = + discard genTypeInfo(m, s.loc.t, info) var c: TTraversalClosure var p = newProc(nil, m) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 4c85294b2..c9cd3b125 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -119,7 +119,7 @@ proc scopeMangledParam(p: BProc; param: PSym) = const irrelevantForBackend = {tyGenericBody, tyGenericInst, tyGenericInvocation, - tyDistinct, tyRange, tyStatic, tyAlias} + tyDistinct, tyRange, tyStatic, tyAlias, tyInferred} proc typeName(typ: PType): Rope = let typ = typ.skipTypes(irrelevantForBackend) @@ -278,7 +278,10 @@ proc ccgIntroducedPtr(s: PSym): bool = elif tfByCopy in pt.flags: return false case pt.kind of tyObject: - if (optByRef in s.options) or (getSize(pt) > platform.floatSize * 3): + if s.typ.sym != nil and sfForward in s.typ.sym.flags: + # forwarded objects are *always* passed by pointers for consistency! + result = true + elif (optByRef in s.options) or (getSize(pt) > platform.floatSize * 3): result = true # requested anyway elif (tfFinal in pt.flags) and (pt.sons[0] == nil): result = false # no need, because no subtyping possible @@ -806,7 +809,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = var chunkStart = 0 while i < cppName.data.len: if cppName.data[i] == '\'': - var chunkEnd = <i + var chunkEnd = i-1 var idx, stars: int if scanCppGenericSlot(cppName.data, i, idx, stars): result.add cppName.data.substr(chunkStart, chunkEnd) @@ -854,11 +857,12 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = [structOrUnion(t), result]) assert m.forwTypeCache[sig] == result m.typeCache[sig] = result # always call for sideeffects: - let recdesc = if t.kind != tyTuple: getRecordDesc(m, t, result, check) - else: getTupleDesc(m, t, result, check) - if not isImportedType(t): - add(m.s[cfsTypes], recdesc) - elif tfIncompleteStruct notin t.flags: addAbiCheck(m, t, result) + if not incompleteType(t): + let recdesc = if t.kind != tyTuple: getRecordDesc(m, t, result, check) + else: getTupleDesc(m, t, result, check) + if not isImportedType(t): + add(m.s[cfsTypes], recdesc) + elif tfIncompleteStruct notin t.flags: addAbiCheck(m, t, result) of tySet: result = $t.kind & '_' & getTypeName(m, t.lastSon, hashType t.lastSon) m.typeCache[sig] = result @@ -921,6 +925,8 @@ proc genProcHeader(m: BModule, prc: PSym): Rope = result.add "N_LIB_EXPORT " elif prc.typ.callConv == ccInline: result.add "static " + elif {sfImportc, sfExportc} * prc.flags == {}: + result.add "N_LIB_PRIVATE " var check = initIntSet() fillLoc(prc.loc, locProc, prc.ast[namePos], mangleName(m, prc), OnUnknown) genProcParams(m, prc.typ, rettype, params, check) @@ -935,12 +941,13 @@ proc genProcHeader(m: BModule, prc: PSym): Rope = # ------------------ type info generation ------------------------------------- -proc genTypeInfo(m: BModule, t: PType): Rope +proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope proc getNimNode(m: BModule): Rope = result = "$1[$2]" % [m.typeNodesName, rope(m.typeNodes)] inc(m.typeNodes) -proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: Rope) = +proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; + name, base: Rope; info: TLineInfo) = var nimtypeKind: int #allocMemTI(m, typ, name) if isObjLackingTypeField(typ): @@ -963,22 +970,29 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: Rope) = addf(m.s[cfsTypeInit3], "$1.flags = $2;$n", [name, rope(flags)]) discard cgsym(m, "TNimType") if isDefined("nimTypeNames"): + var typename = typeToString(origType, preferName) + if typename == "ref object" and origType.skipTypes(skipPtrs).sym != nil: + typename = "anon ref object from " & $origType.skipTypes(skipPtrs).sym.info addf(m.s[cfsTypeInit3], "$1.name = $2;$n", - [name, makeCstring typeToString(origType, preferName)]) + [name, makeCstring typename]) discard cgsym(m, "nimTypeRoot") addf(m.s[cfsTypeInit3], "$1.nextType = nimTypeRoot; nimTypeRoot=&$1;$n", [name]) addf(m.s[cfsVars], "TNimType $1;$n", [name]) -proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope) = +proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope; + info: TLineInfo) = var base: Rope if sonsLen(typ) > 0 and typ.lastSon != nil: var x = typ.lastSon if typ.kind == tyObject: x = x.skipTypes(skipPtrs) - base = genTypeInfo(m, x) + if typ.kind == tyPtr and x.kind == tyObject and incompleteType(x): + base = rope("0") + else: + base = genTypeInfo(m, x, info) else: base = rope("0") - genTypeInfoAuxBase(m, typ, origType, name, base) + genTypeInfoAuxBase(m, typ, origType, name, base, info) proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope = # bugfix: we need to search the type that contains the discriminator: @@ -994,19 +1008,20 @@ proc discriminatorTableDecl(m: BModule, objtype: PType, d: PSym): Rope = var tmp = discriminatorTableName(m, objtype, d) result = "TNimNode* $1[$2];$n" % [tmp, rope(lengthOrd(d.typ)+1)] -proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope) = +proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope; + info: TLineInfo) = case n.kind of nkRecList: var L = sonsLen(n) if L == 1: - genObjectFields(m, typ, origType, n.sons[0], expr) + genObjectFields(m, typ, origType, n.sons[0], expr, info) elif L > 0: var tmp = getTempName(m) addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, rope(L)]) for i in countup(0, L-1): var tmp2 = getNimNode(m) addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(i), tmp2]) - genObjectFields(m, typ, origType, n.sons[i], tmp2) + genObjectFields(m, typ, origType, n.sons[i], tmp2, info) addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n", [expr, rope(L), tmp]) else: @@ -1024,14 +1039,14 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope) = "$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" & "$1.name = $5;$n" & "$1.sons = &$6[0];$n" & "$1.len = $7;$n", [expr, getTypeDesc(m, origType), field.loc.r, - genTypeInfo(m, field.typ), + genTypeInfo(m, field.typ, info), makeCString(field.name.s), tmp, rope(L)]) addf(m.s[cfsData], "TNimNode* $1[$2];$n", [tmp, rope(L+1)]) for i in countup(1, sonsLen(n)-1): var b = n.sons[i] # branch var tmp2 = getNimNode(m) - genObjectFields(m, typ, origType, lastSon(b), tmp2) + genObjectFields(m, typ, origType, lastSon(b), tmp2, info) case b.kind of nkOfBranch: if sonsLen(b) < 2: @@ -1059,15 +1074,20 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope) = addf(m.s[cfsTypeInit3], "$1.kind = 1;$n" & "$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" & "$1.name = $5;$n", [expr, getTypeDesc(m, origType), - field.loc.r, genTypeInfo(m, field.typ), makeCString(field.name.s)]) + field.loc.r, genTypeInfo(m, field.typ, info), makeCString(field.name.s)]) else: internalError(n.info, "genObjectFields") -proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope) = - if typ.kind == tyObject: genTypeInfoAux(m, typ, origType, name) - else: genTypeInfoAuxBase(m, typ, origType, name, rope("0")) +proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo) = + if typ.kind == tyObject: + if incompleteType(typ): + localError(info, "request for RTTI generation for incomplete object: " & + typeToString(typ)) + genTypeInfoAux(m, typ, origType, name, info) + else: + genTypeInfoAuxBase(m, typ, origType, name, rope("0"), info) var tmp = getNimNode(m) if not isImportedType(typ): - genObjectFields(m, typ, origType, typ.n, tmp) + genObjectFields(m, typ, origType, typ.n, tmp, info) addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, tmp]) var t = typ.sons[0] while t != nil: @@ -1075,8 +1095,8 @@ proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope) = t.flags.incl tfObjHasKids t = t.sons[0] -proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope) = - genTypeInfoAuxBase(m, typ, typ, name, rope("0")) +proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo) = + genTypeInfoAuxBase(m, typ, typ, name, rope("0"), info) var expr = getNimNode(m) var length = sonsLen(typ) if length > 0: @@ -1090,7 +1110,7 @@ proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope) = "$1.offset = offsetof($2, Field$3);$n" & "$1.typ = $4;$n" & "$1.name = \"Field$3\";$n", - [tmp2, getTypeDesc(m, origType), rope(i), genTypeInfo(m, a)]) + [tmp2, getTypeDesc(m, origType), rope(i), genTypeInfo(m, a, info)]) addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n", [expr, rope(length), tmp]) else: @@ -1098,12 +1118,12 @@ proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope) = [expr, rope(length)]) addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, expr]) -proc genEnumInfo(m: BModule, typ: PType, name: Rope) = +proc genEnumInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) = # Type information for enumerations is quite heavy, so we do some # optimizations here: The ``typ`` field is never set, as it is redundant # anyway. We generate a cstring array and a loop over it. Exceptional # positions will be reset after the loop. - genTypeInfoAux(m, typ, typ, name) + genTypeInfoAux(m, typ, typ, name, info) var nodePtrs = getTempName(m) var length = sonsLen(typ.n) addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", @@ -1141,15 +1161,15 @@ proc genEnumInfo(m: BModule, typ: PType, name: Rope) = # 1 << 2 is {ntfEnumHole} addf(m.s[cfsTypeInit3], "$1.flags = 1<<2;$n", [name]) -proc genSetInfo(m: BModule, typ: PType, name: Rope) = +proc genSetInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) = assert(typ.sons[0] != nil) - genTypeInfoAux(m, typ, typ, name) + genTypeInfoAux(m, typ, typ, name, info) var tmp = getNimNode(m) addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 0;$n" & "$3.node = &$1;$n", [tmp, rope(firstOrd(typ)), name]) -proc genArrayInfo(m: BModule, typ: PType, name: Rope) = - genTypeInfoAuxBase(m, typ, typ, name, genTypeInfo(m, typ.sons[1])) +proc genArrayInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) = + genTypeInfoAuxBase(m, typ, typ, name, genTypeInfo(m, typ.sons[1], info), info) proc fakeClosureType(owner: PSym): PType = # we generate the same RTTI as for a tuple[pointer, ref tuple[]] @@ -1171,11 +1191,11 @@ proc genDeepCopyProc(m: BModule; s: PSym; result: Rope) = addf(m.s[cfsTypeInit3], "$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n", [result, s.loc.r]) -proc genTypeInfo(m: BModule, t: PType): Rope = +proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope = let origType = t var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses) if t.kind == tyOpt: - return genTypeInfo(m, optLowering(t)) + return genTypeInfo(m, optLowering(t), info) let sig = hashType(origType) result = m.typeInfoMarker.getOrDefault(sig) @@ -1197,7 +1217,7 @@ proc genTypeInfo(m: BModule, t: PType): Rope = let owner = t.skipTypes(typedescPtrs).owner.getModule if owner != m.module: # make sure the type info is created in the owner module - discard genTypeInfo(m.g.modules[owner.position], origType) + discard genTypeInfo(m.g.modules[owner.position], origType, info) # reference the type info as extern here discard cgsym(m, "TNimType") discard cgsym(m, "TNimNode") @@ -1208,35 +1228,35 @@ proc genTypeInfo(m: BModule, t: PType): Rope = case t.kind of tyEmpty, tyVoid: result = rope"0" of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar: - genTypeInfoAuxBase(m, t, t, result, rope"0") + genTypeInfoAuxBase(m, t, t, result, rope"0", info) of tyStatic: - if t.n != nil: result = genTypeInfo(m, lastSon t) + if t.n != nil: result = genTypeInfo(m, lastSon t, info) else: internalError("genTypeInfo(" & $t.kind & ')') of tyUserTypeClasses: internalAssert t.isResolvedUserTypeClass - return genTypeInfo(m, t.lastSon) + return genTypeInfo(m, t.lastSon, info) of tyProc: if t.callConv != ccClosure: - genTypeInfoAuxBase(m, t, t, result, rope"0") + genTypeInfoAuxBase(m, t, t, result, rope"0", info) else: let x = fakeClosureType(t.owner) - genTupleInfo(m, x, x, result) + genTupleInfo(m, x, x, result, info) of tySequence, tyRef, tyOptAsRef: - genTypeInfoAux(m, t, t, result) + genTypeInfoAux(m, t, t, result, info) if gSelectedGC >= gcMarkAndSweep: let markerProc = genTraverseProc(m, origType, sig, tiNew) addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc]) - of tyPtr, tyRange: genTypeInfoAux(m, t, t, result) - of tyArray: genArrayInfo(m, t, result) - of tySet: genSetInfo(m, t, result) - of tyEnum: genEnumInfo(m, t, result) - of tyObject: genObjectInfo(m, t, origType, result) + of tyPtr, tyRange: genTypeInfoAux(m, t, t, result, info) + of tyArray: genArrayInfo(m, t, result, info) + of tySet: genSetInfo(m, t, result, info) + of tyEnum: genEnumInfo(m, t, result, info) + of tyObject: genObjectInfo(m, t, origType, result, info) of tyTuple: # if t.n != nil: genObjectInfo(m, t, result) # else: # BUGFIX: use consistently RTTI without proper field names; otherwise # results are not deterministic! - genTupleInfo(m, t, origType, result) + genTupleInfo(m, t, origType, result, info) else: internalError("genTypeInfo(" & $t.kind & ')') if t.deepCopy != nil: genDeepCopyProc(m, t.deepCopy, result) diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 4cfeeb3c3..b1a268c9e 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -16,11 +16,11 @@ import proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode = case n.kind of nkStmtList: - for i in 0 .. < n.len: + for i in 0 ..< n.len: result = getPragmaStmt(n[i], w) if result != nil: break of nkPragma: - for i in 0 .. < n.len: + for i in 0 ..< n.len: if whichPragma(n[i]) == w: return n[i] else: discard diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 367fced9a..630426cfd 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -271,11 +271,11 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc, while (s.kind == tyObject) and (s.sons[0] != nil): add(r, ".Sup") s = skipTypes(s.sons[0], skipPtrs) - linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t)) + linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t, a.lode.info)) of frEmbedded: # worst case for performance: var r = if takeAddr: addrLoc(a) else: rdLoc(a) - linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t)) + linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t, a.lode.info)) type TAssignmentFlag = enum @@ -306,7 +306,7 @@ proc resetLoc(p: BProc, loc: var TLoc) = linefmt(p, cpsStmts, "#chckNil((void*)$1);$n", addrLoc(loc)) if loc.storage != OnStack: linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n", - addrLoc(loc), genTypeInfo(p.module, loc.t)) + addrLoc(loc), genTypeInfo(p.module, loc.t, loc.lode.info)) # XXX: generated reset procs should not touch the m_type # field, so disabling this should be safe: genObjectInit(p, cpsStmts, loc.t, loc, true) @@ -381,7 +381,7 @@ proc localDebugInfo(p: BProc, s: PSym) = lineF(p, cpsInit, "FR_.s[$1].address = (void*)$3; FR_.s[$1].typ = $4; FR_.s[$1].name = $2;$n", [p.maxFrameLen.rope, makeCString(normalize(s.name.s)), a, - genTypeInfo(p.module, s.loc.t)]) + genTypeInfo(p.module, s.loc.t, s.info)]) inc(p.maxFrameLen) inc p.blocks[p.blocks.len-1].frameLen @@ -451,7 +451,7 @@ proc assignGlobalVar(p: BProc, n: PNode) = appcg(p.module, p.module.s[cfsDebugInit], "#dbgRegisterGlobal($1, &$2, $3);$n", [makeCString(normalize(s.owner.name.s & '.' & s.name.s)), - s.loc.r, genTypeInfo(p.module, s.typ)]) + s.loc.r, genTypeInfo(p.module, s.typ, n.info)]) proc assignParam(p: BProc, s: PSym) = assert(s.loc.r != nil) @@ -493,7 +493,32 @@ proc initLocExprSingleUse(p: BProc, e: PNode, result: var TLoc) = proc lenField(p: BProc): Rope = result = rope(if p.module.compileToCpp: "len" else: "Sup.len") -include ccgcalls, "ccgstmts.nim", "ccgexprs.nim" +include ccgcalls, "ccgstmts.nim" + +proc initFrame(p: BProc, procname, filename: Rope): Rope = + discard cgsym(p.module, "nimFrame") + if p.maxFrameLen > 0: + discard cgsym(p.module, "VarSlot") + result = rfmt(nil, "\tnimfrs_($1, $2, $3, $4);$n", + procname, filename, p.maxFrameLen.rope, + p.blocks[0].frameLen.rope) + else: + result = rfmt(nil, "\tnimfr_($1, $2);$n", procname, filename) + +proc initFrameNoDebug(p: BProc; frame, procname, filename: Rope; line: int): Rope = + discard cgsym(p.module, "nimFrame") + addf(p.blocks[0].sections[cpsLocals], "TFrame $1;$n", [frame]) + result = rfmt(nil, "\t$1.procname = $2; $1.filename = $3; " & + " $1.line = $4; $1.len = -1; nimFrame(&$1);$n", + frame, procname, filename, rope(line)) + +proc deinitFrameNoDebug(p: BProc; frame: Rope): Rope = + result = rfmt(p.module, "\t#popFrameOfAddr(&$1);$n", frame) + +proc deinitFrame(p: BProc): Rope = + result = rfmt(p.module, "\t#popFrame();$n") + +include ccgexprs # ----------------------------- dynamic library handling ----------------- # We don't finalize dynamic libs as the OS does this for us. @@ -600,7 +625,7 @@ proc symInDynamicLibPartial(m: BModule, sym: PSym) = sym.typ.sym = nil # generate a new name proc cgsym(m: BModule, name: string): Rope = - var sym = magicsys.getCompilerProc(name) + let sym = magicsys.getCompilerProc(name) if sym != nil: case sym.kind of skProc, skFunc, skMethod, skConverter, skIterator: genProc(m, sym) @@ -637,19 +662,6 @@ proc generateHeaders(m: BModule) = add(m.s[cfsHeaders], "#undef powerpc" & tnl) add(m.s[cfsHeaders], "#undef unix" & tnl) -proc initFrame(p: BProc, procname, filename: Rope): Rope = - discard cgsym(p.module, "nimFrame") - if p.maxFrameLen > 0: - discard cgsym(p.module, "VarSlot") - result = rfmt(nil, "\tnimfrs_($1, $2, $3, $4);$n", - procname, filename, p.maxFrameLen.rope, - p.blocks[0].frameLen.rope) - else: - result = rfmt(nil, "\tnimfr_($1, $2);$n", procname, filename) - -proc deinitFrame(p: BProc): Rope = - result = rfmt(p.module, "\t#popFrame();$n") - proc closureSetup(p: BProc, prc: PSym) = if tfCapturesEnv notin prc.typ.flags: return # prc.ast[paramsPos].last contains the type we're after: @@ -896,14 +908,15 @@ proc addIntTypes(result: var Rope) {.inline.} = platform.CPU[targetCPU].intSize.rope]) proc getCopyright(cfile: Cfile): Rope = + const copyrightYear = "2017" if optCompileOnly in gGlobalOptions: result = ("/* Generated by Nim Compiler v$1 */$N" & - "/* (c) " & CompileDate.substr(0, 3) & " Andreas Rumpf */$N" & + "/* (c) " & copyrightYear & " Andreas Rumpf */$N" & "/* The generated code is subject to the original license. */$N") % [rope(VersionAsString)] else: result = ("/* Generated by Nim Compiler v$1 */$N" & - "/* (c) " & CompileDate.substr(0, 3) & " Andreas Rumpf */$N" & + "/* (c) " & copyrightYear & " Andreas Rumpf */$N" & "/* The generated code is subject to the original license. */$N" & "/* Compiled for: $2, $3, $4 */$N" & "/* Command for C compiler:$n $5 */$N") % @@ -920,7 +933,7 @@ proc getFileHeader(cfile: Cfile): Rope = proc genFilenames(m: BModule): Rope = discard cgsym(m, "dbgRegisterFilename") result = nil - for i in 0.. <fileInfos.len: + for i in 0..<fileInfos.len: result.addf("dbgRegisterFilename($1);$N", [fileInfos[i].projPath.makeCString]) proc genMainProc(m: BModule) = @@ -1013,10 +1026,9 @@ proc genMainProc(m: BModule) = ComponentConstruct = "void Libc::Component::construct(Libc::Env &env) {$N" & "\tgenodeEnv = &env;$N" & - "\tLibc::with_libc([&] () {$n\t" & + "\tLibc::with_libc([&] () {$N\t" & MainProcs & "\t});$N" & - "\tenv.parent().exit(0);$N" & "}$N$N" var nimMain, otherMain: FormatStr @@ -1154,7 +1166,7 @@ proc genInitCode(m: BModule) = for i, el in pairs(m.extensionLoaders): if el != nil: - let ex = "N_NIMCALL(void, nimLoadProcs$1)(void) {$2}$N$N" % + let ex = "NIM_EXTERNC N_NIMCALL(void, nimLoadProcs$1)(void) {$2}$N$N" % [(i.ord - '0'.ord).rope, el] add(m.s[cfsInitProc], ex) @@ -1246,7 +1258,7 @@ proc resetModule*(m: BModule) = # indicate that this is now cached module # the cache will be invalidated by nullifying gModules - m.fromCache = true + #m.fromCache = true m.g = nil # we keep only the "merge info" information for the module @@ -1293,7 +1305,7 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = proc writeHeader(m: BModule) = var result = ("/* Generated by Nim Compiler v$1 */$N" & - "/* (c) " & CompileDate.substr(0, 3) & " Andreas Rumpf */$N" & + "/* (c) 2017 Andreas Rumpf */$N" & "/* The generated code is subject to the original license. */$N") % [rope(VersionAsString)] @@ -1324,7 +1336,6 @@ proc getCFile(m: BModule): string = proc myOpenCached(graph: ModuleGraph; module: PSym, rd: PRodReader): PPassContext = injectG(graph.config) - assert optSymbolFiles in gGlobalOptions var m = newModule(g, module) readMergeInfo(getCFile(m), m) result = m @@ -1378,7 +1389,7 @@ proc writeModule(m: BModule, pending: bool) = # generate code for the init statements of the module: let cfile = getCFile(m) - if not m.fromCache or optForceFullMake in gGlobalOptions: + if m.rd == nil or optForceFullMake in gGlobalOptions: genInitCode(m) finishTypeDescriptions(m) if sfMainModule in m.module.flags: @@ -1431,6 +1442,10 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode = result = n if b == nil or passes.skipCodegen(n): return var m = BModule(b) + # if the module is cached, we don't regenerate the main proc + # nor the dispatchers? But if the dispatchers changed? + # XXX emit the dispatchers into its own .c file? + if b.rd != nil: return if n != nil: m.initProc.options = initProcOptions(m) genStmts(m.initProc, n) @@ -1453,10 +1468,10 @@ proc cgenWriteModules*(backend: RootRef, config: ConfigRef) = if g.generatedHeader != nil: finishModule(g.generatedHeader) while g.forwardedProcsCounter > 0: for m in cgenModules(g): - if not m.fromCache: + if m.rd == nil: finishModule(m) for m in cgenModules(g): - if m.fromCache: + if m.rd != nil: m.updateCachedModule else: m.writeModule(pending=true) diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index be087095f..0f8fa760e 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -54,7 +54,7 @@ type TCProcSections* = array[TCProcSection, Rope] # represents a generated C proc BModule* = ref TCGen BProc* = ref TCProc - TBlock*{.final.} = object + TBlock* = object id*: int # the ID of the label; positive means that it label*: Rope # generated text for the label # nil if label is not used @@ -64,7 +64,7 @@ type nestedExceptStmts*: int16 # how many except statements is it nested into frameLen*: int16 - TCProc{.final.} = object # represents C proc that is currently generated + TCProc = object # represents C proc that is currently generated prc*: PSym # the Nim proc that this C proc belongs to beforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed threadVarAccessed*: bool # true if the proc already accessed some threadvar @@ -154,7 +154,7 @@ proc includeHeader*(this: BModule; header: string) = proc s*(p: BProc, s: TCProcSection): var Rope {.inline.} = # section in the current block - result = p.blocks[^1].sections[s] + result = p.blocks[p.blocks.len-1].sections[s] proc procSec*(p: BProc, s: TCProcSection): var Rope {.inline.} = # top level proc sections diff --git a/compiler/commands.nim b/compiler/commands.nim index bae1fda38..2d9f76959 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -53,8 +53,8 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; # implementation const - HelpMessage = "Nim Compiler Version $1 (" & CompileDate & ") [$2: $3]\n" & - "Copyright (c) 2006-" & CompileDate.substr(0, 3) & " by Andreas Rumpf\n" + HelpMessage = "Nim Compiler Version $1 [$2: $3]\n" & + "Copyright (c) 2006-2017 by Andreas Rumpf\n" const Usage = slurp"../doc/basicopt.txt".replace("//", "") @@ -261,7 +261,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool = of "assertions", "a": result = contains(gOptions, optAssert) of "deadcodeelim": result = contains(gGlobalOptions, optDeadCodeElim) of "run", "r": result = contains(gGlobalOptions, optRun) - of "symbolfiles": result = contains(gGlobalOptions, optSymbolFiles) + of "symbolfiles": result = gSymbolFiles != disabledSf of "genscript": result = contains(gGlobalOptions, optGenScript) of "threads": result = contains(gGlobalOptions, optThreads) of "taintmode": result = contains(gGlobalOptions, optTaintMode) @@ -343,7 +343,9 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; # keep the old name for compat if pass in {passCmd2, passPP} and not options.gNoNimblePath: expectArg(switch, arg, pass, info) - let path = processPath(arg, info, notRelativeToProj=true) + var path = processPath(arg, info, notRelativeToProj=true) + let nimbleDir = getEnv("NIMBLE_DIR") + if nimbleDir.len > 0 and pass == passPP: path = nimbleDir / "pkgs" nimblePath(path, info) of "nonimblepath", "nobabelpath": expectNoArg(switch, arg, pass, info) @@ -596,7 +598,12 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; expectNoArg(switch, arg, pass, info) helpOnError(pass) of "symbolfiles": - processOnOffSwitchG({optSymbolFiles}, arg, pass, info) + case arg.normalize + of "on": gSymbolFiles = enabledSf + of "off": gSymbolFiles = disabledSf + of "writeonly": gSymbolFiles = writeOnlySf + of "readonly": gSymbolFiles = readOnlySf + else: localError(info, errOnOrOffExpectedButXFound, arg) of "skipcfg": expectNoArg(switch, arg, pass, info) incl(gGlobalOptions, optSkipConfigFile) @@ -609,7 +616,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "skipparentcfg": expectNoArg(switch, arg, pass, info) incl(gGlobalOptions, optSkipParentConfigFiles) - of "genscript": + of "genscript", "gendeps": expectNoArg(switch, arg, pass, info) incl(gGlobalOptions, optGenScript) of "colors": processOnOffSwitchG({optUseColors}, arg, pass, info) @@ -652,6 +659,9 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; gListFullPaths = true of "dynliboverride": dynlibOverride(switch, arg, pass, info) + of "dynliboverrideall": + expectNoArg(switch, arg, pass, info) + gDynlibOverrideAll = true of "cs": # only supported for compatibility. Does nothing. expectArg(switch, arg, pass, info) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 02c31163a..a52214e73 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -109,3 +109,6 @@ proc initDefines*() = defineSymbol("nimGenericInOutFlags") when false: defineSymbol("nimHasOpt") defineSymbol("nimNoArrayToCstringConversion") + defineSymbol("nimNewRoof") + defineSymbol("nimHasRunnableExamples") + defineSymbol("nimNewDot") diff --git a/compiler/depends.nim b/compiler/depends.nim index e8c295a34..2b600c1da 100644 --- a/compiler/depends.nim +++ b/compiler/depends.nim @@ -10,7 +10,7 @@ # This module implements a dependency file generator. import - os, options, ast, astalgo, msgs, ropes, idents, passes, importer + os, options, ast, astalgo, msgs, ropes, idents, passes, modulepaths from modulegraphs import ModuleGraph diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index afa2e5e50..0fdeceba0 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -93,9 +93,7 @@ import intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, - strutils, options, dfa, lowerings - -template hasDestructor(t: PType): bool = tfHasAsgn in t.flags + strutils, options, dfa, lowerings, rodread const InterestingSyms = {skVar, skResult, skLet} @@ -166,18 +164,50 @@ proc isHarmlessVar*(s: PSym; c: Con): bool = template interestingSym(s: PSym): bool = s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ) -proc genSink(t: PType; dest: PNode): PNode = - let op = if t.sink != nil: t.sink else: t.assignment - assert op != nil +proc patchHead(n: PNode) = + if n.kind in nkCallKinds and n[0].kind == nkSym and n.len > 1: + let s = n[0].sym + if s.name.s[0] == '=' and s.name.s in ["=sink", "=", "=destroy"]: + if sfFromGeneric in s.flags: + excl(s.flags, sfFromGeneric) + patchHead(s.getBody) + if n[1].typ.isNil: + # XXX toptree crashes without this workaround. Figure out why. + return + let t = n[1].typ.skipTypes({tyVar, tyGenericInst, tyAlias, tyInferred}) + template patch(op, field) = + if s.name.s == op and field != nil and field != s: + n.sons[0].sym = field + patch "=sink", t.sink + patch "=", t.assignment + patch "=destroy", t.destructor + for x in n: + patchHead(x) + +proc patchHead(s: PSym) = + if sfFromGeneric in s.flags: + patchHead(s.ast[bodyPos]) + +template genOp(opr, opname) = + let op = opr + if op == nil: + globalError(dest.info, "internal error: '" & opname & "' operator not found for type " & typeToString(t)) + elif op.ast[genericParamsPos].kind != nkEmpty: + globalError(dest.info, "internal error: '" & opname & "' operator is generic") + patchHead op result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest)) +proc genSink(t: PType; dest: PNode): PNode = + let t = t.skipTypes({tyGenericInst, tyAlias}) + genOp(if t.sink != nil: t.sink else: t.assignment, "=sink") + proc genCopy(t: PType; dest: PNode): PNode = - assert t.assignment != nil - result = newTree(nkCall, newSymNode(t.assignment), newTree(nkHiddenAddr, dest)) + let t = t.skipTypes({tyGenericInst, tyAlias}) + genOp(t.assignment, "=") proc genDestroy(t: PType; dest: PNode): PNode = - assert t.destructor != nil - result = newTree(nkCall, newSymNode(t.destructor), newTree(nkHiddenAddr, dest)) + let t = t.skipTypes({tyGenericInst, tyAlias}) + genOp(t.destructor, "=destroy") proc addTopVar(c: var Con; v: PNode) = c.topLevelVars.add newTree(nkIdentDefs, v, emptyNode, emptyNode) @@ -189,7 +219,7 @@ template recurse(n, dest) = dest.add p(n[i], c) proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = - if ri.kind in nkCallKinds: + if ri.kind in nkCallKinds+{nkObjConstr}: result = genSink(ri.typ, dest) # watch out and no not transform 'ri' twice if it's a call: let ri2 = copyNode(ri) @@ -253,7 +283,7 @@ proc p(n: PNode; c: var Con): PNode = result = copyNode(n) recurse(n, result) of nkAsgn, nkFastAsgn: - if n[0].kind == nkSym and interestingSym(n[0].sym): + if hasDestructor(n[0].typ): result = moveOrCopy(n[0], n[1], c) else: result = copyNode(n) @@ -266,6 +296,8 @@ proc p(n: PNode; c: var Con): PNode = recurse(n, result) proc injectDestructorCalls*(owner: PSym; n: PNode): PNode = + when defined(nimDebugDestroys): + echo "injecting into ", n var c: Con c.owner = owner c.tmp = newSym(skTemp, getIdent":d", owner, n.info) @@ -291,6 +323,7 @@ proc injectDestructorCalls*(owner: PSym; n: PNode): PNode = result.add body when defined(nimDebugDestroys): - echo "------------------------------------" - echo owner.name.s, " transformed to: " - echo result + if owner.name.s == "main" or true: + echo "------------------------------------" + echo owner.name.s, " transformed to: " + echo result diff --git a/compiler/dfa.nim b/compiler/dfa.nim index ca1849a3c..b648995f4 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -132,7 +132,7 @@ proc gen(c: var Con; n: PNode) # {.noSideEffect.} proc genWhile(c: var Con; n: PNode) = # L1: # cond, tmp - # fjmp tmp, L2 + # fork tmp, L2 # body # jmp L1 # L2: @@ -168,15 +168,13 @@ proc genIf(c: var Con, n: PNode) = var endings: seq[TPosition] = @[] for i in countup(0, len(n) - 1): var it = n.sons[i] + c.gen(it.sons[0]) if it.len == 2: - c.gen(it.sons[0].sons[1]) - var elsePos = c.forkI(it.sons[0].sons[1]) + let elsePos = c.forkI(it.sons[1]) c.gen(it.sons[1]) if i < sonsLen(n)-1: endings.add(c.gotoI(it.sons[1])) c.patch(elsePos) - else: - c.gen(it.sons[0]) for endPos in endings: c.patch(endPos) proc genAndOr(c: var Con; n: PNode) = @@ -202,7 +200,7 @@ proc genCase(c: var Con; n: PNode) = # Lend: var endings: seq[TPosition] = @[] c.gen(n.sons[0]) - for i in 1 .. <n.len: + for i in 1 ..< n.len: let it = n.sons[i] if it.len == 1: c.gen(it.sons[0]) @@ -219,7 +217,7 @@ proc genTry(c: var Con; n: PNode) = let elsePos = c.forkI(n) c.gen(n.sons[0]) c.patch(elsePos) - for i in 1 .. <n.len: + for i in 1 ..< n.len: let it = n.sons[i] if it.kind != nkFinally: var blen = len(it) @@ -337,100 +335,107 @@ proc gen(c: var Con; n: PNode) = else: discard proc dfa(code: seq[Instr]) = - # We aggressively push 'undef' values for every 'use v' instruction - # until they are eliminated via a 'def v' instructions. - # If we manage to push one 'undef' to a 'use' instruction, we produce - # an error: - var undef = initIntSet() + var u = newSeq[IntSet](code.len) # usages + var d = newSeq[IntSet](code.len) # defs + var c = newSeq[IntSet](code.len) # consumed + var backrefs = initTable[int, int]() for i in 0..<code.len: - if code[i].kind == use: undef.incl(code[i].sym.id) + u[i] = initIntSet() + d[i] = initIntSet() + c[i] = initIntSet() + case code[i].kind + of use, useWithinCall: u[i].incl(code[i].sym.id) + of def: d[i].incl(code[i].sym.id) + of fork, goto: + let d = i+code[i].dest + backrefs.add(d, i) - var s = newSeq[IntSet](code.len) - for i in 0..<code.len: - assign(s[i], undef) - - # In the original paper, W := {0,...,n} is done. This is wasteful, we - # have no intention to analyse a program like - # - # return 3 - # echo a + b - # - # any further than necessary. var w = @[0] - while w.len > 0: - var pc = w[^1] + var maxIters = 50 + var someChange = true + var takenGotos = initIntSet() + var consuming = -1 + while w.len > 0 and maxIters > 0: # and someChange: + dec maxIters + var pc = w.pop() # w[^1] + var prevPc = -1 # this simulates a single linear control flow execution: - while true: - # according to the paper, it is better to shrink the working set here - # in this inner loop: - let widx = w.find(pc) - if widx >= 0: w.del(widx) + while pc < code.len: + if prevPc >= 0: + someChange = false + # merge step and test for changes (we compute the fixpoints here): + # 'u' needs to be the union of prevPc, pc + # 'd' needs to be the intersection of 'pc' + for id in u[prevPc]: + if not u[pc].containsOrIncl(id): + someChange = true + # in (a; b) if ``a`` sets ``v`` so does ``b``. The intersection + # is only interesting on merge points: + for id in d[prevPc]: + if not d[pc].containsOrIncl(id): + someChange = true + # if this is a merge point, we take the intersection of the 'd' sets: + if backrefs.hasKey(pc): + var intersect = initIntSet() + assign(intersect, d[pc]) + var first = true + for prevPc in backrefs.allValues(pc): + for def in d[pc]: + if def notin d[prevPc]: + excl(intersect, def) + someChange = true + when defined(debugDfa): + echo "Excluding ", pc, " prev ", prevPc + assign d[pc], intersect + if consuming >= 0: + if not c[pc].containsOrIncl(consuming): + someChange = true + consuming = -1 + # our interpretation ![I!]: - var sid = -1 + prevPc = pc case code[pc].kind - of goto, fork: discard + of goto: + # we must leave endless loops eventually: + if not takenGotos.containsOrIncl(pc) or someChange: + pc = pc + code[pc].dest + else: + inc pc + of fork: + # we follow the next instruction but push the dest onto our "work" stack: + #if someChange: + w.add pc + code[pc].dest + inc pc of use, useWithinCall: - let sym = code[pc].sym - if s[pc].contains(sym.id): - localError(code[pc].n.info, "variable read before initialized: " & sym.name.s) - of def: - sid = code[pc].sym.id - - var pc2: int - if code[pc].kind == goto: - pc2 = pc + code[pc].dest - else: - pc2 = pc + 1 - if code[pc].kind == fork: - let l = pc + code[pc].dest - if sid >= 0 and s[l].missingOrExcl(sid): - w.add l - - if sid >= 0 and s[pc2].missingOrExcl(sid): - pc = pc2 - else: - break - if pc >= code.len: break - - when false: - case code[pc].kind - of use: - let s = code[pc].sym - if undefB.contains(s.id): - localError(code[pc].n.info, "variable read before initialized: " & s.name.s) - break + #if not d[prevPc].missingOrExcl(): + # someChange = true + consuming = code[pc].sym.id inc pc of def: - let s = code[pc].sym - # exclude 'undef' for s for this path through the graph. - if not undefB.missingOrExcl(s.id): - inc pc - else: - break - #undefB.excl s.id - #inc pc - when false: - let prev = bindings.getOrDefault(s.id) - if prev != value: - # well now it has a value and we made progress, so - bindings[s.id] = value - inc pc - else: - break - of fork: - let diff = code[pc].dest - # we follow pc + 1 and remember the label for later: - w.add pc+diff + if not d[pc].containsOrIncl(code[pc].sym.id): + someChange = true inc pc - of goto: - let diff = code[pc].dest - pc = pc + diff - if pc >= code.len: break + + when defined(useDfa) and defined(debugDfa): + for i in 0..<code.len: + echo "PC ", i, ": defs: ", d[i], "; uses ", u[i], "; consumes ", c[i] + + # now check the condition we're interested in: + for i in 0..<code.len: + case code[i].kind + of use, useWithinCall: + let s = code[i].sym + if s.id notin d[i]: + localError(code[i].n.info, "usage of uninitialized variable: " & s.name.s) + if s.id in c[i]: + localError(code[i].n.info, "usage of an already consumed variable: " & s.name.s) + + else: discard proc dataflowAnalysis*(s: PSym; body: PNode) = var c = Con(code: @[], blocks: @[]) gen(c, body) - #echoCfg(c.code) + when defined(useDfa) and defined(debugDfa): echoCfg(c.code) dfa(c.code) proc constructCfg*(s: PSym; body: PNode): ControlFlowGraph = diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 8c50a4f1d..65dcb73c9 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -15,14 +15,13 @@ import ast, strutils, strtabs, options, msgs, os, ropes, idents, wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast, packages/docutils/rst, packages/docutils/rstgen, times, - packages/docutils/highlite, importer, sempass2, json, xmltree, cgi, - typesrenderer, astalgo + packages/docutils/highlite, sempass2, json, xmltree, cgi, + typesrenderer, astalgo, modulepaths type TSections = array[TSymKind, Rope] TDocumentor = object of rstgen.RstGenerator modDesc: Rope # module description - id: int # for generating IDs toc, section: TSections indexValFilename: string analytics: string # Google Analytics javascript, "" if doesn't exist @@ -109,6 +108,8 @@ proc newDocumentor*(filename: string, config: StringTableRef): PDoc = result.id = 100 result.jArray = newJArray() initStrTable result.types + result.onTestSnippet = proc (d: var RstGenerator; filename, cmd: string; status: int; content: string) = + localError(newLineInfo(d.filename, -1, -1), warnUser, "only 'rst2html' supports the ':test:' attribute") proc dispA(dest: var Rope, xml, tex: string, args: openArray[Rope]) = if gCmd != cmdRst2tex: addf(dest, xml, args) @@ -204,10 +205,87 @@ proc getPlainDocstring(n: PNode): string = if n.comment != nil and startsWith(n.comment, "##"): result = n.comment if result.len < 1: - if n.kind notin {nkEmpty..nkNilLit}: - for i in countup(0, len(n)-1): - result = getPlainDocstring(n.sons[i]) - if result.len > 0: return + for i in countup(0, safeLen(n)-1): + result = getPlainDocstring(n.sons[i]) + if result.len > 0: return + +proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRenderFlags = {}) = + var r: TSrcGen + var literal = "" + initTokRender(r, n, renderFlags) + var kind = tkEof + while true: + getNextTok(r, kind, literal) + case kind + of tkEof: + break + of tkComment: + dispA(result, "<span class=\"Comment\">$1</span>", "\\spanComment{$1}", + [rope(esc(d.target, literal))]) + of tokKeywordLow..tokKeywordHigh: + dispA(result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}", + [rope(literal)]) + of tkOpr: + dispA(result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}", + [rope(esc(d.target, literal))]) + of tkStrLit..tkTripleStrLit: + dispA(result, "<span class=\"StringLit\">$1</span>", + "\\spanStringLit{$1}", [rope(esc(d.target, literal))]) + of tkCharLit: + dispA(result, "<span class=\"CharLit\">$1</span>", "\\spanCharLit{$1}", + [rope(esc(d.target, literal))]) + of tkIntLit..tkUInt64Lit: + dispA(result, "<span class=\"DecNumber\">$1</span>", + "\\spanDecNumber{$1}", [rope(esc(d.target, literal))]) + of tkFloatLit..tkFloat128Lit: + dispA(result, "<span class=\"FloatNumber\">$1</span>", + "\\spanFloatNumber{$1}", [rope(esc(d.target, literal))]) + of tkSymbol: + dispA(result, "<span class=\"Identifier\">$1</span>", + "\\spanIdentifier{$1}", [rope(esc(d.target, literal))]) + of tkSpaces, tkInvalid: + add(result, literal) + of tkCurlyDotLe: + dispA(result, """<span class="Other pragmabegin">$1</span><div class="pragma">""", + "\\spanOther{$1}", + [rope(esc(d.target, literal))]) + of tkCurlyDotRi: + dispA(result, "</div><span class=\"Other pragmaend\">$1</span>", + "\\spanOther{$1}", + [rope(esc(d.target, literal))]) + of tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi, + tkBracketDotLe, tkBracketDotRi, tkParDotLe, + tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot, + tkAccent, tkColonColon, + tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr: + dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}", + [rope(esc(d.target, literal))]) + +proc getAllRunnableExamples(d: PDoc; n: PNode; dest: var Rope) = + case n.kind + of nkCallKinds: + if n[0].kind == nkSym and n[0].sym.magic == mRunnableExamples and + n.len >= 2 and n.lastSon.kind == nkStmtList: + dispA(dest, "\n<strong class=\"examples_text\">$1</strong>\n", + "\n\\textbf{$1}\n", [rope"Examples:"]) + inc d.listingCounter + let id = $d.listingCounter + dest.add(d.config.getOrDefault"doc.listing_start" % [id, "langNim"]) + # this is a rather hacky way to get rid of the initial indentation + # that the renderer currently produces: + var i = 0 + var body = n.lastSon + if body.len == 1 and body.kind == nkStmtList and + body.lastSon.kind == nkStmtList: + body = body.lastSon + for b in body: + if i > 0: dest.add "\n" + inc i + nodeToHighlightedHtml(d, b, dest, {}) + dest.add(d.config.getOrDefault"doc.listing_end" % id) + else: discard + for i in 0 ..< n.safeLen: + getAllRunnableExamples(d, n[i], dest) when false: proc findDocComment(n: PNode): PNode = @@ -252,7 +330,7 @@ proc getName(d: PDoc, n: PNode, splitAfter = -1): string = of nkIdent: result = esc(d.target, n.ident.s, splitAfter) of nkAccQuoted: result = esc(d.target, "`") - for i in 0.. <n.len: result.add(getName(d, n[i], splitAfter)) + for i in 0..<n.len: result.add(getName(d, n[i], splitAfter)) result.add esc(d.target, "`") of nkOpenSymChoice, nkClosedSymChoice: result = getName(d, n[0], splitAfter) @@ -268,7 +346,7 @@ proc getNameIdent(n: PNode): PIdent = of nkIdent: result = n.ident of nkAccQuoted: var r = "" - for i in 0.. <n.len: r.add(getNameIdent(n[i]).s) + for i in 0..<n.len: r.add(getNameIdent(n[i]).s) result = getIdent(r) of nkOpenSymChoice, nkClosedSymChoice: result = getNameIdent(n[0]) @@ -283,7 +361,7 @@ proc getRstName(n: PNode): PRstNode = of nkIdent: result = newRstNode(rnLeaf, n.ident.s) of nkAccQuoted: result = getRstName(n.sons[0]) - for i in 1 .. <n.len: result.text.add(getRstName(n[i]).text) + for i in 1 ..< n.len: result.text.add(getRstName(n[i]).text) of nkOpenSymChoice, nkClosedSymChoice: result = getRstName(n[0]) else: @@ -379,11 +457,12 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = let name = getName(d, nameNode) nameRope = name.rope - plainDocstring = getPlainDocstring(n) # call here before genRecComment! + var plainDocstring = getPlainDocstring(n) # call here before genRecComment! var result: Rope = nil var literal, plainName = "" var kind = tkEof var comm = genRecComment(d, n) # call this here for the side-effect! + getAllRunnableExamples(d, n, comm) var r: TSrcGen # Obtain the plain rendered string for hyperlink titles. initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments, @@ -395,53 +474,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = plainName.add(literal) # Render the HTML hyperlink. - initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments}) - while true: - getNextTok(r, kind, literal) - case kind - of tkEof: - break - of tkComment: - dispA(result, "<span class=\"Comment\">$1</span>", "\\spanComment{$1}", - [rope(esc(d.target, literal))]) - of tokKeywordLow..tokKeywordHigh: - dispA(result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}", - [rope(literal)]) - of tkOpr: - dispA(result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}", - [rope(esc(d.target, literal))]) - of tkStrLit..tkTripleStrLit: - dispA(result, "<span class=\"StringLit\">$1</span>", - "\\spanStringLit{$1}", [rope(esc(d.target, literal))]) - of tkCharLit: - dispA(result, "<span class=\"CharLit\">$1</span>", "\\spanCharLit{$1}", - [rope(esc(d.target, literal))]) - of tkIntLit..tkUInt64Lit: - dispA(result, "<span class=\"DecNumber\">$1</span>", - "\\spanDecNumber{$1}", [rope(esc(d.target, literal))]) - of tkFloatLit..tkFloat128Lit: - dispA(result, "<span class=\"FloatNumber\">$1</span>", - "\\spanFloatNumber{$1}", [rope(esc(d.target, literal))]) - of tkSymbol: - dispA(result, "<span class=\"Identifier\">$1</span>", - "\\spanIdentifier{$1}", [rope(esc(d.target, literal))]) - of tkSpaces, tkInvalid: - add(result, literal) - of tkCurlyDotLe: - dispA(result, """<span class="Other pragmabegin">$1</span><div class="pragma">""", - "\\spanOther{$1}", - [rope(esc(d.target, literal))]) - of tkCurlyDotRi: - dispA(result, "</div><span class=\"Other pragmaend\">$1</span>", - "\\spanOther{$1}", - [rope(esc(d.target, literal))]) - of tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi, - tkBracketDotLe, tkBracketDotRi, tkParDotLe, - tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot, - tkAccent, tkColonColon, - tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr: - dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}", - [rope(esc(d.target, literal))]) + nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments, renderDocComments}) inc(d.id) let @@ -520,12 +553,24 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonNode = proc checkForFalse(n: PNode): bool = result = n.kind == nkIdent and cmpIgnoreStyle(n.ident.s, "false") == 0 -proc traceDeps(d: PDoc, n: PNode) = +proc traceDeps(d: PDoc, it: PNode) = const k = skModule - if d.section[k] != nil: add(d.section[k], ", ") - dispA(d.section[k], - "<a class=\"reference external\" href=\"$1.html\">$1</a>", - "$1", [rope(getModuleName(n))]) + + if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket: + let sep = it[0] + let dir = it[1] + let a = newNodeI(nkInfix, it.info) + a.add sep + a.add dir + a.add sep # dummy entry, replaced in the loop + for x in it[2]: + a.sons[2] = x + traceDeps(d, a) + else: + if d.section[k] != nil: add(d.section[k], ", ") + dispA(d.section[k], + "<a class=\"reference external\" href=\"$1.html\">$1</a>", + "$1", [rope(getModuleName(it))]) proc generateDoc*(d: PDoc, n: PNode) = case n.kind @@ -608,6 +653,49 @@ proc generateJson*(d: PDoc, n: PNode) = generateJson(d, lastSon(n.sons[0])) else: discard +proc genTagsItem(d: PDoc, n, nameNode: PNode, k: TSymKind): string = + result = getName(d, nameNode) & "\n" + +proc generateTags*(d: PDoc, n: PNode, r: var Rope) = + case n.kind + of nkCommentStmt: + if n.comment != nil and startsWith(n.comment, "##"): + let stripped = n.comment.substr(2).strip + r.add stripped + of nkProcDef: + when useEffectSystem: documentRaises(n) + r.add genTagsItem(d, n, n.sons[namePos], skProc) + of nkFuncDef: + when useEffectSystem: documentRaises(n) + r.add genTagsItem(d, n, n.sons[namePos], skFunc) + of nkMethodDef: + when useEffectSystem: documentRaises(n) + r.add genTagsItem(d, n, n.sons[namePos], skMethod) + of nkIteratorDef: + when useEffectSystem: documentRaises(n) + r.add genTagsItem(d, n, n.sons[namePos], skIterator) + of nkMacroDef: + r.add genTagsItem(d, n, n.sons[namePos], skMacro) + of nkTemplateDef: + r.add genTagsItem(d, n, n.sons[namePos], skTemplate) + of nkConverterDef: + when useEffectSystem: documentRaises(n) + r.add genTagsItem(d, n, n.sons[namePos], skConverter) + of nkTypeSection, nkVarSection, nkLetSection, nkConstSection: + for i in countup(0, sonsLen(n) - 1): + if n.sons[i].kind != nkCommentStmt: + # order is always 'type var let const': + r.add genTagsItem(d, n.sons[i], n.sons[i].sons[0], + succ(skType, ord(n.kind)-ord(nkTypeSection))) + of nkStmtList: + for i in countup(0, sonsLen(n) - 1): + generateTags(d, n.sons[i], r) + of nkWhenStmt: + # generate documentation for the first branch only: + if not checkForFalse(n.sons[0].sons[0]): + generateTags(d, lastSon(n.sons[0]), r) + else: discard + proc genSection(d: PDoc, kind: TSymKind) = const sectionNames: array[skModule..skTemplate, string] = [ "Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Funcs", @@ -712,6 +800,26 @@ proc commandDoc*() = proc commandRstAux(filename, outExt: string) = var filen = addFileExt(filename, "txt") var d = newDocumentor(filen, options.gConfigVars) + d.onTestSnippet = proc (d: var RstGenerator; filename, cmd: string; + status: int; content: string) = + var outp: string + if filename.len == 0: + inc(d.id) + let nameOnly = splitFile(d.filename).name + let subdir = getNimcacheDir() / nameOnly + createDir(subdir) + outp = subdir / (nameOnly & "_snippet_" & $d.id & ".nim") + elif isAbsolute(filename): + outp = filename + else: + # Nim's convention: every path is relative to the file it was written in: + outp = splitFile(d.filename).dir / filename + writeFile(outp, content) + let cmd = unescape(cmd) % quoteShell(outp) + rawMessage(hintExecuting, cmd) + if execShellCmd(cmd) != status: + rawMessage(errExecutionOfProgramFailed, cmd) + d.isPureRst = true var rst = parseRst(readFile(filen), filen, 0, 1, d.hasToc, {roSupportRawDirective}) @@ -745,6 +853,21 @@ proc commandJson*() = #echo getOutFile(gProjectFull, JsonExt) writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false) +proc commandTags*() = + var ast = parseFile(gProjectMainIdx, newIdentCache()) + if ast == nil: return + var d = newDocumentor(gProjectFull, options.gConfigVars) + d.hasToc = true + var + content: Rope + generateTags(d, ast, content) + + if optStdout in gGlobalOptions: + writeRope(stdout, content) + else: + #echo getOutFile(gProjectFull, TagsExt) + writeRope(content, getOutFile(gProjectFull, TagsExt), useWarning = false) + proc commandBuildIndex*() = var content = mergeIndexes(gProjectFull).rope diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index 6789df87d..51b65258b 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -225,7 +225,7 @@ proc pack(v: PNode, typ: PType, res: pointer) = awr(pointer, res +! sizeof(pointer)) of tyArray: let baseSize = typ.sons[1].getSize - for i in 0 .. <v.len: + for i in 0 ..< v.len: pack(v.sons[i], typ.sons[1], res +! i * baseSize) of tyObject, tyTuple: packObject(v, typ, res) @@ -291,7 +291,7 @@ proc unpackArray(x: pointer, typ: PType, n: PNode): PNode = if result.kind != nkBracket: globalError(n.info, "cannot map value from FFI") let baseSize = typ.sons[1].getSize - for i in 0 .. < result.len: + for i in 0 ..< result.len: result.sons[i] = unpack(x +! i * baseSize, typ.sons[1], result.sons[i]) proc canonNodeKind(k: TNodeKind): TNodeKind = diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index f088afcdb..704ff819c 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -42,7 +42,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam: handleParam actual.sons[s.owner.typ.len + s.position - 1] else: - internalAssert sfGenSym in s.flags + internalAssert sfGenSym in s.flags or s.kind == skType var x = PSym(idTableGet(c.mapping, s)) if x == nil: x = copySym(s, false) @@ -77,7 +77,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode = # now that we have working untyped parameters. genericParams = if sfImmediate in s.flags or fromHlo: 0 else: s.ast[genericParamsPos].len - expectedRegularParams = <s.typ.len + expectedRegularParams = s.typ.len-1 givenRegularParams = totalParams - genericParams if givenRegularParams < 0: givenRegularParams = 0 @@ -109,7 +109,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode = var evalTemplateCounter* = 0 # to prevent endless recursion in templates instantiation -proc wrapInComesFrom*(info: TLineInfo; res: PNode): PNode = +proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode = when true: result = res result.info = info @@ -124,8 +124,12 @@ proc wrapInComesFrom*(info: TLineInfo; res: PNode): PNode = if x[i].kind in nkCallKinds: x.sons[i].info = info else: - result = newNodeI(nkPar, info) + result = newNodeI(nkStmtListExpr, info) + var d = newNodeI(nkComesFrom, info) + d.add newSymNode(sym, info) + result.add d result.add res + result.typ = res.typ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode = inc(evalTemplateCounter) @@ -156,6 +160,6 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode = for i in countup(0, safeLen(body) - 1): evalTemplateAux(body.sons[i], args, ctx, result) result.flags.incl nfFromTemplate - result = wrapInComesFrom(n.info, result) + result = wrapInComesFrom(n.info, tmpl, result) dec(evalTemplateCounter) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 4614eafe6..62990593d 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -21,7 +21,7 @@ import type TSystemCC* = enum ccNone, ccGcc, ccLLVM_Gcc, ccCLang, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc, - ccTcc, ccPcc, ccUcc, ccIcl + ccTcc, ccPcc, ccUcc, ccIcl, ccIcc TInfoCCProp* = enum # properties of the C compiler: hasSwitchRange, # CC allows ranges in switch statements (GNU C) hasComputedGoto, # CC has computed goto (GNU C extension) @@ -95,7 +95,11 @@ compiler llvmGcc: result.name = "llvm_gcc" result.compilerExe = "llvm-gcc" result.cppCompiler = "llvm-g++" - result.buildLib = "llvm-ar rcs $libfile $objfiles" + when defined(macosx): + # OS X has no 'llvm-ar' tool: + result.buildLib = "ar rcs $libfile $objfiles" + else: + result.buildLib = "llvm-ar rcs $libfile $objfiles" # Clang (LLVM) C/C++ Compiler compiler clang: @@ -131,16 +135,18 @@ compiler vcc: # Intel C/C++ Compiler compiler icl: - # Intel compilers try to imitate the native ones (gcc and msvc) - when defined(windows): - result = vcc() - else: - result = gcc() - + result = vcc() result.name = "icl" result.compilerExe = "icl" result.linkerExe = "icl" +# Intel compilers try to imitate the native ones (gcc and msvc) +compiler icc: + result = gcc() + result.name = "icc" + result.compilerExe = "icc" + result.linkerExe = "icc" + # Local C Compiler compiler lcc: result = ( @@ -247,7 +253,7 @@ compiler tcc: compilerExe: "tcc", cppCompiler: "", compileTmpl: "-c $options $include -o $objfile $file", - buildGui: "UNAVAILABLE!", + buildGui: "-Wl,-subsystem=gui", buildDll: " -shared", buildLib: "", # XXX: not supported yet linkerExe: "tcc", @@ -323,7 +329,8 @@ const tcc(), pcc(), ucc(), - icl()] + icl(), + icc()] hExt* = ".h" @@ -724,13 +731,13 @@ proc execCmdsInParallel(cmds: seq[string]; prettyCb: proc (idx: int)) = else: tryExceptOSErrorMessage("invocation of external compiler program failed."): if optListCmd in gGlobalOptions or gVerbosity > 1: - res = execProcesses(cmds, {poEchoCmd, poStdErrToStdOut, poUsePath, poParentStreams}, + res = execProcesses(cmds, {poEchoCmd, poStdErrToStdOut, poUsePath}, gNumberOfProcessors, afterRunEvent=runCb) elif gVerbosity == 1: - res = execProcesses(cmds, {poStdErrToStdOut, poUsePath, poParentStreams}, + res = execProcesses(cmds, {poStdErrToStdOut, poUsePath}, gNumberOfProcessors, prettyCb, afterRunEvent=runCb) else: - res = execProcesses(cmds, {poStdErrToStdOut, poUsePath, poParentStreams}, + res = execProcesses(cmds, {poStdErrToStdOut, poUsePath}, gNumberOfProcessors, afterRunEvent=runCb) if res != 0: if gNumberOfProcessors <= 1: @@ -760,8 +767,9 @@ proc callCCompiler*(projectfile: string) = add(objfiles, quoteShell( addFileExt(objFile, CC[cCompiler].objExt))) for x in toCompile: + let objFile = if noAbsolutePaths(): x.obj.extractFilename else: x.obj add(objfiles, ' ') - add(objfiles, quoteShell(x.obj)) + add(objfiles, quoteShell(objFile)) linkCmd = getLinkCmd(projectfile, objfiles) if optCompileOnly notin gGlobalOptions: @@ -786,42 +794,40 @@ proc writeJsonBuildInstructions*(projectfile: string) = else: f.write escapeJson(x) - proc cfiles(f: File; buf: var string; list: CfileList, isExternal: bool) = - var i = 0 - for it in list: + proc cfiles(f: File; buf: var string; clist: CfileList, isExternal: bool) = + var pastStart = false + for it in clist: if CfileFlag.Cached in it.flags: continue let compileCmd = getCompileCFileCmd(it) + if pastStart: lit "],\L" lit "[" str it.cname lit ", " str compileCmd - inc i - if i == list.len: - lit "]\L" - else: - lit "],\L" - - proc linkfiles(f: File; buf, objfiles: var string) = - for i, it in externalToLink: - let - objFile = if noAbsolutePaths(): it.extractFilename else: it - objStr = addFileExt(objFile, CC[cCompiler].objExt) + pastStart = true + lit "]\L" + + proc linkfiles(f: File; buf, objfiles: var string; clist: CfileList; + llist: seq[string]) = + var pastStart = false + for it in llist: + let objfile = if noAbsolutePaths(): it.extractFilename + else: it + let objstr = addFileExt(objfile, CC[cCompiler].objExt) add(objfiles, ' ') - add(objfiles, objStr) - str objStr - if toCompile.len == 0 and i == externalToLink.high: - lit "\L" - else: - lit ",\L" - for i, x in toCompile: - let objStr = quoteShell(x.obj) + add(objfiles, objstr) + if pastStart: lit ",\L" + str objstr + pastStart = true + + for it in clist: + let objstr = quoteShell(it.obj) add(objfiles, ' ') - add(objfiles, objStr) - str objStr - if i == toCompile.high: - lit "\L" - else: - lit ",\L" + add(objfiles, objstr) + if pastStart: lit ",\L" + str objstr + pastStart = true + lit "\L" var buf = newStringOfCap(50) @@ -835,7 +841,7 @@ proc writeJsonBuildInstructions*(projectfile: string) = lit "],\L\"link\":[\L" var objfiles = "" # XXX add every file here that is to link - linkfiles(f, buf, objfiles) + linkfiles(f, buf, objfiles, toCompile, externalToLink) lit "],\L\"linkcmd\": " str getLinkCmd(projectfile, objfiles) diff --git a/compiler/forloops.nim b/compiler/forloops.nim index 5074d79d5..2cd1db7f7 100644 --- a/compiler/forloops.nim +++ b/compiler/forloops.nim @@ -45,13 +45,13 @@ proc counterInTree(n, loop: PNode; counter: PSym): bool = for it in n: if counterInTree(it.lastSon): return true else: - for i in 0 .. <safeLen(n): + for i in 0 ..< safeLen(n): if counterInTree(n[i], loop, counter): return true proc copyExcept(n: PNode, x, dest: PNode) = if x == n: return if n.kind in {nkStmtList, nkStmtListExpr}: - for i in 0 .. <n.len: copyExcept(n[i], x, dest) + for i in 0 ..< n.len: copyExcept(n[i], x, dest) else: dest.add n diff --git a/compiler/gorgeimpl.nim b/compiler/gorgeimpl.nim index 4e1ce6d50..2c51752cd 100644 --- a/compiler/gorgeimpl.nim +++ b/compiler/gorgeimpl.nim @@ -7,8 +7,7 @@ # distribution, for details about the copyright. # -## Module that implements ``gorge`` for the compiler as well as -## the scriptable import mechanism. +## Module that implements ``gorge`` for the compiler. import msgs, securehash, os, osproc, streams, strutils, options @@ -56,28 +55,3 @@ proc opGorge*(cmd, input, cache: string, info: TLineInfo): (string, int) = result = p.readOutput except IOError, OSError: result = ("", -1) - -proc scriptableImport*(pkg, subdir: string; info: TLineInfo): string = - var cmd = getConfigVar("resolver.exe") - if cmd.len == 0: cmd = "nimresolve" - else: cmd = quoteShell(cmd) - cmd.add " --source:" - cmd.add quoteShell(info.toFullPath()) - cmd.add " --stdlib:" - cmd.add quoteShell(options.libpath) - cmd.add " --project:" - cmd.add quoteShell(gProjectFull) - if subdir.len != 0: - cmd.add " --subdir:" - cmd.add quoteShell(subdir) - if options.gNoNimblePath: - cmd.add " --nonimblepath" - cmd.add ' ' - cmd.add quoteShell(pkg) - let (res, exitCode) = opGorge(cmd, "", cmd, info) - if exitCode == 0: - result = res.strip() - elif res.len > 0: - localError(info, res) - else: - localError(info, "cannot resolve: " & (pkg / subdir)) diff --git a/compiler/guards.nim b/compiler/guards.nim index df32cf98c..a5e6058c9 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -52,7 +52,7 @@ proc isLet(n: PNode): bool = proc isVar(n: PNode): bool = n.kind == nkSym and n.sym.kind in {skResult, skVar} and - {sfGlobal, sfAddrTaken} * n.sym.flags == {} + {sfAddrTaken} * n.sym.flags == {} proc isLetLocation(m: PNode, isApprox: bool): bool = # consider: 'n[].kind' --> we really need to support 1 deref op even if this @@ -247,7 +247,7 @@ proc canon*(n: PNode): PNode = # XXX for now only the new code in 'semparallel' uses this if n.safeLen >= 1: result = shallowCopy(n) - for i in 0 .. < n.len: + for i in 0 ..< n.len: result.sons[i] = canon(n.sons[i]) elif n.kind == nkSym and n.sym.kind == skLet and n.sym.ast.getMagic in (someEq + someAdd + someMul + someMin + @@ -768,8 +768,10 @@ macro `=~`(x: PNode, pat: untyped): bool = var conds = newTree(nnkBracket) m(x, pat, conds) - result = nestList(!"and", conds) - + when declared(macros.toNimIdent): + result = nestList(toNimIdent"and", conds) + else: + result = nestList(!"and", conds) proc isMinusOne(n: PNode): bool = n.kind in {nkCharLit..nkUInt64Lit} and n.intVal == -1 diff --git a/compiler/hlo.nim b/compiler/hlo.nim index 9491eef83..2bffaa173 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -36,7 +36,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode = # we apply the last pattern first, so that pattern overriding is possible; # however the resulting AST would better not trigger the old rule then # anymore ;-) - for i in countdown(<c.patterns.len, 0): + for i in countdown(c.patterns.len-1, 0): let pattern = c.patterns[i] if not isNil(pattern): let x = applyRule(c, pattern, result) @@ -75,7 +75,7 @@ proc hlo(c: PContext, n: PNode): PNode = result = applyPatterns(c, n) if result == n: # no optimization applied, try subtrees: - for i in 0 .. < safeLen(result): + for i in 0 ..< safeLen(result): let a = result.sons[i] let h = hlo(c, a) if h != a: result.sons[i] = h diff --git a/compiler/importer.nim b/compiler/importer.nim index 07f42a147..46d675b27 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -11,83 +11,11 @@ import intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups, - semdata, passes, renderer, gorgeimpl + semdata, passes, renderer, modulepaths proc evalImport*(c: PContext, n: PNode): PNode proc evalFrom*(c: PContext, n: PNode): PNode -proc lookupPackage(pkg, subdir: PNode): string = - let sub = if subdir != nil: renderTree(subdir, {renderNoComments}).replace(" ") else: "" - case pkg.kind - of nkStrLit, nkRStrLit, nkTripleStrLit: - result = scriptableImport(pkg.strVal, sub, pkg.info) - of nkIdent: - result = scriptableImport(pkg.ident.s, sub, pkg.info) - else: - localError(pkg.info, "package name must be an identifier or string literal") - result = "" - -proc getModuleName*(n: PNode): string = - # This returns a short relative module name without the nim extension - # e.g. like "system", "importer" or "somepath/module" - # The proc won't perform any checks that the path is actually valid - case n.kind - of nkStrLit, nkRStrLit, nkTripleStrLit: - try: - result = pathSubs(n.strVal, n.info.toFullPath().splitFile().dir) - except ValueError: - localError(n.info, "invalid path: " & n.strVal) - result = n.strVal - of nkIdent: - result = n.ident.s - of nkSym: - result = n.sym.name.s - of nkInfix: - let n0 = n[0] - let n1 = n[1] - if n0.kind == nkIdent and n0.ident.id == getIdent("as").id: - # XXX hack ahead: - n.kind = nkImportAs - n.sons[0] = n.sons[1] - n.sons[1] = n.sons[2] - n.sons.setLen(2) - return getModuleName(n.sons[0]) - if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$": - if n0.kind == nkIdent and n0.ident.s == "/": - result = lookupPackage(n1[1], n[2]) - else: - localError(n.info, "only '/' supported with $package notation") - result = "" - else: - # hacky way to implement 'x / y /../ z': - result = getModuleName(n1) - result.add renderTree(n0, {renderNoComments}) - result.add getModuleName(n[2]) - of nkPrefix: - if n.sons[0].kind == nkIdent and n.sons[0].ident.s == "$": - result = lookupPackage(n[1], nil) - else: - # hacky way to implement 'x / y /../ z': - result = renderTree(n, {renderNoComments}).replace(" ") - of nkDotExpr: - result = renderTree(n, {renderNoComments}).replace(".", "/") - of nkImportAs: - result = getModuleName(n.sons[0]) - else: - localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree) - result = "" - -proc checkModuleName*(n: PNode; doLocalError=true): int32 = - # This returns the full canonical path for a given module import - let modulename = n.getModuleName - let fullPath = findModule(modulename, n.info.toFullPath) - if fullPath.len == 0: - if doLocalError: - localError(n.info, errCannotOpenFile, modulename) - result = InvalidFileIDX - else: - result = fullPath.fileInfoIdx - proc importPureEnumField*(c: PContext; s: PSym) = var check = strTableGet(c.importTable.symbols, s.name) if check == nil: @@ -99,7 +27,7 @@ proc rawImportSymbol(c: PContext, s: PSym) = # check if we have already a symbol of the same name: var check = strTableGet(c.importTable.symbols, s.name) if check != nil and check.id != s.id: - if s.kind notin OverloadableSyms: + if s.kind notin OverloadableSyms or check.kind notin OverloadableSyms: # s and check need to be qualified: incl(c.ambiguousSymbols, s.id) incl(c.ambiguousSymbols, check.id) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 7b1c43817..dac2de746 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -191,11 +191,12 @@ proc mapType(typ: PType): TJSTypeKind = of tyObject, tyArray, tyTuple, tyOpenArray, tyVarargs: result = etyObject of tyNil: result = etyNull - of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvocation, + of tyGenericParam, tyGenericBody, tyGenericInvocation, tyNone, tyFromExpr, tyForward, tyEmpty, - tyExpr, tyStmt, tyTypeDesc, tyTypeClasses, tyVoid, tyAlias: + tyExpr, tyStmt, tyTypeDesc, tyBuiltInTypeClass, tyCompositeTypeClass, + tyAnd, tyOr, tyNot, tyAnything, tyVoid: result = etyNone - of tyInferred: + of tyGenericInst, tyInferred, tyAlias, tyUserTypeClass, tyUserTypeClassInst: result = mapType(typ.lastSon) of tyStatic: if t.n != nil: result = mapType(lastSon t) @@ -376,8 +377,8 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # AddI ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI ["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI - ["divInt", "", "divInt($1, $2)", "Math.floor($1 / $2)"], # DivI - ["modInt", "", "modInt($1, $2)", "Math.floor($1 % $2)"], # ModI + ["divInt", "", "divInt($1, $2)", "Math.trunc($1 / $2)"], # DivI + ["modInt", "", "modInt($1, $2)", "Math.trunc($1 % $2)"], # ModI ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred ["", "", "($1 + $2)", "($1 + $2)"], # AddF64 @@ -444,8 +445,8 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["toU32", "toU32", "toU32($1)", "toU32($1)"], # toU32 ["", "", "$1", "$1"], # ToFloat ["", "", "$1", "$1"], # ToBiggestFloat - ["", "", "Math.floor($1)", "Math.floor($1)"], # ToInt - ["", "", "Math.floor($1)", "Math.floor($1)"], # ToBiggestInt + ["", "", "Math.trunc($1)", "Math.trunc($1)"], # ToInt + ["", "", "Math.trunc($1)", "Math.trunc($1)"], # ToBiggestInt ["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"], ["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], @@ -1067,7 +1068,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) = else: r.res = "chckIndx($1, $2, strlen($3))-$2" % [b.res, rope(first), a.res] else: - r.res = "chckIndx($1, $2, $3.length-1)-$2" % [b.res, rope(first), a.res] + r.res = "chckIndx($1, $2, $3.length+$2-1)-$2" % [b.res, rope(first), a.res] elif first != 0: r.res = "($1)-$2" % [b.res, rope(first)] else: @@ -1363,7 +1364,7 @@ proc genPatternCall(p: PProc; n: PNode; pat: string; typ: PType; case pat[i] of '@': var generated = 0 - for k in j .. < n.len: + for k in j ..< n.len: if generated > 0: add(r.res, ", ") genOtherArg(p, n, k, typ, generated, r) inc i @@ -1528,7 +1529,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope = of tyTuple: if p.target == targetJS: result = rope("{") - for i in 0.. <t.sonsLen: + for i in 0..<t.sonsLen: if i > 0: add(result, ", ") addf(result, "Field$1: $2", [i.rope, createVar(p, t.sons[i], false)]) @@ -1536,7 +1537,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope = if indirect: result = "[$1]" % [result] else: result = rope("array(") - for i in 0.. <t.sonsLen: + for i in 0..<t.sonsLen: if i > 0: add(result, ", ") add(result, createVar(p, t.sons[i], false)) add(result, ")") @@ -1562,14 +1563,22 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope = internalError("createVar: " & $t.kind) result = nil +template returnType: untyped = + ~"" + proc genVarInit(p: PProc, v: PSym, n: PNode) = var a: TCompRes s: Rope + varCode: string + if v.constraint.isNil: + varCode = "var $2" + else: + varCode = v.constraint.strVal if n.kind == nkEmpty: let mname = mangleName(v, p.target) - lineF(p, "var $1 = $2;$n" | "$$$1 = $2;$n", - [mname, createVar(p, v.typ, isIndirect(v))]) + lineF(p, varCode & " = $3;$n" | "$$$2 = $3;$n", + [returnType, mname, createVar(p, v.typ, isIndirect(v))]) if v.typ.kind in { tyVar, tyPtr, tyRef } and mapType(p, v.typ) == etyBaseIndex: lineF(p, "var $1_Idx = 0;$n", [ mname ]) else: @@ -1586,25 +1595,25 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) = let targetBaseIndex = {sfAddrTaken, sfGlobal} * v.flags == {} if a.typ == etyBaseIndex: if targetBaseIndex: - lineF(p, "var $1 = $2, $1_Idx = $3;$n", - [v.loc.r, a.address, a.res]) + lineF(p, varCode & " = $3, $2_Idx = $4;$n", + [returnType, v.loc.r, a.address, a.res]) else: - lineF(p, "var $1 = [$2, $3];$n", - [v.loc.r, a.address, a.res]) + lineF(p, varCode & " = [$3, $4];$n", + [returnType, v.loc.r, a.address, a.res]) else: if targetBaseIndex: let tmp = p.getTemp lineF(p, "var $1 = $2, $3 = $1[0], $3_Idx = $1[1];$n", [tmp, a.res, v.loc.r]) else: - lineF(p, "var $1 = $2;$n", [v.loc.r, a.res]) + lineF(p, varCode & " = $3;$n", [returnType, v.loc.r, a.res]) return else: s = a.res if isIndirect(v): - lineF(p, "var $1 = [$2];$n", [v.loc.r, s]) + lineF(p, varCode & " = [$3];$n", [returnType, v.loc.r, s]) else: - lineF(p, "var $1 = $2;$n" | "$$$1 = $2;$n", [v.loc.r, s]) + lineF(p, varCode & " = $3;$n" | "$$$2 = $3;$n", [returnType, v.loc.r, s]) proc genVarStmt(p: PProc, n: PNode) = for i in countup(0, sonsLen(n) - 1): @@ -1650,7 +1659,7 @@ proc genNewSeq(p: PProc, n: PNode) = proc genOrd(p: PProc, n: PNode, r: var TCompRes) = case skipTypes(n.sons[1].typ, abstractVar).kind - of tyEnum, tyInt..tyInt64, tyChar: gen(p, n.sons[1], r) + of tyEnum, tyInt..tyUInt64, tyChar: gen(p, n.sons[1], r) of tyBool: unaryExpr(p, n, r, "", "($1 ? 1:0)") else: internalError(n.info, "genOrd") @@ -2042,10 +2051,10 @@ proc genConv(p: PProc, n: PNode, r: var TCompRes) = return case dest.kind: of tyBool: - r.res = "(($1)? 1:0)" % [r.res] + r.res = "(!!($1))" % [r.res] r.kind = resExpr of tyInt: - r.res = "($1|0)" % [r.res] + r.res = "(($1)|0)" % [r.res] else: # TODO: What types must we handle here? discard @@ -2161,8 +2170,22 @@ proc genProc(oldProc: PProc, prc: PSym): Rope = returnStmt = "return $#;$n" % [a.res] p.nested: genStmt(p, prc.getBody) - let def = "function $#($#) {$n$#$#$#$#$#" % - [name, header, + + var def: Rope + if not prc.constraint.isNil: + def = (prc.constraint.strVal & " {$n$#$#$#$#$#") % + [ returnType, + name, + header, + optionaLine(p.globals), + optionaLine(p.locals), + optionaLine(resultAsgn), + optionaLine(genProcBody(p, prc)), + optionaLine(p.indentLine(returnStmt))] + else: + def = "function $#($#) {$n$#$#$#$#$#" % + [ name, + header, optionaLine(p.globals), optionaLine(p.locals), optionaLine(resultAsgn), @@ -2229,7 +2252,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = case n.kind of nkSym: genSym(p, n, r) - of nkCharLit..nkUInt32Lit: + of nkCharLit..nkUInt64Lit: if n.typ.kind == tyBool: r.res = if n.intVal == 0: rope"false" else: rope"true" else: @@ -2346,6 +2369,8 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = of nkGotoState, nkState: internalError(n.info, "first class iterators not implemented") of nkPragmaBlock: gen(p, n.lastSon, r) + of nkComesFrom: + discard "XXX to implement for better stack traces" else: internalError(n.info, "gen: unknown node type: " & $n.kind) var globals: PGlobals diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index 0d5b29ace..d9df04e4b 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -84,7 +84,7 @@ proc genObjectInfo(p: PProc, typ: PType, name: Rope) = proc genTupleFields(p: PProc, typ: PType): Rope = var s: Rope = nil - for i in 0 .. <typ.len: + for i in 0 ..< typ.len: if i > 0: add(s, ", " & tnl) s.addf("{kind: 1, offset: \"Field$1\", len: 0, " & "typ: $2, name: \"Field$1\", sons: null}", diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index e64e0a898..cf43ba15d 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -455,6 +455,7 @@ type LiftingPass = object processed: IntSet envVars: Table[int, PNode] + inContainer: int proc initLiftingPass(fn: PSym): LiftingPass = result.processed = initIntSet() @@ -597,6 +598,8 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass; proc transformYield(n: PNode; owner: PSym; d: DetectionPass; c: var LiftingPass): PNode = + if c.inContainer > 0: + localError(n.info, "invalid control flow: 'yield' within a constructor") let state = getStateField(owner) assert state != nil assert state.typ != nil @@ -703,11 +706,14 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass; if not c.processed.containsOrIncl(s.id): #if s.name.s == "temp": # echo renderTree(s.getBody, {renderIds}) + let oldInContainer = c.inContainer + c.inContainer = 0 let body = wrapIterBody(liftCapturedVars(s.getBody, s, d, c), s) if c.envvars.getOrDefault(s.id).isNil: s.ast.sons[bodyPos] = body else: s.ast.sons[bodyPos] = newTree(nkStmtList, rawClosureCreation(s, d, c), body) + c.inContainer = oldInContainer if s.typ.callConv == ccClosure: result = symToClosure(n, owner, d, c) elif s.id in d.capturedVars: @@ -717,7 +723,7 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass; result = accessViaEnvParam(n, owner) else: result = accessViaEnvVar(n, owner, d, c) - of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, + of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkComesFrom, nkTemplateDef, nkTypeSection: discard of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef: @@ -733,9 +739,12 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass; n.sons[1] = x.sons[1] of nkLambdaKinds, nkIteratorDef, nkFuncDef: if n.typ != nil and n[namePos].kind == nkSym: + let oldInContainer = c.inContainer + c.inContainer = 0 let m = newSymNode(n[namePos].sym) m.typ = n.typ result = liftCapturedVars(m, owner, d, c) + c.inContainer = oldInContainer of nkHiddenStdConv: if n.len == 2: n.sons[1] = liftCapturedVars(n[1], owner, d, c) @@ -750,8 +759,12 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass; # special case 'when nimVm' due to bug #3636: n.sons[1] = liftCapturedVars(n[1], owner, d, c) return + + let inContainer = n.kind in {nkObjConstr, nkBracket} + if inContainer: inc c.inContainer for i in 0..<n.len: n.sons[i] = liftCapturedVars(n[i], owner, d, c) + if inContainer: dec c.inContainer # ------------------ old stuff ------------------------------------------- @@ -764,7 +777,10 @@ proc semCaptureSym*(s, owner: PSym) = var o = owner.skipGenericOwner while o.kind != skModule and o != nil: if s.owner == o: - owner.typ.callConv = ccClosure + if owner.typ.callConv in {ccClosure, ccDefault} or owner.kind == skIterator: + owner.typ.callConv = ccClosure + else: + discard "do not produce an error here, but later" #echo "computing .closure for ", owner.name.s, " ", owner.info, " because of ", s.name.s o = o.skipGenericOwner # since the analysis is not entirely correct, we don't set 'tfCapturesEnv' diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 9b37b499b..bca07e500 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -33,13 +33,13 @@ type TTokType* = enum tkInvalid, tkEof, # order is important here! tkSymbol, # keywords: - tkAddr, tkAnd, tkAs, tkAsm, tkAtomic, + tkAddr, tkAnd, tkAs, tkAsm, tkBind, tkBlock, tkBreak, tkCase, tkCast, tkConcept, tkConst, tkContinue, tkConverter, tkDefer, tkDiscard, tkDistinct, tkDiv, tkDo, tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkExport, tkFinally, tkFor, tkFrom, tkFunc, - tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, + tkIf, tkImport, tkIn, tkInclude, tkInterface, tkIs, tkIsnot, tkIterator, tkLet, tkMacro, tkMethod, tkMixin, tkMod, tkNil, tkNot, tkNotin, @@ -75,12 +75,12 @@ const tokKeywordHigh* = pred(tkIntLit) TokTypeToStr*: array[TTokType, string] = ["tkInvalid", "[EOF]", "tkSymbol", - "addr", "and", "as", "asm", "atomic", + "addr", "and", "as", "asm", "bind", "block", "break", "case", "cast", "concept", "const", "continue", "converter", "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", - "finally", "for", "from", "func", "generic", "if", + "finally", "for", "from", "func", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", "let", "macro", "method", "mixin", "mod", @@ -129,6 +129,7 @@ type when defined(nimpretty): offsetA*, offsetB*: int # used for pretty printing so that literals # like 0b01 or r"\L" are unaffected + commentOffsetA*, commentOffsetB*: int TErrorHandler* = proc (info: TLineInfo; msg: TMsgKind; arg: string) TLexer* = object of TBaseLexer @@ -144,6 +145,10 @@ type when defined(nimsuggest): previousToken: TLineInfo +when defined(nimpretty): + var + gIndentationWidth*: int + var gLinesCompiled*: int # all lines that have been compiled proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} = @@ -151,6 +156,8 @@ proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} = when defined(nimpretty): result.offsetA = tok.offsetA result.offsetB = tok.offsetB + result.commentOffsetA = tok.commentOffsetA + result.commentOffsetB = tok.commentOffsetB proc isKeyword*(kind: TTokType): bool = result = (kind >= tokKeywordLow) and (kind <= tokKeywordHigh) @@ -198,6 +205,9 @@ proc initToken*(L: var TToken) = L.fNumber = 0.0 L.base = base10 L.ident = nil + when defined(nimpretty): + L.commentOffsetA = 0 + L.commentOffsetB = 0 proc fillToken(L: var TToken) = L.tokType = tkInvalid @@ -208,6 +218,9 @@ proc fillToken(L: var TToken) = L.fNumber = 0.0 L.base = base10 L.ident = nil + when defined(nimpretty): + L.commentOffsetA = 0 + L.commentOffsetB = 0 proc openLexer*(lex: var TLexer, fileIdx: int32, inputstream: PLLStream; cache: IdentCache) = @@ -680,7 +693,7 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) = proc newString(s: cstring, len: int): string = ## XXX, how come there is no support for this? result = newString(len) - for i in 0 .. <len: + for i in 0 ..< len: result[i] = s[i] proc handleCRLF(L: var TLexer, pos: int): int = @@ -847,6 +860,23 @@ proc getOperator(L: var TLexer, tok: var TToken) = if buf[pos] in {CR, LF, nimlexbase.EndOfFile}: tok.strongSpaceB = -1 +proc newlineFollows*(L: var TLexer): bool = + var pos = L.bufpos + var buf = L.buf + while true: + case buf[pos] + of ' ', '\t': + inc(pos) + of CR, LF: + result = true + break + of '#': + inc(pos) + if buf[pos] == '#': inc(pos) + if buf[pos] != '[': return true + else: + break + proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int; isDoc: bool) = var pos = start @@ -996,18 +1026,27 @@ proc skip(L: var TLexer, tok: var TToken) = of '#': # do not skip documentation comment: if buf[pos+1] == '#': break + when defined(nimpretty): + tok.commentOffsetA = L.offsetBase + pos if buf[pos+1] == '[': skipMultiLineComment(L, tok, pos+2, false) pos = L.bufpos buf = L.buf + when defined(nimpretty): + tok.commentOffsetB = L.offsetBase + pos else: tokenBegin(tok, pos) while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}: inc(pos) tokenEndIgnore(tok, pos+1) + when defined(nimpretty): + tok.commentOffsetB = L.offsetBase + pos + 1 else: break # EndOfFile also leaves the loop tokenEndPrevious(tok, pos-1) L.bufpos = pos + when defined(nimpretty): + if gIndentationWidth <= 0: + gIndentationWidth = tok.indent proc rawGetTok*(L: var TLexer, tok: var TToken) = template atTokenEnd() {.dirty.} = diff --git a/compiler/liftlocals.nim b/compiler/liftlocals.nim new file mode 100644 index 000000000..3610a1486 --- /dev/null +++ b/compiler/liftlocals.nim @@ -0,0 +1,70 @@ +# +# +# The Nim Compiler +# (c) Copyright 2015 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements the '.liftLocals' pragma. + +import + intsets, strutils, options, ast, astalgo, msgs, + idents, renderer, types, lowerings + +from pragmas import getPragmaVal +from wordrecg import wLiftLocals + +type + Ctx = object + partialParam: PSym + objType: PType + +proc interestingVar(s: PSym): bool {.inline.} = + result = s.kind in {skVar, skLet, skTemp, skForVar, skResult} and + sfGlobal notin s.flags + +proc lookupOrAdd(c: var Ctx; s: PSym; info: TLineInfo): PNode = + let field = addUniqueField(c.objType, s) + var deref = newNodeI(nkHiddenDeref, info) + deref.typ = c.objType + add(deref, newSymNode(c.partialParam, info)) + result = newNodeI(nkDotExpr, info) + add(result, deref) + add(result, newSymNode(field)) + result.typ = field.typ + +proc liftLocals(n: PNode; i: int; c: var Ctx) = + let it = n[i] + case it.kind + of nkSym: + if interestingVar(it.sym): + n[i] = lookupOrAdd(c, it.sym, it.info) + of procDefs, nkTypeSection: discard + else: + for i in 0 ..< it.safeLen: + liftLocals(it, i, c) + +proc lookupParam(params, dest: PNode): PSym = + if dest.kind != nkIdent: return nil + for i in 1 ..< params.len: + if params[i].kind == nkSym and params[i].sym.name.id == dest.ident.id: + return params[i].sym + +proc liftLocalsIfRequested*(prc: PSym; n: PNode): PNode = + let liftDest = getPragmaVal(prc.ast, wLiftLocals) + if liftDest == nil: return n + let partialParam = lookupParam(prc.typ.n, liftDest) + if partialParam.isNil: + localError(liftDest.info, "'$1' is not a parameter of '$2'" % + [$liftDest, prc.name.s]) + return n + let objType = partialParam.typ.skipTypes(abstractPtrs) + if objType.kind != tyObject or tfPartial notin objType.flags: + localError(liftDest.info, "parameter '$1' is not a pointer to a partial object" % $liftDest) + return n + var c = Ctx(partialParam: partialParam, objType: objType) + let w = newTree(nkStmtList, n) + liftLocals(w, 0, c) + result = w[0] diff --git a/compiler/lookups.nim b/compiler/lookups.nim index eddfeea56..c409acc59 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -39,14 +39,18 @@ proc considerQuotedIdent*(n: PNode, origin: PNode = nil): PIdent = of 1: result = considerQuotedIdent(n.sons[0], origin) else: var id = "" - for i in 0.. <n.len: + for i in 0..<n.len: let x = n.sons[i] case x.kind of nkIdent: id.add(x.ident.s) of nkSym: id.add(x.sym.name.s) else: handleError(n, origin) result = getIdent(id) - of nkOpenSymChoice, nkClosedSymChoice: result = n.sons[0].sym.name + of nkOpenSymChoice, nkClosedSymChoice: + if n[0].kind == nkSym: + result = n.sons[0].sym.name + else: + handleError(n, origin) else: handleError(n, origin) @@ -155,7 +159,7 @@ proc ensureNoMissingOrUnusedSymbols(scope: PScope) = var s = initTabIter(it, scope.symbols) var missingImpls = 0 while s != nil: - if sfForward in s.flags: + if sfForward in s.flags and s.kind != skType: # too many 'implementation of X' errors are annoying # and slow 'suggest' down: if missingImpls == 0: @@ -379,7 +383,11 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = result = errorSym(c, n.sons[1]) of nkClosedSymChoice, nkOpenSymChoice: o.mode = oimSymChoice - result = n.sons[0].sym + if n[0].kind == nkSym: + result = n.sons[0].sym + else: + o.mode = oimDone + return nil o.symChoiceIndex = 1 o.inSymChoice = initIntSet() incl(o.inSymChoice, result.id) @@ -437,13 +445,14 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = if result != nil and result.kind == skStub: loadStub(result) -proc pickSym*(c: PContext, n: PNode; kind: TSymKind; +proc pickSym*(c: PContext, n: PNode; kinds: set[TSymKind]; flags: TSymFlags = {}): PSym = var o: TOverloadIter var a = initOverloadIter(o, c, n) while a != nil: - if a.kind == kind and flags <= a.flags: - return a + if a.kind in kinds and flags <= a.flags: + if result == nil: result = a + else: return nil # ambiguous a = nextOverloadIter(o, c, n) proc isInfixAs*(n: PNode): bool = diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index f895e887c..9612ff0ab 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -182,8 +182,9 @@ proc addField*(obj: PType; s: PSym) = field.position = sonsLen(obj.n) addSon(obj.n, newSymNode(field)) -proc addUniqueField*(obj: PType; s: PSym) = - if lookupInRecord(obj.n, s.id) == nil: +proc addUniqueField*(obj: PType; s: PSym): PSym {.discardable.} = + result = lookupInRecord(obj.n, s.id) + if result == nil: var field = newSym(skField, getIdent(s.name.s & $obj.n.len), s.owner, s.info) field.id = -s.id let t = skipIntLit(s.typ) @@ -191,6 +192,7 @@ proc addUniqueField*(obj: PType; s: PSym) = assert t.kind != tyStmt field.position = sonsLen(obj.n) addSon(obj.n, newSymNode(field)) + result = field proc newDotExpr(obj, b: PSym): PNode = result = newNodeI(nkDotExpr, obj.info) @@ -463,7 +465,7 @@ proc setupArgsForConcurrency(n: PNode; objType: PType; scratchObj: PSym, varSection, varInit, result: PNode) = let formals = n[0].typ.n let tmpName = getIdent(genPrefix) - for i in 1 .. <n.len: + for i in 1 ..< n.len: # we pick n's type here, which hopefully is 'tyArray' and not # 'tyOpenArray': var argType = n[i].typ.skipTypes(abstractInst) @@ -519,7 +521,7 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym; let tmpName = getIdent(genPrefix) # we need to copy the foreign scratch object fields into local variables # for correctness: These are called 'threadLocal' here. - for i in 1 .. <n.len: + for i in 1 ..< n.len: let n = n[i] let argType = skipTypes(if i < formals.len: formals[i].typ else: n.typ, abstractInst) diff --git a/compiler/main.nim b/compiler/main.nim index 450542c4c..9bf8bb7c0 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -16,12 +16,12 @@ import cgen, jsgen, json, nversion, platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen, docgen2, service, parser, modules, ccgutils, sigmatch, ropes, - modulegraphs + modulegraphs, tables from magicsys import systemModule, resetSysTypes proc rodPass = - if optSymbolFiles in gGlobalOptions: + if gSymbolFiles in {enabledSf, writeOnlySf}: registerPass(rodwritePass) proc codegenPass = @@ -36,6 +36,9 @@ proc writeDepsFile(g: ModuleGraph; project: string) = for m in g.modules: if m != nil: f.writeLine(toFullPath(m.position.int32)) + for k in g.inclToMod.keys: + if g.getModule(k).isNil: # don't repeat includes which are also modules + f.writeLine(k.toFullPath) f.close() proc commandGenDepend(graph: ModuleGraph; cache: IdentCache) = @@ -77,6 +80,8 @@ proc commandCompileToC(graph: ModuleGraph; cache: IdentCache) = let proj = changeFileExt(gProjectFull, "") extccomp.callCCompiler(proj) extccomp.writeJsonBuildInstructions(proj) + if optGenScript in gGlobalOptions: + writeDepsFile(graph, toGeneratedFile(proj, "")) proc commandJsonScript(graph: ModuleGraph; cache: IdentCache) = let proj = changeFileExt(gProjectFull, "") @@ -186,12 +191,12 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) = of "php": gCmd = cmdCompileToPHP commandCompileToJS(graph, cache) - of "doc": + of "doc0": wantMainModule() gCmd = cmdDoc loadConfigs(DocConfig, cache) commandDoc() - of "doc2": + of "doc2", "doc": gCmd = cmdDoc loadConfigs(DocConfig, cache) defineSymbol("nimdoc") @@ -217,6 +222,13 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) = wantMainModule() defineSymbol("nimdoc") commandDoc2(graph, cache, true) + of "ctags": + wantMainModule() + gCmd = cmdDoc + loadConfigs(DocConfig, cache) + wantMainModule() + defineSymbol("nimdoc") + commandTags() of "buildindex": gCmd = cmdDoc loadConfigs(DocConfig, cache) diff --git a/compiler/modulepaths.nim b/compiler/modulepaths.nim new file mode 100644 index 000000000..5d112c6b9 --- /dev/null +++ b/compiler/modulepaths.nim @@ -0,0 +1,174 @@ +# +# +# The Nim Compiler +# (c) Copyright 2017 Contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import ast, renderer, strutils, msgs, options, idents, os + +import nimblecmd + +const + considerParentDirs = not defined(noParentProjects) + considerNimbleDirs = not defined(noNimbleDirs) + +proc findInNimbleDir(pkg, subdir, dir: string): string = + var best = "" + var bestv = "" + for k, p in os.walkDir(dir, relative=true): + if k == pcDir and p.len > pkg.len+1 and + p[pkg.len] == '-' and p.startsWith(pkg): + let (_, a) = getPathVersion(p) + if bestv.len == 0 or bestv < a: + bestv = a + best = dir / p + + if best.len > 0: + var f: File + if open(f, best / changeFileExt(pkg, ".nimble-link")): + # the second line contains what we're interested in, see: + # https://github.com/nim-lang/nimble#nimble-link + var override = "" + discard readLine(f, override) + discard readLine(f, override) + close(f) + if not override.isAbsolute(): + best = best / override + else: + best = override + let f = if subdir.len == 0: pkg else: subdir + let res = addFileExt(best / f, "nim") + if best.len > 0 and fileExists(res): + result = res + +const stdlibDirs = [ + "pure", "core", "arch", + "pure/collections", + "pure/concurrency", "impure", + "wrappers", "wrappers/linenoise", + "windows", "posix", "js"] + +proc resolveDollar(project, source, pkg, subdir: string; info: TLineInfo): string = + template attempt(a) = + let x = addFileExt(a, "nim") + if fileExists(x): return x + + case pkg + of "stdlib": + if subdir.len == 0: + return options.libpath + else: + for candidate in stdlibDirs: + attempt(options.libpath / candidate / subdir) + of "root": + let root = project.splitFile.dir + if subdir.len == 0: + return root + else: + attempt(root / subdir) + else: + when considerParentDirs: + var p = parentDir(source.splitFile.dir) + # support 'import $karax': + let f = if subdir.len == 0: pkg else: subdir + + while p.len > 0: + let dir = p / pkg + if dirExists(dir): + attempt(dir / f) + # 2nd attempt: try to use 'karax/karax' + attempt(dir / pkg / f) + # 3rd attempt: try to use 'karax/src/karax' + attempt(dir / "src" / f) + attempt(dir / "src" / pkg / f) + p = parentDir(p) + + when considerNimbleDirs: + if not options.gNoNimblePath: + var nimbleDir = getEnv("NIMBLE_DIR") + if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble" + result = findInNimbleDir(pkg, subdir, nimbleDir / "pkgs") + if result.len > 0: return result + when not defined(windows): + result = findInNimbleDir(pkg, subdir, "/opt/nimble/pkgs") + if result.len > 0: return result + +proc scriptableImport(pkg, sub: string; info: TLineInfo): string = + result = resolveDollar(gProjectFull, info.toFullPath(), pkg, sub, info) + if result.isNil: result = "" + +proc lookupPackage(pkg, subdir: PNode): string = + let sub = if subdir != nil: renderTree(subdir, {renderNoComments}).replace(" ") else: "" + case pkg.kind + of nkStrLit, nkRStrLit, nkTripleStrLit: + result = scriptableImport(pkg.strVal, sub, pkg.info) + of nkIdent: + result = scriptableImport(pkg.ident.s, sub, pkg.info) + else: + localError(pkg.info, "package name must be an identifier or string literal") + result = "" + +proc getModuleName*(n: PNode): string = + # This returns a short relative module name without the nim extension + # e.g. like "system", "importer" or "somepath/module" + # The proc won't perform any checks that the path is actually valid + case n.kind + of nkStrLit, nkRStrLit, nkTripleStrLit: + try: + result = pathSubs(n.strVal, n.info.toFullPath().splitFile().dir) + except ValueError: + localError(n.info, "invalid path: " & n.strVal) + result = n.strVal + of nkIdent: + result = n.ident.s + of nkSym: + result = n.sym.name.s + of nkInfix: + let n0 = n[0] + let n1 = n[1] + if n0.kind == nkIdent and n0.ident.id == getIdent("as").id: + # XXX hack ahead: + n.kind = nkImportAs + n.sons[0] = n.sons[1] + n.sons[1] = n.sons[2] + n.sons.setLen(2) + return getModuleName(n.sons[0]) + if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$": + if n0.kind == nkIdent and n0.ident.s == "/": + result = lookupPackage(n1[1], n[2]) + else: + localError(n.info, "only '/' supported with $package notation") + result = "" + else: + # hacky way to implement 'x / y /../ z': + result = getModuleName(n1) + result.add renderTree(n0, {renderNoComments}) + result.add getModuleName(n[2]) + of nkPrefix: + if n.sons[0].kind == nkIdent and n.sons[0].ident.s == "$": + result = lookupPackage(n[1], nil) + else: + # hacky way to implement 'x / y /../ z': + result = renderTree(n, {renderNoComments}).replace(" ") + of nkDotExpr: + result = renderTree(n, {renderNoComments}).replace(".", "/") + of nkImportAs: + result = getModuleName(n.sons[0]) + else: + localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree) + result = "" + +proc checkModuleName*(n: PNode; doLocalError=true): int32 = + # This returns the full canonical path for a given module import + let modulename = n.getModuleName + let fullPath = findModule(modulename, n.info.toFullPath) + if fullPath.len == 0: + if doLocalError: + let m = if modulename.len > 0: modulename else: $n + localError(n.info, errCannotOpenFile, m) + result = InvalidFileIDX + else: + result = fullPath.fileInfoIdx diff --git a/compiler/msgs.nim b/compiler/msgs.nim index c988141e5..4e6226122 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -26,7 +26,8 @@ type errAtPopWithoutPush, errEmptyAsm, errInvalidIndentation, errExceptionExpected, errExceptionAlreadyHandled, errYieldNotAllowedHere, errYieldNotAllowedInTryStmt, - errInvalidNumberOfYieldExpr, errCannotReturnExpr, errAttemptToRedefine, + errInvalidNumberOfYieldExpr, errCannotReturnExpr, + errNoReturnWithReturnTypeNotAllowed, errAttemptToRedefine, errStmtInvalidAfterReturn, errStmtExpected, errInvalidLabel, errInvalidCmdLineOption, errCmdLineArgExpected, errCmdLineNoArgExpected, errInvalidVarSubstitution, errUnknownVar, errUnknownCcompiler, @@ -61,7 +62,7 @@ type errBaseTypeMustBeOrdinal, errInheritanceOnlyWithNonFinalObjects, errInheritanceOnlyWithEnums, errIllegalRecursionInTypeX, errCannotInstantiateX, errExprHasNoAddress, errXStackEscape, - errVarForOutParamNeeded, + errVarForOutParamNeededX, errPureTypeMismatch, errTypeMismatch, errButExpected, errButExpectedX, errAmbiguousCallXYZ, errWrongNumberOfArguments, errWrongNumberOfArgumentsInCall, @@ -179,8 +180,9 @@ const errYieldNotAllowedInTryStmt: "'yield' cannot be used within 'try' in a non-inlined iterator", errInvalidNumberOfYieldExpr: "invalid number of \'yield\' expressions", errCannotReturnExpr: "current routine cannot return an expression", + errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type", errAttemptToRedefine: "redefinition of \'$1\'", - errStmtInvalidAfterReturn: "statement not allowed after \'return\', \'break\', \'raise\' or \'continue'", + errStmtInvalidAfterReturn: "statement not allowed after \'return\', \'break\', \'raise\', \'continue\' or proc call with noreturn pragma", errStmtExpected: "statement expected", errInvalidLabel: "\'$1\' is no label", errInvalidCmdLineOption: "invalid command line option: \'$1\'", @@ -268,7 +270,7 @@ const errCannotInstantiateX: "cannot instantiate: \'$1\'", errExprHasNoAddress: "expression has no address", errXStackEscape: "address of '$1' may not escape its stack frame", - errVarForOutParamNeeded: "for a \'var\' type a variable needs to be passed", + errVarForOutParamNeededX: "for a \'var\' type a variable needs to be passed; but '$1' is immutable", errPureTypeMismatch: "type mismatch", errTypeMismatch: "type mismatch: got (", errButExpected: "but expected one of: ", @@ -500,6 +502,7 @@ type fileIndex*: int32 when defined(nimpretty): offsetA*, offsetB*: int + commentOffsetA*, commentOffsetB*: int TErrorOutput* = enum eStdOut diff --git a/compiler/nimblecmd.nim b/compiler/nimblecmd.nim index 39c3a17e7..0f9e03352 100644 --- a/compiler/nimblecmd.nim +++ b/compiler/nimblecmd.nim @@ -28,6 +28,10 @@ proc newVersion*(ver: string): Version = proc isSpecial(ver: Version): bool = return ($ver).len > 0 and ($ver)[0] == '#' +proc isValidVersion(v: string): bool = + if v.len > 0: + if v[0] in {'#'} + Digits: return true + proc `<`*(ver: Version, ver2: Version): bool = ## This is synced from Nimble's version module. @@ -72,15 +76,23 @@ proc getPathVersion*(p: string): tuple[name, version: string] = result.name = p return + for i in sepIdx..<p.len: + if p[i] in {DirSep, AltSep}: + result.name = p + return + result.name = p[0 .. sepIdx - 1] result.version = p.substr(sepIdx + 1) -proc addPackage(packages: StringTableRef, p: string) = +proc addPackage(packages: StringTableRef, p: string; info: TLineInfo) = let (name, ver) = getPathVersion(p) - let version = newVersion(ver) - if packages.getOrDefault(name).newVersion < version or - (not packages.hasKey(name)): - packages[name] = $version + if isValidVersion(ver): + let version = newVersion(ver) + if packages.getOrDefault(name).newVersion < version or + (not packages.hasKey(name)): + packages[name] = $version + else: + localError(info, "invalid package name: " & p) iterator chosen(packages: StringTableRef): string = for key, val in pairs(packages): @@ -109,7 +121,7 @@ proc addPathRec(dir: string, info: TLineInfo) = if dir[pos] in {DirSep, AltSep}: inc(pos) for k,p in os.walkDir(dir): if k == pcDir and p[pos] != '.': - addPackage(packages, p) + addPackage(packages, p, info) for p in packages.chosen: addNimblePath(p, info) diff --git a/compiler/nimlexbase.nim b/compiler/nimlexbase.nim index c395a3709..2e7416645 100644 --- a/compiler/nimlexbase.nim +++ b/compiler/nimlexbase.nim @@ -123,7 +123,7 @@ proc fillBaseLexer(L: var TBaseLexer, pos: int): int = result = pos + 1 # nothing to do else: fillBuffer(L) - L.offsetBase += pos + L.offsetBase += pos + 1 L.bufpos = 0 result = 0 L.lineStart = result diff --git a/compiler/options.nim b/compiler/options.nim index 86e6006d7..0732e4989 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -48,7 +48,6 @@ type # please make sure we have under 32 options optGenScript, # generate a script file to compile the *.c files optGenMapping, # generate a mapping file optRun, # run the compiled project - optSymbolFiles, # use symbol files for speeding up compilation optCaasEnabled # compiler-as-a-service is running optSkipConfigFile, # skip the general config file optSkipProjConfigFile, # skip the project's config file @@ -141,16 +140,25 @@ var gEvalExpr* = "" # expression for idetools --eval gLastCmdTime*: float # when caas is enabled, we measure each command gListFullPaths*: bool - isServing*: bool = false + gPreciseStack*: bool = false gNoNimblePath* = false gExperimentalMode*: bool newDestructors*: bool + gDynlibOverrideAll*: bool + +type + SymbolFilesOption* = enum + disabledSf, enabledSf, writeOnlySf, readOnlySf + +var gSymbolFiles*: SymbolFilesOption proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools} proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc +template preciseStack*(): bool = gPreciseStack template compilationCachePresent*: untyped = - {optCaasEnabled, optSymbolFiles} * gGlobalOptions != {} + gSymbolFiles in {enabledSf, writeOnlySf} +# {optCaasEnabled, optSymbolFiles} * gGlobalOptions != {} template optPreserveOrigSource*: untyped = optEmbedOrigSrc in gGlobalOptions @@ -161,6 +169,7 @@ const RodExt* = "rod" HtmlExt* = "html" JsonExt* = "json" + TagsExt* = "tags" TexExt* = "tex" IniExt* = "ini" DefaultConfig* = "nim.cfg" @@ -425,7 +434,7 @@ proc inclDynlibOverride*(lib: string) = gDllOverrides[lib.canonDynlibName] = "true" proc isDynlibOverride*(lib: string): bool = - result = gDllOverrides.hasKey(lib.canonDynlibName) + result = gDynlibOverrideAll or gDllOverrides.hasKey(lib.canonDynlibName) proc binaryStrSearch*(x: openArray[string], y: string): int = var a = 0 diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index 05b2d8f9c..0b8c8543e 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -122,7 +122,7 @@ proc semNodeKindConstraints*(p: PNode): PNode = result.strVal = newStringOfCap(10) result.strVal.add(chr(aqNone.ord)) if p.len >= 2: - for i in 1.. <p.len: + for i in 1..<p.len: compileConstraints(p.sons[i], result.strVal) if result.strVal.len > MaxStackSize-1: internalError(p.info, "parameter pattern too complex") @@ -152,7 +152,7 @@ proc checkForSideEffects*(n: PNode): TSideEffectAnalysis = # indirect call: assume side effect: return seSideEffect # we need to check n[0] too: (FwithSideEffectButReturnsProcWithout)(args) - for i in 0 .. <n.len: + for i in 0 ..< n.len: let ret = checkForSideEffects(n.sons[i]) if ret == seSideEffect: return ret elif ret == seUnknown and result == seNoSideEffect: @@ -163,7 +163,7 @@ proc checkForSideEffects*(n: PNode): TSideEffectAnalysis = else: # assume no side effect: result = seNoSideEffect - for i in 0 .. <n.len: + for i in 0 ..< n.len: let ret = checkForSideEffects(n.sons[i]) if ret == seSideEffect: return ret elif ret == seUnknown and result == seNoSideEffect: diff --git a/compiler/parser.nim b/compiler/parser.nim index e0885c388..b1cfd7609 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -72,6 +72,7 @@ proc parseStmtPragma(p: var TParser): PNode proc parsePragma(p: var TParser): PNode proc postExprBlocks(p: var TParser, x: PNode): PNode proc parseExprStmt(p: var TParser): PNode +proc parseBlock(p: var TParser): PNode # implementation proc getTok(p: var TParser) = @@ -785,21 +786,58 @@ proc parseIfExpr(p: var TParser, kind: TNodeKind): PNode = #| 'else' colcom expr #| ifExpr = 'if' condExpr #| whenExpr = 'when' condExpr - result = newNodeP(kind, p) - while true: - getTok(p) # skip `if`, `elif` - var branch = newNodeP(nkElifExpr, p) + when true: + result = newNodeP(kind, p) + while true: + getTok(p) # skip `if`, `when`, `elif` + var branch = newNodeP(nkElifExpr, p) + optInd(p, branch) + addSon(branch, parseExpr(p)) + colcom(p, branch) + addSon(branch, parseStmt(p)) + skipComment(p, branch) + addSon(result, branch) + if p.tok.tokType != tkElif: break # or not sameOrNoInd(p): break + if p.tok.tokType == tkElse: # and sameOrNoInd(p): + var branch = newNodeP(nkElseExpr, p) + eat(p, tkElse) + colcom(p, branch) + addSon(branch, parseStmt(p)) + addSon(result, branch) + else: + var + b: PNode + wasIndented = false + result = newNodeP(kind, p) + + getTok(p) + let branch = newNodeP(nkElifExpr, p) addSon(branch, parseExpr(p)) colcom(p, branch) + let oldInd = p.currInd + if realInd(p): + p.currInd = p.tok.indent + wasIndented = true + echo result.info, " yes ", p.currInd addSon(branch, parseExpr(p)) - optInd(p, branch) - addSon(result, branch) - if p.tok.tokType != tkElif: break - var branch = newNodeP(nkElseExpr, p) - eat(p, tkElse) - colcom(p, branch) - addSon(branch, parseExpr(p)) - addSon(result, branch) + result.add branch + while sameInd(p) or not wasIndented: + case p.tok.tokType + of tkElif: + b = newNodeP(nkElifExpr, p) + getTok(p) + optInd(p, b) + addSon(b, parseExpr(p)) + of tkElse: + b = newNodeP(nkElseExpr, p) + getTok(p) + else: break + colcom(p, b) + addSon(b, parseStmt(p)) + addSon(result, b) + if b.kind == nkElseExpr: break + if wasIndented: + p.currInd = oldInd proc parsePragma(p: var TParser): PNode = #| pragma = '{.' optInd (exprColonExpr comma?)* optPar ('.}' | '}') @@ -1041,12 +1079,14 @@ proc parseTypeDescKAux(p: var TParser, kind: TNodeKind, parseSymbolList(p, list) proc parseExpr(p: var TParser): PNode = - #| expr = (ifExpr + #| expr = (blockExpr + #| | ifExpr #| | whenExpr #| | caseExpr #| | tryExpr) #| / simpleExpr case p.tok.tokType: + of tkBlock: result = parseBlock(p) of tkIf: result = parseIfExpr(p, nkIfExpr) of tkWhen: result = parseIfExpr(p, nkWhenExpr) of tkCase: result = parseCase(p) @@ -1100,13 +1140,9 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode = else: result = newNodeP(nkObjectTy, p) getTok(p) - of tkGeneric, tkConcept: + of tkConcept: if mode == pmTypeDef: - let wasGeneric = p.tok.tokType == tkGeneric result = parseTypeClass(p) - # hack so that it's remembered and can be marked as deprecated in - # sem'check: - if wasGeneric: result.flags.incl nfBase2 else: parMessage(p, errInvalidToken, p.tok) of tkStatic: @@ -1480,6 +1516,7 @@ proc parseFor(p: var TParser): PNode = proc parseBlock(p: var TParser): PNode = #| blockStmt = 'block' symbol? colcom stmt + #| blockExpr = 'block' symbol? colcom stmt result = newNodeP(nkBlockStmt, p) getTokNoInd(p) if p.tok.tokType == tkColon: addSon(result, ast.emptyNode) @@ -1905,7 +1942,7 @@ proc parseVariable(p: var TParser): PNode = #| variable = (varTuple / identColonEquals) colonBody? indAndComment if p.tok.tokType == tkParLe: result = parseVarTuple(p) else: result = parseIdentColonEquals(p, {withPragma, withDot}) - result{-1} = postExprBlocks(p, result{-1}) + result[^1] = postExprBlocks(p, result[^1]) indAndComment(p, result) proc parseBind(p: var TParser, k: TNodeKind): PNode = @@ -2036,8 +2073,13 @@ proc parseStmt(p: var TParser): PNode = if a.kind != nkEmpty: addSon(result, a) else: - parMessage(p, errExprExpected, p.tok) - getTok(p) + # This is done to make the new 'if' expressions work better. + # XXX Eventually we need to be more strict here. + if p.tok.tokType notin {tkElse, tkElif}: + parMessage(p, errExprExpected, p.tok) + getTok(p) + else: + break if not p.hasProgress and p.tok.tokType == tkEof: break else: # the case statement is only needed for better error messages: diff --git a/compiler/passes.nim b/compiler/passes.nim index 6efd50385..29b27627d 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -15,9 +15,10 @@ import condsyms, idents, renderer, types, extccomp, math, magicsys, nversion, nimsets, syntaxes, times, rodread, idgen, modulegraphs, reorder + type TPassContext* = object of RootObj # the pass's context - fromCache*: bool # true if created by "openCached" + rd*: PRodReader # != nil if created by "openCached" PPassContext* = ref TPassContext @@ -117,7 +118,7 @@ proc openPassesCached(g: ModuleGraph; a: var TPassContextArray, module: PSym, if not isNil(gPasses[i].openCached): a[i] = gPasses[i].openCached(g, module, rd) if a[i] != nil: - a[i].fromCache = true + a[i].rd = rd else: a[i] = nil @@ -211,7 +212,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream, if n.kind == nkEmpty: break sl.add n if sfReorder in module.flags: - sl = reorder sl + sl = reorder(graph, sl, module, cache) discard processTopLevelStmt(sl, a) break elif not processTopLevelStmt(n, a): break diff --git a/compiler/patterns.nim b/compiler/patterns.nim index 859fe2a81..31b76743e 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -63,7 +63,7 @@ proc sameTrees(a, b: PNode): bool = proc inSymChoice(sc, x: PNode): bool = if sc.kind == nkClosedSymChoice: - for i in 0.. <sc.len: + for i in 0..<sc.len: if sc.sons[i].sym == x.sym: return true elif sc.kind == nkOpenSymChoice: # same name suffices for open sym choices! @@ -83,7 +83,7 @@ proc isPatternParam(c: PPatternContext, p: PNode): bool {.inline.} = result = p.kind == nkSym and p.sym.kind == skParam and p.sym.owner == c.owner proc matchChoice(c: PPatternContext, p, n: PNode): bool = - for i in 1 .. <p.len: + for i in 1 ..< p.len: if matches(c, p.sons[i], n): return true proc bindOrCheck(c: PPatternContext, param: PSym, n: PNode): bool = @@ -115,7 +115,7 @@ proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool = if rpn: arglist.add(n.sons[0]) elif n.kind == nkHiddenStdConv and n.sons[1].kind == nkBracket: let n = n.sons[1] - for i in 0.. <n.len: + for i in 0..<n.len: if not matchStarAux(c, op, n[i], arglist, rpn): return false elif checkTypes(c, p.sons[2].sym, n): add(arglist, n) @@ -186,7 +186,7 @@ proc matches(c: PPatternContext, p, n: PNode): bool = # unpack varargs: let n = lastSon(n).sons[1] arglist = newNodeI(nkArgList, n.info, n.len) - for i in 0.. <n.len: arglist.sons[i] = n.sons[i] + for i in 0..<n.len: arglist.sons[i] = n.sons[i] else: arglist = newNodeI(nkArgList, n.info, sonsLen(n) - plen + 1) # f(1, 2, 3) @@ -206,7 +206,7 @@ proc matches(c: PPatternContext, p, n: PNode): bool = proc matchStmtList(c: PPatternContext, p, n: PNode): PNode = proc matchRange(c: PPatternContext, p, n: PNode, i: int): bool = - for j in 0 .. <p.len: + for j in 0 ..< p.len: if not matches(c, p.sons[j], n.sons[i+j]): # we need to undo any bindings: if not isNil(c.mapping): c.mapping = nil @@ -229,7 +229,7 @@ proc matchStmtList(c: PPatternContext, p, n: PNode): PNode = proc aliasAnalysisRequested(params: PNode): bool = if params.len >= 2: - for i in 1 .. < params.len: + for i in 1 ..< params.len: let param = params.sons[i].sym if whichAlias(param) != aqNone: return true @@ -237,7 +237,7 @@ proc addToArgList(result, n: PNode) = if n.typ != nil and n.typ.kind != tyStmt: if n.kind != nkArgList: result.add(n) else: - for i in 0 .. <n.len: result.add(n.sons[i]) + for i in 0 ..< n.len: result.add(n.sons[i]) proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = ## returns a tree to semcheck if the rule triggered; nil otherwise @@ -256,7 +256,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = var args: PNode if requiresAA: args = newNodeI(nkArgList, n.info) - for i in 1 .. < params.len: + for i in 1 ..< params.len: let param = params.sons[i].sym let x = getLazy(ctx, param) # couldn't bind parameter: @@ -265,7 +265,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = if requiresAA: addToArgList(args, x) # perform alias analysis here: if requiresAA: - for i in 1 .. < params.len: + for i in 1 ..< params.len: var rs = result.sons[i] let param = params.sons[i].sym case whichAlias(param) diff --git a/compiler/pluginsupport.nim b/compiler/pluginsupport.nim index 19a0bc84d..f67942c97 100644 --- a/compiler/pluginsupport.nim +++ b/compiler/pluginsupport.nim @@ -7,8 +7,9 @@ # distribution, for details about the copyright. # -## Plugin support for the Nim compiler. Right now they -## need to be build with the compiler, no DLL support. +## Plugin support for the Nim compiler. Right now plugins +## need to be built with the compiler only: plugins using +## DLLs or the FFI will not work. import ast, semdata, idents diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index bc3771700..bdaecf91d 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -21,17 +21,17 @@ const const procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wMagic, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, - wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, + wCompilerProc, wCore, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC, - wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl, + wAsmNoStackFrame, wError, wDiscardable, wNoInit, wCodegenDecl, wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe, - wOverride, wConstructor, wExportNims, wUsed} + wOverride, wConstructor, wExportNims, wUsed, wLiftLocals} converterPragmas* = procPragmas methodPragmas* = procPragmas+{wBase}-{wImportCpp} templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty, wDelegator, wExportNims, wUsed} macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc, - wNodecl, wMagic, wNosideeffect, wCompilerproc, wDeprecated, wExtern, + wNodecl, wMagic, wNosideeffect, wCompilerProc, wCore, wDeprecated, wExtern, wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator, wExportNims, wUsed} iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect, @@ -52,14 +52,14 @@ const wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, wRaises, wLocks, wTags, wGcSafe} typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, - wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow, + wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wExtern, wShallow, wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef, wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, - wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain} + wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain, wPackage} fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, wImportCpp, wImportObjC, wError, wGuard, wBitsize, wUsed} varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, - wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern, + wMagic, wHeader, wDeprecated, wCompilerProc, wCore, wDynlib, wExtern, wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, wGensym, wInject, wCodegenDecl, wGuard, wGoto, wExportNims, wUsed} constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl, @@ -70,6 +70,14 @@ const wThread, wRaises, wLocks, wTags, wGcSafe} allRoutinePragmas* = methodPragmas + iteratorPragmas + lambdaPragmas +proc getPragmaVal*(procAst: PNode; name: TSpecialWord): PNode = + let p = procAst[pragmasPos] + if p.kind == nkEmpty: return nil + for it in p: + if it.kind == nkExprColonExpr and it[0].kind == nkIdent and + it[0].ident.id == ord(name): + return it[1] + proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) # implementation @@ -575,7 +583,7 @@ proc pragmaLockStmt(c: PContext; it: PNode) = if n.kind != nkBracket: localError(n.info, errGenerated, "locks pragma takes a list of expressions") else: - for i in 0 .. <n.len: + for i in 0 ..< n.len: n.sons[i] = c.semExpr(c, n.sons[i]) proc pragmaLocks(c: PContext, it: PNode): TLockLevel = @@ -618,7 +626,8 @@ proc deprecatedStmt(c: PContext; pragma: PNode) = for n in pragma: if n.kind in {nkExprColonExpr, nkExprEqExpr}: let dest = qualifiedLookUp(c, n[1], {checkUndeclared}) - assert dest != nil + if dest == nil or dest.kind in routineKinds: + localError(n.info, warnUser, "the .deprecated pragma is unreliable for routines") let src = considerQuotedIdent(n[0]) let alias = newSym(skAlias, src, dest, n[0].info) incl(alias.flags, sfExported) @@ -750,10 +759,6 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, incl(sym.loc.flags, lfNoDecl) # implies nodecl, because otherwise header would not make sense if sym.loc.r == nil: sym.loc.r = rope(sym.name.s) - of wDestructor: - sym.flags.incl sfOverriden - if sym.name.s.normalize != "destroy": - localError(n.info, errGenerated, "destructor has to be named 'destroy'") of wOverride: sym.flags.incl sfOverriden of wNosideeffect: @@ -766,9 +771,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wNoreturn: noVal(it) incl(sym.flags, sfNoReturn) + if sym.typ[0] != nil: + localError(sym.ast[paramsPos][0].info, errNoReturnWithReturnTypeNotAllowed) of wDynlib: processDynLib(c, it, sym) - of wCompilerproc: + of wCompilerProc, wCore: noVal(it) # compilerproc may not get a string! cppDefine(c.graph.config, sym.name.s) if sfFromGeneric notin sym.flags: markCompilerProc(sym) @@ -799,6 +806,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, noVal(it) if sym.typ == nil or tfFinal in sym.typ.flags: invalidPragma(it) else: incl(sym.typ.flags, tfInheritable) + of wPackage: + noVal(it) + if sym.typ == nil: invalidPragma(it) + else: incl(sym.flags, sfForward) of wAcyclic: noVal(it) if sym.typ == nil: invalidPragma(it) @@ -974,6 +985,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, noVal(it) if sym == nil: invalidPragma(it) else: sym.flags.incl sfUsed + of wLiftLocals: discard else: invalidPragma(it) else: invalidPragma(it) diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 4fbac45ab..6735cc1ce 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -38,6 +38,7 @@ type checkAnon: bool # we're in a context that can contain sfAnon inPragma: int when defined(nimpretty): + pendingNewlineCount: int origContent: string @@ -62,9 +63,31 @@ proc renderDefinitionName*(s: PSym, noQuotes = false): string = else: result = '`' & x & '`' +when not defined(nimpretty): + const + IndentWidth = 2 + longIndentWid = IndentWidth * 2 +else: + template IndentWidth: untyped = lexer.gIndentationWidth + template longIndentWid: untyped = IndentWidth() * 2 + + proc minmaxLine(n: PNode): (int, int) = + case n.kind + of nkTripleStrLit: + result = (n.info.line.int, n.info.line.int + countLines(n.strVal)) + of nkCommentStmt: + result = (n.info.line.int, n.info.line.int + countLines(n.comment)) + else: + result = (n.info.line.int, n.info.line.int) + for i in 0 ..< safeLen(n): + let (currMin, currMax) = minmaxLine(n[i]) + if currMin < result[0]: result[0] = currMin + if currMax > result[1]: result[1] = currMax + + proc lineDiff(a, b: PNode): int = + result = minmaxLine(b)[0] - minmaxLine(a)[1] + const - IndentWidth = 2 - longIndentWid = 4 MaxLineLen = 80 LineCommentColumn = 30 @@ -90,7 +113,11 @@ proc addTok(g: var TSrcGen, kind: TTokType, s: string) = proc addPendingNL(g: var TSrcGen) = if g.pendingNL >= 0: - addTok(g, tkSpaces, "\n" & spaces(g.pendingNL)) + when defined(nimpretty): + let newlines = repeat("\n", clamp(g.pendingNewlineCount, 1, 3)) + else: + const newlines = "\n" + addTok(g, tkSpaces, newlines & spaces(g.pendingNL)) g.lineLen = g.pendingNL g.pendingNL = - 1 g.pendingWhitespace = -1 @@ -114,11 +141,17 @@ proc putNL(g: var TSrcGen) = proc optNL(g: var TSrcGen, indent: int) = g.pendingNL = indent - g.lineLen = indent # BUGFIX + g.lineLen = indent + when defined(nimpretty): g.pendingNewlineCount = 0 proc optNL(g: var TSrcGen) = optNL(g, g.indent) +proc optNL(g: var TSrcGen; a, b: PNode) = + g.pendingNL = g.indent + g.lineLen = g.indent + when defined(nimpretty): g.pendingNewlineCount = lineDiff(a, b) + proc indentNL(g: var TSrcGen) = inc(g.indent, IndentWidth) g.pendingNL = g.indent @@ -142,8 +175,17 @@ proc put(g: var TSrcGen, kind: TTokType, s: string) = proc toNimChar(c: char): string = case c - of '\0': result = "\\0" - of '\x01'..'\x1F', '\x80'..'\xFF': result = "\\x" & strutils.toHex(ord(c), 2) + of '\0': result = "\\x00" # not "\\0" to avoid ambiguous cases like "\\012". + of '\a': result = "\\a" # \x07 + of '\b': result = "\\b" # \x08 + of '\t': result = "\\t" # \x09 + of '\L': result = "\\L" # \x0A + of '\v': result = "\\v" # \x0B + of '\f': result = "\\f" # \x0C + of '\c': result = "\\c" # \x0D + of '\e': result = "\\e" # \x1B + of '\x01'..'\x06', '\x0E'..'\x1A', '\x1C'..'\x1F', '\x80'..'\xFF': + result = "\\x" & strutils.toHex(ord(c), 2) of '\'', '\"', '\\': result = '\\' & c else: result = c & "" @@ -306,10 +348,14 @@ proc ulitAux(g: TSrcGen; n: PNode, x: BiggestInt, size: int): string = proc atom(g: TSrcGen; n: PNode): string = when defined(nimpretty): + let comment = if n.info.commentOffsetA < n.info.commentOffsetB: + " " & substr(g.origContent, n.info.commentOffsetA, n.info.commentOffsetB) + else: + "" if n.info.offsetA <= n.info.offsetB: # for some constructed tokens this can not be the case and we're better # off to not mess with the offset then. - return substr(g.origContent, n.info.offsetA, n.info.offsetB) + return substr(g.origContent, n.info.offsetA, n.info.offsetB) & comment var f: float32 case n.kind of nkEmpty: result = "" @@ -577,12 +623,16 @@ proc gstmts(g: var TSrcGen, n: PNode, c: TContext, doIndent=true) = if n.kind == nkEmpty: return if n.kind in {nkStmtList, nkStmtListExpr, nkStmtListType}: if doIndent: indentNL(g) - for i in countup(0, sonsLen(n) - 1): - optNL(g) - if n.sons[i].kind in {nkStmtList, nkStmtListExpr, nkStmtListType}: - gstmts(g, n.sons[i], c, doIndent=false) + let L = n.len + for i in 0 .. L-1: + if i > 0: + optNL(g, n[i-1], n[i]) else: - gsub(g, n.sons[i]) + optNL(g) + if n[i].kind in {nkStmtList, nkStmtListExpr, nkStmtListType}: + gstmts(g, n[i], c, doIndent=false) + else: + gsub(g, n[i]) gcoms(g) if doIndent: dedent(g) else: @@ -669,6 +719,7 @@ proc gcase(g: var TSrcGen, n: PNode) = var c: TContext initContext(c) var length = sonsLen(n) + if length == 0: return var last = if n.sons[length-1].kind == nkElse: -2 else: -1 if longMode(g, n, 0, last): incl(c.flags, rfLongMode) putWithSpace(g, tkCase, "case") @@ -785,7 +836,10 @@ proc gident(g: var TSrcGen, n: PNode) = t = tkOpr put(g, t, s) if n.kind == nkSym and (renderIds in g.flags or sfGenSym in n.sym.flags): - put(g, tkIntLit, $n.sym.id) + when defined(debugMagics): + put(g, tkIntLit, $n.sym.id & $n.sym.magic) + else: + put(g, tkIntLit, $n.sym.id) proc doParamsAux(g: var TSrcGen, params: PNode) = if params.len > 1: @@ -816,7 +870,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = a: TContext if n.comment != nil: pushCom(g, n) case n.kind # atoms: - of nkTripleStrLit: putRawStr(g, tkTripleStrLit, n.strVal) + of nkTripleStrLit: put(g, tkTripleStrLit, atom(g, n)) of nkEmpty: discard of nkType: put(g, tkInvalid, atom(g, n)) of nkSym, nkIdent: gident(g, n) @@ -1035,7 +1089,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = of nkAccQuoted: put(g, tkAccent, "`") if n.len > 0: gsub(g, n.sons[0]) - for i in 1 .. <n.len: + for i in 1 ..< n.len: put(g, tkSpaces, Space) gsub(g, n.sons[i]) put(g, tkAccent, "`") @@ -1353,8 +1407,8 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkBracketRi, "]") of nkTupleClassTy: put(g, tkTuple, "tuple") - of nkMetaNode_Obsolete: - put(g, tkParLe, "(META|") + of nkComesFrom: + put(g, tkParLe, "(ComesFrom|") gsub(g, n, 0) put(g, tkParRi, ")") of nkGotoState, nkState: @@ -1384,7 +1438,7 @@ proc renderTree*(n: PNode, renderFlags: TRenderFlags = {}): string = proc `$`*(n: PNode): string = n.renderTree -proc renderModule*(n: PNode, filename: string, +proc renderModule*(n: PNode, infile, outfile: string, renderFlags: TRenderFlags = {}) = var f: File @@ -1392,9 +1446,9 @@ proc renderModule*(n: PNode, filename: string, initSrcGen(g, renderFlags) when defined(nimpretty): try: - g.origContent = readFile(filename) + g.origContent = readFile(infile) except IOError: - rawMessage(errCannotOpenFile, filename) + rawMessage(errCannotOpenFile, infile) for i in countup(0, sonsLen(n) - 1): gsub(g, n.sons[i]) @@ -1406,11 +1460,11 @@ proc renderModule*(n: PNode, filename: string, gcoms(g) if optStdout in gGlobalOptions: write(stdout, g.buf) - elif open(f, filename, fmWrite): + elif open(f, outfile, fmWrite): write(f, g.buf) close(f) else: - rawMessage(errCannotOpenFile, filename) + rawMessage(errCannotOpenFile, outfile) proc initTokRender*(r: var TSrcGen, n: PNode, renderFlags: TRenderFlags = {}) = initSrcGen(r, renderFlags) diff --git a/compiler/reorder.nim b/compiler/reorder.nim index a9ad1fd97..cde5b3a9f 100644 --- a/compiler/reorder.nim +++ b/compiler/reorder.nim @@ -1,13 +1,40 @@ -import intsets, tables, ast, idents, renderer +import + intsets, ast, idents, algorithm, renderer, parser, ospaths, strutils, + sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables -const - nfTempMark = nfTransf - nfPermMark = nfNoRewrite +type + DepN = ref object + pnode: PNode + id, idx, lowLink: int + onStack: bool + kids: seq[DepN] + hAQ, hIS, hB, hCmd: int + when not defined(release): + expls: seq[string] + DepG = seq[DepN] + +when not defined(release): + var idNames = newTable[int, string]() + +proc newDepN(id: int, pnode: PNode): DepN = + new(result) + result.id = id + result.pnode = pnode + result.idx = -1 + result.lowLink = -1 + result.onStack = false + result.kids = @[] + result.hAQ = -1 + result.hIS = -1 + result.hB = -1 + result.hCmd = -1 + when not defined(release): + result.expls = @[] proc accQuoted(n: PNode): PIdent = var id = "" - for i in 0 .. <n.len: + for i in 0 ..< n.len: let x = n[i] case x.kind of nkIdent: id.add(x.ident.s) @@ -21,10 +48,19 @@ proc addDecl(n: PNode; declares: var IntSet) = of nkPragmaExpr: addDecl(n[0], declares) of nkIdent: declares.incl n.ident.id + when not defined(release): + idNames[n.ident.id] = n.ident.s of nkSym: declares.incl n.sym.name.id + when not defined(release): + idNames[n.sym.name.id] = n.sym.name.s of nkAccQuoted: - declares.incl accQuoted(n).id + let a = accQuoted(n) + declares.incl a.id + when not defined(release): + idNames[a.id] = a.s + of nkEnumFieldDef: + addDecl(n[0], declares) else: discard proc computeDeps(n: PNode, declares, uses: var IntSet; topLevel: bool) = @@ -32,7 +68,7 @@ proc computeDeps(n: PNode, declares, uses: var IntSet; topLevel: bool) = template decl(n) = if topLevel: addDecl(n, declares) case n.kind - of procDefs: + of procDefs, nkMacroDef, nkTemplateDef: decl(n[0]) for i in 1..bodyPos: deps(n[i]) of nkLetSection, nkVarSection, nkUsingStmt: @@ -44,43 +80,358 @@ proc computeDeps(n: PNode, declares, uses: var IntSet; topLevel: bool) = for a in n: if a.len >= 3: decl(a[0]) - for i in 1..<a.len: deps(a[i]) + for i in 1..<a.len: + if a[i].kind == nkEnumTy: + # declare enum members + for b in a[i]: + decl(b) + else: + deps(a[i]) + of nkIdentDefs: + for i in 1..<n.len: # avoid members identifiers in object definition + deps(n[i]) of nkIdent: uses.incl n.ident.id of nkSym: uses.incl n.sym.name.id of nkAccQuoted: uses.incl accQuoted(n).id of nkOpenSymChoice, nkClosedSymChoice: uses.incl n.sons[0].sym.name.id - of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse: + of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse, nkStaticStmt: for i in 0..<len(n): computeDeps(n[i], declares, uses, topLevel) + of nkPragma: + let a = n.sons[0] + if a.kind == nkExprColonExpr and a.sons[0].kind == nkIdent and + a.sons[0].ident.s == "pragma": + # user defined pragma + decl(a.sons[1]) + else: + for i in 0..<safeLen(n): deps(n[i]) else: for i in 0..<safeLen(n): deps(n[i]) -proc visit(i: int; all, res: PNode; deps: var seq[(IntSet, IntSet)]): bool = - let n = all[i] - if nfTempMark in n.flags: - # not a DAG! +proc cleanPath(s: string): string = + # Here paths may have the form A / B or "A/B" + result = "" + for c in s: + if c != ' ' and c != '\"': + result.add c + +proc joinPath(parts: seq[string]): string = + let nb = parts.len + assert nb > 0 + if nb == 1: + return parts[0] + result = parts[0] / parts[1] + for i in 2..<parts.len: + result = result / parts[i] + +proc getIncludePath(n: PNode, modulePath: string): string = + let istr = n.renderTree.cleanPath + let (pdir, _) = modulePath.splitPath + let p = istr.split('/').joinPath.addFileExt("nim") + result = pdir / p + +proc hasIncludes(n:PNode): bool = + for a in n: + if a.kind == nkIncludeStmt: + return true + +proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: int32; + cache: IdentCache): PNode {.procvar.} = + result = syntaxes.parseFile(fileIdx, cache) + graph.addDep(s, fileIdx) + graph.addIncludeDep(s.position.int32, fileIdx) + +proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode, + modulePath: string, includedFiles: var IntSet, + cache: IdentCache): PNode = + # Parses includes and injects them in the current tree + if not n.hasIncludes: + return n + result = newNodeI(nkStmtList, n.info) + for a in n: + if a.kind == nkIncludeStmt: + for i in 0..<a.len: + var f = checkModuleName(a.sons[i]) + if f != InvalidFileIDX: + if containsOrIncl(includedFiles, f): + localError(a.info, errRecursiveDependencyX, f.toFilename) + else: + let nn = includeModule(graph, module, f, cache) + let nnn = expandIncludes(graph, module, nn, modulePath, + includedFiles, cache) + excl(includedFiles, f) + for b in nnn: + result.add b + else: + result.add a + +proc splitSections(n: PNode): PNode = + # Split typeSections and ConstSections into + # sections that contain only one definition + assert n.kind == nkStmtList + result = newNodeI(nkStmtList, n.info) + for a in n: + if a.kind in {nkTypeSection, nkConstSection} and a.len > 1: + for b in a: + var s = newNode(a.kind) + s.info = b.info + s.add b + result.add s + else: + result.add a + +proc haveSameKind(dns: seq[DepN]): bool = + # Check if all the nodes in a strongly connected + # component have the same kind + result = true + let kind = dns[0].pnode.kind + for dn in dns: + if dn.pnode.kind != kind: + return false + +proc mergeSections(comps: seq[seq[DepN]], res: PNode) = + # Merges typeSections and ConstSections when they form + # a strong component (ex: circular type definition) + for c in comps: + assert c.len > 0 + if c.len == 1: + res.add c[0].pnode + else: + let fstn = c[0].pnode + let kind = fstn.kind + # always return to the original order when we got circular dependencies + let cs = c.sortedByIt(it.id) + if kind in {nkTypeSection, nkConstSection} and haveSameKind(cs): + # Circular dependency between type or const sections, we just + # need to merge them + var sn = newNode(kind) + for dn in cs: + sn.add dn.pnode.sons[0] + res.add sn + else: + # Problematic circular dependency, we arrange the nodes into + # their original relative order and make sure to re-merge + # consecutive type and const sections + var wmsg = "Circular dependency detected. reorder pragma may not be able to" & + " reorder some nodes properely" + when not defined(release): + wmsg &= ":\n" + for i in 0..<cs.len-1: + for j in i..<cs.len: + for ci in 0..<cs[i].kids.len: + if cs[i].kids[ci].id == cs[j].id: + wmsg &= "line " & $cs[i].pnode.info.line & + " depends on line " & $cs[j].pnode.info.line & + ": " & cs[i].expls[ci] & "\n" + for j in 0..<cs.len-1: + for ci in 0..<cs[^1].kids.len: + if cs[^1].kids[ci].id == cs[j].id: + wmsg &= "line " & $cs[^1].pnode.info.line & + " depends on line " & $cs[j].pnode.info.line & + ": " & cs[^1].expls[ci] & "\n" + message(cs[0].pnode.info, warnUser, wmsg) + + var i = 0 + while i < cs.len: + if cs[i].pnode.kind in {nkTypeSection, nkConstSection}: + let ckind = cs[i].pnode.kind + var sn = newNode(ckind) + sn.add cs[i].pnode[0] + inc i + while i < cs.len and cs[i].pnode.kind == ckind : + sn.add cs[i].pnode[0] + inc i + res.add sn + else: + res.add cs[i].pnode + inc i + +proc hasImportStmt(n: PNode): bool = + # Checks if the node is an import statement or + # i it contains one + case n.kind + of nkImportStmt, nkFromStmt, nkImportExceptStmt: return true - if nfPermMark notin n.flags: - incl n.flags, nfTempMark - var uses = deps[i][1] - for j in 0..<all.len: - if j != i: - let declares = deps[j][0] + of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse, nkStaticStmt: + for a in n: + if a.hasImportStmt: + return true + else: + result = false + +proc hasImportStmt(n: DepN): bool = + if n.hIS < 0: + n.hIS = ord(n.pnode.hasImportStmt) + result = bool(n.hIS) + +proc hasCommand(n: PNode): bool = + # Checks if the node is a command or a call + # or if it contains one + case n.kind + of nkCommand, nkCall: + result = true + of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse, + nkStaticStmt, nkLetSection, nkConstSection, nkVarSection, + nkIdentDefs: + for a in n: + if a.hasCommand: + return true + else: + return false + +proc hasCommand(n: DepN): bool = + if n.hCmd < 0: + n.hCmd = ord(n.pnode.hasCommand) + result = bool(n.hCmd) + +proc hasAccQuoted(n: PNode): bool = + if n.kind == nkAccQuoted: + return true + for a in n: + if hasAccQuoted(a): + return true + +const extandedProcDefs = procDefs + {nkMacroDef, nkTemplateDef} + +proc hasAccQuotedDef(n: PNode): bool = + # Checks if the node is a function, macro, template ... + # with a quoted name or if it contains one + case n.kind + of extandedProcDefs: + result = n[0].hasAccQuoted + of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse, nkStaticStmt: + for a in n: + if a.hasAccQuotedDef: + return true + else: + result = false + +proc hasAccQuotedDef(n: DepN): bool = + if n.hAQ < 0: + n.hAQ = ord(n.pnode.hasAccQuotedDef) + result = bool(n.hAQ) + +proc hasBody(n: PNode): bool = + # Checks if the node is a function, macro, template ... + # with a body or if it contains one + case n.kind + of nkCommand, nkCall: + result = true + of extandedProcDefs: + result = n[^1].kind == nkStmtList + of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse, nkStaticStmt: + for a in n: + if a.hasBody: + return true + else: + result = false + +proc hasBody(n: DepN): bool = + if n.hB < 0: + n.hB = ord(n.pnode.hasBody) + result = bool(n.hB) + +proc intersects(s1, s2: IntSet): bool = + for a in s1: + if s2.contains(a): + return true + +proc buildGraph(n: PNode, deps: seq[(IntSet, IntSet)]): DepG = + # Build a dependency graph + result = newSeqOfCap[DepN](deps.len) + for i in 0..<deps.len: + result.add newDepN(i, n.sons[i]) + for i in 0..<deps.len: + var ni = result[i] + let uses = deps[i][1] + let niHasBody = ni.hasBody + let niHasCmd = ni.hasCommand + for j in 0..<deps.len: + if i == j: continue + var nj = result[j] + let declares = deps[j][0] + if j < i and nj.hasCommand and niHasCmd: + # Preserve order for commands and calls + ni.kids.add nj + when not defined(release): + ni.expls.add "both have commands and one comes after the other" + elif j < i and nj.hasImportStmt: + # Every node that comes after an import statement must + # depend on that import + ni.kids.add nj + when not defined(release): + ni.expls.add "parent is, or contains, an import statement and child comes after it" + elif j < i and niHasBody and nj.hasAccQuotedDef: + # Every function, macro, template... with a body depends + # on precedent function declarations that have quoted names. + # That's because it is hard to detect the use of functions + # like "[]=", "[]", "or" ... in their bodies. + ni.kids.add nj + when not defined(release): + ni.expls.add "one declares a quoted identifier and the other has a body and comes after it" + elif j < i and niHasBody and not nj.hasBody and + intersects(deps[i][0], declares): + # Keep function declaration before function definition + ni.kids.add nj + when not defined(release): + for dep in deps[i][0]: + if dep in declares: + ni.expls.add "one declares \"" & idNames[dep] & "\" and the other defines it" + else: for d in declares: if uses.contains(d): - let oldLen = res.len - if visit(j, all, res, deps): - result = true - # rollback what we did, it turned out to be a dependency that caused - # trouble: - for k in oldLen..<res.len: - res.sons[k].flags = res.sons[k].flags - {nfPermMark, nfTempMark} - if oldLen != res.len: res.sons.setLen oldLen - break - n.flags = n.flags + {nfPermMark} - {nfTempMark} - res.add n - -proc reorder*(n: PNode): PNode = + ni.kids.add nj + when not defined(release): + ni.expls.add "one declares \"" & idNames[d] & "\" and the other uses it" + +proc strongConnect(v: var DepN, idx: var int, s: var seq[DepN], + res: var seq[seq[DepN]]) = + # Recursive part of trajan's algorithm + v.idx = idx + v.lowLink = idx + inc idx + s.add v + v.onStack = true + for w in v.kids.mitems: + if w.idx < 0: + strongConnect(w, idx, s, res) + v.lowLink = min(v.lowLink, w.lowLink) + elif w.onStack: + v.lowLink = min(v.lowLink, w.idx) + if v.lowLink == v.idx: + var comp = newSeq[DepN]() + while true: + var w = s.pop + w.onStack = false + comp.add w + if w.id == v.id: break + res.add comp + +proc getStrongComponents(g: var DepG): seq[seq[DepN]] = + ## Tarjan's algorithm. Performs a topological sort + ## and detects strongly connected components. + result = newSeq[seq[DepN]]() + var s = newSeq[DepN]() + var idx = 0 + for v in g.mitems: + if v.idx < 0: + strongConnect(v, idx, s, result) + +proc hasForbiddenPragma(n: PNode): bool = + # Checks if the tree node has some pragmas that do not + # play well with reordering, like the push/pop pragma + for a in n: + if a.kind == nkPragma and a[0].kind == nkIdent and + a[0].ident.s == "push": + return true + +proc reorder*(graph: ModuleGraph, n: PNode, module: PSym, cache: IdentCache): PNode = + if n.hasForbiddenPragma: + return n + var includedFiles = initIntSet() + let mpath = module.fileIdx.toFullPath + let n = expandIncludes(graph, module, n, mpath, + includedFiles, cache).splitSections result = newNodeI(nkStmtList, n.info) var deps = newSeq[(IntSet, IntSet)](n.len) for i in 0..<n.len: @@ -88,15 +439,6 @@ proc reorder*(n: PNode): PNode = deps[i][1] = initIntSet() computeDeps(n[i], deps[i][0], deps[i][1], true) - for i in 0 .. n.len-1: - discard visit(i, n, result, deps) - for i in 0..<result.len: - result.sons[i].flags = result.sons[i].flags - {nfTempMark, nfPermMark} - when false: - # reverse the result: - let L = result.len-1 - for i in 0 .. result.len div 2: - result.sons[i].flags = result.sons[i].flags - {nfTempMark, nfPermMark} - result.sons[L - i].flags = result.sons[L - i].flags - {nfTempMark, nfPermMark} - swap(result.sons[i], result.sons[L - i]) - #echo result + var g = buildGraph(n, deps) + let comps = getStrongComponents(g) + mergeSections(comps, result) diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 2546aa77a..dfa8fc52b 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -795,7 +795,7 @@ proc getReader(moduleId: int): PRodReader = # the module ID! We could introduce a mapping ID->PRodReader but I'll leave # this for later versions if benchmarking shows the linear search causes # problems: - for i in 0 .. <gMods.len: + for i in 0 ..< gMods.len: result = gMods[i].rd if result != nil and result.moduleID == moduleId: return result return nil @@ -861,12 +861,11 @@ proc loadMethods(r: PRodReader) = if r.s[r.pos] == ' ': inc(r.pos) proc getHash*(fileIdx: int32): SecureHash = - internalAssert fileIdx >= 0 and fileIdx < gMods.len - - if gMods[fileIdx].hashDone: + if fileIdx <% gMods.len and gMods[fileIdx].hashDone: return gMods[fileIdx].hash result = secureHashFile(fileIdx.toFullPath) + if fileIdx >= gMods.len: setLen(gMods, fileIdx+1) gMods[fileIdx].hash = result template growCache*(cache, pos) = @@ -912,7 +911,7 @@ proc checkDep(fileIdx: int32; cache: IdentCache): TReasonForRecompile = proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader = let fileIdx = module.fileIdx - if optSymbolFiles notin gGlobalOptions: + if gSymbolFiles in {disabledSf, writeOnlySf}: module.id = getID() return nil idgen.loadMaxIds(options.gProjectPath / options.gProjectName) diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 1bc136acf..9aed33ec9 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -13,8 +13,8 @@ import intsets, os, options, strutils, nversion, ast, astalgo, msgs, platform, - condsyms, ropes, idents, securehash, rodread, passes, importer, idgen, - rodutils + condsyms, ropes, idents, securehash, rodread, passes, idgen, + rodutils, modulepaths from modulegraphs import ModuleGraph diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim index 0c31eadbe..8eb76457c 100644 --- a/compiler/scriptconfig.nim +++ b/compiler/scriptconfig.nim @@ -73,13 +73,14 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string; cbos copyFile: os.copyFile(getString(a, 0), getString(a, 1)) cbos getLastModificationTime: - setResult(a, toSeconds(getLastModificationTime(getString(a, 0)))) + # depends on Time's implementation! + setResult(a, int64(getLastModificationTime(getString(a, 0)))) cbos rawExec: setResult(a, osproc.execCmd getString(a, 0)) cbconf getEnv: - setResult(a, os.getEnv(a.getString 0)) + setResult(a, os.getEnv(a.getString 0, a.getString 1)) cbconf existsEnv: setResult(a, os.existsEnv(a.getString 0)) cbconf dirExists: @@ -143,6 +144,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string; proc runNimScript*(cache: IdentCache; scriptName: string; freshDefines=true; config: ConfigRef=nil) = + rawMessage(hintConf, scriptName) passes.gIncludeFile = includeModule passes.gImportModule = importModule let graph = newModuleGraph(config) diff --git a/compiler/sem.nim b/compiler/sem.nim index ebfdafea7..1098e9961 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -12,7 +12,7 @@ import ast, strutils, hashes, options, lexer, astalgo, trees, treetab, wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math, - magicsys, parser, nversion, nimsets, semfold, importer, + magicsys, parser, nversion, nimsets, semfold, modulepaths, importer, procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch, intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting, evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity, @@ -74,7 +74,7 @@ proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode = localError(arg.info, errExprXHasNoType, renderTree(arg, {renderNoComments})) # error correction: - result = copyNode(arg) + result = copyTree(arg) result.typ = formal else: result = indexTypesMatch(c, formal, arg.typ, arg) @@ -122,7 +122,7 @@ proc commonType*(x, y: PType): PType = if a.sons[idx].kind == tyEmpty: return y elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len: var nt: PType - for i in 0.. <a.len: + for i in 0..<a.len: let aEmpty = isEmptyContainer(a.sons[i]) let bEmpty = isEmptyContainer(b.sons[i]) if aEmpty != bEmpty: @@ -165,6 +165,19 @@ proc commonType*(x, y: PType): PType = result = newType(k, r.owner) result.addSonSkipIntLit(r) +proc endsInNoReturn(n: PNode): bool = + # check if expr ends in raise exception or call of noreturn proc + var it = n + while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0: + it = it.lastSon + result = it.kind == nkRaiseStmt or + it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags + +proc commonType*(x: PType, y: PNode): PType = + # ignore exception raising branches in case/if expressions + if endsInNoReturn(y): return x + commonType(x, y.typ) + proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = result = newSym(kind, considerQuotedIdent(n), getCurrOwner(c), n.info) when defined(nimsuggest): @@ -423,7 +436,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, result = evalMacroCall(c.module, c.cache, n, nOrig, sym) if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, sym, flags) - result = wrapInComesFrom(nOrig.info, result) + result = wrapInComesFrom(nOrig.info, sym, result) popInfoContext() proc forceBool(c: PContext, n: PNode): PNode = @@ -488,6 +501,8 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = proc myOpenCached(graph: ModuleGraph; module: PSym; rd: PRodReader): PPassContext = result = myOpen(graph, module, rd.cache) + +proc replayMethodDefs(graph: ModuleGraph; rd: PRodReader) = for m in items(rd.methods): methodDef(graph, m, true) proc isImportSystemStmt(n: PNode): bool = @@ -522,14 +537,18 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = else: result = n result = semStmt(c, result) - # BUGFIX: process newly generated generics here, not at the end! - if c.lastGenericIdx < c.generics.len: - var a = newNodeI(nkStmtList, n.info) - addCodeForGenerics(c, a) - if sonsLen(a) > 0: - # a generic has been added to `a`: - if result.kind != nkEmpty: addSon(a, result) - result = a + when false: + # Code generators are lazy now and can deal with undeclared procs, so these + # steps are not required anymore and actually harmful for the upcoming + # destructor support. + # BUGFIX: process newly generated generics here, not at the end! + if c.lastGenericIdx < c.generics.len: + var a = newNodeI(nkStmtList, n.info) + addCodeForGenerics(c, a) + if sonsLen(a) > 0: + # a generic has been added to `a`: + if result.kind != nkEmpty: addSon(a, result) + result = a result = hloStmt(c, result) if gCmd == cmdInteractive and not isEmptyType(result.typ): result = buildEchoStmt(c, result) @@ -566,6 +585,18 @@ proc myProcess(context: PPassContext, n: PNode): PNode = result = ast.emptyNode #if gCmd == cmdIdeTools: findSuggest(c, n) +proc testExamples(c: PContext) = + let inp = toFullPath(c.module.info) + let outp = inp.changeFileExt"" & "_examples.nim" + renderModule(c.runnableExamples, inp, outp) + let backend = if isDefined("js"): "js" + elif isDefined("cpp"): "cpp" + elif isDefined("objc"): "objc" + else: "c" + if os.execShellCmd("nim " & backend & " -r " & outp) != 0: + quit "[Examples] failed" + removeFile(outp) + proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = var c = PContext(context) if gCmd == cmdIdeTools and not c.suggestionsMade: @@ -578,7 +609,10 @@ proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = addCodeForGenerics(c, result) if c.module.ast != nil: result.add(c.module.ast) + if c.rd != nil: + replayMethodDefs(graph, c.rd) popOwner(c) popProcCon(c) + if c.runnableExamples != nil: testExamples(c) const semPass* = makePass(myOpen, myOpenCached, myProcess, myClose) diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index caed11341..67af6ade7 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -7,8 +7,8 @@ # distribution, for details about the copyright. # -## This module implements lifting for assignments. Later versions of this code -## will be able to also lift ``=deepCopy`` and ``=destroy``. +## This module implements lifting for type-bound operations +## (``=sink``, ``=``, ``=destroy``, ``=deepCopy``). # included from sem.nim @@ -22,7 +22,8 @@ type recurse: bool proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) -proc liftBody(c: PContext; typ: PType; info: TLineInfo): PSym +proc liftBody(c: PContext; typ: PType; kind: TTypeAttachedOp; + info: TLineInfo): PSym {.discardable.} proc at(a, i: PNode, elemType: PType): PNode = result = newNodeI(nkBracketExpr, a.info, 2) @@ -31,7 +32,7 @@ proc at(a, i: PNode, elemType: PType): PNode = result.typ = elemType proc liftBodyTup(c: var TLiftCtx; t: PType; body, x, y: PNode) = - for i in 0 .. <t.len: + for i in 0 ..< t.len: let lit = lowerings.newIntLit(i) liftBodyAux(c, t.sons[i], body, x.at(lit, t.sons[i]), y.at(lit, t.sons[i])) @@ -57,7 +58,7 @@ proc liftBodyObj(c: var TLiftCtx; n, body, x, y: PNode) = var access = dotField(x, n[0].sym) caseStmt.add(access) # copy the branches over, but replace the fields with the for loop body: - for i in 1 .. <n.len: + for i in 1 ..< n.len: var branch = copyTree(n[i]) let L = branch.len branch.sons[L-1] = newNodeI(nkStmtList, c.info) @@ -97,9 +98,37 @@ proc newOpCall(op: PSym; x: PNode): PNode = result.add(newSymNode(op)) result.add x +proc destructorCall(c: PContext; op: PSym; x: PNode): PNode = + result = newNodeIT(nkCall, x.info, op.typ.sons[0]) + result.add(newSymNode(op)) + if newDestructors: + result.add genAddr(c, x) + else: + result.add x + proc newDeepCopyCall(op: PSym; x, y: PNode): PNode = result = newAsgnStmt(x, newOpCall(op, y)) +proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode; + field: PSym): bool = + if tfHasAsgn in t.flags: + var op: PSym + if sameType(t, c.asgnForType): + # generate recursive call: + if c.recurse: + op = c.fn + else: + c.recurse = true + return false + else: + op = field + if op == nil: + op = liftBody(c.c, t, c.kind, c.info) + markUsed(c.info, op, c.c.graph.usageSym) + styleCheckUse(c.info, op) + body.add newAsgnCall(c.c, op, x, y) + result = true + proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool = case c.kind of attachedDestructor: @@ -107,26 +136,12 @@ proc considerOverloadedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool = if op != nil: markUsed(c.info, op, c.c.graph.usageSym) styleCheckUse(c.info, op) - body.add newOpCall(op, x) + body.add destructorCall(c.c, op, x) result = true of attachedAsgn: - if tfHasAsgn in t.flags: - var op: PSym - if sameType(t, c.asgnForType): - # generate recursive call: - if c.recurse: - op = c.fn - else: - c.recurse = true - return false - else: - op = t.assignment - if op == nil: - op = liftBody(c.c, t, c.info) - markUsed(c.info, op, c.c.graph.usageSym) - styleCheckUse(c.info, op) - body.add newAsgnCall(c.c, op, x, y) - result = true + result = considerAsgnOrSink(c, t, body, x, y, t.assignment) + of attachedSink: + result = considerAsgnOrSink(c, t, body, x, y, t.sink) of attachedDeepCopy: let op = t.deepCopy if op != nil: @@ -188,7 +203,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) = tyPtr, tyString, tyRef, tyOpt: defaultOp(c, t, body, x, y) of tyArray, tySequence: - if tfHasAsgn in t.flags: + if {tfHasAsgn, tfUncheckedArray} * t.flags == {tfHasAsgn}: if t.kind == tySequence: # XXX add 'nil' handling here body.add newSeqCall(c.c, x, y) @@ -245,12 +260,20 @@ proc addParam(procType: PType; param: PSym) = addSon(procType.n, newSymNode(param)) rawAddSon(procType, param.typ) -proc liftBody(c: PContext; typ: PType; info: TLineInfo): PSym = +proc liftBody(c: PContext; typ: PType; kind: TTypeAttachedOp; + info: TLineInfo): PSym = var a: TLiftCtx a.info = info a.c = c + a.kind = kind let body = newNodeI(nkStmtList, info) - result = newSym(skProc, getIdent":lifted=", typ.owner, info) + let procname = case kind + of attachedAsgn: getIdent"=" + of attachedSink: getIdent"=sink" + of attachedDeepCopy: getIdent"=deepcopy" + of attachedDestructor: getIdent"=destroy" + + result = newSym(skProc, procname, typ.owner, info) a.fn = result a.asgnForType = typ @@ -261,27 +284,54 @@ proc liftBody(c: PContext; typ: PType; info: TLineInfo): PSym = result.typ = newProcType(info, typ.owner) result.typ.addParam dest - result.typ.addParam src + if kind != attachedDestructor: + result.typ.addParam src liftBodyAux(a, typ, body, newSymNode(dest).newDeref, newSymNode(src)) + # recursion is handled explicitly, do not register the type based operation + # before 'liftBodyAux': + case kind + of attachedAsgn: typ.assignment = result + of attachedSink: typ.sink = result + of attachedDeepCopy: typ.deepCopy = result + of attachedDestructor: typ.destructor = result var n = newNodeI(nkProcDef, info, bodyPos+1) - for i in 0 .. < n.len: n.sons[i] = emptyNode + for i in 0 ..< n.len: n.sons[i] = emptyNode n.sons[namePos] = newSymNode(result) n.sons[paramsPos] = result.typ.n n.sons[bodyPos] = body result.ast = n + incl result.flags, sfFromGeneric - # register late as recursion is handled differently - typ.assignment = result - #echo "Produced this ", n proc getAsgnOrLiftBody(c: PContext; typ: PType; info: TLineInfo): PSym = let t = typ.skipTypes({tyGenericInst, tyVar, tyAlias}) result = t.assignment if result.isNil: - result = liftBody(c, t, info) + result = liftBody(c, t, attachedAsgn, info) proc overloadedAsgn(c: PContext; dest, src: PNode): PNode = let a = getAsgnOrLiftBody(c, dest.typ, dest.info) result = newAsgnCall(c, a, dest, src) + +proc liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) = + ## In the semantic pass this is called in strategic places + ## to ensure we lift assignment, destructors and moves properly. + ## The later 'destroyer' pass depends on it. + if not newDestructors or not hasDestructor(typ): return + when false: + # do not produce wrong liftings while we're still instantiating generics: + # now disabled; breaks topttree.nim! + if c.typesWithOps.len > 0: return + let typ = typ.skipTypes({tyGenericInst, tyAlias}) + # we generate the destructor first so that other operators can depend on it: + if typ.destructor == nil: + liftBody(c, typ, attachedDestructor, info) + if typ.assignment == nil: + liftBody(c, typ, attachedAsgn, info) + if typ.sink == nil: + liftBody(c, typ, attachedSink, info) + +#proc patchResolvedTypeBoundOp*(c: PContext; n: PNode): PNode = +# if n.kind == nkCall and diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 9492e63f4..a51b9afe3 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -27,7 +27,7 @@ proc sameMethodDispatcher(a, b: PSym): bool = # method collide[T](a: TThing, b: TUnit[T]) is instantiated and not # method collide[T](a: TUnit[T], b: TThing)! This means we need to # *instantiate* every candidate! However, we don't keep more than 2-3 - # candidated around so we cannot implement that for now. So in order + # candidates around so we cannot implement that for now. So in order # to avoid subtle problems, the call remains ambiguous and needs to # be disambiguated by the programmer; this way the right generic is # instantiated. @@ -90,6 +90,10 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, if c.currentScope.symbols.counter == counterInitial or syms != nil: matches(c, n, orig, z) if z.state == csMatch: + #if sym.name.s == "==" and (n.info ?? "temp3"): + # echo typeToString(sym.typ) + # writeMatches(z) + # little hack so that iterators are preferred over everything else: if sym.kind == skIterator: inc(z.exactMatches, 200) case best.state @@ -175,7 +179,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) = add(result, ')') if candidates != "": add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates) - localError(n.info, errGenerated, result) + localError(n.info, errGenerated, result & "\nexpression: " & $n) proc bracketNotFoundError(c: PContext; n: PNode) = var errors: CandidateErrors = @[] @@ -231,12 +235,11 @@ proc resolveOverloads(c: PContext, n, orig: PNode, if nfDotField in n.flags: internalAssert f.kind == nkIdent and n.sonsLen >= 2 - let calleeName = newStrNode(nkStrLit, f.ident.s).withInfo(n.info) # leave the op head symbol empty, # we are going to try multiple variants - n.sons[0..1] = [nil, n[1], calleeName] - orig.sons[0..1] = [nil, orig[1], calleeName] + n.sons[0..1] = [nil, n[1], f] + orig.sons[0..1] = [nil, orig[1], f] template tryOp(x) = let op = newIdentNode(getIdent(x), n.info) @@ -251,8 +254,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode, tryOp "." elif nfDotSetter in n.flags and f.kind == nkIdent and n.len == 3: - let calleeName = newStrNode(nkStrLit, - f.ident.s[0..f.ident.s.len-2]).withInfo(n.info) + # we need to strip away the trailing '=' here: + let calleeName = newIdentNode(getIdent(f.ident.s[0..f.ident.s.len-2]), n.info) let callOp = newIdentNode(getIdent".=", n.info) n.sons[0..1] = [callOp, n[1], calleeName] orig.sons[0..1] = [callOp, orig[1], calleeName] @@ -306,7 +309,7 @@ proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) = proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) = assert n.kind in nkCallKinds if x.genericConverter: - for i in 1 .. <n.len: + for i in 1 ..< n.len: instGenericConvertersArg(c, n.sons[i], x) proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = @@ -490,7 +493,7 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = var call = newNodeI(nkCall, fn.info) var hasDistinct = false call.add(newIdentNode(fn.name, fn.info)) - for i in 1.. <fn.typ.n.len: + for i in 1..<fn.typ.n.len: let param = fn.typ.n.sons[i] let t = skipTypes(param.typ, abstractVar-{tyTypeDesc, tyDistinct}) if t.kind == tyDistinct or param.typ.kind == tyDistinct: hasDistinct = true diff --git a/compiler/semdata.nim b/compiler/semdata.nim index a3f0f715b..8affee649 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -37,7 +37,6 @@ type # in standalone ``except`` and ``finally`` next*: PProcCon # used for stacking procedure contexts wasForwarded*: bool # whether the current proc has a separate header - bracketExpr*: PNode # current bracket expression (for ^ support) mapping*: TIdTable TMatchedConcept* = object @@ -70,6 +69,7 @@ type TTypeAttachedOp* = enum attachedAsgn, + attachedSink, attachedDeepCopy, attachedDestructor @@ -131,6 +131,12 @@ type recursiveDep*: string suggestionsMade*: bool inTypeContext*: int + typesWithOps*: seq[(PType, PType)] #\ + # We need to instantiate the type bound ops lazily after + # the generic type has been constructed completely. See + # tests/destructor/topttree.nim for an example that + # would otherwise fail. + runnableExamples*: PNode proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = result.genericSym = s @@ -218,6 +224,7 @@ proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext result.cache = cache result.graph = graph initStrTable(result.signatures) + result.typesWithOps = @[] proc inclSym(sq: var TSymSeq, s: PSym) = @@ -333,7 +340,7 @@ proc makeNotType*(c: PContext, t1: PType): PType = proc nMinusOne*(n: PNode): PNode = result = newNode(nkCall, n.info, @[ - newSymNode(getSysMagic("<", mUnaryLt)), + newSymNode(getSysMagic("pred", mPred)), n]) # Remember to fix the procs below this one when you make changes! diff --git a/compiler/semdestruct.nim b/compiler/semdestruct.nim deleted file mode 100644 index 51109ec37..000000000 --- a/compiler/semdestruct.nim +++ /dev/null @@ -1,186 +0,0 @@ -# -# -# The Nim Compiler -# (c) Copyright 2013 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module implements destructors. - -# included from sem.nim - -# special marker values that indicates that we are -# 1) AnalyzingDestructor: currently analyzing the type for destructor -# generation (needed for recursive types) -# 2) DestructorIsTrivial: completed the analysis before and determined -# that the type has a trivial destructor -var analyzingDestructor, destructorIsTrivial: PSym -new(analyzingDestructor) -new(destructorIsTrivial) - -var - destructorName = getIdent"destroy_" - destructorParam = getIdent"this_" - destructorPragma = newIdentNode(getIdent"destructor", unknownLineInfo()) - -proc instantiateDestructor(c: PContext, typ: PType): PType - -proc doDestructorStuff(c: PContext, s: PSym, n: PNode) = - var t = s.typ.sons[1].skipTypes({tyVar}) - if t.kind == tyGenericInvocation: - for i in 1 .. <t.sonsLen: - if t.sons[i].kind != tyGenericParam: - localError(n.info, errDestructorNotGenericEnough) - return - t = t.base - elif t.kind == tyCompositeTypeClass: - t = t.base - if t.kind != tyGenericBody: - localError(n.info, errDestructorNotGenericEnough) - return - - t.destructor = s - # automatically insert calls to base classes' destructors - if n.sons[bodyPos].kind != nkEmpty: - for i in countup(0, t.sonsLen - 1): - # when inheriting directly from object - # there will be a single nil son - if t.sons[i] == nil: continue - let destructableT = instantiateDestructor(c, t.sons[i]) - if destructableT != nil: - n.sons[bodyPos].addSon(newNode(nkCall, t.sym.info, @[ - useSym(destructableT.destructor, c.graph.usageSym), - n.sons[paramsPos][1][0]])) - -proc destroyFieldOrFields(c: PContext, field: PNode, holder: PNode): PNode - -proc destroySym(c: PContext, field: PSym, holder: PNode): PNode = - let destructableT = instantiateDestructor(c, field.typ) - if destructableT != nil: - result = newNode(nkCall, field.info, @[ - useSym(destructableT.destructor, c.graph.usageSym), - newNode(nkDotExpr, field.info, @[holder, useSym(field, c.graph.usageSym)])]) - -proc destroyCase(c: PContext, n: PNode, holder: PNode): PNode = - var nonTrivialFields = 0 - result = newNode(nkCaseStmt, n.info, @[]) - # case x.kind - result.addSon(newNode(nkDotExpr, n.info, @[holder, n.sons[0]])) - for i in countup(1, n.len - 1): - # of A, B: - let ni = n[i] - var caseBranch = newNode(ni.kind, ni.info, ni.sons[0..ni.len-2]) - - let stmt = destroyFieldOrFields(c, ni.lastSon, holder) - if stmt == nil: - caseBranch.addSon(newNode(nkStmtList, ni.info, @[])) - else: - caseBranch.addSon(stmt) - nonTrivialFields += stmt.len - - result.addSon(caseBranch) - - # maybe no fields were destroyed? - if nonTrivialFields == 0: - result = nil - -proc destroyFieldOrFields(c: PContext, field: PNode, holder: PNode): PNode = - template maybeAddLine(e) = - let stmt = e - if stmt != nil: - if result == nil: result = newNode(nkStmtList) - result.addSon(stmt) - - case field.kind - of nkRecCase: - maybeAddLine destroyCase(c, field, holder) - of nkSym: - maybeAddLine destroySym(c, field.sym, holder) - of nkRecList: - for son in field: - maybeAddLine destroyFieldOrFields(c, son, holder) - else: - internalAssert false - -proc generateDestructor(c: PContext, t: PType): PNode = - ## generate a destructor for a user-defined object or tuple type - ## returns nil if the destructor turns out to be trivial - - # XXX: This may be true for some C-imported types such as - # Tposix_spawnattr - if t.n == nil or t.n.sons == nil: return - internalAssert t.n.kind == nkRecList - let destructedObj = newIdentNode(destructorParam, unknownLineInfo()) - # call the destructods of all fields - result = destroyFieldOrFields(c, t.n, destructedObj) - # base classes' destructors will be automatically called by - # semProcAux for both auto-generated and user-defined destructors - -proc instantiateDestructor(c: PContext, typ: PType): PType = - # returns nil if a variable of type `typ` doesn't require a - # destructor. Otherwise, returns the type, which holds the - # destructor that must be used for the varialbe. - # The destructor is either user-defined or automatically - # generated by the compiler in a member-wise fashion. - var t = typ.skipGenericAlias - let typeHoldingUserDefinition = if t.kind == tyGenericInst: t.base else: t - - if typeHoldingUserDefinition.destructor != nil: - # XXX: This is not entirely correct for recursive types, but we need - # it temporarily to hide the "destroy is already defined" problem - if typeHoldingUserDefinition.destructor notin - [analyzingDestructor, destructorIsTrivial]: - return typeHoldingUserDefinition - else: - return nil - - t = t.skipTypes({tyGenericInst, tyAlias}) - case t.kind - of tySequence, tyArray, tyOpenArray, tyVarargs: - t.destructor = analyzingDestructor - if instantiateDestructor(c, t.sons[0]) != nil: - t.destructor = getCompilerProc"nimDestroyRange" - return t - else: - return nil - of tyTuple, tyObject: - t.destructor = analyzingDestructor - let generated = generateDestructor(c, t) - if generated != nil: - internalAssert t.sym != nil - var i = t.sym.info - let fullDef = newNode(nkProcDef, i, @[ - newIdentNode(destructorName, i), - emptyNode, - emptyNode, - newNode(nkFormalParams, i, @[ - emptyNode, - newNode(nkIdentDefs, i, @[ - newIdentNode(destructorParam, i), - symNodeFromType(c, makeVarType(c, t), t.sym.info), - emptyNode]), - ]), - newNode(nkPragma, i, @[destructorPragma]), - emptyNode, - generated - ]) - let semantizedDef = semProc(c, fullDef) - t.destructor = semantizedDef[namePos].sym - return t - else: - t.destructor = destructorIsTrivial - return nil - else: - return nil - -proc createDestructorCall(c: PContext, s: PSym): PNode = - let varTyp = s.typ - if varTyp == nil or sfGlobal in s.flags: return - let destructableT = instantiateDestructor(c, varTyp) - if destructableT != nil: - let call = semStmt(c, newNode(nkCall, s.info, @[ - useSym(destructableT.destructor, c.graph.usageSym), - useSym(s, c.graph.usageSym)])) - result = newNode(nkDefer, s.info, @[call]) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 180754168..51e75e91f 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -53,7 +53,6 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = else: if efNoProcvarCheck notin flags: semProcvarCheck(c, result) if result.typ.kind == tyVar: result = newDeref(result) - semDestructorCheck(c, result, flags) proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExpr(c, n, flags) @@ -66,7 +65,6 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result.typ = errorType(c) else: semProcvarCheck(c, result) - semDestructorCheck(c, result, flags) proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = result = symChoice(c, n, s, scClosed) @@ -436,12 +434,12 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = #addSon(result, fitNode(c, typ, n.sons[i])) inc(lastIndex) addSonSkipIntLit(result.typ, typ) - for i in 0 .. <result.len: + for i in 0 ..< result.len: result.sons[i] = fitNode(c, typ, result.sons[i], result.sons[i].info) result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info) proc fixAbstractType(c: PContext, n: PNode) = - for i in 1 .. < n.len: + for i in 1 ..< n.len: let it = n.sons[i] # do not get rid of nkHiddenSubConv for OpenArrays, the codegen needs it: if it.kind == nkHiddenSubConv and @@ -465,7 +463,7 @@ proc newHiddenAddrTaken(c: PContext, n: PNode): PNode = result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ)) addSon(result, n) if isAssignable(c, n) notin {arLValue, arLocalLValue}: - localError(n.info, errVarForOutParamNeeded) + localError(n.info, errVarForOutParamNeededX, $n) proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = result = n @@ -509,9 +507,10 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = for i in countup(1, sonsLen(n) - 1): if i < sonsLen(t) and t.sons[i] != nil and skipTypes(t.sons[i], abstractInst-{tyTypeDesc}).kind == tyVar: - if isAssignable(c, n.sons[i]) notin {arLValue, arLocalLValue}: - if n.sons[i].kind != nkHiddenAddr: - localError(n.sons[i].info, errVarForOutParamNeeded) + let it = n[i] + if isAssignable(c, it) notin {arLValue, arLocalLValue}: + if it.kind != nkHiddenAddr: + localError(it.info, errVarForOutParamNeededX, $it) return for i in countup(1, sonsLen(n) - 1): if n.sons[i].kind == nkHiddenCallConv: @@ -539,7 +538,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = var call = newNodeIT(nkCall, n.info, n.typ) call.add(n.sons[0]) var allConst = true - for i in 1 .. < n.len: + for i in 1 ..< n.len: var a = getConstExpr(c.module, n.sons[i]) if a == nil: allConst = false @@ -550,7 +549,6 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = result = semfold.getConstExpr(c.module, call) if result.isNil: result = n else: return result - result.typ = semfold.getIntervalType(callee.magic, call) block maybeLabelAsStatic: # XXX: temporary work-around needed for tlateboundstatic. @@ -558,7 +556,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = # done until we have a more robust infrastructure for # implicit statics. if n.len > 1: - for i in 1 .. <n.len: + for i in 1 ..< n.len: # see bug #2113, it's possible that n[i].typ for errornous code: if n[i].typ.isNil or n[i].typ.kind != tyStatic or tfUnresolved notin n[i].typ.flags: @@ -580,7 +578,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = var call = newNodeIT(nkCall, n.info, n.typ) call.add(n.sons[0]) - for i in 1 .. < n.len: + for i in 1 ..< n.len: let a = getConstExpr(c.module, n.sons[i]) if a == nil: return n call.add(a) @@ -654,7 +652,7 @@ proc bracketedMacro(n: PNode): PSym = result = nil proc setGenericParams(c: PContext, n: PNode) = - for i in 1 .. <n.len: + for i in 1 ..< n.len: n[i].typ = semTypeNode(c, n[i], nil) proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode = @@ -670,6 +668,8 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode = analyseIfAddressTakenInCall(c, result) if callee.magic != mNone: result = magicsAfterOverloadResolution(c, result, flags) + if result.typ != nil: liftTypeBoundOps(c, result.typ, n.info) + #result = patchResolvedTypeBoundOp(c, result) if c.matchedConcept == nil: result = evalAtCompileTime(c, result) @@ -780,6 +780,19 @@ proc buildEchoStmt(c: PContext, n: PNode): PNode = proc semExprNoType(c: PContext, n: PNode): PNode = result = semExpr(c, n, {efWantStmt}) + # make an 'if' expression an 'if' statement again for backwards + # compatibility (.discardable was a bad idea!); bug #6980 + var isStmt = false + if result.kind == nkIfExpr: + isStmt = true + for condActionPair in result: + let action = condActionPair.lastSon + if not implicitlyDiscardable(action) and not + endsInNoReturn(action): + isStmt = false + if isStmt: + result.kind = nkIfStmt + result.typ = nil discardCheck(c, result) proc isTypeExpr(n: PNode): bool = @@ -1188,7 +1201,6 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = tyCString: if n.len != 2: return nil n.sons[0] = makeDeref(n.sons[0]) - c.p.bracketExpr = n.sons[0] for i in countup(1, sonsLen(n) - 1): n.sons[i] = semExprWithType(c, n.sons[i], flags*{efInTypeof, efDetermineType}) @@ -1209,7 +1221,6 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = of tyTuple: if n.len != 2: return nil n.sons[0] = makeDeref(n.sons[0]) - c.p.bracketExpr = n.sons[0] # [] operator for tuples requires constant expression: n.sons[1] = semConstExpr(c, n.sons[1]) if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal, tyAlias}).kind in @@ -1247,17 +1258,13 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = of skType: result = symNodeFromType(c, semTypeNode(c, n, nil), n.info) else: - c.p.bracketExpr = n.sons[0] - else: - c.p.bracketExpr = n.sons[0] + discard proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = - let oldBracketExpr = c.p.bracketExpr result = semSubscript(c, n, flags) if result == nil: # overloaded [] operator: result = semExpr(c, buildOverloadedSubscripts(n, getIdent"[]")) - c.p.bracketExpr = oldBracketExpr proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode = var id = considerQuotedIdent(a[1], a) @@ -1296,13 +1303,10 @@ proc takeImplicitAddr(c: PContext, n: PNode): PNode = proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} = if le.kind == nkHiddenDeref: var x = le.sons[0] - if x.typ.kind == tyVar and x.kind == nkSym: - if x.sym.kind == skResult: - n.sons[0] = x # 'result[]' --> 'result' - n.sons[1] = takeImplicitAddr(c, ri) - if x.sym.kind != skParam: - # XXX This is hacky. See bug #4910. - x.typ.flags.incl tfVarIsPtr + if x.typ.kind == tyVar and x.kind == nkSym and x.sym.kind == skResult: + n.sons[0] = x # 'result[]' --> 'result' + n.sons[1] = takeImplicitAddr(c, ri) + x.typ.flags.incl tfVarIsPtr #echo x.info, " setting it for this type ", typeToString(x.typ), " ", n.info template resultTypeIsInferrable(typ: PType): untyped = @@ -1329,7 +1333,6 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = of nkBracketExpr: # a[i] = x # --> `[]=`(a, i, x) - let oldBracketExpr = c.p.bracketExpr a = semSubscript(c, a, {efLValue}) if a == nil: result = buildOverloadedSubscripts(n.sons[0], getIdent"[]=") @@ -1339,9 +1342,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = return n else: result = semExprNoType(c, result) - c.p.bracketExpr = oldBracketExpr return result - c.p.bracketExpr = oldBracketExpr of nkCurlyExpr: # a{i} = x --> `{}=`(a, i, x) result = buildOverloadedSubscripts(n.sons[0], getIdent"{}=") @@ -1377,19 +1378,24 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = if lhsIsResult: n.typ = enforceVoidContext if c.p.owner.kind != skMacro and resultTypeIsInferrable(lhs.sym.typ): - if cmpTypes(c, lhs.typ, rhs.typ) == isGeneric: + var rhsTyp = rhs.typ + if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass: + rhsTyp = rhsTyp.lastSon + if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}: internalAssert c.p.resultSym != nil - lhs.typ = rhs.typ - c.p.resultSym.typ = rhs.typ - c.p.owner.typ.sons[0] = rhs.typ + lhs.typ = rhsTyp + c.p.resultSym.typ = rhsTyp + c.p.owner.typ.sons[0] = rhsTyp else: - typeMismatch(n.info, lhs.typ, rhs.typ) + typeMismatch(n.info, lhs.typ, rhsTyp) n.sons[1] = fitNode(c, le, rhs, n.info) if not newDestructors: if tfHasAsgn in lhs.typ.flags and not lhsIsResult and mode != noOverloadedAsgn: return overloadedAsgn(c, lhs, n.sons[1]) + else: + liftTypeBoundOps(c, lhs.typ, lhs.info) fixAbstractType(c, n) asgnToResultVar(c, n, n.sons[0], n.sons[1]) @@ -1419,11 +1425,7 @@ proc semProcBody(c: PContext, n: PNode): PNode = openScope(c) result = semExpr(c, n) if c.p.resultSym != nil and not isEmptyType(result.typ): - # transform ``expr`` to ``result = expr``, but not if the expr is already - # ``result``: - if result.kind == nkSym and result.sym == c.p.resultSym: - discard - elif result.kind == nkNilLit: + if result.kind == nkNilLit: # or ImplicitlyDiscardable(result): # new semantic: 'result = x' triggers the void context result.typ = nil @@ -1456,14 +1458,15 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) = var t = skipTypes(restype, {tyGenericInst, tyAlias}) case t.kind of tyVar: + t.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892 if n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv}: n.sons[0] = n.sons[0].sons[1] - n.sons[0] = takeImplicitAddr(c, n.sons[0]) of tyTuple: - for i in 0.. <t.sonsLen: + for i in 0..<t.sonsLen: var e = skipTypes(t.sons[i], {tyGenericInst, tyAlias}) if e.kind == tyVar: + e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892 if n.sons[0].kind == nkPar: n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i]) elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and @@ -1654,7 +1657,7 @@ proc processQuotations(n: var PNode, op: string, elif n.kind == nkAccQuoted and op == "``": returnQuote n[0] - for i in 0 .. <n.safeLen: + for i in 0 ..< n.safeLen: processQuotations(n.sons[i], op, quotes, ids) proc semQuoteAst(c: PContext, n: PNode): PNode = @@ -1662,7 +1665,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = # We transform the do block into a template with a param for # each interpolation. We'll pass this template to getAst. var - quotedBlock = n{-1} + quotedBlock = n[^1] op = if n.len == 3: expectString(c, n[1]) else: "``" quotes = newSeq[PNode](1) # the quotes will be added to a nkCall statement @@ -1782,6 +1785,13 @@ proc setMs(n: PNode, s: PSym): PNode = n.sons[0] = newSymNode(s) n.sons[0].info = n.info +proc extractImports(n: PNode; result: PNode) = + if n.kind in {nkImportStmt, nkImportExceptStmt, nkFromStmt}: + result.add copyTree(n) + n.kind = nkEmpty + return + for i in 0..<n.safeLen: extractImports(n[i], result) + proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = # this is a hotspot in the compiler! # DON'T forget to update ast.SpecialSemMagics if you add a magic here! @@ -1822,7 +1832,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = dec c.inParallelStmt of mSpawn: result = setMs(n, s) - for i in 1 .. <n.len: + for i in 1 ..< n.len: result.sons[i] = semExpr(c, n.sons[i]) let typ = result[^1].typ if not typ.isEmptyType: @@ -1853,6 +1863,21 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = analyseIfAddressTakenInCall(c, result) if callee.magic != mNone: result = magicsAfterOverloadResolution(c, result, flags) + of mRunnableExamples: + if gCmd == cmdDoc and n.len >= 2 and n.lastSon.kind == nkStmtList: + if n.sons[0].kind == nkIdent: + if sfMainModule in c.module.flags: + let inp = toFullPath(c.module.info) + if c.runnableExamples == nil: + c.runnableExamples = newTree(nkStmtList, + newTree(nkImportStmt, newStrNode(nkStrLit, expandFilename(inp)))) + let imports = newTree(nkStmtList) + extractImports(n.lastSon, imports) + for imp in imports: c.runnableExamples.add imp + c.runnableExamples.add newTree(nkBlockStmt, emptyNode, copyTree n.lastSon) + result = setMs(n, s) + else: + result = emptyNode else: result = semDirectOp(c, n, flags) @@ -2073,7 +2098,7 @@ proc semBlock(c: PContext, n: PNode): PNode = proc semExport(c: PContext, n: PNode): PNode = var x = newNodeI(n.kind, n.info) #let L = if n.kind == nkExportExceptStmt: L = 1 else: n.len - for i in 0.. <n.len: + for i in 0..<n.len: let a = n.sons[i] var o: TOverloadIter var s = initOverloadIter(o, c, a) @@ -2104,7 +2129,7 @@ proc shouldBeBracketExpr(n: PNode): bool = let b = a[0] if b.kind in nkSymChoices: for i in 0..<b.len: - if b[i].sym.magic == mArrGet: + if b[i].kind == nkSym and b[i].sym.magic == mArrGet: let be = newNodeI(nkBracketExpr, n.info) for i in 1..<a.len: be.add(a[i]) n.sons[0] = be @@ -2118,6 +2143,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkIdent, nkAccQuoted: let checks = if efNoEvaluateGeneric in flags: {checkUndeclared, checkPureEnumFields} + elif efInCall in flags: + {checkUndeclared, checkModule, checkPureEnumFields} else: {checkUndeclared, checkModule, checkAmbiguity, checkPureEnumFields} var s = qualifiedLookUp(c, n, checks) @@ -2212,10 +2239,10 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # XXX think about this more (``set`` procs) if n.len == 2: result = semConv(c, n) + elif contains(c.ambiguousSymbols, s.id) and n.len == 1: + errorUseQualifier(c, n.info, s) elif n.len == 1: result = semObjConstr(c, n, flags) - elif contains(c.ambiguousSymbols, s.id): - errorUseQualifier(c, n.info, s) elif s.magic == mNone: result = semDirectOp(c, n, flags) else: result = semMagic(c, n, s, flags) of skProc, skFunc, skMethod, skConverter, skIterator: @@ -2365,6 +2392,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if n.len != 1 and n.len != 2: illFormedAst(n) for i in 0 ..< n.len: n.sons[i] = semExpr(c, n.sons[i]) + of nkComesFrom: discard "ignore the comes from information for now" else: localError(n.info, errInvalidExpressionX, renderTree(n, {renderNoComments})) diff --git a/compiler/semfields.nim b/compiler/semfields.nim index 6002705b3..c5bc07d77 100644 --- a/compiler/semfields.nim +++ b/compiler/semfields.nim @@ -89,7 +89,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) = access.sons[1] = newSymNode(typ.sons[0].sym, forLoop.info) caseStmt.add(semExprWithType(c.c, access)) # copy the branches over, but replace the fields with the for loop body: - for i in 1 .. <typ.len: + for i in 1 ..< typ.len: var branch = copyTree(typ[i]) let L = branch.len branch.sons[L-1] = newNodeI(nkStmtList, forLoop.info) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index d961a47a3..d2d36140d 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -92,26 +92,6 @@ proc pickIntRange(a, b: PType): PType = proc isIntRangeOrLit(t: PType): bool = result = isIntRange(t) or isIntLit(t) -proc pickMinInt(n: PNode): BiggestInt = - if n.kind in {nkIntLit..nkUInt64Lit}: - result = n.intVal - elif isIntLit(n.typ): - result = n.typ.n.intVal - elif isIntRange(n.typ): - result = firstOrd(n.typ) - else: - internalError(n.info, "pickMinInt") - -proc pickMaxInt(n: PNode): BiggestInt = - if n.kind in {nkIntLit..nkUInt64Lit}: - result = n.intVal - elif isIntLit(n.typ): - result = n.typ.n.intVal - elif isIntRange(n.typ): - result = lastOrd(n.typ) - else: - internalError(n.info, "pickMaxInt") - proc makeRange(typ: PType, first, last: BiggestInt): PType = let minA = min(first, last) let maxA = max(first, last) @@ -137,116 +117,6 @@ proc makeRangeF(typ: PType, first, last: BiggestFloat): PType = result.n = n addSonSkipIntLit(result, skipTypes(typ, {tyRange})) -proc getIntervalType*(m: TMagic, n: PNode): PType = - # Nim requires interval arithmetic for ``range`` types. Lots of tedious - # work but the feature is very nice for reducing explicit conversions. - const ordIntLit = {nkIntLit..nkUInt64Lit} - result = n.typ - - template commutativeOp(opr: untyped) = - let a = n.sons[1] - let b = n.sons[2] - if isIntRangeOrLit(a.typ) and isIntRangeOrLit(b.typ): - result = makeRange(pickIntRange(a.typ, b.typ), - opr(pickMinInt(a), pickMinInt(b)), - opr(pickMaxInt(a), pickMaxInt(b))) - - template binaryOp(opr: untyped) = - let a = n.sons[1] - let b = n.sons[2] - if isIntRange(a.typ) and b.kind in {nkIntLit..nkUInt64Lit}: - result = makeRange(a.typ, - opr(pickMinInt(a), pickMinInt(b)), - opr(pickMaxInt(a), pickMaxInt(b))) - - case m - of mUnaryMinusI, mUnaryMinusI64: - let a = n.sons[1].typ - if isIntRange(a): - # (1..3) * (-1) == (-3.. -1) - result = makeRange(a, 0|-|lastOrd(a), 0|-|firstOrd(a)) - of mUnaryMinusF64: - let a = n.sons[1].typ - if isFloatRange(a): - result = makeRangeF(a, -getFloat(a.n.sons[1]), - -getFloat(a.n.sons[0])) - of mAbsF64: - let a = n.sons[1].typ - if isFloatRange(a): - # abs(-5.. 1) == (1..5) - if a.n[0].floatVal <= 0.0: - result = makeRangeF(a, 0.0, abs(getFloat(a.n.sons[0]))) - else: - result = makeRangeF(a, abs(getFloat(a.n.sons[1])), - abs(getFloat(a.n.sons[0]))) - of mAbsI: - let a = n.sons[1].typ - if isIntRange(a): - if a.n[0].intVal <= 0: - result = makeRange(a, 0, `|abs|`(getInt(a.n.sons[0]))) - else: - result = makeRange(a, `|abs|`(getInt(a.n.sons[1])), - `|abs|`(getInt(a.n.sons[0]))) - of mSucc: - let a = n.sons[1].typ - let b = n.sons[2].typ - if isIntRange(a) and isIntLit(b): - # (-5.. 1) + 6 == (-5 + 6)..(-1 + 6) - result = makeRange(a, pickMinInt(n.sons[1]) |+| pickMinInt(n.sons[2]), - pickMaxInt(n.sons[1]) |+| pickMaxInt(n.sons[2])) - of mPred: - let a = n.sons[1].typ - let b = n.sons[2].typ - if isIntRange(a) and isIntLit(b): - result = makeRange(a, pickMinInt(n.sons[1]) |-| pickMinInt(n.sons[2]), - pickMaxInt(n.sons[1]) |-| pickMaxInt(n.sons[2])) - of mAddI, mAddU: - commutativeOp(`|+|`) - of mMulI, mMulU: - commutativeOp(`|*|`) - of mSubI, mSubU: - binaryOp(`|-|`) - of mBitandI: - # since uint64 is still not even valid for 'range' (since it's no ordinal - # yet), we exclude it from the list (see bug #1638) for now: - var a = n.sons[1] - var b = n.sons[2] - # symmetrical: - if b.kind notin ordIntLit: swap(a, b) - if b.kind in ordIntLit: - let x = b.intVal|+|1 - if (x and -x) == x and x >= 0: - result = makeRange(n.typ, 0, b.intVal) - of mModU: - let a = n.sons[1] - let b = n.sons[2] - if b.kind in ordIntLit: - if b.intVal >= 0: - result = makeRange(n.typ, 0, b.intVal-1) - else: - result = makeRange(n.typ, b.intVal+1, 0) - of mModI: - # so ... if you ever wondered about modulo's signedness; this defines it: - let a = n.sons[1] - let b = n.sons[2] - if b.kind in {nkIntLit..nkUInt64Lit}: - if b.intVal >= 0: - result = makeRange(n.typ, -(b.intVal-1), b.intVal-1) - else: - result = makeRange(n.typ, b.intVal+1, -(b.intVal+1)) - of mDivI, mDivU: - binaryOp(`|div|`) - of mMinI: - commutativeOp(min) - of mMaxI: - commutativeOp(max) - else: discard - -discard """ - mShlI, - mShrI, mAddF64, mSubF64, mMulF64, mDivF64, mMaxF64, mMinF64 -""" - proc evalIs(n, a: PNode): PNode = # XXX: This should use the standard isOpImpl internalAssert a.kind == nkSym and a.sym.kind == skType @@ -736,13 +606,13 @@ proc getConstExpr(m: PSym, n: PNode): PNode = if a == nil: return nil result.sons[i] = a incl(result.flags, nfAllConst) - of nkObjConstr: - result = copyTree(n) - for i in countup(1, sonsLen(n) - 1): - var a = getConstExpr(m, n.sons[i].sons[1]) - if a == nil: return nil - result.sons[i].sons[1] = a - incl(result.flags, nfAllConst) + #of nkObjConstr: + # result = copyTree(n) + # for i in countup(1, sonsLen(n) - 1): + # var a = getConstExpr(m, n.sons[i].sons[1]) + # if a == nil: return nil + # result.sons[i].sons[1] = a + # incl(result.flags, nfAllConst) of nkPar: # tuple constructor result = copyTree(n) @@ -785,5 +655,8 @@ proc getConstExpr(m: PSym, n: PNode): PNode = result.typ = n.typ of nkBracketExpr: result = foldArrayAccess(m, n) of nkDotExpr: result = foldFieldAccess(m, n) + of nkStmtListExpr: + if n.len == 2 and n[0].kind == nkComesFrom: + result = getConstExpr(m, n[1]) else: discard diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 3cdb68df6..16da06952 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -186,7 +186,7 @@ proc semGenericStmt(c: PContext, n: PNode, let a = n.sym let b = getGenSym(c, a) if b != a: n.sym = b - of nkEmpty, succ(nkSym)..nkNilLit: + of nkEmpty, succ(nkSym)..nkNilLit, nkComesFrom: # see tests/compile/tgensymgeneric.nim: # We need to open the gensym'ed symbol again so that the instantiation # creates a fresh copy; but this is wrong the very first reason for gensym @@ -210,7 +210,7 @@ proc semGenericStmt(c: PContext, n: PNode, considerQuotedIdent(fn).id notin ctx.toMixin: errorUndeclaredIdentifier(c, n.info, fn.renderTree) - var first = ord(withinConcept in flags) + var first = int ord(withinConcept in flags) var mixinContext = false if s != nil: incl(s.flags, sfUsed) @@ -335,8 +335,10 @@ proc semGenericStmt(c: PContext, n: PNode, n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, ctx) for i in countup(0, L - 3): addTempDecl(c, n.sons[i], skForVar) + openScope(c) n.sons[L - 1] = semGenericStmt(c, n.sons[L-1], flags, ctx) closeScope(c) + closeScope(c) of nkBlockStmt, nkBlockExpr, nkBlockType: checkSonsLen(n, 2) openScope(c) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 6abb34e90..acea9330b 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -121,14 +121,14 @@ proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) = idTablePut(symMap, s, x) n.sym = x else: - for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, orig, symMap) + for i in 0 ..< safeLen(n): freshGenSyms(n.sons[i], owner, orig, symMap) proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) = if n.sons[bodyPos].kind != nkEmpty: let procParams = result.typ.n - for i in 1 .. <procParams.len: + for i in 1 ..< procParams.len: addDecl(c, procParams[i].sym) maybeAddResult(c, result, result.ast) @@ -138,7 +138,7 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) = var symMap: TIdTable initIdTable symMap if params != nil: - for i in 1 .. <params.len: + for i in 1 ..< params.len: let param = params[i].sym if sfGenSym in param.flags: idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym) @@ -211,7 +211,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable, let originalParams = result.n result.n = originalParams.shallowCopy - for i in 1 .. <result.len: + for i in 1 ..< result.len: # twrong_field_caching requires these 'resetIdTable' calls: if i > 1: resetIdTable(cl.symMap) @@ -240,6 +240,8 @@ proc instantiateProcType(c: PContext, pt: TIdTable, resetIdTable(cl.localCache) result.sons[0] = replaceTypeVarsT(cl, result.sons[0]) result.n.sons[0] = originalParams[0].copyTree + if result.sons[0] != nil: + propagateToOwner(result, result.sons[0]) eraseVoidParams(result) skipIntLiteralParams(result) diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim index a6024a42f..fe9bb6c8d 100644 --- a/compiler/semmacrosanity.nim +++ b/compiler/semmacrosanity.nim @@ -42,7 +42,7 @@ proc annotateType*(n: PNode, t: PType) = of nkObjConstr: let x = t.skipTypes(abstractPtrs) n.typ = t - for i in 1 .. <n.len: + for i in 1 ..< n.len: var j = i-1 let field = x.n.ithField(j) if field.isNil: @@ -53,7 +53,7 @@ proc annotateType*(n: PNode, t: PType) = of nkPar: if x.kind == tyTuple: n.typ = t - for i in 0 .. <n.len: + for i in 0 ..< n.len: if i >= x.len: globalError n.info, "invalid field at index " & $i else: annotateType(n.sons[i], x.sons[i]) elif x.kind == tyProc and x.callConv == ccClosure: diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 8b3d9c014..0d0f2ee82 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -38,9 +38,7 @@ proc skipAddr(n: PNode): PNode {.inline.} = proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode = result = newNodeI(nkBracketExpr, n.info) for i in 1..<n.len: result.add(n[i]) - let oldBracketExpr = c.p.bracketExpr result = semSubscript(c, result, flags) - c.p.bracketExpr = oldBracketExpr if result.isNil: let x = copyTree(n) x.sons[0] = newIdentNode(getIdent"[]", n.info) @@ -129,7 +127,7 @@ proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode = of "not": return typeWithSonsResult(tyNot, @[operand]) of "name": - result = newStrNode(nkStrLit, operand.typeToString(preferName)) + result = newStrNode(nkStrLit, operand.typeToString(preferTypeName)) result.typ = newType(tyString, context) result.info = traitCall.info of "arity": @@ -146,8 +144,14 @@ proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode = result = res.base.toNode(traitCall.info) of "stripGenericParams": result = uninstantiate(operand).toNode(traitCall.info) + of "supportsCopyMem": + let t = operand.skipTypes({tyVar, tyGenericInst, tyAlias, tyInferred}) + let complexObj = containsGarbageCollectedRef(t) or + hasDestructor(t) + result = newIntNodeT(ord(not complexObj), traitCall) else: - internalAssert false + localError(traitCall.info, "unknown trait") + result = emptyNode proc semTypeTraits(c: PContext, n: PNode): PNode = checkMinSonsLen(n, 2) @@ -164,7 +168,9 @@ proc semTypeTraits(c: PContext, n: PNode): PNode = proc semOrd(c: PContext, n: PNode): PNode = result = n let parType = n.sons[1].typ - if isOrdinalType(parType) or parType.kind == tySet: + if isOrdinalType(parType): + discard + elif parType.kind == tySet: result.typ = makeRangeType(c, firstOrd(parType), lastOrd(parType), n.info) else: localError(n.info, errOrdinalTypeExpected) @@ -246,7 +252,11 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, result = semTypeOf(c, n.sons[1]) of mArrGet: result = semArrGet(c, n, flags) of mArrPut: result = semArrPut(c, n, flags) - of mAsgn: result = semAsgnOpr(c, n) + of mAsgn: + if n[0].sym.name.s == "=": + result = semAsgnOpr(c, n) + else: + result = n of mIsPartOf: result = semIsPartOf(c, n, flags) of mTypeTrait: result = semTypeTraits(c, n) of mAstToStr: @@ -264,35 +274,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, of mDotDot: result = n of mRoof: - let bracketExpr = if n.len == 3: n.sons[2] else: c.p.bracketExpr - if bracketExpr.isNil: - localError(n.info, "no surrounding array access context for '^'") - result = n.sons[1] - elif bracketExpr.checkForSideEffects != seNoSideEffect: - localError(n.info, "invalid context for '^' as '$#' has side effects" % - renderTree(bracketExpr)) - result = n.sons[1] - elif bracketExpr.typ.isStrangeArray: - localError(n.info, "invalid context for '^' as len!=high+1 for '$#'" % - renderTree(bracketExpr)) - result = n.sons[1] - else: - # ^x is rewritten to: len(a)-x - let lenExpr = newNodeI(nkCall, n.info) - lenExpr.add newIdentNode(getIdent"len", n.info) - lenExpr.add bracketExpr - let lenExprB = semExprWithType(c, lenExpr) - if lenExprB.typ.isNil or not isOrdinalType(lenExprB.typ): - localError(n.info, "'$#' has to be of an ordinal type for '^'" % - renderTree(lenExpr)) - result = n.sons[1] - else: - result = newNodeIT(nkCall, n.info, getSysType(tyInt)) - let subi = getSysMagic("-", mSubI) - #echo "got ", typeToString(subi.typ) - result.add newSymNode(subi, n.info) - result.add lenExprB - result.add n.sons[1] + localError(n.info, "builtin roof operator is not supported anymore") of mPlugin: let plugin = getPlugin(n[0].sym) if plugin.isNil: diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index b331d05a1..a0bf084fa 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -39,13 +39,19 @@ proc mergeInitStatus(existing: var InitStatus, newStatus: InitStatus) = of initUnknown: discard +proc invalidObjConstr(n: PNode) = + if n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s[0] == ':': + localError(n.info, "incorrect object construction syntax; use a space after the colon") + else: + localError(n.info, "incorrect object construction syntax") + proc locateFieldInInitExpr(field: PSym, initExpr: PNode): PNode = # Returns the assignment nkExprColonExpr node or nil let fieldId = field.name.id - for i in 1 .. <initExpr.len: + for i in 1 ..< initExpr.len: let assignment = initExpr[i] if assignment.kind != nkExprColonExpr: - localError(initExpr.info, "incorrect object construction syntax") + invalidObjConstr(assignment) continue if fieldId == considerQuotedIdent(assignment[0]).id: @@ -78,13 +84,13 @@ proc caseBranchMatchesExpr(branch, matched: PNode): bool = proc pickCaseBranch(caseExpr, matched: PNode): PNode = # XXX: Perhaps this proc already exists somewhere - let endsWithElse = caseExpr{-1}.kind == nkElse + let endsWithElse = caseExpr[^1].kind == nkElse for i in 1 .. caseExpr.len - 1 - int(endsWithElse): if caseExpr[i].caseBranchMatchesExpr(matched): return caseExpr[i] if endsWithElse: - return caseExpr{-1} + return caseExpr[^1] iterator directFieldsInRecList(recList: PNode): PNode = # XXX: We can remove this case by making all nkOfBranch nodes @@ -136,17 +142,20 @@ proc semConstructFields(c: PContext, recNode: PNode, of nkRecCase: template fieldsPresentInBranch(branchIdx: int): string = - fieldsPresentInInitExpr(recNode[branchIdx]{-1}, initExpr) + let branch = recNode[branchIdx] + let fields = branch[branch.len - 1] + fieldsPresentInInitExpr(fields, initExpr) template checkMissingFields(branchNode: PNode) = - checkForMissingFields(branchNode{-1}, initExpr) + let fields = branchNode[branchNode.len - 1] + checkForMissingFields(fields, initExpr) let discriminator = recNode.sons[0]; internalAssert discriminator.kind == nkSym var selectedBranch = -1 - for i in 1 .. <recNode.len: - let innerRecords = recNode[i]{-1} + for i in 1 ..< recNode.len: + let innerRecords = recNode[i][^1] let status = semConstructFields(c, innerRecords, initExpr, flags) if status notin {initNone, initUnknown}: mergeInitStatus(result, status) @@ -220,7 +229,7 @@ proc semConstructFields(c: PContext, recNode: PNode, else: # All bets are off. If any of the branches has a mandatory # fields we must produce an error: - for i in 1 .. <recNode.len: checkMissingFields recNode[i] + for i in 1 ..< recNode.len: checkMissingFields recNode[i] of nkSym: let field = recNode.sym @@ -250,7 +259,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = var t = semTypeNode(c, n.sons[0], nil) result = newNodeIT(nkObjConstr, n.info, t) for child in n: result.add child - + t = skipTypes(t, {tyGenericInst, tyAlias}) if t.kind == tyRef: t = skipTypes(t.sons[0], {tyGenericInst, tyAlias}) if t.kind != tyObject: @@ -277,16 +286,16 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = # Since we were traversing the object fields, it's possible that # not all of the fields specified in the constructor was visited. # We'll check for such fields here: - for i in 1.. <result.len: + for i in 1..<result.len: let field = result[i] if nfSem notin field.flags: if field.kind != nkExprColonExpr: - localError(n.info, "incorrect object construction syntax") + invalidObjConstr(field) continue let id = considerQuotedIdent(field[0]) # This node was not processed. There are two possible reasons: # 1) It was shadowed by a field with the same name on the left - for j in 1 .. <i: + for j in 1 ..< i: let prevId = considerQuotedIdent(result[j][0]) if prevId.id == id.id: localError(field.info, errFieldInitTwice, id.s) diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim index 2581f5728..057ade01d 100644 --- a/compiler/semparallel.nim +++ b/compiler/semparallel.nim @@ -81,7 +81,7 @@ proc initAnalysisCtx(): AnalysisCtx = result.guards = @[] proc lookupSlot(c: AnalysisCtx; s: PSym): int = - for i in 0.. <c.locals.len: + for i in 0..<c.locals.len: if c.locals[i].v == s or c.locals[i].alias == s: return i return -1 @@ -94,7 +94,7 @@ proc getSlot(c: var AnalysisCtx; v: PSym): ptr MonotonicVar = return addr(c.locals[L]) proc gatherArgs(c: var AnalysisCtx; n: PNode) = - for i in 0.. <n.safeLen: + for i in 0..<n.safeLen: let root = getRoot n[i] if root != nil: block addRoot: @@ -119,7 +119,7 @@ proc checkLocal(c: AnalysisCtx; n: PNode) = if s >= 0 and c.locals[s].stride != nil: localError(n.info, "invalid usage of counter after increment") else: - for i in 0 .. <n.safeLen: checkLocal(c, n.sons[i]) + for i in 0 ..< n.safeLen: checkLocal(c, n.sons[i]) template `?`(x): untyped = x.renderTree @@ -180,7 +180,7 @@ proc stride(c: AnalysisCtx; n: PNode): BiggestInt = if s >= 0 and c.locals[s].stride != nil: result = c.locals[s].stride.intVal else: - for i in 0 .. <n.safeLen: result += stride(c, n.sons[i]) + for i in 0 ..< n.safeLen: result += stride(c, n.sons[i]) proc subStride(c: AnalysisCtx; n: PNode): PNode = # substitute with stride: @@ -192,7 +192,7 @@ proc subStride(c: AnalysisCtx; n: PNode): PNode = result = n elif n.safeLen > 0: result = shallowCopy(n) - for i in 0 .. <n.len: result.sons[i] = subStride(c, n.sons[i]) + for i in 0 ..< n.len: result.sons[i] = subStride(c, n.sons[i]) else: result = n @@ -251,7 +251,7 @@ proc checkSlicesAreDisjoint(c: var AnalysisCtx) = proc analyse(c: var AnalysisCtx; n: PNode) proc analyseSons(c: var AnalysisCtx; n: PNode) = - for i in 0 .. <safeLen(n): analyse(c, n[i]) + for i in 0 ..< safeLen(n): analyse(c, n[i]) proc min(a, b: PNode): PNode = if a.isNil: result = b @@ -293,11 +293,11 @@ proc analyseCall(c: var AnalysisCtx; n: PNode; op: PSym) = proc analyseCase(c: var AnalysisCtx; n: PNode) = analyse(c, n.sons[0]) let oldFacts = c.guards.len - for i in 1.. <n.len: + for i in 1..<n.len: let branch = n.sons[i] setLen(c.guards, oldFacts) addCaseBranchFacts(c.guards, n, i) - for i in 0 .. <branch.len: + for i in 0 ..< branch.len: analyse(c, branch.sons[i]) setLen(c.guards, oldFacts) @@ -307,14 +307,14 @@ proc analyseIf(c: var AnalysisCtx; n: PNode) = addFact(c.guards, canon(n.sons[0].sons[0])) analyse(c, n.sons[0].sons[1]) - for i in 1.. <n.len: + for i in 1..<n.len: let branch = n.sons[i] setLen(c.guards, oldFacts) for j in 0..i-1: addFactNeg(c.guards, canon(n.sons[j].sons[0])) if branch.len > 1: addFact(c.guards, canon(branch.sons[0])) - for i in 0 .. <branch.len: + for i in 0 ..< branch.len: analyse(c, branch.sons[i]) setLen(c.guards, oldFacts) @@ -407,7 +407,7 @@ proc transformSlices(n: PNode): PNode = return result if n.safeLen > 0: result = shallowCopy(n) - for i in 0 .. < n.len: + for i in 0 ..< n.len: result.sons[i] = transformSlices(n.sons[i]) else: result = n @@ -415,7 +415,7 @@ proc transformSlices(n: PNode): PNode = proc transformSpawn(owner: PSym; n, barrier: PNode): PNode proc transformSpawnSons(owner: PSym; n, barrier: PNode): PNode = result = shallowCopy(n) - for i in 0 .. < n.len: + for i in 0 ..< n.len: result.sons[i] = transformSpawn(owner, n.sons[i], barrier) proc transformSpawn(owner: PSym; n, barrier: PNode): PNode = diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 17d9c9840..d427750e4 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -248,7 +248,7 @@ type TIntersection = seq[tuple[id, count: int]] # a simple count table proc addToIntersection(inter: var TIntersection, s: int) = - for j in 0.. <inter.len: + for j in 0..<inter.len: if s == inter[j].id: inc inter[j].count return @@ -282,7 +282,7 @@ proc createTag(n: PNode): PNode = proc addEffect(a: PEffects, e: PNode, useLineInfo=true) = assert e.kind != nkRaiseStmt var aa = a.exc - for i in a.bottom .. <aa.len: + for i in a.bottom ..< aa.len: if sameType(aa[i].excType, e.excType): if not useLineInfo or gCmd == cmdDoc: return elif aa[i].info == e.info: return @@ -290,7 +290,7 @@ proc addEffect(a: PEffects, e: PNode, useLineInfo=true) = proc addTag(a: PEffects, e: PNode, useLineInfo=true) = var aa = a.tags - for i in 0 .. <aa.len: + for i in 0 ..< aa.len: if sameType(aa[i].typ.skipTypes(skipPtrs), e.typ.skipTypes(skipPtrs)): if not useLineInfo or gCmd == cmdDoc: return elif aa[i].info == e.info: return @@ -345,12 +345,12 @@ proc trackTryStmt(tracked: PEffects, n: PNode) = inc tracked.inTryStmt track(tracked, n.sons[0]) dec tracked.inTryStmt - for i in oldState.. <tracked.init.len: + for i in oldState..<tracked.init.len: addToIntersection(inter, tracked.init[i]) var branches = 1 var hasFinally = false - for i in 1 .. < n.len: + for i in 1 ..< n.len: let b = n.sons[i] let blen = sonsLen(b) if b.kind == nkExceptBranch: @@ -364,7 +364,7 @@ proc trackTryStmt(tracked: PEffects, n: PNode) = setLen(tracked.init, oldState) track(tracked, b.sons[blen-1]) - for i in oldState.. <tracked.init.len: + for i in oldState..<tracked.init.len: addToIntersection(inter, tracked.init[i]) else: assert b.kind == nkFinally @@ -420,7 +420,7 @@ proc documentEffect(n, x: PNode, effectType: TSpecialWord, idx: int): PNode = # warning: hack ahead: var effects = newNodeI(nkBracket, n.info, real.len) - for i in 0 .. <real.len: + for i in 0 ..< real.len: var t = typeToString(real[i].typ) if t.startsWith("ref "): t = substr(t, 4) effects.sons[i] = newIdentNode(getIdent(t), n.info) @@ -518,13 +518,15 @@ proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = procVarcheck skipConvAndClosure(n) #elif n.kind in nkSymChoices: # echo "came here" + let paramType = paramType.skipTypesOrNil(abstractInst) if paramType != nil and tfNotNil in paramType.flags and n.typ != nil and tfNotNil notin n.typ.flags: if n.kind == nkAddr: # addr(x[]) can't be proven, but addr(x) can: if not containsNode(n, {nkDerefExpr, nkHiddenDeref}): return elif (n.kind == nkSym and n.sym.kind in routineKinds) or - n.kind in procDefs+{nkObjConstr, nkBracket}: + (n.kind in procDefs+{nkObjConstr, nkBracket, nkClosure, nkStrLit..nkTripleStrLit}) or + (n.kind in nkCallKinds and n[0].kind == nkSym and n[0].sym.magic == mArrToSeq): # 'p' is not nil obviously: return case impliesNotNil(tracked.guards, n) @@ -613,16 +615,16 @@ proc trackCase(tracked: PEffects, n: PNode) = warnProveField in gNotes var inter: TIntersection = @[] var toCover = 0 - for i in 1.. <n.len: + for i in 1..<n.len: let branch = n.sons[i] setLen(tracked.init, oldState) if interesting: setLen(tracked.guards, oldFacts) addCaseBranchFacts(tracked.guards, n, i) - for i in 0 .. <branch.len: + for i in 0 ..< branch.len: track(tracked, branch.sons[i]) if not breaksBlock(branch.lastSon): inc toCover - for i in oldState.. <tracked.init.len: + for i in oldState..<tracked.init.len: addToIntersection(inter, tracked.init[i]) setLen(tracked.init, oldState) @@ -642,10 +644,10 @@ proc trackIf(tracked: PEffects, n: PNode) = var toCover = 0 track(tracked, n.sons[0].sons[1]) if not breaksBlock(n.sons[0].sons[1]): inc toCover - for i in oldState.. <tracked.init.len: + for i in oldState..<tracked.init.len: addToIntersection(inter, tracked.init[i]) - for i in 1.. <n.len: + for i in 1..<n.len: let branch = n.sons[i] setLen(tracked.guards, oldFacts) for j in 0..i-1: @@ -653,10 +655,10 @@ proc trackIf(tracked: PEffects, n: PNode) = if branch.len > 1: addFact(tracked.guards, branch.sons[0]) setLen(tracked.init, oldState) - for i in 0 .. <branch.len: + for i in 0 ..< branch.len: track(tracked, branch.sons[i]) if not breaksBlock(branch.lastSon): inc toCover - for i in oldState.. <tracked.init.len: + for i in oldState..<tracked.init.len: addToIntersection(inter, tracked.init[i]) setLen(tracked.init, oldState) if lastSon(n).len == 1: @@ -668,7 +670,7 @@ proc trackIf(tracked: PEffects, n: PNode) = proc trackBlock(tracked: PEffects, n: PNode) = if n.kind in {nkStmtList, nkStmtListExpr}: var oldState = -1 - for i in 0.. <n.len: + for i in 0..<n.len: if hasSubnodeWith(n.sons[i], nkBreakStmt): # block: # x = def @@ -701,7 +703,7 @@ proc track(tracked: PEffects, n: PNode) = n.sons[0].info = n.info #throws(tracked.exc, n.sons[0]) addEffect(tracked, n.sons[0], useLineInfo=false) - for i in 0 .. <safeLen(n): + for i in 0 ..< safeLen(n): track(tracked, n.sons[i]) of nkCallKinds: # p's effects are ours too: @@ -752,11 +754,11 @@ proc track(tracked: PEffects, n: PNode) = discard else: message(arg.info, warnProveInit, $arg) - for i in 0 .. <safeLen(n): + for i in 0 ..< safeLen(n): track(tracked, n.sons[i]) of nkDotExpr: guardDotAccess(tracked, n) - for i in 0 .. <len(n): track(tracked, n.sons[i]) + for i in 0 ..< len(n): track(tracked, n.sons[i]) of nkCheckedFieldExpr: track(tracked, n.sons[0]) if warnProveField in gNotes: checkFieldAccess(tracked.guards, n) @@ -804,13 +806,13 @@ proc track(tracked: PEffects, n: PNode) = of nkForStmt, nkParForStmt: # we are very conservative here and assume the loop is never executed: let oldState = tracked.init.len - for i in 0 .. <len(n): + for i in 0 ..< len(n): track(tracked, n.sons[i]) setLen(tracked.init, oldState) of nkObjConstr: when false: track(tracked, n.sons[0]) let oldFacts = tracked.guards.len - for i in 1 .. <len(n): + for i in 1 ..< len(n): let x = n.sons[i] track(tracked, x) if x.sons[0].kind == nkSym and sfDiscriminant in x.sons[0].sym.flags: @@ -821,7 +823,7 @@ proc track(tracked: PEffects, n: PNode) = let oldLocked = tracked.locked.len let oldLockLevel = tracked.currLockLevel var enforcedGcSafety = false - for i in 0 .. <pragmaList.len: + for i in 0 ..< pragmaList.len: let pragma = whichPragma(pragmaList.sons[i]) if pragma == wLocks: lockLocations(tracked, pragmaList.sons[i]) @@ -840,7 +842,7 @@ proc track(tracked: PEffects, n: PNode) = of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64: if n.len == 1: track(tracked, n.sons[0]) else: - for i in 0 .. <safeLen(n): track(tracked, n.sons[i]) + for i in 0 ..< safeLen(n): track(tracked, n.sons[i]) proc subtypeRelation(spec, real: PNode): bool = result = safeInheritanceDiff(real.excType, spec.typ) <= 0 @@ -852,7 +854,7 @@ proc checkRaisesSpec(spec, real: PNode, msg: string, hints: bool; var used = initIntSet() for r in items(real): block search: - for s in 0 .. <spec.len: + for s in 0 ..< spec.len: if effectPredicate(spec[s], r): used.incl(s) break search @@ -862,7 +864,7 @@ proc checkRaisesSpec(spec, real: PNode, msg: string, hints: bool; popInfoContext() # hint about unnecessarily listed exception types: if hints: - for s in 0 .. <spec.len: + for s in 0 ..< spec.len: if not used.contains(s): message(spec[s].info, hintXDeclaredButNotUsed, renderTree(spec[s])) @@ -977,10 +979,10 @@ proc trackProc*(s: PSym, body: PNode) = message(s.info, warnLockLevel, "declared lock level is $1, but real lock level is $2" % [$s.typ.lockLevel, $t.maxLockLevel]) - when false: + when defined(useDfa): if s.kind == skFunc: - when defined(dfa): dataflowAnalysis(s, body) - trackWrites(s, body) + dataflowAnalysis(s, body) + when false: trackWrites(s, body) proc trackTopLevelStmt*(module: PSym; n: PNode) = if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef, nkFuncDef, diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index c6e03cef3..dcaa0263b 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -97,27 +97,12 @@ template semProcvarCheck(c: PContext, n: PNode) = proc semProc(c: PContext, n: PNode): PNode -include semdestruct - -proc semDestructorCheck(c: PContext, n: PNode, flags: TExprFlags) {.inline.} = - if not newDestructors: - if efAllowDestructor notin flags and - n.kind in nkCallKinds+{nkObjConstr,nkBracket}: - if instantiateDestructor(c, n.typ) != nil: - localError(n.info, warnDestructor) - # This still breaks too many things: - when false: - if efDetermineType notin flags and n.typ.kind == tyTypeDesc and - c.p.owner.kind notin {skTemplate, skMacro}: - localError(n.info, errGenerated, "value expected, but got a type") - proc semExprBranch(c: PContext, n: PNode): PNode = result = semExpr(c, n) if result.typ != nil: # XXX tyGenericInst here? semProcvarCheck(c, result) if result.typ.kind == tyVar: result = newDeref(result) - semDestructorCheck(c, result, {}) proc semExprBranchScope(c: PContext, n: PNode): PNode = openScope(c) @@ -180,14 +165,14 @@ proc semIf(c: PContext, n: PNode): PNode = it.sons[0] = forceBool(c, semExprWithType(c, it.sons[0])) when not newScopeForIf: openScope(c) it.sons[1] = semExprBranch(c, it.sons[1]) - typ = commonType(typ, it.sons[1].typ) + typ = commonType(typ, it.sons[1]) closeScope(c) elif it.len == 1: hasElse = true it.sons[0] = semExprBranchScope(c, it.sons[0]) - typ = commonType(typ, it.sons[0].typ) + typ = commonType(typ, it.sons[0]) else: illFormedAst(it) - if isEmptyType(typ) or typ.kind == tyNil or not hasElse: + if isEmptyType(typ) or typ.kind in {tyNil, tyExpr} or not hasElse: for it in n: discardCheck(c, it.lastSon) result.kind = nkIfStmt # propagate any enforced VoidContext: @@ -195,7 +180,8 @@ proc semIf(c: PContext, n: PNode): PNode = else: for it in n: let j = it.len-1 - it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info) + if not endsInNoReturn(it.sons[j]): + it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info) result.kind = nkIfExpr result.typ = typ @@ -228,7 +214,7 @@ proc semCase(c: PContext, n: PNode): PNode = semCaseBranch(c, n, x, i, covered) var last = sonsLen(x)-1 x.sons[last] = semExprBranchScope(c, x.sons[last]) - typ = commonType(typ, x.sons[last].typ) + typ = commonType(typ, x.sons[last]) of nkElifBranch: chckCovered = false checkSonsLen(x, 2) @@ -236,13 +222,13 @@ proc semCase(c: PContext, n: PNode): PNode = x.sons[0] = forceBool(c, semExprWithType(c, x.sons[0])) when not newScopeForIf: openScope(c) x.sons[1] = semExprBranch(c, x.sons[1]) - typ = commonType(typ, x.sons[1].typ) + typ = commonType(typ, x.sons[1]) closeScope(c) of nkElse: chckCovered = false checkSonsLen(x, 1) x.sons[0] = semExprBranchScope(c, x.sons[0]) - typ = commonType(typ, x.sons[0].typ) + typ = commonType(typ, x.sons[0]) hasElse = true else: illFormedAst(x) @@ -252,7 +238,7 @@ proc semCase(c: PContext, n: PNode): PNode = else: localError(n.info, errNotAllCasesCovered) closeScope(c) - if isEmptyType(typ) or typ.kind == tyNil or not hasElse: + if isEmptyType(typ) or typ.kind in {tyNil, tyExpr} or not hasElse: for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon) # propagate any enforced VoidContext: if typ == enforceVoidContext: @@ -261,7 +247,8 @@ proc semCase(c: PContext, n: PNode): PNode = for i in 1..n.len-1: var it = n.sons[i] let j = it.len-1 - it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info) + if not endsInNoReturn(it.sons[j]): + it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info) result.typ = typ proc semTry(c: PContext, n: PNode): PNode = @@ -421,15 +408,6 @@ proc addToVarSection(c: PContext; result: var PNode; orig, identDefs: PNode) = else: result.add identDefs -proc addDefer(c: PContext; result: var PNode; s: PSym) = - let deferDestructorCall = createDestructorCall(c, s) - if deferDestructorCall != nil: - if result.kind != nkStmtList: - let oldResult = result - result = newNodeI(nkStmtList, result.info) - result.add oldResult - result.add deferDestructorCall - proc isDiscardUnderscore(v: PSym): bool = if v.name.s == "_": v.flags.incl(sfGenSym) @@ -465,9 +443,10 @@ proc hasEmpty(typ: PType): bool = result = result or hasEmpty(s) proc makeDeref(n: PNode): PNode = - var t = skipTypes(n.typ, {tyGenericInst, tyAlias}) + var t = n.typ if t.kind in tyUserTypeClasses and t.isResolvedUserTypeClass: t = t.lastSon + t = skipTypes(t, {tyGenericInst, tyAlias}) result = n if t.kind == tyVar: result = newNodeIT(nkHiddenDeref, n.info, t.sons[0]) @@ -553,6 +532,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = # this can only happen for errornous var statements: if typ == nil: continue typeAllowedCheck(a.info, typ, symkind) + liftTypeBoundOps(c, typ, a.info) var tup = skipTypes(typ, {tyGenericInst, tyAlias}) if a.kind == nkVarTuple: if tup.kind != tyTuple: @@ -608,7 +588,6 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if def.kind == nkPar: v.ast = def[j] setVarType(v, tup.sons[j]) b.sons[j] = newSymNode(v) - if not newDestructors: addDefer(c, result, v) checkNilable(v) if sfCompileTime in v.flags: hasCompileTime = true if hasCompileTime: vm.setupCompileTimeVar(c.module, c.cache, result) @@ -696,7 +675,9 @@ proc semForVars(c: PContext, n: PNode): PNode = if sfGenSym notin v.flags and not isDiscardUnderscore(v): addForVarDecl(c, v) inc(c.p.nestedLoopCounter) + openScope(c) n.sons[length-1] = semStmt(c, n.sons[length-1]) + closeScope(c) dec(c.p.nestedLoopCounter) proc implicitIterator(c: PContext, it: string, arg: PNode): PNode = @@ -752,6 +733,16 @@ proc semRaise(c: PContext, n: PNode): PNode = if typ.kind != tyRef or typ.lastSon.kind != tyObject: localError(n.info, errExprCannotBeRaised) + # check if the given object inherits from Exception + var base = typ.lastSon + while true: + if base.sym.magic == mException: + break + if base.lastSon == nil: + localError(n.info, "raised object of type $1 does not inherit from Exception", [typ.sym.name.s]) + return + base = base.lastSon + proc addGenericParamListToScope(c: PContext, n: PNode) = if n.kind != nkGenericParams: illFormedAst(n) for i in countup(0, sonsLen(n)-1): @@ -774,24 +765,55 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = checkSonsLen(a, 3) let name = a.sons[0] var s: PSym - if name.kind == nkDotExpr: - s = qualifiedLookUp(c, name, {checkUndeclared, checkModule}) - if s.kind != skType or - s.typ.skipTypes(abstractPtrs).kind != tyObject or - tfPartial notin s.typ.skipTypes(abstractPtrs).flags: - localError(name.info, "only .partial objects can be extended") + if name.kind == nkDotExpr and a[2].kind == nkObjectTy: + let pkgName = considerQuotedIdent(name[0]) + let typName = considerQuotedIdent(name[1]) + let pkg = c.graph.packageSyms.strTableGet(pkgName) + if pkg.isNil or pkg.kind != skPackage: + localError(name.info, "unknown package name: " & pkgName.s) + else: + let typsym = pkg.tab.strTableGet(typName) + if typsym.isNil: + s = semIdentDef(c, name[1], skType) + s.typ = newTypeS(tyObject, c) + s.typ.sym = s + s.flags.incl sfForward + pkg.tab.strTableAdd s + addInterfaceDecl(c, s) + elif typsym.kind == skType and sfForward in typsym.flags: + s = typsym + addInterfaceDecl(c, s) + else: + localError(name.info, typsym.name.s & " is not a type that can be forwarded") + s = typsym else: s = semIdentDef(c, name, skType) s.typ = newTypeS(tyForward, c) s.typ.sym = s # process pragmas: if name.kind == nkPragmaExpr: pragma(c, s, name.sons[1], typePragmas) + if sfForward in s.flags: + # check if the symbol already exists: + let pkg = c.module.owner + if not isTopLevel(c) or pkg.isNil: + localError(name.info, "only top level types in a package can be 'package'") + else: + let typsym = pkg.tab.strTableGet(s.name) + if typsym != nil: + if sfForward notin typsym.flags or sfNoForward notin typsym.flags: + typeCompleted(typsym) + typsym.info = s.info + else: + localError(name.info, "cannot complete type '" & s.name.s & "' twice; " & + "previous type completion was here: " & $typsym.info) + s = typsym # add it here, so that recursive types are possible: if sfGenSym notin s.flags: addInterfaceDecl(c, s) + a.sons[0] = newSymNode(s) proc checkCovariantParamsUsages(genericType: PType) = - var body = genericType{-1} + var body = genericType[^1] proc traverseSubTypes(t: PType): bool = template error(msg) = localError(genericType.sym.info, msg) @@ -826,7 +848,7 @@ proc checkCovariantParamsUsages(genericType: PType) = of tyGenericInvocation: let targetBody = t[0] - for i in 1 .. <t.len: + for i in 1 ..< t.len: let param = t[i] if param.kind == tyGenericParam: if tfCovariant in param.flags: @@ -972,8 +994,8 @@ proc checkForMetaFields(n: PNode) = case t.kind of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyPtr, tyRef, tyProc, tyGenericInvocation, tyGenericInst, tyAlias: - let start = ord(t.kind in {tyGenericInvocation, tyGenericInst}) - for i in start .. <t.sons.len: + let start = int ord(t.kind in {tyGenericInvocation, tyGenericInst}) + for i in start ..< t.sons.len: checkMeta(t.sons[i]) else: checkMeta(t) @@ -1007,6 +1029,8 @@ proc typeSectionFinalPass(c: PContext, n: PNode) = checkConstructedType(s.info, s.typ) if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil: checkForMetaFields(s.typ.n) + instAllTypeBoundOp(c, n.info) + proc semAllTypeSections(c: PContext; n: PNode): PNode = proc gatherStmts(c: PContext; n: PNode; result: PNode) {.nimcall.} = @@ -1061,9 +1085,11 @@ proc semTypeSection(c: PContext, n: PNode): PNode = ## to allow the type definitions in the section to reference each other ## without regard for the order of their definitions. if sfNoForward notin c.module.flags or nfSem notin n.flags: + inc c.inTypeContext typeSectionLeftSidePass(c, n) typeSectionRightSidePass(c, n) typeSectionFinalPass(c, n) + dec c.inTypeContext result = n proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) = @@ -1099,7 +1125,7 @@ proc addResultNode(c: PContext, n: PNode) = proc copyExcept(n: PNode, i: int): PNode = result = copyNode(n) - for j in 0.. <n.len: + for j in 0..<n.len: if j != i: result.add(n.sons[j]) proc lookupMacro(c: PContext, n: PNode): PSym = @@ -1113,7 +1139,7 @@ proc semProcAnnotation(c: PContext, prc: PNode; validPragmas: TSpecialWords): PNode = var n = prc.sons[pragmasPos] if n == nil or n.kind == nkEmpty: return - for i in countup(0, <n.len): + for i in countup(0, n.len-1): var it = n.sons[i] var key = if it.kind == nkExprColonExpr: it.sons[0] else: it let m = lookupMacro(c, key) @@ -1264,7 +1290,7 @@ proc activate(c: PContext, n: PNode) = of nkLambdaKinds: discard semLambda(c, n, {}) of nkCallKinds: - for i in 1 .. <n.len: activate(c, n[i]) + for i in 1 ..< n.len: activate(c, n[i]) else: discard @@ -1284,7 +1310,7 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = var obj = t.sons[1].sons[0] while true: incl(obj.flags, tfHasAsgn) - if obj.kind == tyGenericBody: obj = obj.lastSon + if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon elif obj.kind == tyGenericInvocation: obj = obj.sons[0] else: break if obj.kind in {tyObject, tyDistinct}: @@ -1294,13 +1320,9 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = localError(n.info, errGenerated, "cannot bind another '" & s.name.s & "' to: " & typeToString(obj)) noError = true - if not noError: + if not noError and sfSystemModule notin s.owner.flags: localError(n.info, errGenerated, "signature for '" & s.name.s & "' must be proc[T: object](x: var T)") - else: - doDestructorStuff(c, s, n) - if not experimentalMode(c): - localError n.info, "use the {.experimental.} pragma to enable destructors" incl(s.flags, sfUsed) of "deepcopy", "=deepcopy": if s.typ.len == 2 and @@ -1350,8 +1372,9 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = localError(n.info, errGenerated, "cannot bind another '" & s.name.s & "' to: " & typeToString(obj)) return - localError(n.info, errGenerated, - "signature for '" & s.name.s & "' must be proc[T: object](x: var T; y: T)") + if sfSystemModule notin s.owner.flags: + localError(n.info, errGenerated, + "signature for '" & s.name.s & "' must be proc[T: object](x: var T; y: T)") else: if sfOverriden in s.flags: localError(n.info, errGenerated, @@ -1526,8 +1549,11 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, s.options = gOptions if sfOverriden in s.flags or s.name.s[0] == '=': semOverride(c, s, n) if s.name.s[0] in {'.', '('}: - if s.name.s in [".", ".()", ".=", "()"] and not experimentalMode(c): + if s.name.s in [".", ".()", ".="] and not experimentalMode(c) and not newDestructors: message(n.info, warnDeprecated, "overloaded '.' and '()' operators are now .experimental; " & s.name.s) + elif s.name.s == "()" and not experimentalMode(c): + message(n.info, warnDeprecated, "overloaded '()' operators are now .experimental; " & s.name.s) + if n.sons[bodyPos].kind != nkEmpty: # for DLL generation it is annoying to check for sfImportc! if sfBorrow in s.flags: @@ -1686,7 +1712,7 @@ proc evalInclude(c: PContext, n: PNode): PNode = excl(c.includedFiles, f) proc setLine(n: PNode, info: TLineInfo) = - for i in 0 .. <safeLen(n): setLine(n.sons[i], info) + for i in 0 ..< safeLen(n): setLine(n.sons[i], info) n.info = info proc semPragmaBlock(c: PContext, n: PNode): PNode = @@ -1694,7 +1720,7 @@ proc semPragmaBlock(c: PContext, n: PNode): PNode = pragma(c, nil, pragmaList, exprPragmas) result = semExpr(c, n.sons[1]) n.sons[1] = result - for i in 0 .. <pragmaList.len: + for i in 0 ..< pragmaList.len: case whichPragma(pragmaList.sons[i]) of wLine: setLine(result, pragmaList.sons[i].info) of wLocks, wGcSafe: @@ -1827,11 +1853,12 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = else: n.typ = n.sons[i].typ if not isEmptyType(n.typ): n.kind = nkStmtListExpr - case n.sons[i].kind - of LastBlockStmts: + if n.sons[i].kind in LastBlockStmts or + n.sons[i].kind in nkCallKinds and n.sons[i][0].kind == nkSym and sfNoReturn in n.sons[i][0].sym.flags: for j in countup(i + 1, length - 1): case n.sons[j].kind - of nkPragma, nkCommentStmt, nkNilLit, nkEmpty: discard + of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkBlockExpr, + nkBlockStmt, nkState: discard else: localError(n.sons[j].info, errStmtInvalidAfterReturn) else: discard diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index be8567c9c..f90dff8f1 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -75,7 +75,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode = a = nextOverloadIter(o, c, n) proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode = - for i in 0 .. < n.len: + for i in 0 ..< n.len: var a = n.sons[i] # If 'a' is an overloaded symbol, we used to use the first symbol # as a 'witness' and use the fact that subsequent lookups will yield @@ -95,7 +95,7 @@ proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode = result = newNodeI(nkEmpty, n.info) proc semMixinStmt(c: PContext, n: PNode, toMixin: var IntSet): PNode = - for i in 0 .. < n.len: + for i in 0 ..< n.len: toMixin.incl(considerQuotedIdent(n.sons[i]).id) result = newNodeI(nkEmpty, n.info) @@ -113,13 +113,9 @@ type owner: PSym cursorInBody: bool # only for nimsuggest scopeN: int - bracketExpr: PNode template withBracketExpr(ctx, x, body: untyped) = - let old = ctx.bracketExpr - ctx.bracketExpr = x body - ctx.bracketExpr = old proc getIdentNode(c: var TemplCtx, n: PNode): PNode = case n.kind @@ -163,7 +159,7 @@ proc onlyReplaceParams(c: var TemplCtx, n: PNode): PNode = result = newSymNode(s, n.info) styleCheckUse(n.info, s) else: - for i in 0 .. <n.safeLen: + for i in 0 ..< n.safeLen: result.sons[i] = onlyReplaceParams(c, n.sons[i]) proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym = @@ -301,21 +297,9 @@ proc semPattern(c: PContext, n: PNode): PNode proc semTemplBodySons(c: var TemplCtx, n: PNode): PNode = result = n - for i in 0.. < n.len: + for i in 0 ..< n.len: result.sons[i] = semTemplBody(c, n.sons[i]) -proc oprIsRoof(n: PNode): bool = - const roof = "^" - case n.kind - of nkIdent: result = n.ident.s == roof - of nkSym: result = n.sym.name.s == roof - of nkAccQuoted: - if n.len == 1: - result = oprIsRoof(n.sons[0]) - of nkOpenSymChoice, nkClosedSymChoice: - result = oprIsRoof(n.sons[0]) - else: discard - proc semTemplBody(c: var TemplCtx, n: PNode): PNode = result = n semIdeForTemplateOrGenericCheck(n, c.cursorInBody) @@ -347,7 +331,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = of nkMixinStmt: if c.scopeN > 0: result = semTemplBodySons(c, n) else: result = semMixinStmt(c.c, n, c.toMixin) - of nkEmpty, nkSym..nkNilLit: + of nkEmpty, nkSym..nkNilLit, nkComesFrom: discard of nkIfStmt: for i in countup(0, sonsLen(n)-1): @@ -382,8 +366,10 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = n.sons[L-2] = semTemplBody(c, n.sons[L-2]) for i in countup(0, L - 3): addLocalDecl(c, n.sons[i], skForVar) + openScope(c) n.sons[L-1] = semTemplBody(c, n.sons[L-1]) closeScope(c) + closeScope(c) of nkBlockStmt, nkBlockExpr, nkBlockType: checkSonsLen(n, 2) openScope(c) @@ -506,8 +492,6 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = result = semTemplBodySons(c, n) of nkCallKinds-{nkPostfix}: result = semTemplBodySons(c, n) - if c.bracketExpr != nil and n.len == 2 and oprIsRoof(n.sons[0]): - result.add c.bracketExpr of nkDotExpr, nkAccQuoted: # dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam', # so we use the generic code for nkDotExpr too @@ -544,7 +528,7 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode = result = semTemplBodyDirty(c, n.sons[0]) of nkBindStmt: result = semBindStmt(c.c, n, c.toBind) - of nkEmpty, nkSym..nkNilLit: + of nkEmpty, nkSym..nkNilLit, nkComesFrom: discard else: # dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam', diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index fbb5d0b6b..cb66685b2 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -138,7 +138,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = if n.len < 1: result = newConstraint(c, kind) else: - let isCall = ord(n.kind in nkCallKinds+{nkBracketExpr}) + let isCall = int ord(n.kind in nkCallKinds+{nkBracketExpr}) let n = if n[0].kind == nkBracket: n[0] else: n checkMinSonsLen(n, 1) var t = semTypeNode(c, n.lastSon, nil) @@ -235,7 +235,10 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType = n.sons[1].floatVal < 0.0: incl(result.flags, tfNeedsInit) else: - localError(n.sons[0].info, errRangeExpected) + if n[1].kind == nkInfix and considerQuotedIdent(n[1][0]).s == "..<": + localError(n[0].info, "range types need to be constructed with '..', '..<' is not supported") + else: + localError(n.sons[0].info, errRangeExpected) result = newOrPrevType(tyError, prev, c) else: localError(n.info, errXExpectsOneTypeParam, "range") @@ -293,7 +296,9 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = base = semTypeNode(c, n.sons[2], nil) # ensure we only construct a tyArray when there was no error (bug #3048): result = newOrPrevType(tyArray, prev, c) - addSonSkipIntLit(result, indx) + # bug #6682: Do not propagate initialization requirements etc for the + # index type: + rawAddSonNoPropagationOfTypeFlags(result, indx) addSonSkipIntLit(result, base) else: localError(n.info, errArrayExpectsTwoTypeParams) @@ -315,11 +320,8 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = if n.kind == nkSym: result = getGenSym(c, n.sym) else: - when defined(nimfix): - result = pickSym(c, n, skType) - if result.isNil: - result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) - else: + result = pickSym(c, n, {skType, skGenericParam}) + if result.isNil: result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) if result != nil: markUsed(n.info, result, c.graph.usageSym) @@ -515,7 +517,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, # first element is special and will overwrite: branch.sons[i]: branch.sons[i] = semCaseBranchSetElem(c, t, r[0], covered) # other elements have to be added to ``branch`` - for j in 1 .. <r.len: + for j in 1 ..< r.len: branch.add(semCaseBranchSetElem(c, t, r[j], covered)) # caution! last son of branch must be the actions to execute: var L = branch.len @@ -846,7 +848,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, @[newTypeS(paramType.kind, c)]) result = addImplicitGeneric(typ) else: - for i in 0 .. <paramType.len: + for i in 0 ..< paramType.len: if paramType.sons[i] == paramType: globalError(info, errIllegalRecursionInTypeX, typeToString(paramType)) var lifted = liftingWalk(paramType.sons[i]) @@ -897,7 +899,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result.shouldHaveMeta of tyGenericInvocation: - for i in 1 .. <paramType.len: + for i in 1 ..< paramType.len: let lifted = liftingWalk(paramType.sons[i]) if lifted != nil: paramType.sons[i] = lifted @@ -1045,6 +1047,12 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, result.flags.incl tfIterator # XXX Would be nice if we could get rid of this result.sons[0] = r + let oldFlags = result.flags + propagateToOwner(result, r) + if oldFlags != result.flags: + # XXX This rather hacky way keeps 'tflatmap' compiling: + if tfHasMeta notin oldFlags: + result.flags.excl tfHasMeta result.n.typ = r if genericParams != nil and genericParams.len > 0: @@ -1146,7 +1154,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = var isConcrete = true - for i in 1 .. <m.call.len: + for i in 1 ..< m.call.len: var typ = m.call[i].typ if typ.kind == tyTypeDesc and typ.sons[0].kind == tyNone: isConcrete = false @@ -1167,7 +1175,10 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = # special check for generic object with # generic/partial specialized parent - let tx = result.skipTypes(abstractPtrs) + let tx = result.skipTypes(abstractPtrs, 50) + if tx.isNil: + localError(n.info, "invalid recursion in type '$1'" % typeToString(result[0])) + return errorType(c) if tx != result and tx.kind == tyObject and tx.sons[0] != nil: semObjectTypeForInheritedGenericInst(c, n, tx) @@ -1215,8 +1226,6 @@ template modifierTypeKindOfNode(n: PNode): TTypeKind = proc semTypeClass(c: PContext, n: PNode, prev: PType): PType = # if n.sonsLen == 0: return newConstraint(c, tyTypeClass) - if nfBase2 in n.flags: - message(n.info, warnDeprecated, "use 'concept' instead; 'generic'") let pragmas = n[1] inherited = n[2] @@ -1295,8 +1304,7 @@ proc symFromExpectedTypeNode(c: PContext, n: PNode): PSym = proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = nil - when defined(nimsuggest): - inc c.inTypeContext + inc c.inTypeContext if gCmd == cmdIdeTools: suggestExpr(c, n) case n.kind @@ -1355,7 +1363,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = case n.len of 3: result = semTypeNode(c, n.sons[1], prev) - if result.skipTypes({tyGenericInst, tyAlias}).kind in NilableTypes+GenericTypes and + if result.skipTypes({tyGenericInst, tyAlias}).kind in NilableTypes+GenericTypes+{tyForward} and n.sons[2].kind == nkNilLit: result = freshType(result, prev) result.flags.incl(tfNotNil) @@ -1418,9 +1426,13 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = else: result = semGeneric(c, n, s, prev) of nkDotExpr: let typeExpr = semExpr(c, n) - if typeExpr.typ.kind == tyFromExpr: - return typeExpr.typ - if typeExpr.typ.kind != tyTypeDesc: + if typeExpr.typ.isNil: + localError(n.info, "object constructor needs an object type;" & + " for named arguments use '=' instead of ':'") + result = errorType(c) + elif typeExpr.typ.kind == tyFromExpr: + result = typeExpr.typ + elif typeExpr.typ.kind != tyTypeDesc: localError(n.info, errTypeExpected) result = errorType(c) else: @@ -1511,8 +1523,13 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = localError(n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) n.typ = result - when defined(nimsuggest): - dec c.inTypeContext + dec c.inTypeContext + if c.inTypeContext == 0: instAllTypeBoundOp(c, n.info) + +when false: + proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = + result = semTypeNodeInner(c, n, prev) + instAllTypeBoundOp(c, n.info) proc setMagicType(m: PSym, kind: TTypeKind, size: int) = # source : https://en.wikipedia.org/wiki/Data_structure_alignment#x86 @@ -1600,6 +1617,7 @@ proc processMagicType(c: PContext, m: PSym) = rawAddSon(m.typ, newTypeS(tyNone, c)) of mPNimrodNode: incl m.typ.flags, tfTriggersCompileTime + of mException: discard else: localError(m.info, errTypeExpected) proc semGenericConstraints(c: PContext, x: PType): PType = @@ -1614,8 +1632,8 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = var a = n.sons[i] if a.kind != nkIdentDefs: illFormedAst(n) let L = a.len - var def = a{-1} - let constraint = a{-2} + var def = a[^1] + let constraint = a[^2] var typ: PType if constraint.kind != nkEmpty: diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 172a557b3..a42092ae0 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -77,7 +77,7 @@ type topLayer*: TIdTable nextLayer*: ptr LayeredIdTable - TReplTypeVars* {.final.} = object + TReplTypeVars* = object c*: PContext typeMap*: ptr LayeredIdTable # map PType to PType symMap*: TIdTable # map PSym to PSym @@ -133,7 +133,7 @@ proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode = result.typ = t if result.kind == nkSym: result.sym = replaceTypeVarsS(cl, n.sym) let isCall = result.kind in nkCallKinds - for i in 0 .. <n.safeLen: + for i in 0 ..< n.safeLen: # XXX HACK: ``f(a, b)``, avoid to instantiate `f` if isCall and i == 0: result.add(n[i]) else: result.add(prepareNode(cl, n[i])) @@ -151,7 +151,7 @@ proc hasGenericArguments*(n: PNode): bool = (n.sym.kind == skType and n.sym.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} != {}) else: - for i in 0.. <n.safeLen: + for i in 0..<n.safeLen: if hasGenericArguments(n.sons[i]): return true return false @@ -166,13 +166,13 @@ proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode = # overload resolution is executed again (which may trigger generateInstance). if n.kind in nkCallKinds and sfFromGeneric in n[0].sym.flags: var needsFixing = false - for i in 1 .. <n.safeLen: + for i in 1 ..< n.safeLen: if isTypeParam(n[i]): needsFixing = true if needsFixing: n.sons[0] = newSymNode(n.sons[0].sym.owner) return cl.c.semOverloadedCall(cl.c, n, n, {skProc, skFunc}, {}) - for i in 0 .. <n.safeLen: + for i in 0 ..< n.safeLen: n.sons[i] = reResolveCallsWithTypedescParams(cl, n[i]) return n @@ -261,6 +261,17 @@ proc instCopyType*(cl: var TReplTypeVars, t: PType): PType = if not (t.kind in tyMetaTypes or (t.kind == tyStatic and t.n == nil)): result.flags.excl tfInstClearedFlags + when false: + if newDestructors: + result.assignment = nil + #result.destructor = nil + result.sink = nil + +template typeBound(c, newty, oldty, field, info) = + let opr = newty.field + if opr != nil and sfFromGeneric notin opr.flags: + # '=' needs to be instantiated for generics when the type is constructed: + newty.field = c.instTypeBoundOp(c, opr, oldty, info, attachedAsgn, 1) proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = # tyGenericInvocation[A, tyGenericInvocation[A, B]] @@ -357,17 +368,10 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = assert newbody.kind in {tyRef, tyPtr} assert newbody.lastSon.typeInst == nil newbody.lastSon.typeInst = result - template typeBound(field) = - let opr = newbody.field - if opr != nil and sfFromGeneric notin opr.flags: - # '=' needs to be instantiated for generics when the type is constructed: - newbody.field = cl.c.instTypeBoundOp(cl.c, opr, result, cl.info, - attachedAsgn, 1) - # we need to produce the destructor first here because generated '=' - # and '=sink' operators can rely on it: - if newDestructors: typeBound(destructor) - typeBound(assignment) - typeBound(sink) + if newDestructors: + cl.c.typesWithOps.add((newbody, result)) + else: + typeBound(cl.c, newbody, result, assignment, cl.info) let methods = skipTypes(bbody, abstractPtrs).methods for col, meth in items(methods): # we instantiate the known methods belonging to that type, this causes @@ -381,11 +385,11 @@ proc eraseVoidParams*(t: PType) = if t.sons[0] != nil and t.sons[0].kind == tyVoid: t.sons[0] = nil - for i in 1 .. <t.sonsLen: + for i in 1 ..< t.sonsLen: # don't touch any memory unless necessary if t.sons[i].kind == tyVoid: var pos = i - for j in i+1 .. <t.sonsLen: + for j in i+1 ..< t.sonsLen: if t.sons[j].kind != tyVoid: t.sons[pos] = t.sons[j] t.n.sons[pos] = t.n.sons[j] @@ -395,7 +399,7 @@ proc eraseVoidParams*(t: PType) = return proc skipIntLiteralParams*(t: PType) = - for i in 0 .. <t.sonsLen: + for i in 0 ..< t.sonsLen: let p = t.sons[i] if p == nil: continue let skipped = p.skipIntLit @@ -496,7 +500,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = bailout() result = instCopyType(cl, t) idTablePut(cl.localCache, t, result) - for i in 1 .. <result.sonsLen: + for i in 1 ..< result.sonsLen: result.sons[i] = replaceTypeVarsT(cl, result.sons[i]) propagateToOwner(result, result.lastSon) @@ -518,7 +522,8 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = if r2.kind in {tyPtr, tyRef}: r = skipTypes(r2, {tyPtr, tyRef}) result.sons[i] = r - propagateToOwner(result, r) + if result.kind != tyArray or i != 0: + propagateToOwner(result, r) # bug #4677: Do not instantiate effect lists result.n = replaceTypeVarsN(cl, result.n, ord(result.kind==tyProc)) case result.kind @@ -535,6 +540,17 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = else: discard +proc instAllTypeBoundOp*(c: PContext, info: TLineInfo) = + if not newDestructors: return + var i = 0 + while i < c.typesWithOps.len: + let (newty, oldty) = c.typesWithOps[i] + typeBound(c, newty, oldty, destructor, info) + typeBound(c, newty, oldty, sink, info) + typeBound(c, newty, oldty, assignment, info) + inc i + setLen(c.typesWithOps, 0) + proc initTypeVars*(p: PContext, typeMap: ptr LayeredIdTable, info: TLineInfo; owner: PSym): TReplTypeVars = initIdTable(result.symMap) diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 6043eb4a7..5d6b5978d 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -87,6 +87,7 @@ type CoProc CoType CoOwnerSig + CoIgnoreRange proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) @@ -136,7 +137,7 @@ proc hashTree(c: var MD5Context, n: PNode) = of nkStrLit..nkTripleStrLit: c &= n.strVal else: - for i in 0.. <n.len: hashTree(c, n.sons[i]) + for i in 0..<n.len: hashTree(c, n.sons[i]) proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = if t == nil: @@ -159,14 +160,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = return else: discard - c &= char(t.kind) case t.kind of tyBool, tyChar, tyInt..tyUInt64: # no canonicalization for integral types, so that e.g. ``pid_t`` is # produced instead of ``NI``: + c &= char(t.kind) if t.sym != nil and {sfImportc, sfExportc} * t.sym.flags != {}: c.hashSym(t.sym) of tyObject, tyEnum: + c &= char(t.kind) if t.typeInst != nil: assert t.typeInst.kind == tyGenericInst for i in countup(1, sonsLen(t.typeInst) - 2): @@ -199,26 +201,35 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = if t.len > 0 and t.sons[0] != nil: hashType c, t.sons[0], flags of tyRef, tyPtr, tyGenericBody, tyVar: + c &= char(t.kind) c.hashType t.lastSon, flags if tfVarIsPtr in t.flags: c &= ".varisptr" of tyFromExpr: + c &= char(t.kind) c.hashTree(t.n) of tyTuple: + c &= char(t.kind) if t.n != nil and CoType notin flags: assert(sonsLen(t.n) == sonsLen(t)) for i in countup(0, sonsLen(t.n) - 1): assert(t.n.sons[i].kind == nkSym) c &= t.n.sons[i].sym.name.s c &= ':' - c.hashType(t.sons[i], flags) + c.hashType(t.sons[i], flags+{CoIgnoreRange}) c &= ',' else: - for i in countup(0, sonsLen(t) - 1): c.hashType t.sons[i], flags - of tyRange, tyStatic: - #if CoType notin flags: + for i in countup(0, sonsLen(t) - 1): c.hashType t.sons[i], flags+{CoIgnoreRange} + of tyRange: + if CoIgnoreRange notin flags: + c &= char(t.kind) + c.hashTree(t.n) + c.hashType(t.sons[0], flags) + of tyStatic: + c &= char(t.kind) c.hashTree(t.n) c.hashType(t.sons[0], flags) of tyProc: + c &= char(t.kind) c &= (if tfIterator in t.flags: "iterator " else: "proc ") if CoProc in flags and t.n != nil: let params = t.n @@ -230,14 +241,18 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = c &= ',' c.hashType(t.sons[0], flags) else: - for i in 0.. <t.len: c.hashType(t.sons[i], flags) + for i in 0..<t.len: c.hashType(t.sons[i], flags) c &= char(t.callConv) if CoType notin flags: if tfNoSideEffect in t.flags: c &= ".noSideEffect" if tfThread in t.flags: c &= ".thread" if tfVarargs in t.flags: c &= ".varargs" + of tyArray: + c &= char(t.kind) + for i in 0..<t.len: c.hashType(t.sons[i], flags-{CoIgnoreRange}) else: - for i in 0.. <t.len: c.hashType(t.sons[i], flags) + c &= char(t.kind) + for i in 0..<t.len: c.hashType(t.sons[i], flags) if tfNotNil in t.flags and CoType notin flags: c &= "not nil" when defined(debugSigHashes): diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 50d4178b6..3d0b0ed3d 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -55,6 +55,7 @@ type # a distrinct type typedescMatched*: bool isNoCall*: bool # misused for generic type instantiations C[T] + mutabilityProblem*: uint8 # tyVar mismatch inferredTypes: seq[PType] # inferred types during the current signature # matching. they will be reset if the matching # is not successful. may replace the bindings @@ -66,7 +67,6 @@ type # or when the explain pragma is used. may be # triggered with an idetools command in the # future. - mutabilityProblem*: uint8 # tyVar mismatch inheritancePenalty: int # to prefer closest father object type TTypeRelFlag* = enum @@ -200,7 +200,7 @@ proc sumGeneric(t: PType): int = inc result of tyGenericInvocation, tyTuple, tyProc, tyAnd: result += ord(t.kind in {tyGenericInvocation, tyAnd}) - for i in 0 .. <t.len: + for i in 0 ..< t.len: if t.sons[i] != nil: result += t.sons[i].sumGeneric break @@ -220,11 +220,12 @@ proc sumGeneric(t: PType): int = proc complexDisambiguation(a, b: PType): int = # 'a' matches better if *every* argument matches better or equal than 'b'. var winner = 0 - for i in 1 .. <min(a.len, b.len): + for i in 1 ..< min(a.len, b.len): let x = a.sons[i].sumGeneric let y = b.sons[i].sumGeneric #if ggDebug: - # echo "came her ", typeToString(a.sons[i]), " ", typeToString(b.sons[i]) + #echo "came herA ", typeToString(a.sons[i]), " ", x + #echo "came herB ", typeToString(b.sons[i]), " ", y if x != y: if winner == 0: if x > y: winner = 1 @@ -239,8 +240,8 @@ proc complexDisambiguation(a, b: PType): int = result = winner when false: var x, y: int - for i in 1 .. <a.len: x += a.sons[i].sumGeneric - for i in 1 .. <b.len: y += b.sons[i].sumGeneric + for i in 1 ..< a.len: x += a.sons[i].sumGeneric + for i in 1 ..< b.len: y += b.sons[i].sumGeneric result = x - y proc writeMatches*(c: TCandidate) = @@ -275,7 +276,7 @@ proc cmpCandidates*(a, b: TCandidate): int = proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string = if arg.kind in nkSymChoices: result = typeToString(arg[0].typ, prefer) - for i in 1 .. <arg.len: + for i in 1 ..< arg.len: result.add(" | ") result.add typeToString(arg[i].typ, prefer) elif arg.typ == nil: @@ -389,7 +390,16 @@ proc isConvertibleToRange(f, a: PType): bool = # be less picky for tyRange, as that it is used for array indexing: if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}: - result = true + case f.kind + of tyInt, tyInt64: result = true + of tyInt8: result = a.kind in {tyInt8, tyInt} + of tyInt16: result = a.kind in {tyInt8, tyInt16, tyInt} + of tyInt32: result = a.kind in {tyInt8, tyInt16, tyInt32, tyInt} + of tyUInt, tyUInt64: result = true + of tyUInt8: result = a.kind in {tyUInt8, tyUInt} + of tyUInt16: result = a.kind in {tyUInt8, tyUInt16, tyUInt} + of tyUInt32: result = a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt} + else: result = false elif f.kind in {tyFloat..tyFloat128} and a.kind in {tyFloat..tyFloat128}: result = true @@ -580,7 +590,7 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = # Note: We have to do unification for the parameters before the # return type! - for i in 1 .. <f.sonsLen: + for i in 1 ..< f.sonsLen: checkParam(f.sons[i], a.sons[i]) if f.sons[0] != nil: @@ -658,7 +668,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType = var typeParams: seq[(PSym, PType)] if ff.kind == tyUserTypeClassInst: - for i in 1 .. <(ff.len - 1): + for i in 1 ..< (ff.len - 1): var typeParamName = ff.base.sons[i-1].sym.name typ = ff.sons[i] @@ -1047,9 +1057,10 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, else: isNone of tyUserTypeClass, tyUserTypeClassInst: - if c.c.matchedConcept != nil: + if c.c.matchedConcept != nil and c.c.matchedConcept.depth <= 4: # consider this: 'var g: Node' *within* a concept where 'Node' # is a concept too (tgraph) + inc c.c.matchedConcept.depth let x = typeRel(c, a, f, flags + {trDontBind}) if x >= isGeneric: return isGeneric @@ -1374,7 +1385,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, # XXX: This is very hacky. It should be moved back into liftTypeParam if x.kind in {tyGenericInst, tyArray} and c.calleeSym != nil and - c.calleeSym.kind in {skProc, skFunc}: + c.calleeSym.kind in {skProc, skFunc} and c.call != nil: let inst = prepareMetatypeForSigmatch(c.c, c.bindings, c.call.info, f) return typeRel(c, inst, a) @@ -1451,8 +1462,13 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, of tyOr: considerPreviousT: result = isNone + let oldInheritancePenalty = c.inheritancePenalty + var maxInheritance = 0 for branch in f.sons: + c.inheritancePenalty = 0 let x = typeRel(c, branch, aOrig) + maxInheritance = max(maxInheritance, c.inheritancePenalty) + # 'or' implies maximum matching result: if x > result: result = x if result >= isSubtype: @@ -1460,6 +1476,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, bindingRet result else: result = isNone + c.inheritancePenalty = oldInheritancePenalty + maxInheritance of tyNot: considerPreviousT: @@ -1550,11 +1567,19 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, result = isNone else: if f.sonsLen > 0 and f.sons[0].kind != tyNone: + let oldInheritancePenalty = c.inheritancePenalty result = typeRel(c, f.lastSon, a, flags + {trDontBind}) if doBind and result notin {isNone, isGeneric}: let concrete = concreteType(c, a) if concrete == nil: return isNone put(c, f, concrete) + # bug #6526 + if result in {isEqual, isSubtype}: + # 'T: Class' is a *better* match than just 'T' + # but 'T: Subclass' is even better: + c.inheritancePenalty = oldInheritancePenalty - c.inheritancePenalty - + 100 * ord(result == isEqual) + result = isGeneric else: result = isGeneric @@ -1588,7 +1613,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, if not exprStructuralEquivalent(f.n, aOrig.n): result = isNone if result != isNone: put(c, f, aOrig) - elif aOrig.n != nil: + elif aOrig.n != nil and aOrig.n.typ != nil: result = typeRel(c, f.lastSon, aOrig.n.typ) if result != isNone: var boundType = newTypeWithSons(c.c, tyStatic, @[aOrig.n.typ]) @@ -2218,7 +2243,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, proc semFinishOperands*(c: PContext, n: PNode) = # this needs to be called to ensure that after overloading resolution every # argument has been sem'checked: - for i in 1 .. <n.len: + for i in 1 ..< n.len: n.sons[i] = prepareOperand(c, n.sons[i]) proc partialMatch*(c: PContext, n, nOrig: PNode, m: var TCandidate) = @@ -2288,7 +2313,8 @@ proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo; localError(info, errGenerated, "cannot instantiate '" & dc.name.s & "'") else: result = c.semGenerateInstance(c, dc, m.bindings, info) - assert sfFromGeneric in result.flags + if op == attachedDeepCopy: + assert sfFromGeneric in result.flags include suggest diff --git a/compiler/transf.nim b/compiler/transf.nim index c3d12dafe..f8f7f8746 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -21,7 +21,7 @@ import intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os, idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread, - lambdalifting, sempass2, lowerings, lookups, destroyer + lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals type PTransNode* = distinct PNode @@ -231,7 +231,7 @@ proc freshLabels(c: PTransf, n: PNode; symMap: var TIdTable) = let x = PSym(idTableGet(symMap, n.sym)) if x != nil: n.sym = x else: - for i in 0 .. <safeLen(n): freshLabels(c, n.sons[i], symMap) + for i in 0 ..< safeLen(n): freshLabels(c, n.sons[i], symMap) proc transformBlock(c: PTransf, n: PNode): PTransNode = var labl: PSym @@ -275,7 +275,7 @@ proc transformWhile(c: PTransf; n: PNode): PTransNode = var body = newTransNode(n) for i in 0..n.len-2: body[i] = transform(c, n.sons[i]) - body[<n.len] = transformLoopBody(c, n.sons[<n.len]) + body[n.len-1] = transformLoopBody(c, n.sons[n.len-1]) result[1] = body discard c.breakSyms.pop @@ -365,16 +365,22 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode = # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x) n.sons[0].sons[0] = m.sons[0] result = PTransNode(n.sons[0]) + if n.typ.skipTypes(abstractVar).kind != tyOpenArray: + PNode(result).typ = n.typ of nkHiddenStdConv, nkHiddenSubConv, nkConv: var m = n.sons[0].sons[1] if m.kind == a or m.kind == b: # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x) n.sons[0].sons[1] = m.sons[0] result = PTransNode(n.sons[0]) + if n.typ.skipTypes(abstractVar).kind != tyOpenArray: + PNode(result).typ = n.typ else: if n.sons[0].kind == a or n.sons[0].kind == b: # addr ( deref ( x )) --> x result = PTransNode(n.sons[0].sons[0]) + if n.typ.skipTypes(abstractVar).kind != tyOpenArray: + PNode(result).typ = n.typ proc generateThunk(prc: PNode, dest: PType): PNode = ## Converts 'prc' into '(thunk, nil)' so that it's compatible with @@ -510,7 +516,7 @@ proc findWrongOwners(c: PTransf, n: PNode) = internalError(x.info, "bah " & x.sym.name.s & " " & x.sym.owner.name.s & " " & getCurrOwner(c).name.s) else: - for i in 0 .. <safeLen(n): findWrongOwners(c, n.sons[i]) + for i in 0 ..< safeLen(n): findWrongOwners(c, n.sons[i]) proc transformFor(c: PTransf, n: PNode): PTransNode = # generate access statements for the parameters (unless they are constant) @@ -640,7 +646,7 @@ proc transformArrayAccess(c: PTransf, n: PNode): PTransNode = result = n.PTransNode else: result = newTransNode(n) - for i in 0 .. < n.len: + for i in 0 ..< n.len: result[i] = transform(c, skipConv(n.sons[i])) proc getMergeOp(n: PNode): PSym = @@ -687,7 +693,7 @@ proc transformCall(c: PTransf, n: PNode): PTransNode = inc(j) add(result, a.PTransNode) if len(result) == 2: result = result[1] - elif magic in {mNBindSym, mTypeOf}: + elif magic in {mNBindSym, mTypeOf, mRunnableExamples}: # for bindSym(myconst) we MUST NOT perform constant folding: result = n.PTransNode elif magic == mProcCall: @@ -744,7 +750,7 @@ proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} = proc commonOptimizations*(c: PSym, n: PNode): PNode = result = n - for i in 0 .. < n.safeLen: + for i in 0 ..< n.safeLen: result.sons[i] = commonOptimizations(c, n.sons[i]) var op = getMergeOp(n) if (op != nil) and (op.magic != mNone) and (sonsLen(n) >= 3): @@ -785,7 +791,7 @@ proc transform(c: PTransf, n: PNode): PTransNode = case n.kind of nkSym: result = transformSym(c, n) - of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: + of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkComesFrom: # nothing to be done for leaves: result = PTransNode(n) of nkBracketExpr: result = transformArrayAccess(c, n) @@ -908,7 +914,7 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode = # Note: For interactive mode we cannot call 'passes.skipCodegen' and skip # this step! We have to rely that the semantic pass transforms too errornous # nodes into an empty node. - if c.fromCache or nfTransf in n.flags: return n + if c.rd != nil or nfTransf in n.flags: return n pushTransCon(c, newTransCon(owner)) result = PNode(transform(c, n)) popTransCon(c) @@ -972,6 +978,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode = liftDefer(c, result) #result = liftLambdas(prc, result) when useEffectSystem: trackProc(prc, result) + result = liftLocalsIfRequested(prc, result) if c.needsDestroyPass and newDestructors: result = injectDestructorCalls(prc, result) incl(result.flags, nfTransf) diff --git a/compiler/trees.nim b/compiler/trees.nim index c77dab349..7efefdc2e 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -98,7 +98,7 @@ proc isDeepConstExpr*(n: PNode): bool = of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv: result = isDeepConstExpr(n.sons[1]) of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure, nkRange: - for i in ord(n.kind == nkObjConstr) .. <n.len: + for i in ord(n.kind == nkObjConstr) ..< n.len: if not isDeepConstExpr(n.sons[i]): return false if n.typ.isNil: result = true else: diff --git a/compiler/types.nim b/compiler/types.nim index f32b0da18..495a1977d 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -14,7 +14,8 @@ import type TPreferedDesc* = enum - preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg + preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg, + preferTypeName proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string template `$`*(typ: PType): string = typeToString(typ) @@ -394,7 +395,7 @@ const "and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor", "void"] -const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg} +const preferToResolveSymbols = {preferName, preferTypeName, preferModuleInfo, preferGenericArg} template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) = tc.sons.safeAdd concrete @@ -420,7 +421,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = sfAnon notin t.sym.flags: if t.kind == tyInt and isIntLit(t): result = t.sym.name.s & " literal(" & $t.n.intVal & ")" - elif prefer == preferName or t.sym.owner.isNil: + elif prefer in {preferName, preferTypeName} or t.sym.owner.isNil: result = t.sym.name.s if t.kind == tyGenericParam and t.sons != nil and t.sonsLen > 0: result.add ": " @@ -518,7 +519,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = "openarray[" & typeToString(t.sons[0]) & ']' of tyDistinct: result = "distinct " & typeToString(t.sons[0], - if prefer == preferModuleInfo: preferModuleInfo else: preferName) + if prefer == preferModuleInfo: preferModuleInfo else: preferTypeName) of tyTuple: # we iterate over t.sons here, because t.n may be nil if t.n != nil: @@ -532,7 +533,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = elif sonsLen(t) == 0: result = "tuple[]" else: - result = "(" + if prefer == preferTypeName: result = "(" + else: result = "tuple of (" for i in countup(0, sonsLen(t) - 1): add(result, typeToString(t.sons[i])) if i < sonsLen(t) - 1: add(result, ", ") @@ -742,7 +744,7 @@ proc equalParam(a, b: PSym): TParamsEquality = proc sameConstraints(a, b: PNode): bool = if isNil(a) and isNil(b): return true internalAssert a.len == b.len - for i in 1 .. <a.len: + for i in 1 ..< a.len: if not exprStructuralEquivalent(a[i].sym.constraint, b[i].sym.constraint): return false @@ -970,7 +972,12 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyOpt: cycleCheck() if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n - result = sameChildrenAux(a, b, c) and sameFlags(a, b) + result = sameChildrenAux(a, b, c) + if result: + if IgnoreTupleFields in c.flags: + result = a.flags * {tfVarIsPtr} == b.flags * {tfVarIsPtr} + else: + result = sameFlags(a, b) if result and ExactGcSafety in c.flags: result = a.flags * {tfThread} == b.flags * {tfThread} if result and a.kind == tyProc: @@ -990,6 +997,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = proc sameBackendType*(x, y: PType): bool = var c = initSameTypeClosure() c.flags.incl IgnoreTupleFields + c.cmp = dcEqIgnoreDistinct result = sameTypeAux(x, y, c) proc compareTypes*(x, y: PType, @@ -1509,7 +1517,7 @@ proc isCompileTimeOnly*(t: PType): bool {.inline.} = proc containsCompileTimeOnly*(t: PType): bool = if isCompileTimeOnly(t): return true if t.sons != nil: - for i in 0 .. <t.sonsLen: + for i in 0 ..< t.sonsLen: if t.sons[i] != nil and isCompileTimeOnly(t.sons[i]): return true return false diff --git a/compiler/typesrenderer.nim b/compiler/typesrenderer.nim index 74eb00f4e..4a9b8d1a9 100644 --- a/compiler/typesrenderer.nim +++ b/compiler/typesrenderer.nim @@ -20,7 +20,7 @@ proc renderPlainSymbolName*(n: PNode): string = result = "" case n.kind of nkPostfix, nkAccQuoted: - result = renderPlainSymbolName(n[<n.len]) + result = renderPlainSymbolName(n[n.len-1]) of nkIdent: result = n.ident.s of nkSym: @@ -58,8 +58,8 @@ proc renderType(n: PNode): string = assert params.kind == nkFormalParams assert len(params) > 0 result = "proc(" - for i in 1 .. <len(params): result.add(renderType(params[i]) & ',') - result[<len(result)] = ')' + for i in 1 ..< len(params): result.add(renderType(params[i]) & ',') + result[len(result)-1] = ')' else: result = "proc" of nkIdentDefs: @@ -67,18 +67,18 @@ proc renderType(n: PNode): string = let typePos = len(n) - 2 let typeStr = renderType(n[typePos]) result = typeStr - for i in 1 .. <typePos: + for i in 1 ..< typePos: assert n[i].kind == nkIdent result.add(',' & typeStr) of nkTupleTy: result = "tuple[" - for i in 0 .. <len(n): result.add(renderType(n[i]) & ',') - result[<len(result)] = ']' + for i in 0 ..< len(n): result.add(renderType(n[i]) & ',') + result[len(result)-1] = ']' of nkBracketExpr: assert len(n) >= 2 result = renderType(n[0]) & '[' - for i in 1 .. <len(n): result.add(renderType(n[i]) & ',') - result[<len(result)] = ']' + for i in 1 ..< len(n): result.add(renderType(n[i]) & ',') + result[len(result)-1] = ']' else: result = "" assert(not result.isNil) @@ -91,7 +91,7 @@ proc renderParamTypes(found: var seq[string], n: PNode) = ## generator does include the information. case n.kind of nkFormalParams: - for i in 1 .. <len(n): renderParamTypes(found, n[i]) + for i in 1 ..< len(n): renderParamTypes(found, n[i]) of nkIdentDefs: # These are parameter names + type + default value node. let typePos = len(n) - 2 @@ -102,7 +102,7 @@ proc renderParamTypes(found: var seq[string], n: PNode) = let typ = n[typePos+1].typ if not typ.isNil: typeStr = typeToString(typ, preferExported) if typeStr.len < 1: return - for i in 0 .. <typePos: + for i in 0 ..< typePos: found.add(typeStr) else: internalError(n.info, "renderParamTypes(found,n) with " & $n.kind) diff --git a/compiler/vm.nim b/compiler/vm.nim index 08605cad1..5c9a982ab 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -322,7 +322,7 @@ proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool = if x <% n.len and (let f = n.sons[x].sym; f.position == x): dest.node.strVal = if f.ast.isNil: f.name.s else: f.ast.strVal else: - for i in 0.. <n.len: + for i in 0..<n.len: if n.sons[i].kind != nkSym: internalError("opConv for enum") let f = n.sons[i].sym if f.position == x: @@ -431,7 +431,7 @@ proc setLenSeq(c: PCtx; node: PNode; newLen: int; info: TLineInfo) = setLen(node.sons, newLen) if oldLen < newLen: # TODO: This is still not correct for tyPtr, tyRef default value - for i in oldLen .. <newLen: + for i in oldLen ..< newLen: node.sons[i] = newNodeI(typeKind, info) proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = @@ -1078,7 +1078,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].node = newNodeI(nkBracket, c.debug[pc]) regs[ra].node.typ = typ newSeq(regs[ra].node.sons, count) - for i in 0 .. <count: + for i in 0 ..< count: regs[ra].node.sons[i] = getNullValue(typ.sons[0], c.debug[pc]) of opcNewStr: decodeB(rkNode) @@ -1213,7 +1213,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = var u = regs[rb].node if u.kind notin {nkEmpty..nkNilLit}: # XXX can be optimized: - for i in 0.. <x.len: u.add(x.sons[i]) + for i in 0..<x.len: u.add(x.sons[i]) else: stackTrace(c, tos, pc, errGenerated, "cannot add to node kind: " & $u.kind) regs[ra].node = u @@ -1555,7 +1555,7 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode = if not isEmptyType(sym.typ.sons[0]) or sym.kind == skMacro: putIntoReg(tos.slots[0], getNullValue(sym.typ.sons[0], sym.info)) # XXX We could perform some type checking here. - for i in 1.. <sym.typ.len: + for i in 1..<sym.typ.len: putIntoReg(tos.slots[i], args[i-1]) result = rawExecute(c, start, tos).regToNode @@ -1637,7 +1637,7 @@ proc evalConstExprAux(module: PSym; cache: IdentCache; prc: PSym, n: PNode, when debugEchoCode: c.echoCode start var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil) newSeq(tos.slots, c.prc.maxSlots) - #for i in 0 .. <c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty) + #for i in 0 ..< c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty) result = rawExecute(c, start, tos).regToNode if result.info.line < 0: result.info = n.info @@ -1670,7 +1670,7 @@ proc setupMacroParam(x: PNode, typ: PType): TFullReg = iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) = let gp = macroSym.ast[genericParamsPos] - for i in 0 .. <gp.len: + for i in 0 ..< gp.len: let genericParam = gp[i].sym let posInCall = macroSym.typ.len + i yield (genericParam, call[posInCall]) @@ -1688,8 +1688,7 @@ proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode, # arity here too: if sym.typ.len > n.safeLen and sym.typ.len > 1: globalError(n.info, "in call '$#' got $#, but expected $# argument(s)" % [ - n.renderTree, - $ <n.safeLen, $ <sym.typ.len]) + n.renderTree, $(n.safeLen-1), $(sym.typ.len-1)]) setupGlobalCtx(module, cache) var c = globalCtx @@ -1713,11 +1712,11 @@ proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode, tos.slots[0].node = newNodeI(nkEmpty, n.info) # setup parameters: - for i in 1.. <sym.typ.len: + for i in 1..<sym.typ.len: tos.slots[i] = setupMacroParam(n.sons[i], sym.typ.sons[i]) let gp = sym.ast[genericParamsPos] - for i in 0 .. <gp.len: + for i in 0 ..< gp.len: if sfImmediate notin sym.flags: let idx = sym.typ.len + i if idx < n.len: @@ -1732,7 +1731,7 @@ proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode, c.callsite = nil globalError(n.info, "static[T] or typedesc nor supported for .immediate macros") # temporary storage: - #for i in L .. <maxSlots: tos.slots[i] = newNode(nkEmpty) + #for i in L ..< maxSlots: tos.slots[i] = newNode(nkEmpty) result = rawExecute(c, start, tos).regToNode if result.info.line < 0: result.info = n.info if cyclicTree(result): globalError(n.info, errCyclicTree) diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 29c1129b5..fb277272b 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -41,7 +41,7 @@ proc mapTypeToBracketX(name: string; m: TMagic; t: PType; info: TLineInfo; inst=false): PNode = result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t) result.add atomicTypeX(name, m, t, info) - for i in 0 .. < t.len: + for i in 0 ..< t.len: if t.sons[i] == nil: let void = atomicTypeX("void", mVoid, t, info) void.typ = newType(tyVoid, t.owner) @@ -84,10 +84,10 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; if inst: if t.sym != nil: # if this node has a symbol - if allowRecursion: # getTypeImpl behavior: turn off recursion - allowRecursion = false - else: # getTypeInst behavior: return symbol + if not allowRecursion: # getTypeInst behavior: return symbol return atomicType(t.sym) + #else: # getTypeImpl behavior: turn off recursion + # allowRecursion = false case t.kind of tyNone: result = atomicType("none", mNone) @@ -119,24 +119,27 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; result = atomicType("typeDesc", mTypeDesc) of tyGenericInvocation: result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t) - for i in 0 .. < t.len: + for i in 0 ..< t.len: result.add mapTypeToAst(t.sons[i], info) - of tyGenericInst, tyAlias: + of tyGenericInst: if inst: if allowRecursion: result = mapTypeToAstR(t.lastSon, info) else: result = newNodeX(nkBracketExpr) - result.add mapTypeToAst(t.lastSon, info) - for i in 1 .. < t.len-1: + #result.add mapTypeToAst(t.lastSon, info) + result.add mapTypeToAst(t[0], info) + for i in 1 ..< t.len-1: result.add mapTypeToAst(t.sons[i], info) else: result = mapTypeToAstX(t.lastSon, info, inst, allowRecursion) of tyGenericBody: if inst: - result = mapTypeToAstX(t.lastSon, info, inst, true) + result = mapTypeToAstR(t.lastSon, info) else: result = mapTypeToAst(t.lastSon, info) + of tyAlias: + result = mapTypeToAstX(t.lastSon, info, inst, allowRecursion) of tyOrdinal: result = mapTypeToAst(t.lastSon, info) of tyDistinct: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index ee9af7de2..17878b656 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -30,7 +30,7 @@ import strutils, ast, astalgo, types, msgs, renderer, vmdef, trees, intsets, rodread, magicsys, options, lowerings - +import platform from os import splitFile when hasFFI: @@ -401,7 +401,7 @@ proc sameConstant*(a, b: PNode): bool = proc genLiteral(c: PCtx; n: PNode): int = # types do not matter here: - for i in 0 .. <c.constants.len: + for i in 0 ..< c.constants.len: if sameConstant(c.constants[i], n): return i result = rawGenLiteral(c, n) @@ -430,7 +430,7 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) = c.gen(n.sons[0], tmp) # branch tmp, codeIdx # fjmp elseLabel - for i in 1 .. <n.len: + for i in 1 ..< n.len: let it = n.sons[i] if it.len == 1: # else stmt: @@ -460,7 +460,7 @@ proc genTry(c: PCtx; n: PNode; dest: var TDest) = c.gen(n.sons[0], dest) c.clearDest(n, dest) c.patch(elsePos) - for i in 1 .. <n.len: + for i in 1 ..< n.len: let it = n.sons[i] if it.kind != nkFinally: var blen = len(it) @@ -518,7 +518,7 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) = let x = c.getTempRange(n.len, slotTempUnknown) # varargs need 'opcSetType' for the FFI support: let fntyp = skipTypes(n.sons[0].typ, abstractInst) - for i in 0.. <n.len: + for i in 0..<n.len: #if i > 0 and i < sonsLen(fntyp): # let paramType = fntyp.n.sons[i] # if paramType.typ.isCompileTimeOnly: continue @@ -761,6 +761,49 @@ proc genCard(c: PCtx; n: PNode; dest: var TDest) = c.gABC(n, opcCard, dest, tmp) c.freeTemp(tmp) +proc genIntCast(c: PCtx; n: PNode; dest: var TDest) = + const allowedIntegers = {tyInt..tyInt64, tyUInt..tyUInt64, tyChar} + var signedIntegers = {tyInt8..tyInt32} + var unsignedIntegers = {tyUInt8..tyUInt32, tyChar} + let src = n.sons[1].typ.skipTypes(abstractRange)#.kind + let dst = n.sons[0].typ.skipTypes(abstractRange)#.kind + let src_size = src.getSize + + if platform.intSize < 8: + signedIntegers.incl(tyInt) + unsignedIntegers.incl(tyUInt) + if src_size == dst.getSize and src.kind in allowedIntegers and + dst.kind in allowedIntegers: + let tmp = c.genx(n.sons[1]) + var tmp2 = c.getTemp(n.sons[1].typ) + let tmp3 = c.getTemp(n.sons[1].typ) + if dest < 0: dest = c.getTemp(n[0].typ) + proc mkIntLit(ival: int): int = + result = genLiteral(c, newIntTypeNode(nkIntLit, ival, getSysType(tyInt))) + if src.kind in unsignedIntegers and dst.kind in signedIntegers: + # cast unsigned to signed integer of same size + # signedVal = (unsignedVal xor offset) -% offset + let offset = 1 shl (src_size * 8 - 1) + c.gABx(n, opcLdConst, tmp2, mkIntLit(offset)) + c.gABC(n, opcBitxorInt, tmp3, tmp, tmp2) + c.gABC(n, opcSubInt, dest, tmp3, tmp2) + elif src.kind in signedIntegers and dst.kind in unsignedIntegers: + # cast signed to unsigned integer of same size + # unsignedVal = (offset +% signedVal +% 1) and offset + let offset = (1 shl (src_size * 8)) - 1 + c.gABx(n, opcLdConst, tmp2, mkIntLit(offset)) + c.gABx(n, opcLdConst, dest, mkIntLit(offset+1)) + c.gABC(n, opcAddu, tmp3, tmp, dest) + c.gABC(n, opcNarrowU, tmp3, TRegister(src_size*8)) + c.gABC(n, opcBitandInt, dest, tmp3, tmp2) + else: + c.gABC(n, opcAsgnInt, dest, tmp) + c.freeTemp(tmp) + c.freeTemp(tmp2) + c.freeTemp(tmp3) + else: + globalError(n.info, errGenerated, "VM is only allowed to 'cast' between integers of same size") + proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = case m of mAnd: c.genAndOr(n, opcFJmp, dest) @@ -995,7 +1038,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = let n = n[1].skipConv let x = c.getTempRange(n.len, slotTempUnknown) internalAssert n.kind == nkBracket - for i in 0.. <n.len: + for i in 0..<n.len: var r: TRegister = x+i c.gen(n.sons[i], r) c.gABC(n, opcEcho, x, n.len) @@ -1130,6 +1173,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = # produces a value else: globalError(n.info, "expandToAst requires a call expression") + of mRunnableExamples: + discard "just ignore any call to runnableExamples" else: # mGCref, mGCunref, globalError(n.info, "cannot generate code for: " & $m) @@ -1645,7 +1690,7 @@ proc genObjConstr(c: PCtx, n: PNode, dest: var TDest) = c.gABx(n, opcNew, dest, c.genType(t.sons[0])) else: c.gABx(n, opcLdNull, dest, c.genType(n.typ)) - for i in 1.. <n.len: + for i in 1..<n.len: let it = n.sons[i] if it.kind == nkExprColonExpr and it.sons[0].kind == nkSym: let idx = genField(it.sons[0]) @@ -1660,7 +1705,7 @@ proc genTupleConstr(c: PCtx, n: PNode, dest: var TDest) = if dest < 0: dest = c.getTemp(n.typ) c.gABx(n, opcLdNull, dest, c.genType(n.typ)) # XXX x = (x.old, 22) produces wrong code ... stupid self assignments - for i in 0.. <n.len: + for i in 0..<n.len: let it = n.sons[i] if it.kind == nkExprColonExpr: let idx = genField(it.sons[0]) @@ -1773,8 +1818,8 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = of nkAddr, nkHiddenAddr: genAddrDeref(c, n, dest, opcAddrNode, flags) of nkIfStmt, nkIfExpr: genIf(c, n, dest) of nkWhenStmt: - # This is "when nimvm" node. Chose the first branch. - gen(c, n.sons[0].sons[1], dest) + # This is "when nimvm" node. Chose the first branch. + gen(c, n.sons[0].sons[1], dest) of nkCaseStmt: genCase(c, n, dest) of nkWhileStmt: unused(n, dest) @@ -1796,7 +1841,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = for x in n: gen(c, x) of nkStmtListExpr: let L = n.len-1 - for i in 0 .. <L: gen(c, n.sons[i]) + for i in 0 ..< L: gen(c, n.sons[i]) gen(c, n.sons[L], dest, flags) of nkPragmaBlock: gen(c, n.lastSon, dest, flags) @@ -1810,7 +1855,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = of nkVarSection, nkLetSection: unused(n, dest) genVarSection(c, n) - of declarativeDefs: + of declarativeDefs, nkMacroDef: unused(n, dest) of nkLambdaKinds: #let s = n.sons[namePos].sym @@ -1842,9 +1887,11 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = if allowCast in c.features: genConv(c, n, n.sons[1], dest, opcCast) else: - globalError(n.info, errGenerated, "VM is not allowed to 'cast'") + genIntCast(c, n, dest) of nkTypeOfExpr: genTypeLit(c, n.typ, dest) + of nkComesFrom: + discard "XXX to implement for better stack traces" else: globalError(n.info, errGenerated, "cannot generate VM code for " & $n) @@ -1882,7 +1929,7 @@ proc genExpr*(c: PCtx; n: PNode, requiresValue = true): int = proc genParams(c: PCtx; params: PNode) = # res.sym.position is already 0 c.prc.slots[0] = (inUse: true, kind: slotFixedVar) - for i in 1.. <params.len: + for i in 1..<params.len: c.prc.slots[i] = (inUse: true, kind: slotFixedLet) c.prc.maxSlots = max(params.len, 1) @@ -1895,7 +1942,7 @@ proc finalJumpTarget(c: PCtx; pc, diff: int) = proc genGenericParams(c: PCtx; gp: PNode) = var base = c.prc.maxSlots - for i in 0.. <gp.len: + for i in 0..<gp.len: var param = gp.sons[i].sym param.position = base + i # XXX: fix this earlier; make it consistent with templates c.prc.slots[base + i] = (inUse: true, kind: slotFixedLet) @@ -1903,7 +1950,7 @@ proc genGenericParams(c: PCtx; gp: PNode) = proc optimizeJumps(c: PCtx; start: int) = const maxIterations = 10 - for i in start .. <c.code.len: + for i in start ..< c.code.len: let opc = c.code[i].opcode case opc of opcTJmp, opcFJmp: diff --git a/compiler/vmmarshal.nim b/compiler/vmmarshal.nim index 51301b931..0939a5953 100644 --- a/compiler/vmmarshal.nim +++ b/compiler/vmmarshal.nim @@ -78,7 +78,7 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet) = s.add("]") of tyTuple: s.add("{") - for i in 0.. <t.len: + for i in 0..<t.len: if i > 0: s.add(", ") s.add("\"Field" & $i) s.add("\": ") @@ -90,7 +90,7 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet) = s.add("}") of tySet: s.add("[") - for i in 0.. <a.len: + for i in 0..<a.len: if i > 0: s.add(", ") if a[i].kind == nkRange: var x = copyNode(a[i][0]) diff --git a/compiler/vmops.nim b/compiler/vmops.nim index 38135951d..2a00f207a 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -47,6 +47,11 @@ template wrap1s_ospaths(op) {.dirty.} = setResult(a, op(getString(a, 0))) ospathsop op +template wrap2s_ospaths(op) {.dirty.} = + proc `op Wrapper`(a: VmArgs) {.nimcall.} = + setResult(a, op(getString(a, 0), getString(a, 1))) + ospathsop op + template wrap1s_system(op) {.dirty.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} = setResult(a, op(getString(a, 0))) @@ -96,7 +101,7 @@ proc registerAdditionalOps*(c: PCtx) = wrap1f_math(ceil) wrap2f_math(fmod) - wrap1s_ospaths(getEnv) + wrap2s_ospaths(getEnv) wrap1s_ospaths(existsEnv) wrap1s_os(dirExists) wrap1s_os(fileExists) diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 1e89ea1e2..e458cad03 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -21,11 +21,11 @@ type TSpecialWord* = enum wInvalid, - wAddr, wAnd, wAs, wAsm, wAtomic, + wAddr, wAnd, wAs, wAsm, wBind, wBlock, wBreak, wCase, wCast, wConcept, wConst, wContinue, wConverter, wDefer, wDiscard, wDistinct, wDiv, wDo, wElif, wElse, wEnd, wEnum, wExcept, wExport, - wFinally, wFor, wFrom, wFunc, wGeneric, wIf, wImport, wIn, + wFinally, wFor, wFrom, wFunc, wIf, wImport, wIn, wInclude, wInterface, wIs, wIsnot, wIterator, wLet, wMacro, wMethod, wMixin, wMod, wNil, wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, @@ -45,7 +45,7 @@ type wImportc, wExportc, wExportNims, wIncompleteStruct, wRequiresInit, wAlign, wNodecl, wPure, wSideeffect, wHeader, wNosideeffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib, - wCompilerproc, wProcVar, wBase, wUsed, + wCompilerproc, wCore, wProcVar, wBase, wUsed, wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef, wLinedir, wStacktrace, wLinetrace, wLink, wCompile, wLinksys, wDeprecated, wVarargs, wCallconv, wBreakpoint, wDebugger, @@ -55,7 +55,7 @@ type wFloatchecks, wNanChecks, wInfChecks, wAssertions, wPatterns, wWarnings, wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags, - wDeadCodeElim, wSafecode, wNoForward, wReorder, wNoRewrite, + wDeadCodeElim, wSafecode, wPackage, wNoForward, wReorder, wNoRewrite, wPragma, wCompileTime, wNoInit, wPassc, wPassl, wBorrow, wDiscardable, @@ -66,7 +66,7 @@ type wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, wAsmNoStackFrame, wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks, - wPartial, wExplain, + wPartial, wExplain, wLiftLocals, wAuto, wBool, wCatch, wChar, wClass, wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast, @@ -103,12 +103,12 @@ const specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["", - "addr", "and", "as", "asm", "atomic", + "addr", "and", "as", "asm", "bind", "block", "break", "case", "cast", "concept", "const", "continue", "converter", "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", - "finally", "for", "from", "func", "generic", "if", + "finally", "for", "from", "func", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", "let", "macro", "method", "mixin", "mod", "nil", "not", "notin", @@ -131,7 +131,7 @@ const "incompletestruct", "requiresinit", "align", "nodecl", "pure", "sideeffect", "header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib", - "compilerproc", "procvar", "base", "used", + "compilerproc", "core", "procvar", "base", "used", "fatal", "error", "warning", "hint", "line", "push", "pop", "define", "undef", "linedir", "stacktrace", "linetrace", "link", "compile", "linksys", "deprecated", "varargs", @@ -143,7 +143,7 @@ const "assertions", "patterns", "warnings", "hints", "optimization", "raises", "writes", "reads", "size", "effects", "tags", - "deadcodeelim", "safecode", "noforward", "reorder", "norewrite", + "deadcodeelim", "safecode", "package", "noforward", "reorder", "norewrite", "pragma", "compiletime", "noinit", "passc", "passl", "borrow", "discardable", "fieldchecks", @@ -152,7 +152,7 @@ const "computedgoto", "injectstmt", "experimental", "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit", "asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked", - "guard", "locks", "partial", "explain", + "guard", "locks", "partial", "explain", "liftlocals", "auto", "bool", "catch", "char", "class", "const_cast", "default", "delete", "double", diff --git a/compiler/writetracking.nim b/compiler/writetracking.nim index fe71e5b31..577db613d 100644 --- a/compiler/writetracking.nim +++ b/compiler/writetracking.nim @@ -123,7 +123,7 @@ proc returnsNewExpr*(n: PNode): NewLocation = of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure, nkIfExpr, nkIfStmt, nkWhenStmt, nkCaseStmt, nkTryStmt: result = newLit - for i in ord(n.kind == nkObjConstr) .. <n.len: + for i in ord(n.kind == nkObjConstr) ..< n.len: let x = returnsNewExpr(n.sons[i]) case x of newNone: return newNone diff --git a/config/nim.cfg b/config/nim.cfg index 7ac87cc33..a146c4ebf 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -98,7 +98,6 @@ path="$lib/pure" clang.options.linker = "-landroid-glob" clang.cpp.options.linker = "-landroid-glob" tcc.options.linker = "-landroid-glob" - define:"useShPath:/system/bin/sh" @end @end @@ -202,6 +201,11 @@ vcc.cpp.linkerexe = "vccexe.exe" # set the options for specific platforms: vcc.options.always = "/nologo" +@if release: + # no debug symbols in release builds +@else: + vcc.options.always %= "${vcc.options.always} /Z7" # Get VCC to output full debug symbols in the obj file +@end vcc.cpp.options.always %= "${vcc.options.always} /EHsc" vcc.options.linker = "/nologo /DEBUG /Zi /F33554432" # set the stack size to 32 MiB vcc.cpp.options.linker %= "${vcc.options.linker}" @@ -222,8 +226,8 @@ vcc.options.linker %= "--platform:arm ${vcc.options.linker}" vcc.cpp.options.linker %= "--platform:arm ${vcc.cpp.options.linker}" @end -vcc.options.debug = "/Zi /FS /Od" -vcc.cpp.options.debug = "/Zi /FS /Od" +vcc.options.debug = "/Od" +vcc.cpp.options.debug = "/Od" vcc.options.speed = "/O2" vcc.cpp.options.speed = "/O2" vcc.options.size = "/O1" diff --git a/config/nimdoc.cfg b/config/nimdoc.cfg index 3e656cb8f..2800bc581 100644 --- a/config/nimdoc.cfg +++ b/config/nimdoc.cfg @@ -88,10 +88,58 @@ doc.body_toc = """ </div> """ +@if boot: +# This is enabled with the "boot" directive to generate +# the compiler documentation. +# As a user, tweak the block below instead. +# You can add your own global-links entries doc.body_toc_group = """ <div class="row"> <div class="three columns"> - <div> + <div id="global-links"> + <ul class="simple"> + <li> + <a href="manual.html">Manual</a> + </li> + <li> + <a href="lib.html">Standard library</a> + </li> + <li> + <a href="theindex.html">Index</a> + </li> + </ul> + </div> + <div id="searchInput"> + Search: <input type="text" id="searchInput" + onkeyup="search()" /> + </div> + <div class="search-groupby"> + Group by: + <select onchange="groupBy(this.value)"> + <option value="section">Section</option> + <option value="type">Type</option> + </select> + </div> + $tableofcontents + </div> + <div class="nine columns" id="content"> + <div id="tocRoot"></div> + <p class="module-desc">$moduledesc</p> + $content + </div> +</div> +""" + +@else + +doc.body_toc_group = """ +<div class="row"> + <div class="three columns"> + <div id="global-links"> + <ul class="simple"> + </ul> + </div> + <div id="searchInput"> Search: <input type="text" id="searchInput" onkeyup="search()" /> </div> @@ -111,6 +159,7 @@ doc.body_toc_group = """ </div> </div> """ +@end doc.body_no_toc = """ $moduledesc @@ -135,7 +184,7 @@ doc.file = """<?xml version="1.0" encoding="utf-8" ?> <link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/> <!-- Google fonts --> -<link href='https://fonts.googleapis.com/css?family=Raleway:400,600,900' rel='stylesheet' type='text/css'/> +<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/> <!-- CSS --> @@ -168,18 +217,19 @@ html { /* Where we want fancier font if available */ h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Raleway", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } h1.title { font-weight: 900; } body { - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 14px; + font-size: 16px; line-height: 20px; - color: #666; - background-color: rgba(252, 248, 244, 0.75); } + color: #444; + letter-spacing: 0.15px; + background-color: rgba(252, 248, 244, 0.45); } /* Skeleton grid */ .container { @@ -295,8 +345,8 @@ cite { font-style: italic !important; } dt > pre { - border-color: rgba(0, 0, 0, 0.15); - background-color: transparent; + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); margin: 15px 0px 5px; } dd > pre { @@ -313,6 +363,17 @@ dd > pre { width: 100%; table-layout: fixed; } +/* Nim search input */ +div#searchInput { + margin-bottom: 8px; +} +div#searchInput input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; +} + table.line-nums-table { border-radius: 4px; border: 1px solid #cccccc; @@ -456,7 +517,7 @@ img { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 12px; } + margin: 0 0 8px; } small { font-size: 85%; } @@ -476,7 +537,7 @@ h3, h4, h5, h6 { - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 600; line-height: 20px; color: inherit; @@ -484,6 +545,7 @@ h6 { h1 { font-size: 2em; + font-weight: 400; padding-bottom: .15em; border-bottom: 1px solid #aaaaaa; margin-top: 1.0em; @@ -614,13 +676,13 @@ pre { box-sizing: border-box; min-width: calc(100% - 19.5px); padding: 9.5px; - margin: 0.25em 10px 0.25em 10px; - font-size: 14px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: whitesmoke; + background-color: rgba(0, 0, 0, 0.01); border: 1px solid #cccccc; -webkit-border-radius: 4px; -moz-border-radius: 4px; @@ -899,14 +961,14 @@ div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold; - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; } + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title, .code .error { color: #b30000; font-weight: bold; - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; } + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } /* Uncomment (and remove this text!) to get reduced vertical space in compound paragraphs. @@ -953,7 +1015,7 @@ div.sidebar { clear: right; } div.sidebar p.rubric { - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-size: medium; } div.system-messages { @@ -1060,12 +1122,12 @@ p.rubric { text-align: center; } p.sidebar-title { - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; font-size: larger; } p.sidebar-subtitle { - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } p.topic-title { @@ -1107,15 +1169,15 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } span.interpreted { - font-family: "Helvetica Neue", "HelveticaNeue", "Raleway", Helvetica, Arial, sans-serif; } + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } span.option { white-space: nowrap; } @@ -1138,7 +1200,7 @@ table.docinfo { margin: 0em; margin-top: 2em; margin-bottom: 2em; - font-family: "Raleway", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; color: #444444; } table.docutils { @@ -1268,15 +1330,15 @@ dt pre > span.Operator ~ span.Identifier, dt pre > span.Operator ~ span.Operator background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } - div.pragma { - display: none; - } - span.pragmabegin { - cursor: pointer; - } - span.pragmaend { - cursor: pointer; - } +div.pragma { + display: none; +} +span.pragmabegin { + cursor: pointer; +} +span.pragmaend { + cursor: pointer; +} div.search_results { background-color: antiquewhite; @@ -1284,6 +1346,11 @@ div.search_results { padding: 1em; border: 1px solid #4d4d4d; } + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} </style> <script type="text/javascript" src="../dochack.js"></script> diff --git a/doc/advopt.txt b/doc/advopt.txt index fb6fd719b..a1210118e 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -7,7 +7,8 @@ Advanced commands: //rst2html convert a reStructuredText file to HTML //rst2tex convert a reStructuredText file to TeX //jsondoc extract the documentation to a json file - //jsondoc2 extract documentation to a json file (uses doc2) + //jsondoc2 extract the documentation to a json file (uses doc2) + //ctags create a tags file //buildIndex build an index for the whole documentation //run run the project (with Tiny C backend; buggy!) //genDepend generate a DOT file containing the @@ -36,6 +37,7 @@ Advanced options: --noMain do not generate a main procedure --genScript generate a compile script (in the 'nimcache' subdirectory named 'compile_$project$scriptext') + --genDeps generate a '.deps' file containing the dependencies --os:SYMBOL set the target operating system (cross-compilation) --cpu:SYMBOL set the target processor (cross-compilation) --debuginfo enables debug information @@ -78,6 +80,7 @@ Advanced options: symbol matching is fuzzy so that --dynlibOverride:lua matches dynlib: "liblua.so.3" + --dynlibOverrideAll makes the dynlib pragma have no effect --listCmd list the commands used to execute external programs --parallelBuild:0|1|... perform a parallel build value = number of processors (0 for auto-detect) diff --git a/doc/backends.txt b/doc/backends.txt index 6446103ed..b7f5308ab 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -20,10 +20,12 @@ to compile to C++, Objective-C or JavaScript. This document tries to concentrate in a single place all the backend and interfacing options. The Nim compiler supports mainly two backend families: the C, C++ and -Objective-C targets and the JavaScript target. `The C like targets`_ creates -source files which can be compiled into a library or a final executable. `The -JavaScript target`_ can generate a ``.js`` file which you reference from an -HTML file or create a `standalone nodejs program <http://nodejs.org>`_. +Objective-C targets and the JavaScript target. `The C like targets +<#backends-the-c-like-targets>`_ creates source files which can be compiled +into a library or a final executable. `The JavaScript target +<#backends-the-javascript-target>`_ can generate a ``.js`` file which you +reference from an HTML file or create a `standalone nodejs program +<http://nodejs.org>`_. On top of generating libraries or standalone applications, Nim offers bidirectional interfacing with the backend targets through generic and @@ -205,9 +207,10 @@ from the previous section): Compile the Nim code to JavaScript with ``nim js -o:calculator.js calculator.nim`` and open ``host.html`` in a browser. If the browser supports -javascript, you should see the value ``10``. In JavaScript the `echo proc -<system.html#echo>`_ will modify the HTML DOM and append the string. Use the -`dom module <dom.html>`_ for specific DOM querying and modification procs. +javascript, you should see the value ``10`` in the browser's console. Use the +`dom module <dom.html>`_ for specific DOM querying and modification procs +or take a look at `karax <https://github.com/pragmagic/karax>`_ for how to +develop browser based applications. Backend code calling Nim diff --git a/doc/basicopt.txt b/doc/basicopt.txt index 3b0271077..4db2d5af7 100644 --- a/doc/basicopt.txt +++ b/doc/basicopt.txt @@ -5,7 +5,6 @@ Command: //compile, c compile project with default code generator (C) //doc generate the documentation for inputfile - //doc2 generate the documentation for inputfile Arguments: arguments are passed to the program being run (if --run option is selected) diff --git a/doc/grammar.txt b/doc/grammar.txt index 58b119331..eae3694a0 100644 --- a/doc/grammar.txt +++ b/doc/grammar.txt @@ -83,7 +83,8 @@ paramListColon = paramList? (':' optInd typeDesc)? doBlock = 'do' paramListArrow pragmas? colcom stmt procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)? distinct = 'distinct' optInd typeDesc -expr = (ifExpr +expr = (blockExpr + | ifExpr | whenExpr | caseExpr | tryExpr) @@ -141,6 +142,7 @@ tryExpr = 'try' colcom stmt &(optInd 'except'|'finally') exceptBlock = 'except' colcom stmt forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt blockStmt = 'block' symbol? colcom stmt +blockExpr = 'block' symbol? colcom stmt staticStmt = 'static' colcom stmt deferStmt = 'defer' colcom stmt asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLE_STR_LIT) diff --git a/doc/keywords.txt b/doc/keywords.txt index f8b444924..4eea3403a 100644 --- a/doc/keywords.txt +++ b/doc/keywords.txt @@ -1,10 +1,9 @@ -addr and as asm atomic +addr and as asm bind block break case cast concept const continue converter defer discard distinct div do elif else end enum except export finally for from func -generic if import in include interface is isnot iterator let macro method mixin mod diff --git a/doc/lib.rst b/doc/lib.rst index 64c3c11eb..755c11899 100644 --- a/doc/lib.rst +++ b/doc/lib.rst @@ -64,6 +64,10 @@ Core * `cpuinfo <cpuinfo.html>`_ This module implements procs to determine the number of CPUs / cores. +* `lenientops <lenientops.html>`_ + Provides binary operators for mixed integer/float expressions for convenience. + + Collections and algorithms -------------------------- @@ -88,6 +92,10 @@ Collections and algorithms * `sequtils <sequtils.html>`_ This module implements operations for the built-in seq type which were inspired by functional programming languages. +* `sharedtables <sharedtables.html>`_ + Nim shared hash table support. Contains shared tables. +* `sharedlist <sharedlist.html>`_ + Nim shared linked list support. Contains shared singly linked list. String handling @@ -98,6 +106,10 @@ String handling case of a string, splitting a string into substrings, searching for substrings, replacing substrings. +* `strformat <strformat.html>`_ + Macro based standard string interpolation / formatting. Inpired by + Python's ```f``-strings. + * `strmisc <strmisc.html>`_ This module contains uncommon string handling operations that do not fit with the commonly used operations in strutils. @@ -182,6 +194,12 @@ Generic Operating System Services This module implements asynchronous file reading and writing using ``asyncdispatch``. +* `distros <distros.html>`_ + This module implements the basics for OS distribution ("distro") detection and the OS's native package manager. + Its primary purpose is to produce output for Nimble packages, but it also contains the widely used **Distribution** enum + that is useful for writing platform specific code. + + Math libraries -------------- @@ -369,6 +387,7 @@ Cryptography and Hashing * `securehash <securehash.html>`_ This module implements a sha1 encoder and decoder. + Multimedia support ------------------ @@ -409,6 +428,9 @@ Miscellaneous * `unittest <unittest.html>`_ Implements a Unit testing DSL. +* `segfaults <segfaults.html>`_ + Turns access violations or segfaults into a ``NilAccessError`` exception. + Modules for JS backend --------------------------- @@ -418,6 +440,8 @@ Modules for JS backend * `jsffi <jsffi.html>`_ Types and macros for easier interaction with JavaScript. +* `asyncjs <asyncjs.html>`_ + Types and macros for writing asynchronous procedures in JavaScript. Deprecated modules ------------------ @@ -533,9 +557,6 @@ Database support Network Programming and Internet Protocols ------------------------------------------ -* `libuv <libuv.html>`_ - Wrapper for the libuv library used for async I/O programming. - * `joyent_http_parser <joyent_http_parser.html>`_ Wrapper for the joyent's high-performance HTTP parser. diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt index 06fed1430..67a4c7caa 100644 --- a/doc/manual/ffi.txt +++ b/doc/manual/ffi.txt @@ -206,7 +206,7 @@ strings, because they are precompiled. **Note**: Passing variables to the ``dynlib`` pragma will fail at runtime because of order of initialization problems. -**Note**: A ``dynlib`` import can be overriden with +**Note**: A ``dynlib`` import can be overridden with the ``--dynlibOverride:name`` command line option. The Compiler User Guide contains further information. diff --git a/doc/manual/generics.txt b/doc/manual/generics.txt index cceea33c0..1ba62bb5c 100644 --- a/doc/manual/generics.txt +++ b/doc/manual/generics.txt @@ -9,26 +9,26 @@ The following example shows a generic binary tree can be modelled: .. code-block:: nim type - BinaryTreeObj[T] = object # BinaryTreeObj is a generic type with - # with generic param ``T`` - le, ri: BinaryTree[T] # left and right subtrees; may be nil - data: T # the data stored in a node - BinaryTree[T] = ref BinaryTreeObj[T] # a shorthand for notational convenience + BinaryTree*[T] = ref object # BinaryTree is a generic type with + # generic param ``T`` + le, ri: BinaryTree[T] # left and right subtrees; may be nil + data: T # the data stored in a node - proc newNode[T](data: T): BinaryTree[T] = # constructor for a node + proc newNode*[T](data: T): BinaryTree[T] = + # constructor for a node new(result) result.data = data - proc add[T](root: var BinaryTree[T], n: BinaryTree[T]) = + proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) = + # insert a node into the tree if root == nil: root = n else: var it = root while it != nil: - var c = cmp(it.data, n.data) # compare the data items; uses - # the generic ``cmp`` proc that works for - # any type that has a ``==`` and ``<`` - # operator + # compare the data items; uses the generic ``cmp`` proc + # that works for any type that has a ``==`` and ``<`` operator + var c = cmp(it.data, n.data) if c < 0: if it.le == nil: it.le = n @@ -40,20 +40,28 @@ The following example shows a generic binary tree can be modelled: return it = it.ri - iterator inorder[T](root: BinaryTree[T]): T = - # inorder traversal of a binary tree - # recursive iterators are not yet implemented, so this does not work in - # the current compiler! - if root.le != nil: yield inorder(root.le) - yield root.data - if root.ri != nil: yield inorder(root.ri) + proc add*[T](root: var BinaryTree[T], data: T) = + # convenience proc: + add(root, newNode(data)) + + iterator preorder*[T](root: BinaryTree[T]): T = + # Preorder traversal of a binary tree. + # Since recursive iterators are not yet implemented, + # this uses an explicit stack (which is more efficient anyway): + var stack: seq[BinaryTree[T]] = @[root] + while stack.len > 0: + var n = stack.pop() + while n != nil: + yield n.data + add(stack, n.ri) # push right subtree onto the stack + n = n.le # and follow the left pointer var - root: BinaryTree[string] # instantiate a BinaryTree with the type string - add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and - add(root, newNode("world")) # ``add`` - for str in inorder(root): - writeLine(stdout, str) + root: BinaryTree[string] # instantiate a BinaryTree with ``string`` + add(root, newNode("hello")) # instantiates ``newNode`` and ``add`` + add(root, "world") # instantiates the second ``add`` proc + for str in preorder(root): + stdout.writeLine(str) Is operator diff --git a/doc/manual/locking.txt b/doc/manual/locking.txt index c1bd5ca46..99ffe8970 100644 --- a/doc/manual/locking.txt +++ b/doc/manual/locking.txt @@ -2,7 +2,7 @@ Guards and locks ================ Apart from ``spawn`` and ``parallel`` Nim also provides all the common low level -concurrency mechanisms like locks, atomic intristics or condition variables. +concurrency mechanisms like locks, atomic intrinsics or condition variables. Nim significantly improves on the safety of these features via additional pragmas: @@ -74,7 +74,7 @@ model low level lockfree mechanisms: The ``locks`` pragma takes a list of lock expressions ``locks: [a, b, ...]`` in order to support *multi lock* statements. Why these are essential is -explained in the `lock levels`_ section. +explained in the `lock levels <#guards-and-locks-lock-levels>`_ section. Protecting general locations diff --git a/doc/manual/modules.txt b/doc/manual/modules.txt index 9cb6a11af..4ef1bfd99 100644 --- a/doc/manual/modules.txt +++ b/doc/manual/modules.txt @@ -105,7 +105,7 @@ From import statement ~~~~~~~~~~~~~~~~~~~~~ After the ``from`` statement a module name follows followed by -an ``import`` to list the symbols one likes to use without explict +an ``import`` to list the symbols one likes to use without explicit full qualification: .. code-block:: nim @@ -123,7 +123,7 @@ in ``module``. Export statement ~~~~~~~~~~~~~~~~ -An ``export`` statement can be used for symbol fowarding so that client +An ``export`` statement can be used for symbol forwarding so that client modules don't need to import a module's dependencies: .. code-block:: nim diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt index bd90cd73d..835b6909d 100644 --- a/doc/manual/pragmas.txt +++ b/doc/manual/pragmas.txt @@ -70,7 +70,7 @@ compileTime pragma The ``compileTime`` pragma is used to mark a proc or variable to be used at compile time only. No code will be generated for it. Compile time procs are useful as helpers for macros. Since version 0.12.0 of the language, a proc -that uses ``system.NimNode`` within its parameter types is implictly declared +that uses ``system.NimNode`` within its parameter types is implicitly declared ``compileTime``: .. code-block:: nim @@ -102,6 +102,14 @@ collector to not consider objects of this type as part of a cycle: left, right: Node data: string +Or if we directly use a ref object: + +.. code-block:: nim + type + Node = ref object {.acyclic, final.} + left, right: Node + data: string + In the example a tree structure is declared with the ``Node`` type. Note that the type definition is recursive and the GC has to assume that objects of this type may form a cyclic graph. The ``acyclic`` pragma passes the @@ -316,7 +324,7 @@ factor. immediate pragma ---------------- -See `Ordinary vs immediate templates`_. +See `Typed vs untyped parameters`_. compilation option pragmas @@ -733,7 +741,8 @@ about the ``importcpp`` pragma pattern language. It is not necessary to know all the details described here. -Similar to the `importc pragma for C <manual.html#importc-pragma>`_, the +Similar to the `importc pragma for C +<#foreign-function-interface-importc-pragma>`_, the ``importcpp`` pragma can be used to import `C++`:idx: methods or C++ symbols in general. The generated code then uses the C++ method calling syntax: ``obj->method(arg)``. In combination with the ``header`` and ``emit`` @@ -955,10 +964,11 @@ Produces: ImportObjC pragma ----------------- -Similar to the `importc pragma for C <manual.html#importc-pragma>`_, the -``importobjc`` pragma can be used to import `Objective C`:idx: methods. The -generated code then uses the Objective C method calling syntax: ``[obj method -param1: arg]``. In addition with the ``header`` and ``emit`` pragmas this +Similar to the `importc pragma for C +<#foreign-function-interface-importc-pragma>`_, the ``importobjc`` pragma can +be used to import `Objective C`:idx: methods. The generated code then uses the +Objective C method calling syntax: ``[obj method param1: arg]``. +In addition with the ``header`` and ``emit`` pragmas this allows *sloppy* interfacing with libraries written in Objective C: .. code-block:: Nim diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index 6d09ac3f5..44aeb089a 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -142,10 +142,11 @@ The method call syntax conflicts with explicit generic instantiations: parsed as ``(x.p)[T]``. **Future directions**: ``p[.T.]`` might be introduced as an alternative syntax -to pass explict types to a generic and then ``x.p[.T.]`` can be parsed as +to pass explicit types to a generic and then ``x.p[.T.]`` can be parsed as ``x.(p[.T.])``. -See also: `Limitations of the method call syntax`_. +See also: `Limitations of the method call syntax +<#templates-limitations-of-the-method-call-syntax>`_. Properties @@ -178,7 +179,7 @@ different; for this a special setter syntax is needed: Command invocation syntax ------------------------- -Routines can be invoked without the ``()`` if the call is syntatically +Routines can be invoked without the ``()`` if the call is syntactically a statement. This command invocation syntax also works for expressions, but then only a single argument may follow. This restriction means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as diff --git a/doc/manual/special_ops.txt b/doc/manual/special_ops.txt index 1c7136bec..93977f81b 100644 --- a/doc/manual/special_ops.txt +++ b/doc/manual/special_ops.txt @@ -17,8 +17,8 @@ or dynamic file formats such as JSON or XML. When Nim encounters an expression that cannot be resolved by the standard overload resolution rules, the current scope will be searched for a dot operator that can be matched against a re-written form of -the expression, where the unknown field or proc name is converted to -an additional static string parameter: +the expression, where the unknown field or proc name is passed to +an ``untyped`` parameter: .. code-block:: nim a.b # becomes `.`(a, "b") @@ -28,7 +28,7 @@ The matched dot operators can be symbols of any callable kind (procs, templates and macros), depending on the desired effect: .. code-block:: nim - proc `.` (js: PJsonNode, field: string): JSON = js[field] + template `.` (js: PJsonNode, field: untyped): JSON = js[astToStr(field)] var js = parseJson("{ x: 1, y: 2}") echo js.x # outputs 1 diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt index 3a86a9730..721b5cff8 100644 --- a/doc/manual/stmts.txt +++ b/doc/manual/stmts.txt @@ -199,7 +199,7 @@ The rules for compile-time computability are: (possibly empty) list of compile-time computable arguments. -Constants cannot be of type ``ptr``, ``ref``, ``var`` or ``object``, nor can +Constants cannot be of type ``ptr``, ``ref`` or ``var``, nor can they contain such a type. @@ -296,6 +296,10 @@ empty ``discard`` statement should be used. For non ordinal types it is not possible to list every possible value and so these always require an ``else`` part. +As case statements perform compile-time exhaustiveness checks, the value in +every ``of`` branch must be known at compile time. This fact is also exploited +to generate more performant code. + As a special semantic extension, an expression in an ``of`` branch of a case statement may evaluate to a set or array constructor; the set or array is then expanded into a list of its elements: diff --git a/doc/manual/templates.txt b/doc/manual/templates.txt index f01a703cd..af184589c 100644 --- a/doc/manual/templates.txt +++ b/doc/manual/templates.txt @@ -293,7 +293,7 @@ Limitations of the method call syntax The expression ``x`` in ``x.f`` needs to be semantically checked (that means symbol lookup and type checking) before it can be decided that it needs to be -rewritten to ``f(x)``. Therefore the dot syntax has some limiations when it +rewritten to ``f(x)``. Therefore the dot syntax has some limitations when it is used to invoke templates/macros: .. code-block:: nim diff --git a/doc/manual/threads.txt b/doc/manual/threads.txt index 15121ab6d..53071b5a5 100644 --- a/doc/manual/threads.txt +++ b/doc/manual/threads.txt @@ -5,7 +5,7 @@ To enable thread support the ``--threads:on`` command line switch needs to be used. The ``system`` module then contains several threading primitives. See the `threads <threads.html>`_ and `channels <channels.html>`_ modules for the low level thread API. There are also high level parallelism constructs -available. See `spawn`_ for further details. +available. See `spawn <#parallel-spawn>`_ for further details. Nim's memory model for threads is quite different than that of other common programming languages (C, Pascal, Java): Each thread has its own (garbage diff --git a/doc/manual/type_bound_ops.txt b/doc/manual/type_bound_ops.txt index c707979fe..b531abf31 100644 --- a/doc/manual/type_bound_ops.txt +++ b/doc/manual/type_bound_ops.txt @@ -7,12 +7,12 @@ There are 3 operations that are bound to a type: 2. Destruction 3. Deep copying for communication between threads -These operations can be *overriden* instead of *overloaded*. This means the +These operations can be *overridden* instead of *overloaded*. This means the implementation is automatically lifted to structured types. For instance if type -``T`` has an overriden assignment operator ``=`` this operator is also used +``T`` has an overridden assignment operator ``=`` this operator is also used for assignments of the type ``seq[T]``. Since these operations are bound to a type they have to be bound to a nominal type for reasons of simplicity of -implementation: This means an overriden ``deepCopy`` for ``ref T`` is really +implementation: This means an overridden ``deepCopy`` for ``ref T`` is really bound to ``T`` and not to ``ref T``. This also means that one cannot override ``deepCopy`` for both ``ptr T`` and ``ref T`` at the same time; instead a helper distinct or object type has to be used for one pointer type. diff --git a/doc/manual/type_rel.txt b/doc/manual/type_rel.txt index 1d1425934..3372691fb 100644 --- a/doc/manual/type_rel.txt +++ b/doc/manual/type_rel.txt @@ -491,4 +491,4 @@ metatypes ``typed`` and ``typedesc`` are not lazy. Varargs matching ---------------- -See `Varargs`_. +See `Varargs <#types-varargs>`_. diff --git a/doc/manual/type_sections.txt b/doc/manual/type_sections.txt index af761c77e..12b2a11ac 100644 --- a/doc/manual/type_sections.txt +++ b/doc/manual/type_sections.txt @@ -5,8 +5,7 @@ Example: .. code-block:: nim type # example demonstrating mutually recursive types - Node = ref NodeObj # a traced pointer to a NodeObj - NodeObj = object + Node = ref object # an object managed by the garbage collector (ref) le, ri: Node # left and right subtrees sym: ref Sym # leaves contain a reference to a Sym diff --git a/doc/manual/types.txt b/doc/manual/types.txt index 2c4b019ad..1477995dd 100644 --- a/doc/manual/types.txt +++ b/doc/manual/types.txt @@ -41,7 +41,8 @@ These integer types are pre-defined: ``int`` the generic signed integer type; its size is platform dependent and has the same size as a pointer. This type should be used in general. An integer - literal that has no type suffix is of this type. + literal that has no type suffix is of this type if it is in the range + ``low(int32)..high(int32)`` otherwise the literal's type is ``int64``. intXX additional signed integer types of XX bits use this naming scheme @@ -114,7 +115,8 @@ if the literal's value fits this smaller type and such a conversion is less expensive than other implicit conversions, so ``myInt16 + 34`` produces an ``int16`` result. -For further details, see `Convertible relation`_. +For further details, see `Convertible relation +<#type-relations-convertible-relation>`_. Subrange types @@ -136,26 +138,6 @@ determined). Assignments from the base type to one of its subrange types A subrange type has the same size as its base type (``int`` in the example). -Nim requires `interval arithmetic`:idx: for subrange types over a set -of built-in operators that involve constants: ``x %% 3`` is of -type ``range[0..2]``. The following built-in operators for integers are -affected by this rule: ``-``, ``+``, ``*``, ``min``, ``max``, ``succ``, -``pred``, ``mod``, ``div``, ``%%``, ``and`` (bitwise ``and``). - -Bitwise ``and`` only produces a ``range`` if one of its operands is a -constant *x* so that (x+1) is a power of two. -(Bitwise ``and`` is then a ``%%`` operation.) - -This means that the following code is accepted: - -.. code-block:: nim - case (x and 3) + 7 - of 7: echo "A" - of 8: echo "B" - of 9: echo "C" - of 10: echo "D" - # note: no ``else`` required as (x and 3) + 7 has the type: range[7..10] - Pre-defined floating point types -------------------------------- @@ -570,7 +552,7 @@ order. The *names* of the fields also have to be identical. The assignment operator for tuples copies each component. The default assignment operator for objects copies each component. Overloading -of the assignment operator is described in `type-bound-operations-operator`_. +of the assignment operator is described in `type-bound-operations-operator`_. .. code-block:: nim @@ -697,6 +679,44 @@ branch switch ``system.reset`` has to be used. Also, when the fields of a particular branch are specified during object construction, the correct value for the discriminator must be supplied at compile-time. +Package level objects +--------------------- + +Every Nim module resides in a (nimble) package. An object type can be attached +to the package it resides in. If that is done, the type can be referenced from +other modules as an `incomplete`:idx: object type. This features allows to +break up recursive type dependencies accross module boundaries. Incomplete +object types are always passed ``byref`` and can only be used in pointer like +contexts (``var/ref/ptr IncompleteObject``) in general since the compiler does +not yet know the size of the object. To complete an incomplete object +the ``package`` pragma has to be used. ``package`` implies ``byref``. + +As long as a type ``T`` is incomplete ``sizeof(T)`` or "runtime type +information" for ``T`` is not available. + + +Example: + +.. code-block:: nim + + # module A (in an arbitrary package) + type + Pack.SomeObject = object ## declare as incomplete object of package 'Pack' + Triple = object + a, b, c: ref SomeObject ## pointers to incomplete objects are allowed + + ## Incomplete objects can be used as parameters: + proc myproc(x: SomeObject) = discard + + +.. code-block:: nim + + # module B (in package "Pack") + type + SomeObject* {.package.} = object ## Use 'package' to complete the object + s, t: string + x, y: int + Set type -------- @@ -905,8 +925,8 @@ not compatible to ``pointer`` to prevent the following from compiling: Future directions: * Memory regions might become available for ``string`` and ``seq`` too. -* Builtin regions like ``private``, ``global`` and ``local`` will - prove very useful for the upcoming OpenCL target. +* Builtin regions like ``private``, ``global`` and ``local`` might be + useful for an OpenCL target. * Builtin "regions" can model ``lent`` and ``unique`` pointers. * An assignment operator can be attached to a region so that proper write barriers can be generated. This would imply that the GC can be implemented diff --git a/doc/tut1.rst b/doc/tut1.rst index be5cd8c11..9e6f1ab3c 100644 --- a/doc/tut1.rst +++ b/doc/tut1.rst @@ -30,6 +30,7 @@ The first program We start the tour with a modified "hello world" program: .. code-block:: Nim + :test: "nim c $1" # This is a comment echo "What's your name? " var name: string = readLine(stdin) @@ -72,6 +73,7 @@ you can leave out the type in the declaration (this is called `local type inference`:idx:). So this will work too: .. code-block:: Nim + :test: "nim c $1" var name = readLine(stdin) Note that this is basically the only form of type inference that exists in @@ -116,6 +118,7 @@ Comments start anywhere outside a string or character literal with the hash character ``#``. Documentation comments start with ``##``: .. code-block:: nim + :test: "nim c $1" # A comment. var myVariable: int ## a documentation comment @@ -129,6 +132,7 @@ Multiline comments are started with ``#[`` and terminated with ``]#``. Multilin comments can also be nested. .. code-block:: nim + :test: "nim c $1" #[ You can have any Nim code text commented out inside this with no indentation restrictions. @@ -142,6 +146,7 @@ You can also use the `discard statement <#procedures-discard-statement>`_ togeth literals* to create block comments: .. code-block:: nim + :test: "nim c $1" discard """ You can have any Nim code text commented out inside this with no indentation restrictions. yes("May I ask a pointless question?") """ @@ -169,6 +174,7 @@ Indentation can be used after the ``var`` keyword to list a whole section of variables: .. code-block:: + :test: "nim c $1" var x, y: int # a comment can occur here too @@ -186,10 +192,11 @@ to a storage location: x = "xyz" # assigns a new value to `x` ``=`` is the *assignment operator*. The assignment operator can be -overloaded. You can declare multiple variables with a single assignment +overloaded. You can declare multiple variables with a single assignment statement and all the variables will have the same value: .. code-block:: + :test: "nim c $1" var x, y = 3 # assigns 3 to the variables `x` and `y` echo "x ", x # outputs "x 3" echo "y ", y # outputs "y 3" @@ -212,12 +219,14 @@ cannot change. The compiler must be able to evaluate the expression in a constant declaration at compile time: .. code-block:: nim + :test: "nim c $1" const x = "abc" # the constant x contains the string "abc" Indentation can be used after the ``const`` keyword to list a whole section of constants: .. code-block:: + :test: "nim c $1" const x = 1 # a comment can occur here too @@ -243,6 +252,7 @@ and put it into a data section": const input = readLine(stdin) # Error: constant expression expected .. code-block:: + :test: "nim c $1" let input = readLine(stdin) # works @@ -260,6 +270,7 @@ If statement The if statement is one way to branch the control flow: .. code-block:: nim + :test: "nim c $1" let name = readLine(stdin) if name == "": echo "Poor soul, you lost your name?" @@ -281,6 +292,7 @@ Another way to branch is provided by the case statement. A case statement is a multi-branch: .. code-block:: nim + :test: "nim c $1" let name = readLine(stdin) case name of "": @@ -338,6 +350,7 @@ While statement The while statement is a simple looping construct: .. code-block:: nim + :test: "nim c $1" echo "What's your name? " var name = readLine(stdin) @@ -358,6 +371,7 @@ provides. The example uses the built-in `countup <system.html#countup>`_ iterator: .. code-block:: nim + :test: "nim c $1" echo "Counting to ten: " for i in countup(1, 10): echo i @@ -409,6 +423,7 @@ Other useful iterators for collections (like arrays and sequences) are * ``pairs`` and ``mpairs`` which provides the element and an index number (immutable and mutable respectively) .. code-block:: nim + :test: "nim c $1" for index, item in ["a","b"].pairs: echo item, " at index ", index # => a at index 0 @@ -421,6 +436,8 @@ new scope. This means that in the following example, ``x`` is not accessible outside the loop: .. code-block:: nim + :test: "nim c $1" + :status: 1 while false: var x = "hi" echo x # does not work @@ -430,6 +447,8 @@ are only visible within the block they have been declared. The ``block`` statement can be used to open a new block explicitly: .. code-block:: nim + :test: "nim c $1" + :status: 1 block myblock: var x = "hi" echo x # does not work either @@ -444,6 +463,7 @@ can leave a ``while``, ``for``, or a ``block`` statement. It leaves the innermost construct, unless a label of a block is given: .. code-block:: nim + :test: "nim c $1" block myblock: echo "entering block" while true: @@ -465,6 +485,7 @@ Like in many other programming languages, a ``continue`` statement starts the next iteration immediately: .. code-block:: nim + :test: "nim c $1" while true: let x = readLine(stdin) if x == "": continue @@ -477,6 +498,7 @@ When statement Example: .. code-block:: nim + :test: "nim c $1" when system.hostOS == "windows": echo "running on Windows!" @@ -549,6 +571,7 @@ an expression is allowed: .. code-block:: nim # computes fac(4) at compile time: + :test: "nim c $1" const fac4 = (var x = 1; for i in 1..4: x *= i; x) @@ -561,6 +584,7 @@ is needed. (Some languages call them *methods* or *functions*.) In Nim new procedures are defined with the ``proc`` keyword: .. code-block:: nim + :test: "nim c $1" proc yes(question: string): bool = echo question, " (y/n)" while true: @@ -597,6 +621,7 @@ automatically at the end of a procedure if there is no ``return`` statement at the exit. .. code-block:: nim + :test: "nim c $1" proc sumTillNegative(x: varargs[int]): int = for i in x: if i < 0: @@ -624,6 +649,7 @@ to be declared with ``var`` in the procedure body. Shadowing the parameter name is possible, and actually an idiom: .. code-block:: nim + :test: "nim c $1" proc printSeq(s: seq, nprinted: int = -1) = var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len) for i in 0 .. <nprinted: @@ -633,6 +659,7 @@ If the procedure needs to modify the argument for the caller, a ``var`` parameter can be used: .. code-block:: nim + :test: "nim c $1" proc divmod(a, b: int; res, remainder: var int) = res = a div b # integer division remainder = a mod b # integer modulo operation @@ -663,6 +690,7 @@ The return value can be ignored implicitly if the called proc/iterator has been declared with the ``discardable`` pragma: .. code-block:: nim + :test: "nim c $1" proc p(x, y: int): int {.discardable.} = return x + y @@ -772,6 +800,7 @@ The "``" notation can also be used to call an operator just like any other procedure: .. code-block:: nim + :test: "nim c $1" if `==`( `+`(3, 4), 7): echo "True" @@ -819,6 +848,7 @@ Iterators Let's return to the simple counting example: .. code-block:: nim + :test: "nim c $1" echo "Counting to ten: " for i in countup(1, 10): echo i @@ -840,6 +870,7 @@ the only thing left to do is to replace the ``proc`` keyword by ``iterator`` and here it is - our first iterator: .. code-block:: nim + :test: "nim c $1" iterator countup(a, b: int): int = var res = a while res <= b: @@ -894,7 +925,8 @@ evaluation. For example: Characters ---------- The `character type` is called ``char``. Its size is always one byte, so -it cannot represent most UTF-8 characters; but it *can* represent one of the bytes that makes up a multi-byte UTF-8 character. +it cannot represent most UTF-8 characters; but it *can* represent one of the bytes +that makes up a multi-byte UTF-8 character. The reason for this is efficiency: for the overwhelming majority of use-cases, the resulting programs will still handle UTF-8 properly as UTF-8 was specially designed for this. @@ -945,6 +977,7 @@ to specify a non-default integer type: .. code-block:: nim + :test: "nim c $1" let x = 0 # x is of type ``int`` y = 0'i8 # y is of type ``int8`` @@ -981,6 +1014,7 @@ Float literals can have a *type suffix* to specify a non-default float type: .. code-block:: nim + :test: "nim c $1" var x = 0.0 # x is of type ``float`` y = 0.0'f32 # y is of type ``float32`` @@ -1002,6 +1036,7 @@ Conversion between basic types is performed by using the type as a function: .. code-block:: nim + :test: "nim c $1" var x: int32 = 1.int32 # same as calling int32(1) y: int8 = int8('a') # 'a' == 97'i8 @@ -1023,6 +1058,7 @@ graphs with cycles. The following example shows that even for basic types there is a difference between the ``$`` and ``repr`` outputs: .. code-block:: nim + :test: "nim c $1" var myBool = true myCharacter = 'n' @@ -1047,6 +1083,7 @@ Advanced types In Nim new types can be defined within a ``type`` statement: .. code-block:: nim + :test: "nim c $1" type biggestInt = int64 # biggest integer type that is available biggestFloat = float64 # biggest float type that is available @@ -1063,6 +1100,7 @@ to an integer value internally. The first symbol is represented at runtime by 0, the second by 1 and so on. For example: .. code-block:: nim + :test: "nim c $1" type Direction = enum @@ -1087,6 +1125,7 @@ explicitly given is assigned the value of the previous symbol + 1. An explicit ordered enum can have *holes*: .. code-block:: nim + :test: "nim c $1" type MyEnum = enum a = 2, b = 4, c = 89 @@ -1125,6 +1164,7 @@ A subrange type is a range of values from an integer or enumeration type (the base type). Example: .. code-block:: nim + :test: "nim c $1" type MySubrange = range[0..5] @@ -1155,6 +1195,7 @@ an array has the same type. The array's index type can be any ordinal type. Arrays can be constructed using ``[]``: .. code-block:: nim + :test: "nim c $1" type IntArray = array[0..5, int] # an array that is indexed with 0..5 @@ -1177,6 +1218,7 @@ length. `low(a) <system.html#low>`_ returns the lowest valid index for the array `a` and `high(a) <system.html#high>`_ the highest valid index. .. code-block:: nim + :test: "nim c $1" type Direction = enum north, east, south, west @@ -1228,6 +1270,7 @@ It is quite common to have arrays start at zero, so there's a shortcut syntax to specify a range from zero to the specified index minus one: .. code-block:: nim + :test: "nim c $1" type IntArray = array[0..5, int] # an array that is indexed with 0..5 QuickArray = array[6, int] # an array that is indexed with 0..5 @@ -1260,6 +1303,7 @@ A sequence may be passed to an openarray parameter. Example: .. code-block:: nim + :test: "nim c $1" var x: seq[int] # a reference to a sequence of integers @@ -1282,6 +1326,7 @@ value. Here the ``for`` statement is looping over the results from the <system.html>`_ module. Examples: .. code-block:: nim + :test: "nim c $1" for value in @[3, 4, 5]: echo value # --> 3 @@ -1308,6 +1353,7 @@ with a compatible base type can be passed to an openarray parameter, the index type does not matter. .. code-block:: nim + :test: "nim c $1" var fruits: seq[string] # reference to a sequence of strings that is initialized with 'nil' capitals: array[3, string] # array of strings with a fixed size @@ -1337,6 +1383,7 @@ arguments to a procedure. The compiler converts the list of arguments to an array automatically: .. code-block:: nim + :test: "nim c $1" proc myWriteln(f: File, a: varargs[string]) = for s in items(a): write(f, s) @@ -1351,6 +1398,7 @@ last parameter in the procedure header. It is also possible to perform type conversions in this context: .. code-block:: nim + :test: "nim c $1" proc myWriteln(f: File, a: varargs[string, `$`]) = for s in items(a): write(f, s) @@ -1374,6 +1422,7 @@ context. A slice is just an object of type Slice which contains two bounds, define operators which accept Slice objects to define ranges. .. code-block:: nim + :test: "nim c $1" var a = "Nim is a progamming language" @@ -1388,27 +1437,31 @@ slice's bounds can hold any value supported by their type, but it is the proc using the slice object which defines what values are accepted. - To understand some of the different ways of specifying the indices of strings, arrays, sequences, etc., - it must be remembered that Nim uses zero-based indices. +To understand some of the different ways of specifying the indices of +strings, arrays, sequences, etc., it must be remembered that Nim uses +zero-based indices. - So the string ``b`` is of length 19, and two different ways of specifying the indices are +So the string ``b`` is of length 19, and two different ways of specifying the +indices are - .. code-block:: nim +.. code-block:: nim "Slices are useless." | | | 0 11 17 using indices ^19 ^8 ^2 using ^ syntax - where ``b[0..^1]`` is equivalent to ``b[0..b.len-1]`` and ``b[0..<b.len]``, and it can be seen that the ``^1`` provides a short-hand way of specifying the ``b.len-1`` +where ``b[0..^1]`` is equivalent to ``b[0..b.len-1]`` and ``b[0..<b.len]``, and it +can be seen that the ``^1`` provides a short-hand way of specifying the ``b.len-1``. - In the above example, because the string ends in a period, to get the portion of the string that is "useless" and replace it with "useful" +In the above example, because the string ends in a period, to get the portion of the +string that is "useless" and replace it with "useful". - ``b[11..^2]`` is the portion "useless", and - ``b[11..^2] = "useful"`` replaces the "useless" portion with "useful", - giving the result "Slices are useful." +``b[11..^2]`` is the portion "useless", and ``b[11..^2] = "useful"`` replaces the +"useless" portion with "useful", giving the result "Slices are useful." - Note: alternate ways of writing this are ``b[^8..^2] = "useful"`` or as ``b[11..b.len-2] = "useful"`` or as ``b[11..<b.len-1] = "useful"`` or as .... +Note: alternate ways of writing this are ``b[^8..^2] = "useful"`` or +as ``b[11..b.len-2] = "useful"`` or as ``b[11..<b.len-1] = "useful"``. Tuples ------ @@ -1425,6 +1478,7 @@ The assignment operator for tuples copies each component. The notation integer. .. code-block:: nim + :test: "nim c $1" type Person = tuple[name: string, age: int] # type representing a person: @@ -1470,6 +1524,7 @@ otherwise you will be assigning the same value to all the individual variables! For example: .. code-block:: nim + :test: "nim c $1" import os @@ -1509,10 +1564,10 @@ tuple/object field operator) and ``[]`` (array/string/sequence index operator) operators perform implicit dereferencing operations for reference types: .. code-block:: nim + :test: "nim c $1" type - Node = ref NodeObj - NodeObj = object + Node = ref object le, ri: Node data: int var @@ -1539,6 +1594,7 @@ techniques. Example: .. code-block:: nim + :test: "nim c $1" proc echoItem(x: int) = echo x proc forEach(action: proc (x: int)) = @@ -1556,9 +1612,11 @@ listed in the `manual <manual.html#types-procedural-type>`_. Distinct type ------------- -A Distinct type allows for the creation of new type that "does not imply a subtype relationship between it and its base type". +A Distinct type allows for the creation of new type that "does not imply a +subtype relationship between it and its base type". You must **explicitly** define all behaviour for the distinct type. -To help with this, both the distinct type and its base type can cast from one type to the other. +To help with this, both the distinct type and its base type can cast from one +type to the other. Examples are provided in the `manual <manual.html#types-distinct-type>`_. Modules @@ -1593,39 +1651,6 @@ Each module has a special magic constant ``isMainModule`` that is true if the module is compiled as the main file. This is very useful to embed tests within the module as shown by the above example. -Modules that depend on each other are possible, but strongly discouraged, -because then one module cannot be reused without the other. - -The algorithm for compiling modules is: - -- Compile the whole module as usual, following import statements recursively. -- If there is a cycle only import the already parsed symbols (that are - exported); if an unknown identifier occurs then abort. - -This is best illustrated by an example: - -.. code-block:: nim - # Module A - type - T1* = int # Module A exports the type ``T1`` - import B # the compiler starts parsing B - - proc main() = - var i = p(3) # works because B has been parsed completely here - - main() - -.. code-block:: nim - # Module B - import A # A is not parsed here! Only the already known symbols - # of A are imported. - - proc p*(x: A.T1): A.T1 = - # this works because the compiler has already - # added T1 to A's interface symbol table - result = x + 1 - - A symbol of a module *can* be *qualified* with the ``module.symbol`` syntax. And if a symbol is ambiguous, it *must* be qualified. A symbol is ambiguous if it is defined in two (or more) different modules and both modules are diff --git a/doc/tut2.rst b/doc/tut2.rst index 0bb4c94e1..91cb52834 100644 --- a/doc/tut2.rst +++ b/doc/tut2.rst @@ -55,6 +55,7 @@ Objects have access to their type at runtime. There is an ``of`` operator that can be used to check the object's type: .. code-block:: nim + :test: "nim c $1" type Person = ref object of RootObj name*: string # the * means that `name` is accessible from other modules @@ -103,16 +104,16 @@ would require arbitrary symbol lookahead which slows down compilation.) Example: .. code-block:: nim + :test: "nim c $1" type - Node = ref NodeObj # a traced reference to a NodeObj - NodeObj = object + Node = ref object # a reference to an object with the following field: le, ri: Node # left and right subtrees sym: ref Sym # leaves contain a reference to a Sym Sym = object # a symbol name: string # the symbol's name line: int # the line the symbol was declared in - code: Node # the symbol's abstract syntax tree + code: Node # the symbol's abstract syntax tree Type conversions @@ -145,6 +146,7 @@ variant types are needed. An example: .. code-block:: nim + :test: "nim c $1" # This is an example how an abstract syntax tree could be modelled in Nim type @@ -155,8 +157,7 @@ An example: nkAdd, # an addition nkSub, # a subtraction nkIf # an if statement - Node = ref NodeObj - NodeObj = object + Node = ref object case kind: NodeKind # the ``kind`` field is the discriminator of nkInt: intVal: int of nkFloat: floatVal: float @@ -203,9 +204,11 @@ This method call syntax is not restricted to objects, it can be used for any type: .. code-block:: nim + :test: "nim c $1" + import strutils echo "abc".len # is the same as echo len("abc") - echo "abc".toUpper() + echo "abc".toUpperAscii() echo({'a', 'b', 'c'}.card) stdout.writeLine("Hallo") # the same as writeLine(stdout, "Hallo") @@ -215,6 +218,7 @@ postfix notation.) So "pure object oriented" code is easy to write: .. code-block:: nim + :test: "nim c $1" import strutils, sequtils stdout.writeLine("Give a list of numbers (separated by spaces): ") @@ -230,6 +234,7 @@ the same. But setting a value is different; for this a special setter syntax is needed: .. code-block:: nim + :test: "nim c $1" type Socket* = ref object of RootObj @@ -254,6 +259,7 @@ The ``[]`` array access operator can be overloaded to provide `array properties`:idx:\ : .. code-block:: nim + :test: "nim c $1" type Vector* = object x, y, z: float @@ -285,23 +291,24 @@ Procedures always use static dispatch. For dynamic dispatch replace the ``proc`` keyword by ``method``: .. code-block:: nim + :test: "nim c $1" type - PExpr = ref object of RootObj ## abstract base class for an expression - PLiteral = ref object of PExpr + Expression = ref object of RootObj ## abstract base class for an expression + Literal = ref object of Expression x: int - PPlusExpr = ref object of PExpr - a, b: PExpr + PlusExpr = ref object of Expression + a, b: Expression # watch out: 'eval' relies on dynamic binding - method eval(e: PExpr): int = + method eval(e: Expression): int = # override this base method quit "to override!" - method eval(e: PLiteral): int = e.x - method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b) + method eval(e: Literal): int = e.x + method eval(e: PlusExpr): int = eval(e.a) + eval(e.b) - proc newLit(x: int): PLiteral = PLiteral(x: x) - proc newPlus(a, b: PExpr): PPlusExpr = PPlusExpr(a: a, b: b) + proc newLit(x: int): Literal = Literal(x: x) + proc newPlus(a, b: Expression): PlusExpr = PlusExpr(a: a, b: b) echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) @@ -313,6 +320,7 @@ In a multi-method all parameters that have an object type are used for the dispatching: .. code-block:: nim + :test: "nim c $1" type Thing = ref object of RootObj @@ -367,6 +375,7 @@ Raise statement Raising an exception is done with the ``raise`` statement: .. code-block:: nim + :test: "nim c $1" var e: ref OSError new(e) @@ -387,6 +396,9 @@ Try statement The ``try`` statement handles exceptions: .. code-block:: nim + :test: "nim c $1" + from strutils import parseInt + # read the first two lines of a text file that should contain numbers # and tries to add them var @@ -481,12 +493,12 @@ with `type parameters`:idx:. They are most useful for efficient type safe containers: .. code-block:: nim + :test: "nim c $1" type - BinaryTreeObj[T] = object # BinaryTree is a generic type with - # with generic param ``T`` - le, ri: BinaryTree[T] # left and right subtrees; may be nil - data: T # the data stored in a node - BinaryTree*[T] = ref BinaryTreeObj[T] # type that is exported + BinaryTree*[T] = ref object # BinaryTree is a generic type with + # generic param ``T`` + le, ri: BinaryTree[T] # left and right subtrees; may be nil + data: T # the data stored in a node proc newNode*[T](data: T): BinaryTree[T] = # constructor for a node @@ -576,6 +588,7 @@ Templates are especially useful for lazy evaluation purposes. Consider a simple proc for logging: .. code-block:: nim + :test: "nim c $1" const debug = true @@ -593,6 +606,7 @@ evaluation for procedures is *eager*). Turning the ``log`` proc into a template solves this problem: .. code-block:: nim + :test: "nim c $1" const debug = true @@ -614,6 +628,7 @@ If the template has no explicit return type, To pass a block of statements to a template, use 'untyped' for the last parameter: .. code-block:: nim + :test: "nim c $1" template withFile(f: untyped, filename: string, mode: FileMode, body: untyped): typed = @@ -668,6 +683,7 @@ The following example implements a powerful ``debug`` command that accepts a variable number of arguments: .. code-block:: nim + :test: "nim c $1" # to work with Nim syntax trees, we need an API that is defined in the # ``macros`` module: import macros @@ -747,6 +763,7 @@ dynamic code into something that compiles statically. For the exercise we will use the following snippet of code as the starting point: .. code-block:: nim + :test: "nim c $1" import strutils, tables @@ -866,9 +883,9 @@ variables with ``cfg``. In essence, what the compiler is doing is replacing the line calling the macro with the following snippet of code: .. code-block:: nim - const cfgversion= "1.1" - const cfglicenseOwner= "Hyori Lee" - const cfglicenseKey= "M1Tl3PjBWO2CC48m" + const cfgversion = "1.1" + const cfglicenseOwner = "Hyori Lee" + const cfglicenseKey = "M1Tl3PjBWO2CC48m" You can verify this yourself adding the line ``echo source`` somewhere at the end of the macro and compiling the program. Another difference is that instead @@ -894,12 +911,13 @@ an expression macro. Since we know that we want to generate a bunch of see what the compiler *expects* from us: .. code-block:: nim + :test: "nim c $1" import macros dumpTree: const cfgversion: string = "1.1" - const cfglicenseOwner= "Hyori Lee" - const cfglicenseKey= "M1Tl3PjBWO2CC48m" + const cfglicenseOwner = "Hyori Lee" + const cfglicenseKey = "M1Tl3PjBWO2CC48m" During compilation of the source code we should see the following lines in the output (again, since this is a macro, compilation is enough, you don't have to @@ -999,6 +1017,7 @@ Lifting Procs +++++++++++++ .. code-block:: nim + :test: "nim c $1" import math template liftScalarProc(fname) = diff --git a/examples/cross_calculator/ios/resources/ui/NRViewController.xib b/examples/cross_calculator/ios/resources/ui/NRViewController.xib index b260db2af..2118b5044 100644 --- a/examples/cross_calculator/ios/resources/ui/NRViewController.xib +++ b/examples/cross_calculator/ios/resources/ui/NRViewController.xib @@ -85,7 +85,7 @@ <int key="IBUITag">2</int> <bool key="IBUIUserInteractionEnabled">NO</bool> <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string> - <string key="IBUIText">Nimrod Crossplatform Calculator</string> + <string key="IBUIText">Nim Crossplatform Calculator</string> <object class="NSColor" key="IBUITextColor" id="128895179"> <int key="NSColorSpace">1</int> <bytes key="NSRGB">MCAwIDAAA</bytes> diff --git a/examples/cross_calculator/lazarus/unit1.pas b/examples/cross_calculator/lazarus/unit1.pas index aa0ef6cf7..6091a61d3 100644 --- a/examples/cross_calculator/lazarus/unit1.pas +++ b/examples/cross_calculator/lazarus/unit1.pas @@ -42,7 +42,7 @@ function myAdd(x, y: longint): longint; cdecl; external; procedure TForm1.FormCreate(Sender: TObject); begin - // we initialize the Nimrod data structures here: + // we initialize the Nim data structures here: NimMain(); end; diff --git a/examples/cross_calculator/nim_commandline/nim.cfg b/examples/cross_calculator/nim_commandline/nim.cfg index 41c034430..6f0cb4a01 100644 --- a/examples/cross_calculator/nim_commandline/nim.cfg +++ b/examples/cross_calculator/nim_commandline/nim.cfg @@ -1,4 +1,4 @@ -# Nimrod configuration file. +# Nim configuration file. # The file is used only to add the path of the backend to the compiler options. path="../nim_backend" diff --git a/examples/cross_calculator/readme.txt b/examples/cross_calculator/readme.txt index 5011792b9..72e4130eb 100644 --- a/examples/cross_calculator/readme.txt +++ b/examples/cross_calculator/readme.txt @@ -2,7 +2,7 @@ The cross platform calculator illustrates how to use Nim to create a backend called by different native user interfaces. Since the purpose of the example is to show how the cross platform code -interacts with Nimrod the actual backend code is just a simple addition proc. +interacts with Nim the actual backend code is just a simple addition proc. By keeping your program logic in Nim you can easily reuse it in different platforms. diff --git a/examples/cross_todo/nim_backend/backend.nim b/examples/cross_todo/nim_backend/backend.nim index 6869665f8..513fe304f 100644 --- a/examples/cross_todo/nim_backend/backend.nim +++ b/examples/cross_todo/nim_backend/backend.nim @@ -4,9 +4,8 @@ import db_sqlite, parseutils, strutils, times - type - TTodo* = object + Todo* = object ## A todo object holding the information serialized to the database. id: int64 ## Unique identifier of the object in the ## database, use the getId() accessor to read it. @@ -17,7 +16,7 @@ type ## outside of this module, use the ## getModificationDate accessor. - TPagedParams* = object + PagedParams* = object ## Contains parameters for a query, initialize default values with ## initDefaults(). pageSize*: int64 ## Lines per returned query page, -1 for @@ -27,11 +26,10 @@ type showUnchecked*: bool ## Get unchecked objects. showChecked*: bool ## Get checked objects. - # - General procs -# -proc initDefaults*(params: var TPagedParams) = - ## Sets sane defaults for a TPagedParams object. + +proc initDefaults*(params: var PagedParams) = + ## Sets sane defaults for a PagedParams object. ## ## Note that you should always provide a non zero pageSize, either a specific ## positive value or negative for unbounded query results. @@ -41,7 +39,6 @@ proc initDefaults*(params: var TPagedParams) = params.showUnchecked = true params.showChecked = false - proc openDatabase*(path: string): DbConn = ## Creates or opens the sqlite3 database. ## @@ -56,16 +53,14 @@ proc openDatabase*(path: string): DbConn = desc TEXT NOT NULL, modification_date INTEGER NOT NULL, CONSTRAINT Todos UNIQUE (id))""" - db_sqlite.exec(conn, query) result = conn +# - Procs related to Todo objects -# - Procs related to TTodo objects -# proc initFromDB(id: int64; text: string; priority: int, isDone: bool; - modificationDate: Time): TTodo = - ## Returns an initialized TTodo object created from database parameters. + modificationDate: Time): Todo = + ## Returns an initialized Todo object created from database parameters. ## ## The proc assumes all values are right. Note this proc is NOT exported. assert(id >= 0, "Identity identifiers should not be negative") @@ -75,29 +70,25 @@ proc initFromDB(id: int64; text: string; priority: int, isDone: bool; result.isDone = isDone result.modificationDate = modificationDate - -proc getId*(todo: TTodo): int64 = +proc getId*(todo: Todo): int64 = ## Accessor returning the value of the private id property. return todo.id - -proc getModificationDate*(todo: TTodo): Time = - ## Returns the last modification date of a TTodo entry. +proc getModificationDate*(todo: Todo): Time = + ## Returns the last modification date of a Todo entry. return todo.modificationDate - -proc update*(todo: var TTodo; conn: DbConn): bool = +proc update*(todo: var Todo; conn: DbConn): bool = ## Checks the database for the object and refreshes its variables. ## ## Use this method if you (or another entity) have modified the database and ## want to update the object you have with whatever the database has stored. ## Returns true if the update succeeded, or false if the object was not found ## in the database any more, in which case you should probably get rid of the - ## TTodo object. + ## Todo object. assert(todo.id >= 0, "The identifier of the todo entry can't be negative") let query = sql"""SELECT desc, priority, is_done, modification_date FROM Todos WHERE id = ?""" - try: let rows = conn.getAllRows(query, $todo.id) if len(rows) < 1: @@ -111,8 +102,7 @@ proc update*(todo: var TTodo; conn: DbConn): bool = except: echo("Something went wrong selecting for id " & $todo.id) - -proc save*(todo: var TTodo; conn: DbConn): bool = +proc save*(todo: var Todo; conn: DbConn): bool = ## Saves the current state of text, priority and isDone to the database. ## ## Returns true if the database object was updated (in which case the @@ -127,15 +117,13 @@ proc save*(todo: var TTodo; conn: DbConn): bool = WHERE id = ?""" rowsUpdated = conn.execAffectedRows(query, $todo.text, $todo.priority, $todo.isDone, $int(currentDate), $todo.id) - if 1 == rowsUpdated: todo.modificationDate = currentDate result = true - # - Procs dealing directly with the database -# -proc addTodo*(conn: DbConn; priority: int; text: string): TTodo = + +proc addTodo*(conn: DbConn; priority: int; text: string): Todo = ## Inserts a new todo into the database. ## ## Returns the generated todo object. If there is an error EDb will be raised. @@ -145,10 +133,8 @@ proc addTodo*(conn: DbConn; priority: int; text: string): TTodo = (priority, is_done, desc, modification_date) VALUES (?, 'false', ?, ?)""" todoId = conn.insertId(query, priority, text, $int(currentDate)) - result = initFromDB(todoId, text, priority, false, currentDate) - proc deleteTodo*(conn: DbConn; todoId: int64): int64 {.discardable.} = ## Deletes the specified todo identifier. ## @@ -156,7 +142,6 @@ proc deleteTodo*(conn: DbConn; todoId: int64): int64 {.discardable.} = let query = sql"""DELETE FROM Todos WHERE id = ?""" result = conn.execAffectedRows(query, $todoId) - proc getNumEntries*(conn: DbConn): int = ## Returns the number of entries in the Todos table. ## @@ -170,38 +155,30 @@ proc getNumEntries*(conn: DbConn): int = echo("Something went wrong retrieving number of Todos entries") result = -1 - -proc getPagedTodos*(conn: DbConn; params: TPagedParams; - page = 0'i64): seq[TTodo] = +proc getPagedTodos*(conn: DbConn; params: PagedParams; page = 0'i64): seq[Todo] = ## Returns the todo entries for a specific page. ## ## Pages are calculated based on the params.pageSize parameter, which can be ## set to a negative value to specify no limit at all. The query will be - ## affected by the TPagedParams, which should have sane values (call + ## affected by the PagedParams, which should have sane values (call ## initDefaults). assert(page >= 0, "You should request a page zero or bigger than zero") result = @[] - # Well, if you don't want to see anything, there's no point in asking the db. if not params.showUnchecked and not params.showChecked: return - let order_by = [ if params.priorityAscending: "ASC" else: "DESC", if params.dateAscending: "ASC" else: "DESC"] - query = sql("""SELECT id, desc, priority, is_done, modification_date FROM Todos WHERE is_done = ? OR is_done = ? ORDER BY priority $1, modification_date $2, id DESC LIMIT ? * ?,?""" % order_by) - args = @[$params.showChecked, $(not params.showUnchecked), $params.pageSize, $page, $params.pageSize] - #echo("Query " & string(query)) #echo("args: " & args.join(", ")) - var newId: BiggestInt for row in conn.fastRows(query, args): let numChars = row[0].parseBiggestInt(newId) @@ -209,10 +186,9 @@ proc getPagedTodos*(conn: DbConn; params: TPagedParams; result.add(initFromDB(int64(newId), row[1], row[2].parseInt, row[3].parseBool, Time(row[4].parseInt))) - -proc getTodo*(conn: DbConn; todoId: int64): ref TTodo = - ## Returns a reference to a TTodo or nil if the todo could not be found. - var tempTodo: TTodo +proc getTodo*(conn: DbConn; todoId: int64): ref Todo = + ## Returns a reference to a Todo or nil if the todo could not be found. + var tempTodo: Todo tempTodo.id = todoId if tempTodo.update(conn): new(result) diff --git a/examples/cross_todo/nim_backend/testbackend.nim b/examples/cross_todo/nim_backend/testbackend.nim index 6754f013a..4a71d5f2c 100644 --- a/examples/cross_todo/nim_backend/testbackend.nim +++ b/examples/cross_todo/nim_backend/testbackend.nim @@ -2,8 +2,7 @@ import backend, db_sqlite, strutils, times - -proc showPagedResults(conn: DbConn; params: TPagedParams) = +proc showPagedResults(conn: DbConn; params: PagedParams) = ## Shows the contents of the database in pages of specified size. ## ## Hmm... I guess this is more of a debug proc which should be moved outside, @@ -11,7 +10,6 @@ proc showPagedResults(conn: DbConn; params: TPagedParams) = var page = 0'i64 rows = conn.getPagedTodos(params) - while rows.len > 0: echo("page " & $page) for row in rows: @@ -25,7 +23,6 @@ proc showPagedResults(conn: DbConn; params: TPagedParams) = else: break - proc dumTest() = let conn = openDatabase("todo.sqlite3") try: @@ -35,10 +32,8 @@ proc dumTest() = # Fill some dummy rows if there are not many entries yet. discard conn.addTodo(3, "Filler1") discard conn.addTodo(4, "Filler2") - var todo = conn.addTodo(2, "Testing") echo("New todo added with id " & $todo.getId) - # Try changing it and updating the database. var clonedTodo = conn.getTodo(todo.getId)[] assert(clonedTodo.text == todo.text, "Should be equal") @@ -49,13 +44,11 @@ proc dumTest() = echo("Updated priority $1, done $2" % [$todo.priority, $todo.isDone]) else: assert(false, "Uh oh, I wasn't expecting that!") - # Verify our cloned copy is different but can be updated. assert(clonedTodo.text != todo.text, "Should be different") discard clonedTodo.update(conn) assert(clonedTodo.text == todo.text, "Should be equal") - - var params: TPagedParams + var params: PagedParams params.initDefaults conn.showPagedResults(params) conn.deleteTodo(todo.getId) @@ -66,7 +59,6 @@ proc dumTest() = echo("Later priority $1, done $2" % [$todo.priority, $todo.isDone]) else: echo("Can't update object $1 from db!" % $todo.getId) - # Try to list content in a different way. params.pageSize = 5 params.priorityAscending = true @@ -77,7 +69,6 @@ proc dumTest() = conn.close echo("Database closed") - # Code that will be run only on the commandline. when isMainModule: dumTest() diff --git a/examples/cross_todo/nim_commandline/nim.cfg b/examples/cross_todo/nim_commandline/nim.cfg index 41c034430..6f0cb4a01 100644 --- a/examples/cross_todo/nim_commandline/nim.cfg +++ b/examples/cross_todo/nim_commandline/nim.cfg @@ -1,4 +1,4 @@ -# Nimrod configuration file. +# Nim configuration file. # The file is used only to add the path of the backend to the compiler options. path="../nim_backend" diff --git a/examples/cross_todo/nim_commandline/nimtodo.nim b/examples/cross_todo/nim_commandline/nimtodo.nim index c8993b2c8..be5b3407b 100644 --- a/examples/cross_todo/nim_commandline/nimtodo.nim +++ b/examples/cross_todo/nim_commandline/nimtodo.nim @@ -18,8 +18,8 @@ Commands: -h, --help shows this help List options (optional): - -p=+|- Sorts list by ascending|desdencing priority. Default:desdencing. - -m=+|- Sorts list by ascending|desdencing date. Default:desdencing. + -p=+|- Sorts list by ascending|descending priority. Default:descending. + -m=+|- Sorts list by ascending|descending date. Default:descending. -t Show checked entries. By default they are not shown. -z Hide unchecked entries. By default they are shown. @@ -33,7 +33,7 @@ Examples: """ type - TCommand = enum # The possible types of commands + Command = enum # The possible types of commands cmdAdd # The user wants to add a new todo entry. cmdCheck # User wants to check a todo entry. cmdUncheck # User wants to uncheck a todo entry. @@ -42,30 +42,27 @@ type cmdGenerate # Add random rows to the database, for testing. cmdList # User wants to list contents. - TParamConfig = object + ParamConfig = object # Structure containing the parsed options from the commandline. - command: TCommand # Store the type of operation + command: Command # Store the type of operation addPriority: int # Only valid with cmdAdd, stores priority. addText: seq[string] # Only valid with cmdAdd, stores todo text. todoId: int64 # The todo id for operations like check or delete. - listParams: TPagedParams # Uses the backend structure directly for params. + listParams: PagedParams # Uses the backend structure directly for params. - -proc initDefaults(params: var TParamConfig) = +proc initDefaults(params: var ParamConfig) = ## Initialises defaults value in the structure. ## ## Most importantly we want to have an empty list for addText. params.listParams.initDefaults params.addText = @[] - proc abort(message: string, value: int) = # Simple wrapper to abort also displaying the help to the user. stdout.write(USAGE) quit(message, value) - -template parseTodoIdAndSetCommand(newCommand: TCommand): stmt = +template parseTodoIdAndSetCommand(newCommand: Command): untyped = ## Helper to parse a big todo identifier into todoId and set command. try: let numChars = val.parseBiggestInt(newId) @@ -75,8 +72,7 @@ template parseTodoIdAndSetCommand(newCommand: TCommand): stmt = except OverflowError: raise newException(ValueError, "Value $1 too big" % val) - -template verifySingleCommand(actions: stmt): stmt = +template verifySingleCommand(actions: typed): typed = ## Helper to make sure only one command has been specified so far. if specifiedCommand: abort("Only one command can be specified at a time! (extra:$1)" % [key], 2) @@ -84,7 +80,6 @@ template verifySingleCommand(actions: stmt): stmt = actions specifiedCommand = true - proc parsePlusMinus(val: string, debugText: string): bool = ## Helper to process a plus or minus character from the commandline. ## @@ -100,11 +95,10 @@ proc parsePlusMinus(val: string, debugText: string): bool = else: abort("$1 parameter should be + or - but was '$2'." % [debugText, val], 4) - -proc parseCmdLine(): TParamConfig = +proc parseCmdLine(): ParamConfig = ## Parses the commandline. ## - ## Returns a TParamConfig structure filled with the proper values or directly + ## Returns a ParamConfig structure filled with the proper values or directly ## calls quit() with the appropriate error message. var specifiedCommand = false @@ -112,15 +106,12 @@ proc parseCmdLine(): TParamConfig = p = initOptParser() key, val: TaintedString newId: BiggestInt - result.initDefaults - try: while true: next(p) key = p.key val = p.val - case p.kind of cmdArgument: if specifiedCommand and cmdAdd == result.command: @@ -180,17 +171,13 @@ proc parseCmdLine(): TParamConfig = break except ValueError: abort("Invalid integer value '$1' for parameter '$2'." % [val, key], 7) - if not specifiedCommand: abort("Didn't specify any command.", 8) - if cmdAdd == result.command and result.addText.len < 1: abort("Used the add command, but provided no text/description.", 9) - if usesListParams and cmdList != result.command: abort("Used list options, but didn't specify the list command.", 10) - proc generateDatabaseRows(conn: DbConn) = ## Adds some rows to the database ignoring errors. discard conn.addTodo(1, "Watch another random youtube video") @@ -208,19 +195,16 @@ proc generateDatabaseRows(conn: DbConn) = discard conn.addTodo(6, "Learn a functional programming language") echo("Generated some entries, they were added to your database.") - -proc listDatabaseContents(conn: DbConn; listParams: TPagedParams) = +proc listDatabaseContents(conn: DbConn; listParams: PagedParams) = ## Dumps the database contents formatted to the standard output. ## ## Pass the list/filter parameters parsed from the commandline. var params = listParams params.pageSize = -1 - let todos = conn.getPagedTodos(params) if todos.len < 1: echo("Database empty") return - echo("Todo id, is done, priority, last modification date, text:") # First detect how long should be our columns for formatting. var cols: array[0..2, int] @@ -228,7 +212,6 @@ proc listDatabaseContents(conn: DbConn; listParams: TPagedParams) = cols[0] = max(cols[0], ($todo.getId).len) cols[1] = max(cols[1], ($todo.priority).len) cols[2] = max(cols[2], ($todo.getModificationDate).len) - # Now dump all the rows using the calculated alignment sizes. for todo in todos: echo("$1 $2 $3, $4, $5" % [ @@ -238,7 +221,6 @@ proc listDatabaseContents(conn: DbConn; listParams: TPagedParams) = ($todo.getModificationDate).align(cols[2]), todo.text]) - proc deleteOneTodo(conn: DbConn; todoId: int64) = ## Deletes a single todo entry from the database. let numDeleted = conn.deleteTodo(todoId) @@ -247,7 +229,6 @@ proc deleteOneTodo(conn: DbConn; todoId: int64) = else: quit("Couldn't delete todo id " & $todoId, 11) - proc deleteAllTodos(conn: DbConn) = ## Deletes all the contents from the database. ## @@ -256,43 +237,35 @@ proc deleteAllTodos(conn: DbConn) = ## ourselfves to the API exported by backend. var counter: int64 - params: TPagedParams - + params: PagedParams params.initDefaults params.pageSize = -1 params.showUnchecked = true params.showChecked = true - let todos = conn.getPagedTodos(params) for todo in todos: if conn.deleteTodo(todo.getId) > 0: counter += 1 else: quit("Couldn't delete todo id " & $todo.getId, 12) - echo("Deleted $1 todo entries from database." % $counter) - proc setTodoCheck(conn: DbConn; todoId: int64; value: bool) = ## Changes the check state of a todo entry to the specified value. let newState = if value: "checked" else: "unchecked" todo = conn.getTodo(todoId) - if todo == nil: quit("Can't modify todo id $1, its not in the database." % $todoId, 13) - if todo[].isDone == value: echo("Todo id $1 was already set to $2." % [$todoId, newState]) return - todo[].isDone = value if todo[].save(conn): echo("Todo id $1 set to $2." % [$todoId, newState]) else: quit("Error updating todo id $1 to $2." % [$todoId, newState]) - proc addTodo(conn: DbConn; priority: int; tokens: seq[string]) = ## Adds to the database a todo with the specified priority. ## @@ -302,17 +275,14 @@ proc addTodo(conn: DbConn; priority: int; tokens: seq[string]) = echo("Created todo entry with id:$1 for priority $2 and text '$3'." % [ $todo.getId, $todo.priority, todo.text]) - when isMainModule: ## Main entry point. let opt = parseCmdLine() dbPath = getConfigDir() / "nimtodo.sqlite3" - if not dbPath.existsFile: createDir(getConfigDir()) echo("No database found at $1, it will be created for you." % dbPath) - let conn = openDatabase(dbPath) try: case opt.command diff --git a/examples/cross_todo/nim_commandline/readme.txt b/examples/cross_todo/nim_commandline/readme.txt index ca4b67521..7d68bbc8b 100644 --- a/examples/cross_todo/nim_commandline/readme.txt +++ b/examples/cross_todo/nim_commandline/readme.txt @@ -14,6 +14,6 @@ generation switch can be used to fill the database with some basic todo entries you can play with. Compilation is fairly easy despite having the source split in different -directories. Thanks to the Nim.cfg file, which adds the ../Nim_backend +directories. Thanks to the nim.cfg file, which adds the ../Nim_backend directory as a search path, you can compile and run the example just fine from the command line with 'nim c -r nimtodo.nim'. diff --git a/examples/cross_todo/readme.txt b/examples/cross_todo/readme.txt index 5be01e197..44e8c47aa 100644 --- a/examples/cross_todo/readme.txt +++ b/examples/cross_todo/readme.txt @@ -1,4 +1,4 @@ -The cross platform todo illustrates how to use Nim to create a backend +This cross platform todo illustrates how to use Nim to create a backend called by different native user interfaces. This example builds on the knowledge learned from the cross_calculator example. diff --git a/examples/keyval.nim b/examples/keyval.nim index ae8cb8f08..a594c0fa8 100644 --- a/examples/keyval.nim +++ b/examples/keyval.nim @@ -3,7 +3,6 @@ import re for x in lines("myfile.txt"): if x =~ re"(\w+)=(.*)": - echo "Key: ", matches[0], - " Value: ", matches[1] + echo "Key: ", matches[0], " Value: ", matches[1] diff --git a/examples/readme.txt b/examples/readme.txt index dc3d3fb9b..176bc8239 100644 --- a/examples/readme.txt +++ b/examples/readme.txt @@ -1,4 +1,4 @@ -In this directory you will find several examples for how to use the Nimrod +In this directory you will find several examples for how to use the Nim library. Copyright (c) 2004-2012 Andreas Rumpf. diff --git a/examples/talk/dsl.nim b/examples/talk/dsl.nim index 1034c99d4..2dde51790 100644 --- a/examples/talk/dsl.nim +++ b/examples/talk/dsl.nim @@ -1,20 +1,20 @@ import strutils -template html(name: expr, matter: stmt) {.immediate.} = +template html(name, matter: untyped) = proc name(): string = result = "<html>" matter result.add("</html>") -template nestedTag(tag: expr) {.immediate.} = - template tag(matter: stmt) {.immediate.} = +template nestedTag(tag: untyped) = + template tag(matter: typed) = result.add("<" & astToStr(tag) & ">") matter result.add("</" & astToStr(tag) & ">") -template simpleTag(tag: expr) {.immediate.} = - template tag(matter: expr) {.immediate.} = +template simpleTag(tag: untyped) = + template tag(matter: untyped) = result.add("<$1>$2</$1>" % [astToStr(tag), matter]) nestedTag body diff --git a/examples/talk/formatoptimizer.nim b/examples/talk/formatoptimizer.nim index db11d112d..104214e19 100644 --- a/examples/talk/formatoptimizer.nim +++ b/examples/talk/formatoptimizer.nim @@ -5,7 +5,7 @@ import macros proc invalidFormatString() = echo "invalidFormatString" -template formatImpl(handleChar: expr) = +template formatImpl(handleChar: untyped) = var i = 0 while i < f.len: if f[i] == '$': @@ -24,11 +24,11 @@ template formatImpl(handleChar: expr) = i += 1 proc `%`*(f: string, a: openArray[string]): string = - template identity(x: expr): expr = x + template identity(x: untyped): untyped = x result = "" formatImpl(identity) -macro optFormat{`%`(f, a)}(f: string{lit}, a: openArray[string]): expr = +macro optFormat{`%`(f, a)}(f: string{lit}, a: openArray[string]): untyped = result = newNimNode(nnkBracket) #newCall("&") let f = f.strVal diff --git a/examples/talk/quasiquote.nim b/examples/talk/quasiquote.nim index df4003e6e..b3c7bb971 100644 --- a/examples/talk/quasiquote.nim +++ b/examples/talk/quasiquote.nim @@ -1,7 +1,7 @@ import macros -macro check(ex: expr): stmt = +macro check(ex: untyped): typed = var info = ex.lineinfo var expString = ex.toStrLit result = quote do: diff --git a/examples/talk/tags.nim b/examples/talk/tags.nim index 12b9a08c3..8bf3450c9 100644 --- a/examples/talk/tags.nim +++ b/examples/talk/tags.nim @@ -1,8 +1,9 @@ -template htmlTag(tag: expr) {.immediate.} = +template htmlTag(tag: untyped) = proc tag(): string = "<" & astToStr(tag) & ">" htmlTag(br) htmlTag(html) echo br() +echo html() \ No newline at end of file diff --git a/koch.nim b/koch.nim index 6b267ce46..7bb7ea402 100644 --- a/koch.nim +++ b/koch.nim @@ -260,10 +260,10 @@ proc buildTools(latest: bool) = " nimsuggest/nimsuggest.nim" let nimgrepExe = "bin/nimgrep".exe - nimexec "c -o:" & nimgrepExe & " tools/nimgrep.nim" + nimexec "c -d:release -o:" & nimgrepExe & " tools/nimgrep.nim" when defined(windows): buildVccTool() - nimexec "c -o:" & ("bin/nimresolve".exe) & " tools/nimresolve.nim" + #nimexec "c -o:" & ("bin/nimresolve".exe) & " tools/nimresolve.nim" buildNimble(latest) @@ -441,7 +441,7 @@ template `|`(a, b): string = (if a.len > 0: a else: b) proc tests(args: string) = # we compile the tester with taintMode:on to have a basic # taint mode test :-) - nimexec "cc --taintMode:on tests/testament/tester" + nimexec "cc --taintMode:on --opt:speed tests/testament/tester" # Since tests take a long time (on my machine), and we want to defy Murhpys # law - lets make sure the compiler really is freshly compiled! nimexec "c --lib:lib -d:release --opt:speed compiler/nim.nim" @@ -472,7 +472,8 @@ proc temp(args: string) = # 125 is the magic number to tell git bisect to skip the current # commit. let (bootArgs, programArgs) = splitArgs(args) - exec("nim c " & bootArgs & " compiler" / "nim", 125) + let nimexec = findNim() + exec(nimexec & " c -d:debug " & bootArgs & " compiler" / "nim", 125) copyExe(output, finalDest) if programArgs.len > 0: exec(finalDest & " " & programArgs) @@ -481,7 +482,7 @@ proc xtemp(cmd: string) = copyExe(d / "bin" / "nim".exe, d / "bin" / "nim_backup".exe) try: withDir(d): - temp"-d:debug" + temp"" copyExe(d / "bin" / "nim_temp".exe, d / "bin" / "nim".exe) exec(cmd) finally: diff --git a/lib/core/allocators.nim b/lib/core/allocators.nim new file mode 100644 index 000000000..d6608a203 --- /dev/null +++ b/lib/core/allocators.nim @@ -0,0 +1,35 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +type + Allocator* {.inheritable.} = ptr object + alloc*: proc (a: Allocator; size: int; alignment = 8): pointer {.nimcall.} + dealloc*: proc (a: Allocator; p: pointer; size: int) {.nimcall.} + realloc*: proc (a: Allocator; p: pointer; oldSize, newSize: int): pointer {.nimcall.} + +var + currentAllocator {.threadvar.}: Allocator + +proc getCurrentAllocator*(): Allocator = + result = currentAllocator + +proc setCurrentAllocator*(a: Allocator) = + currentAllocator = a + +proc alloc*(size: int): pointer = + let a = getCurrentAllocator() + result = a.alloc(a, size) + +proc dealloc*(p: pointer; size: int) = + let a = getCurrentAllocator() + a.dealloc(a, size) + +proc realloc*(p: pointer; oldSize, newSize: int): pointer = + let a = getCurrentAllocator() + result = a.realloc(a, oldSize, newSize) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 8c70d2b47..b08a2198e 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -21,7 +21,7 @@ type nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit, nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit, nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit, - nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall, + nnkTripleStrLit, nnkNilLit, nnkComesFrom, nnkDotCall, nnkCommand, nnkCall, nnkCallStrLit, nnkInfix, nnkPrefix, nnkPostfix, nnkHiddenCallConv, nnkExprEqExpr, @@ -113,7 +113,9 @@ type type NimIdent* = object of RootObj - ## represents a Nim identifier in the AST + ## represents a Nim identifier in the AST. **Note**: This is only + ## rarely useful, for identifier construction from a string + ## use ``ident"abc"``. NimSymObj = object # hidden NimSym* = ref NimSymObj @@ -129,14 +131,11 @@ const nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand, nnkCallStrLit} -proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.} - ## get `n`'s `i`'th child. - -proc `[]=`*(n: NimNode, i: int, child: NimNode) {.magic: "NSetChild", - noSideEffect.} - ## set `n`'s `i`'th child to `child`. +proc `!`*(s: string): NimIdent {.magic: "StrToIdent", noSideEffect, deprecated.} + ## constructs an identifier from the string `s` + ## **Deprecated since version 0.18.0**: Use ``toNimIdent`` instead. -proc `!`*(s: string): NimIdent {.magic: "StrToIdent", noSideEffect.} +proc toNimIdent*(s: string): NimIdent {.magic: "StrToIdent", noSideEffect.} ## constructs an identifier from the string `s` proc `$`*(i: NimIdent): string {.magic: "IdentToStr", noSideEffect.} @@ -162,6 +161,20 @@ proc sameType*(a, b: NimNode): bool {.magic: "SameNodeType", noSideEffect.} = proc len*(n: NimNode): int {.magic: "NLen", noSideEffect.} ## returns the number of children of `n`. +proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.} + ## get `n`'s `i`'th child. + +proc `[]`*(n: NimNode, i: BackwardsIndex): NimNode = n[n.len - i.int] + ## get `n`'s `i`'th child. + +proc `[]=`*(n: NimNode, i: int, child: NimNode) {.magic: "NSetChild", + noSideEffect.} + ## set `n`'s `i`'th child to `child`. + +proc `[]=`*(n: NimNode, i: BackwardsIndex, child: NimNode) = + ## set `n`'s `i`'th child to `child`. + n[n.len - i.int] = child + proc add*(father, child: NimNode): NimNode {.magic: "NAdd", discardable, noSideEffect, locks: 0.} ## Adds the `child` to the `father` node. Returns the @@ -230,7 +243,7 @@ proc `ident=`*(n: NimNode, val: NimIdent) {.magic: "NSetIdent", noSideEffect.} proc `strVal=`*(n: NimNode, val: string) {.magic: "NSetStrVal", noSideEffect.} proc newNimNode*(kind: NimNodeKind, - lineInfoFrom: NimNode=nil): NimNode + lineInfoFrom: NimNode = nil): NimNode {.magic: "NNewNimNode", noSideEffect.} ## Creates a new AST node of the specified kind. ## @@ -283,7 +296,7 @@ proc newIdentNode*(i: NimIdent): NimNode {.compileTime.} = proc newIdentNode*(i: string): NimNode {.compileTime.} = ## creates an identifier node from `i` result = newNimNode(nnkIdent) - result.ident = !i + result.ident = toNimIdent i type @@ -393,7 +406,7 @@ proc quote*(bl: typed, op = "``"): NimNode {.magic: "QuoteAst", noSideEffect.} ## ## .. code-block:: nim ## - ## macro check(ex: expr): stmt = + ## macro check(ex: untyped): typed = ## # this is a simplified version of the check macro from the ## # unittest module. ## @@ -428,6 +441,13 @@ proc expectLen*(n: NimNode, len: int) {.compileTime.} = ## macros that check its number of arguments. if n.len != len: error("macro expects a node with " & $len & " children", n) +proc expectLen*(n: NimNode, min, max: int) {.compileTime.} = + ## checks that `n` has a number of children in the range ``min..max``. + ## If this is not the case, compilation aborts with an error message. + ## This is useful for writing macros that check its number of arguments. + if n.len < min or n.len > max: + error("macro expects a node with " & $min & ".." & $max " children", n) + proc newTree*(kind: NimNodeKind, children: varargs[NimNode]): NimNode {.compileTime.} = ## produces a new node with children. @@ -463,7 +483,6 @@ proc newLit*(c: char): NimNode {.compileTime.} = result = newNimNode(nnkCharLit) result.intVal = ord(c) - proc newLit*(i: int): NimNode {.compileTime.} = ## produces a new integer literal node. result = newNimNode(nnkIntLit) @@ -567,7 +586,7 @@ proc newLit*[T](arg: seq[T]): NimNode {.compileTime.} = proc newLit*(arg: tuple): NimNode {.compileTime.} = result = nnkPar.newTree for a,b in arg.fieldPairs: - result.add nnkExprColonExpr.newTree( newIdentNode(a), newLit(b) ) + result.add nnkExprColonExpr.newTree(newIdentNode(a), newLit(b)) proc newLit*(s: string): NimNode {.compileTime.} = ## produces a new string literal node. @@ -601,7 +620,7 @@ proc treeRepr*(n: NimNode): string {.compileTime, benign.} = of nnkCharLit..nnkInt64Lit: res.add(" " & $n.intVal) of nnkFloatLit..nnkFloat64Lit: res.add(" " & $n.floatVal) of nnkStrLit..nnkTripleStrLit: res.add(" " & $n.strVal) - of nnkIdent: res.add(" !\"" & $n.ident & '"') + of nnkIdent: res.add(" ident\"" & $n.ident & '"') of nnkSym: res.add(" \"" & $n.symbol & '"') of nnkNone: assert false else: @@ -626,7 +645,7 @@ proc lispRepr*(n: NimNode): string {.compileTime, benign.} = of nnkCharLit..nnkInt64Lit: add(result, $n.intVal) of nnkFloatLit..nnkFloat64Lit: add(result, $n.floatVal) of nnkStrLit..nnkTripleStrLit: add(result, $n.strVal) - of nnkIdent: add(result, "!\"" & $n.ident & '"') + of nnkIdent: add(result, "ident\"" & $n.ident & '"') of nnkSym: add(result, $n.symbol) of nnkNone: assert false else: @@ -650,7 +669,7 @@ proc astGenRepr*(n: NimNode): string {.compileTime, benign.} = ## .. code-block:: nim ## nnkStmtList.newTree( ## nnkCommand.newTree( - ## newIdentNode(!"echo"), + ## newIdentNode("echo"), ## newLit("Hello world") ## ) ## ) @@ -704,7 +723,7 @@ proc astGenRepr*(n: NimNode): string {.compileTime, benign.} = of nnkIntLit..nnkInt64Lit: res.add($n.intVal) of nnkFloatLit..nnkFloat64Lit: res.add($n.floatVal) of nnkStrLit..nnkTripleStrLit: res.add($n.strVal.escape()) - of nnkIdent: res.add("!" & ($n.ident).escape()) + of nnkIdent: res.add(($n.ident).escape()) of nnkSym: res.add(($n.symbol).escape()) of nnkNone: assert false else: @@ -839,7 +858,7 @@ proc newNilLit*(): NimNode {.compileTime.} = ## New nil literal shortcut result = newNimNode(nnkNilLit) -proc last*(node: NimNode): NimNode {.compileTime.} = node[<node.len] +proc last*(node: NimNode): NimNode {.compileTime.} = node[node.len-1] ## Return the last item in nodes children. Same as `node[^1]` @@ -884,10 +903,52 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]): for i in branches: result.add(newNimNode(nnkElifBranch).add(i.cond, i.body)) +proc newEnum*(name: NimNode, fields: openArray[NimNode], + public, pure: bool): NimNode {.compileTime.} = + + ## Creates a new enum. `name` must be an ident. Fields are allowed to be + ## either idents or EnumFieldDef + ## + ## .. code-block:: nim + ## + ## newEnum( + ## name = ident("Colors"), + ## fields = [ident("Blue"), ident("Red")], + ## public = true, pure = false) + ## + ## # type Colors* = Blue Red + ## + + expectKind name, nnkIdent + doAssert len(fields) > 0, "Enum must contain at least one field" + for field in fields: + expectKind field, {nnkIdent, nnkEnumFieldDef} + + let enumBody = newNimNode(nnkEnumTy).add(newEmptyNode()).add(fields) + var typeDefArgs = [name, newEmptyNode(), enumBody] + + if public: + let postNode = newNimNode(nnkPostfix).add( + newIdentNode("*"), typeDefArgs[0]) + + typeDefArgs[0] = postNode + + if pure: + let pragmaNode = newNimNode(nnkPragmaExpr).add( + typeDefArgs[0], + add(newNimNode(nnkPragma), newIdentNode("pure"))) + + typeDefArgs[0] = pragmaNode + + let + typeDef = add(newNimNode(nnkTypeDef), typeDefArgs) + typeSect = add(newNimNode(nnkTypeSection), typeDef) + + return typeSect proc copyChildrenTo*(src, dest: NimNode) {.compileTime.}= ## Copy all children from `src` to `dest` - for i in 0 .. < src.len: + for i in 0 ..< src.len: dest.add src[i].copyNimTree template expectRoutine(node: NimNode) = @@ -986,6 +1047,11 @@ iterator items*(n: NimNode): NimNode {.inline.} = for i in 0 ..< n.len: yield n[i] +iterator pairs*(n: NimNode): (int, NimNode) {.inline.} = + ## Iterates over the children of the NimNode ``n`` and its indices. + for i in 0 ..< n.len: + yield (i, n[i]) + iterator children*(n: NimNode): NimNode {.inline.} = ## Iterates over the children of the NimNode ``n``. for i in 0 ..< n.len: @@ -996,7 +1062,7 @@ template findChild*(n: NimNode; cond: untyped): NimNode {.dirty.} = ## ## .. code-block:: nim ## var res = findChild(n, it.kind == nnkPostfix and - ## it.basename.ident == !"foo") + ## it.basename.ident == toNimIdent"foo") block: var res: NimNode for it in n.children: @@ -1030,7 +1096,7 @@ proc basename*(a: NimNode): NimNode = proc `basename=`*(a: NimNode; val: string) {.compileTime.}= case a.kind - of nnkIdent: macros.`ident=`(a, !val) + of nnkIdent: macros.`ident=`(a, toNimIdent val) of nnkPostfix, nnkPrefix: a[1] = ident(val) else: quit "Do not know how to get basename of (" & treeRepr(a) & ")\n" & repr(a) @@ -1091,7 +1157,7 @@ proc eqIdent*(node: NimNode; s: string): bool {.compileTime.} = ## other ways like ``node.ident`` are much more error-prone, unfortunately. case node.kind of nnkIdent: - result = node.ident == !s + result = node.ident == toNimIdent s of nnkSym: result = eqIdent($node.symbol, s) of nnkOpenSymChoice, nnkClosedSymChoice: @@ -1099,10 +1165,10 @@ proc eqIdent*(node: NimNode; s: string): bool {.compileTime.} = else: result = false -proc hasArgOfName* (params: NimNode; name: string): bool {.compiletime.}= +proc hasArgOfName*(params: NimNode; name: string): bool {.compiletime.}= ## Search nnkFormalParams for an argument. assert params.kind == nnkFormalParams - for i in 1 .. <params.len: + for i in 1 ..< params.len: template node: untyped = params[i] if name.eqIdent( $ node[0]): return true @@ -1160,3 +1226,8 @@ when not defined(booting): macro payload: untyped {.gensym.} = result = parseStmt(e) payload() + +macro unpackVarargs*(callee: untyped; args: varargs[untyped]): untyped = + result = newCall(callee) + for i in 0 ..< args.len: + result.add args[i] diff --git a/lib/core/refs.nim b/lib/core/refs.nim new file mode 100644 index 000000000..e1575b68c --- /dev/null +++ b/lib/core/refs.nim @@ -0,0 +1,97 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Default ref implementation used by Nim's core. + +# We cannot use the allocator interface here as we require a heap walker to +# exist. Thus we import 'alloc' directly here to get our own heap that is +# all under the GC's control and can use the ``allObjects`` iterator which +# is crucial for the "sweep" phase. +import typelayouts, alloc + +type + TracingGc = ptr object of Allocator + visit*: proc (fieldAddr: ptr pointer; a: Allocator) {.nimcall.} + + GcColor = enum + white = 0, black = 1, grey = 2 ## to flip the meaning of white/black + ## perform (1 - col) + + GcHeader = object + t: ptr TypeLayout + color: GcColor + Cell = ptr GcHeader + + GcFrame {.core.} = object + prev: ptr GcFrame + marker: proc (self: GcFrame; a: Allocator) + + Phase = enum + None, Marking, Sweeping + + GcHeap = object + r: MemRegion + phase: Phase + currBlack, currWhite: GcColor + greyStack: seq[Cell] + +var + gch {.threadvar.}: GcHeap + +proc `=trace`[T](a: ref T) = + if not marked(a): + mark(a) + `=trace`(a[]) + +template usrToCell(p: pointer): Cell = + +template cellToUsr(cell: Cell): pointer = + cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(GcHeader))) + +template usrToCell(usr: pointer): Cell = + cast[Cell](cast[ByteAddress](usr)-%ByteAddress(sizeof(GcHeader))) + +template markGrey(x: Cell) = + if x.color == gch.currWhite and phase == Marking: + x.color = grey + add(gch.greyStack, x) + +proc `=`[T](dest: var ref T; src: ref T) = + ## full write barrier implementation. + if src != nil: + let s = usrToCell(src) + markGrey(s) + system.`=`(dest, src) + +proc linkGcFrame(f: ptr GcFrame) {.core.} +proc unlinkGcFrame() {.core.} + +proc setGcFrame(f: ptr GcFrame) {.core.} + +proc registerGlobal(p: pointer; t: ptr TypeLayout) {.core.} +proc unregisterGlobal(p: pointer; t: ptr TypeLayout) {.core.} + +proc registerThreadvar(p: pointer; t: ptr TypeLayout) {.core.} +proc unregisterThreadvar(p: pointer; t: ptr TypeLayout) {.core.} + +proc newImpl(t: ptr TypeLayout): pointer = + let r = cast[Cell](rawAlloc(t.size + sizeof(GcHeader))) + r.typ = t + result = r +! sizeof(GcHeader) + +template new*[T](x: var ref T) = + x = newImpl(getTypeLayout(x)) + + +when false: + # implement these if your GC requires them: + proc writeBarrierLocal() {.core.} + proc writeBarrierGlobal() {.core.} + + proc writeBarrierGeneric() {.core.} diff --git a/lib/core/seqs.nim b/lib/core/seqs.nim new file mode 100644 index 000000000..6be95a3bc --- /dev/null +++ b/lib/core/seqs.nim @@ -0,0 +1,117 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import allocators + +## Default seq implementation used by Nim's core. +type + seq*[T] = object + len, cap: int + data: ptr UncheckedArray[T] + +template frees(s) = dealloc(s.data, s.cap * sizeof(T)) + +# XXX make code memory safe for overflows in '*' +proc nimSeqLiteral[T](x: openArray[T]): seq[T] {.core.} = + seq[T](len: x.len, cap: x.len, data: x) + +when defined(nimHasTrace): + proc `=trace`[T](s: seq[T]; a: Allocator) = + for i in 0 ..< s.len: `=trace`(s.data[i], a) + +proc `=destroy`[T](x: var seq[T]) = + if x.data != nil: + when not supportsCopyMem(T): + for i in 0..<x.len: `=destroy`(x[i]) + frees(x) + x.data = nil + x.len = 0 + x.cap = 0 + +proc `=`[T](a: var seq[T]; b: seq[T]) = + if a.data == b.data: return + if a.data != nil: + frees(a) + a.data = nil + a.len = b.len + a.cap = b.cap + if b.data != nil: + a.data = cast[type(a.data)](alloc(a.cap * sizeof(T))) + when supportsCopyMem(T): + copyMem(a.data, b.data, a.cap * sizeof(T)) + else: + for i in 0..<a.len: + a.data[i] = b.data[i] + +proc `=sink`[T](a: var seq[T]; b: seq[T]) = + if a.data != nil and a.data != b.data: + frees(a) + a.len = b.len + a.cap = b.cap + a.data = b.data + +proc resize[T](s: var seq[T]) = + let old = s.cap + if old == 0: s.cap = 8 + else: s.cap = (s.cap * 3) shr 1 + s.data = cast[type(s.data)](realloc(s.data, old * sizeof(T), s.cap * sizeof(T))) + +proc reserveSlot[T](x: var seq[T]): ptr T = + if x.len >= x.cap: resize(x) + result = addr(x.data[x.len]) + inc x.len + +template add*[T](x: var seq[T]; y: T) = + reserveSlot(x)[] = y + +proc shrink*[T](x: var seq[T]; newLen: int) = + assert newLen <= x.len + assert newLen >= 0 + when not supportsCopyMem(T): + for i in countdown(x.len - 1, newLen - 1): + `=destroy`(x.data[i]) + x.len = newLen + +proc grow*[T](x: var seq[T]; newLen: int; value: T) = + if newLen <= x.len: return + assert newLen >= 0 + if x.cap == 0: x.cap = newLen + else: x.cap = max(newLen, (x.cap * 3) shr 1) + x.data = cast[type(x.data)](realloc(x.data, x.cap * sizeof(T))) + for i in x.len..<newLen: + x.data[i] = value + x.len = newLen + +template default[T](t: typedesc[T]): T = + var v: T + v + +proc setLen*[T](x: var seq[T]; newLen: int) {.deprecated.} = + if newlen < x.len: shrink(x, newLen) + else: grow(x, newLen, default(T)) + +template `[]`*[T](x: seq[T]; i: Natural): T = + assert i < x.len + x.data[i] + +template `[]=`*[T](x: seq[T]; i: Natural; y: T) = + assert i < x.len + x.data[i] = y + +proc `@`*[T](elems: openArray[T]): seq[T] = + result.cap = elems.len + result.len = elems.len + result.data = cast[type(result.data)](alloc(result.cap * sizeof(T))) + when supportsCopyMem(T): + copyMem(result.data, unsafeAddr(elems[0]), result.cap * sizeof(T)) + else: + for i in 0..<result.len: + result.data[i] = elems[i] + +proc len*[T](x: seq[T]): int {.inline.} = x.len diff --git a/lib/core/strs.nim b/lib/core/strs.nim new file mode 100644 index 000000000..1958f4974 --- /dev/null +++ b/lib/core/strs.nim @@ -0,0 +1,111 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Default string implementation used by Nim's core. + +import allocators + +type + string {.core.} = object + len, cap: int + data: ptr UncheckedArray[char] + +proc nimStringLiteral(x: cstring; len: int): string {.core.} = + string(len: len, cap: len, data: x) + +template frees(s) = dealloc(s.data, s.cap + 1) + +proc `=destroy`(s: var string) = + if s.data != nil: + frees(s) + s.data = nil + s.len = 0 + s.cap = 0 + +proc `=sink`(a: var string, b: string) = + # we hope this is optimized away for not yet alive objects: + if a.data != nil and a.data != b.data: + frees(a) + a.len = b.len + a.cap = b.cap + a.data = b.data + +proc `=`(a: var string; b: string) = + if a.data != nil and a.data != b.data: + frees(a) + a.data = nil + a.len = b.len + a.cap = b.cap + if b.data != nil: + a.data = cast[type(a.data)](alloc(a.cap + 1)) + copyMem(a.data, b.data, a.cap+1) + +proc resize(s: var string) = + let old = s.cap + if old == 0: s.cap = 8 + else: s.cap = (s.cap * 3) shr 1 + s.data = cast[type(s.data)](realloc(s.data, old + 1, s.cap + 1)) + +proc add*(s: var string; c: char) = + if s.len >= s.cap: resize(s) + s.data[s.len] = c + s.data[s.len+1] = '\0' + inc s.len + +proc ensure(s: var string; newLen: int) = + let old = s.cap + if newLen >= old: + s.cap = max((old * 3) shr 1, newLen) + if s.cap > 0: + s.data = cast[type(s.data)](realloc(s.data, old + 1, s.cap + 1)) + +proc add*(s: var string; y: string) = + if y.len != 0: + let newLen = s.len + y.len + ensure(s, newLen) + copyMem(addr s.data[len], y.data, y.data.len + 1) + s.len = newLen + +proc len*(s: string): int {.inline.} = s.len + +proc newString*(len: int): string = + result.len = len + result.cap = len + if len > 0: + result.data = alloc0(len+1) + +converter toCString(x: string): cstring {.core.} = + if x.len == 0: cstring"" else: cast[cstring](x.data) + +proc newStringOfCap*(cap: int): string = + result.len = 0 + result.cap = cap + if cap > 0: + result.data = alloc(cap+1) + +proc `&`*(a, b: string): string = + let sum = a.len + b.len + result = newStringOfCap(sum) + result.len = sum + copyMem(addr result.data[0], a.data, a.len) + copyMem(addr result.data[a.len], b.data, b.len) + if sum > 0: + result.data[sum] = '\0' + +proc concat(x: openArray[string]): string {.core.} = + ## used be the code generator to optimize 'x & y & z ...' + var sum = 0 + for i in 0 ..< x.len: inc(sum, x[i].len) + result = newStringOfCap(sum) + sum = 0 + for i in 0 ..< x.len: + let L = x[i].len + copyMem(addr result.data[sum], x[i].data, L) + inc(sum, L) + diff --git a/lib/core/typelayouts.nim b/lib/core/typelayouts.nim new file mode 100644 index 000000000..445ce77c4 --- /dev/null +++ b/lib/core/typelayouts.nim @@ -0,0 +1,19 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +type + TypeLayout* = object + size*, alignment*: int + destructor*: proc (self: pointer; a: Allocator) {.nimcall.} + trace*: proc (self: pointer; a: Allocator) {.nimcall.} + when false: + construct*: proc (self: pointer; a: Allocator) {.nimcall.} + copy*, deepcopy*, sink*: proc (self, other: pointer; a: Allocator) {.nimcall.} + +proc getTypeLayout(t: typedesc): ptr TypeLayout {.magic: "getTypeLayout".} diff --git a/lib/deprecated/pure/actors.nim b/lib/deprecated/pure/actors.nim index 36bd41e9e..17321cc0e 100644 --- a/lib/deprecated/pure/actors.nim +++ b/lib/deprecated/pure/actors.nim @@ -18,7 +18,7 @@ ## var ## a: ActorPool[int, void] ## createActorPool(a) -## for i in 0 .. < 300: +## for i in 0 ..< 300: ## a.spawn(i, proc (x: int) {.thread.} = echo x) ## a.join() ## @@ -133,7 +133,7 @@ proc createActorPool*[In, Out](a: var ActorPool[In, Out], poolSize = 4) = newSeq(a.actors, poolSize) when Out isnot void: open(a.outputs) - for i in 0 .. < a.actors.len: + for i in 0 ..< a.actors.len: a.actors[i] = spawn(poolWorker[In, Out]) proc sync*[In, Out](a: var ActorPool[In, Out], polling=50) = @@ -164,8 +164,8 @@ proc terminate*[In, Out](a: var ActorPool[In, Out]) = ## resources attached to `a`. var t: Task[In, Out] t.shutdown = true - for i in 0.. <a.actors.len: send(a.actors[i].i, t) - for i in 0.. <a.actors.len: join(a.actors[i]) + for i in 0..<a.actors.len: send(a.actors[i].i, t) + for i in 0..<a.actors.len: join(a.actors[i]) when Out isnot void: close(a.outputs) a.actors = nil @@ -227,7 +227,7 @@ when not defined(testing) and isMainModule: var a: ActorPool[int, void] createActorPool(a) - for i in 0 .. < 300: + for i in 0 ..< 300: a.spawn(i, proc (x: int) {.thread.} = echo x) when false: diff --git a/lib/deprecated/pure/rawsockets.nim b/lib/deprecated/pure/rawsockets.nim index ee77b232e..876334f9e 100644 --- a/lib/deprecated/pure/rawsockets.nim +++ b/lib/deprecated/pure/rawsockets.nim @@ -3,12 +3,12 @@ export nativesockets {.warning: "rawsockets module is deprecated, use nativesockets instead".} -template newRawSocket*(domain, sockType, protocol: cint): expr = +template newRawSocket*(domain, sockType, protocol: cint): untyped = {.warning: "newRawSocket is deprecated, use newNativeSocket instead".} newNativeSocket(domain, sockType, protocol) template newRawSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM, - protocol: Protocol = IPPROTO_TCP): expr = + protocol: Protocol = IPPROTO_TCP): untyped = {.warning: "newRawSocket is deprecated, use newNativeSocket instead".} newNativeSocket(domain, sockType, protocol) diff --git a/lib/deprecated/pure/sockets.nim b/lib/deprecated/pure/sockets.nim index 153db9ed8..f068c7d56 100644 --- a/lib/deprecated/pure/sockets.nim +++ b/lib/deprecated/pure/sockets.nim @@ -262,7 +262,7 @@ proc socket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, # TODO: Perhaps this should just raise EOS when an error occurs. when defined(Windows): - result = newTSocket(winlean.socket(ord(domain), ord(typ), ord(protocol)), buffered) + result = newTSocket(winlean.socket(cint(domain), cint(typ), cint(protocol)), buffered) else: result = newTSocket(posix.socket(toInt(domain), toInt(typ), toInt(protocol)), buffered) diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index a42950557..1459f0d7e 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -74,7 +74,7 @@ type ## converted to nil. InstantRow* = object ## a handle that can be res: PPGresult ## used to get a row's - line: int ## column text on demand + line: int ## column text on demand SqlPrepared* = distinct string ## a identifier for the prepared queries {.deprecated: [TRow: Row, TDbConn: DbConn, TSqlPrepared: SqlPrepared].} @@ -98,15 +98,18 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string = var a = 0 if args.len > 0 and not string(formatstr).contains("?"): dbError("""parameter substitution expects "?" """) - for c in items(string(formatstr)): - if c == '?': - if args[a] == nil: - add(result, "NULL") + if args.len == 0: + return string(formatstr) + else: + for c in items(string(formatstr)): + if c == '?': + if args[a] == nil: + add(result, "NULL") + else: + add(result, dbQuote(args[a])) + inc(a) else: - add(result, dbQuote(args[a])) - inc(a) - else: - add(result, c) + add(result, c) proc tryExec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): bool {.tags: [ReadDbEffect, WriteDbEffect].} = @@ -172,7 +175,7 @@ proc prepare*(db: DbConn; stmtName: string, query: SqlQuery; return SqlPrepared(stmtName) proc setRow(res: PPGresult, r: var Row, line, cols: int32) = - for col in 0..cols-1: + for col in 0'i32..cols-1: setLen(r[col], 0) let x = pqgetvalue(res, line, col) if x.isNil: @@ -188,7 +191,7 @@ iterator fastRows*(db: DbConn, query: SqlQuery, var res = setupQuery(db, query, args) var L = pqnfields(res) var result = newRow(L) - for i in 0..pqntuples(res)-1: + for i in 0'i32..pqntuples(res)-1: setRow(res, result, i, L) yield result pqclear(res) @@ -199,7 +202,7 @@ iterator fastRows*(db: DbConn, stmtName: SqlPrepared, var res = setupQuery(db, stmtName, args) var L = pqNfields(res) var result = newRow(L) - for i in 0..pqNtuples(res)-1: + for i in 0'i32..pqNtuples(res)-1: setRow(res, result, i, L) yield result pqClear(res) @@ -210,7 +213,7 @@ iterator instantRows*(db: DbConn, query: SqlQuery, ## same as fastRows but returns a handle that can be used to get column text ## on demand using []. Returned handle is valid only within iterator body. var res = setupQuery(db, query, args) - for i in 0..pqNtuples(res)-1: + for i in 0'i32..pqNtuples(res)-1: yield InstantRow(res: res, line: i) pqClear(res) @@ -220,7 +223,7 @@ iterator instantRows*(db: DbConn, stmtName: SqlPrepared, ## same as fastRows but returns a handle that can be used to get column text ## on demand using []. Returned handle is valid only within iterator body. var res = setupQuery(db, stmtName, args) - for i in 0..pqNtuples(res)-1: + for i in 0'i32..pqNtuples(res)-1: yield InstantRow(res: res, line: i) pqClear(res) @@ -237,7 +240,7 @@ proc getColumnType(res: PPGresult, col: int) : DbType = of 21: return DbType(kind: DbTypeKind.dbInt, name: "int2", size: 2) of 23: return DbType(kind: DbTypeKind.dbInt, name: "int4", size: 4) of 20: return DbType(kind: DbTypeKind.dbInt, name: "int8", size: 8) - of 1560: return DbType(kind: DbTypeKind.dbBit, name: "bit") + of 1560: return DbType(kind: DbTypeKind.dbBit, name: "bit") of 1562: return DbType(kind: DbTypeKind.dbInt, name: "varbit") of 18: return DbType(kind: DbTypeKind.dbFixedChar, name: "char") @@ -251,7 +254,7 @@ proc getColumnType(res: PPGresult, col: int) : DbType = of 700: return DbType(kind: DbTypeKind.dbFloat, name: "float4") of 701: return DbType(kind: DbTypeKind.dbFloat, name: "float8") - of 790: return DbType(kind: DbTypeKind.dbDecimal, name: "money") + of 790: return DbType(kind: DbTypeKind.dbDecimal, name: "money") of 1700: return DbType(kind: DbTypeKind.dbDecimal, name: "numeric") of 704: return DbType(kind: DbTypeKind.dbTimeInterval, name: "tinterval") @@ -274,12 +277,12 @@ proc getColumnType(res: PPGresult, col: int) : DbType = of 603: return DbType(kind: DbTypeKind.dbBox, name: "box") of 604: return DbType(kind: DbTypeKind.dbPolygon, name: "polygon") of 628: return DbType(kind: DbTypeKind.dbLine, name: "line") - of 718: return DbType(kind: DbTypeKind.dbCircle, name: "circle") + of 718: return DbType(kind: DbTypeKind.dbCircle, name: "circle") of 650: return DbType(kind: DbTypeKind.dbInet, name: "cidr") of 829: return DbType(kind: DbTypeKind.dbMacAddress, name: "macaddr") of 869: return DbType(kind: DbTypeKind.dbInet, name: "inet") - + of 2950: return DbType(kind: DbTypeKind.dbVarchar, name: "uuid") of 3614: return DbType(kind: DbTypeKind.dbVarchar, name: "tsvector") of 3615: return DbType(kind: DbTypeKind.dbVarchar, name: "tsquery") @@ -361,11 +364,11 @@ proc getColumnType(res: PPGresult, col: int) : DbType = proc setColumnInfo(columns: var DbColumns; res: PPGresult; L: int32) = setLen(columns, L) - for i in 0..<L: + for i in 0'i32..<L: columns[i].name = $pqfname(res, i) columns[i].typ = getColumnType(res, i) columns[i].tableName = $(pqftable(res, i)) ## Returns the OID of the table from which the given column was fetched. - ## Query the system table pg_class to determine exactly which table is referenced. + ## Query the system table pg_class to determine exactly which table is referenced. #columns[i].primaryKey = libpq does not have a function for that #columns[i].foreignKey = libpq does not have a function for that @@ -374,7 +377,7 @@ iterator instantRows*(db: DbConn; columns: var DbColumns; query: SqlQuery; {.tags: [ReadDbEffect].} = var res = setupQuery(db, query, args) setColumnInfo(columns, res, pqnfields(res)) - for i in 0..<pqntuples(res): + for i in 0'i32..<pqntuples(res): yield InstantRow(res: res, line: i) pqClear(res) diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 53dafdda7..21049571f 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -148,7 +148,7 @@ proc setupQuery(db: DbConn, query: SqlQuery, if prepare_v2(db, q, q.len.cint, result, nil) != SQLITE_OK: dbError(db) proc setRow(stmt: Pstmt, r: var Row, cols: cint) = - for col in 0..cols-1: + for col in 0'i32..cols-1: setLen(r[col], column_bytes(stmt, col)) # set capacity setLen(r[col], 0) let x = column_text(stmt, col) diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 4013182af..3d4afc0ae 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -155,7 +155,7 @@ type ## - ``"abc".match(re"(?<letter>\w)").captures["letter"] == "a"`` ## - ``"abc".match(re"(\w)\w").captures[-1] == "ab"`` ## - ## ``captureBounds[]: Option[Slice[int]]`` + ## ``captureBounds[]: Option[HSlice[int, int]]`` ## gets the bounds of the given capture according to the same rules as ## the above. If the capture is not filled, then ``None`` is returned. ## The bounds are both inclusive. @@ -167,7 +167,7 @@ type ## ``match: string`` ## the full text of the match. ## - ## ``matchBounds: Slice[int]`` + ## ``matchBounds: HSlice[int, int]`` ## the bounds of the match, as in ``captureBounds[]`` ## ## ``(captureBounds|captures).toTable`` @@ -182,9 +182,9 @@ type ## Not nil. str*: string ## The string that was matched against. ## Not nil. - pcreMatchBounds: seq[Slice[cint]] ## First item is the bounds of the match - ## Other items are the captures - ## `a` is inclusive start, `b` is exclusive end + pcreMatchBounds: seq[HSlice[cint, cint]] ## First item is the bounds of the match + ## Other items are the captures + ## `a` is inclusive start, `b` is exclusive end Captures* = distinct RegexMatch CaptureBounds* = distinct RegexMatch @@ -251,13 +251,13 @@ proc captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(p proc captures*(pattern: RegexMatch): Captures = return Captures(pattern) -proc `[]`*(pattern: CaptureBounds, i: int): Option[Slice[int]] = +proc `[]`*(pattern: CaptureBounds, i: int): Option[HSlice[int, int]] = let pattern = RegexMatch(pattern) if pattern.pcreMatchBounds[i + 1].a != -1: let bounds = pattern.pcreMatchBounds[i + 1] return some(int(bounds.a) .. int(bounds.b-1)) else: - return none(Slice[int]) + return none(HSlice[int, int]) proc `[]`*(pattern: Captures, i: int): string = let pattern = RegexMatch(pattern) @@ -272,10 +272,10 @@ proc `[]`*(pattern: Captures, i: int): string = proc match*(pattern: RegexMatch): string = return pattern.captures[-1] -proc matchBounds*(pattern: RegexMatch): Slice[int] = +proc matchBounds*(pattern: RegexMatch): HSlice[int, int] = return pattern.captureBounds[-1].get -proc `[]`*(pattern: CaptureBounds, name: string): Option[Slice[int]] = +proc `[]`*(pattern: CaptureBounds, name: string): Option[HSlice[int, int]] = let pattern = RegexMatch(pattern) return pattern.captureBounds[pattern.pattern.captureNameToId.fget(name)] @@ -295,13 +295,13 @@ proc toTable*(pattern: Captures, default: string = nil): Table[string, string] = result = initTable[string, string]() toTableImpl(nextVal == nil) -proc toTable*(pattern: CaptureBounds, default = none(Slice[int])): - Table[string, Option[Slice[int]]] = - result = initTable[string, Option[Slice[int]]]() +proc toTable*(pattern: CaptureBounds, default = none(HSlice[int, int])): + Table[string, Option[HSlice[int, int]]] = + result = initTable[string, Option[HSlice[int, int]]]() toTableImpl(nextVal.isNone) template itemsImpl(cond: untyped) {.dirty.} = - for i in 0 .. <RegexMatch(pattern).pattern.captureCount: + for i in 0 ..< RegexMatch(pattern).pattern.captureCount: let nextVal = pattern[i] # done in this roundabout way to avoid multiple yields (potential code # bloat) @@ -309,13 +309,13 @@ template itemsImpl(cond: untyped) {.dirty.} = yield nextYieldVal -iterator items*(pattern: CaptureBounds, default = none(Slice[int])): Option[Slice[int]] = +iterator items*(pattern: CaptureBounds, default = none(HSlice[int, int])): Option[HSlice[int, int]] = itemsImpl(nextVal.isNone) iterator items*(pattern: Captures, default: string = nil): string = itemsImpl(nextVal == nil) -proc toSeq*(pattern: CaptureBounds, default = none(Slice[int])): seq[Option[Slice[int]]] = +proc toSeq*(pattern: CaptureBounds, default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] = accumulateResult(pattern.items(default)) proc toSeq*(pattern: Captures, default: string = nil): seq[string] = @@ -396,8 +396,6 @@ proc extractOptions(pattern: string): tuple[pattern: string, flags: int, study: # }}} -type UncheckedArray {.unchecked.}[T] = array[0 .. 0, T] - proc destroyRegex(pattern: Regex) = pcre.free_substring(cast[cstring](pattern.pcreObj)) pattern.pcreObj = nil @@ -412,7 +410,7 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] = result = initTable[string, int]() - for i in 0 .. <entryCount: + for i in 0 ..< entryCount: let pos = i * entrySize let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1 var name = "" @@ -464,7 +462,7 @@ proc matchImpl(str: string, pattern: Regex, start, endpos: int, flags: int): Opt # 1x capture count as slack space for PCRE let vecsize = (pattern.captureCount() + 1) * 3 # div 2 because each element is 2 cints long - myResult.pcreMatchBounds = newSeq[Slice[cint]](ceil(vecsize / 2).int) + myResult.pcreMatchBounds = newSeq[HSlice[cint, cint]](ceil(vecsize / 2).int) myResult.pcreMatchBounds.setLen(vecsize div 3) let strlen = if endpos == int.high: str.len else: endpos+1 diff --git a/lib/impure/re.nim b/lib/impure/re.nim index e00f91de1..c7f8f336b 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -13,10 +13,6 @@ ## We had to de-deprecate this module since too much code relies on it ## and many people prefer its API over ``nre``'s. ## -## **Note:** The 're' proc defaults to the **extended regular expression -## syntax** which lets you use whitespace freely to make your regexes readable. -## However, this means matching whitespace requires ``\s`` or something similar. -## ## This module is implemented by providing a wrapper around the ## `PRCE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_ ## C library. This means that your application will depend on the PRCE @@ -53,9 +49,6 @@ type RegexError* = object of ValueError ## is raised if the pattern is no valid regular expression. -{.deprecated: [TRegexFlag: RegexFlag, TRegexDesc: RegexDesc, TRegex: Regex, - EInvalidRegEx: RegexError].} - proc raiseInvalidRegex(msg: string) {.noinline, noreturn.} = var e: ref RegexError new(e) @@ -78,7 +71,7 @@ proc finalizeRegEx(x: Regex) = if not isNil(x.e): pcre.free_substring(cast[cstring](x.e)) -proc re*(s: string, flags = {reExtended, reStudy}): Regex = +proc re*(s: string, flags = {reStudy}): Regex = ## Constructor of regular expressions. ## ## Note that Nim's @@ -96,6 +89,13 @@ proc re*(s: string, flags = {reExtended, reStudy}): Regex = result.e = pcre.study(result.h, options, addr msg) if not isNil(msg): raiseInvalidRegex($msg) +proc rex*(s: string, flags = {reStudy, reExtended}): Regex = + ## Constructor for extended regular expressions. + ## + ## The extended means that comments starting with `#` and + ## whitespace are ignored. + result = re(s, flags) + proc bufSubstr(b: cstring, sPos, ePos: int): string {.inline.} = ## Return a Nim string built from a slice of a cstring buffer. ## Don't assume cstring is '\0' terminated @@ -467,8 +467,8 @@ proc replacef*(s: string, sub: Regex, by: string): string = prev = match.last + 1 add(result, substr(s, prev)) -proc parallelReplace*(s: string, subs: openArray[ - tuple[pattern: Regex, repl: string]]): string = +proc multiReplace*(s: string, subs: openArray[ + tuple[pattern: Regex, repl: string]]): string = ## Returns a modified copy of ``s`` with the substitutions in ``subs`` ## applied in parallel. result = "" @@ -487,13 +487,20 @@ proc parallelReplace*(s: string, subs: openArray[ # copy the rest: add(result, substr(s, i)) +proc parallelReplace*(s: string, subs: openArray[ + tuple[pattern: Regex, repl: string]]): string {.deprecated.} = + ## Returns a modified copy of ``s`` with the substitutions in ``subs`` + ## applied in parallel. + ## **Deprecated since version 0.18.0**: Use ``multiReplace`` instead. + result = multiReplace(s, subs) + proc transformFile*(infile, outfile: string, subs: openArray[tuple[pattern: Regex, repl: string]]) = ## reads in the file ``infile``, performs a parallel replacement (calls ## ``parallelReplace``) and writes back to ``outfile``. Raises ``IOError`` if an ## error occurs. This is supposed to be used for quick scripting. var x = readFile(infile).string - writeFile(outfile, x.parallelReplace(subs)) + writeFile(outfile, x.multiReplace(subs)) iterator split*(s: string, sep: Regex): string = ## Splits the string ``s`` into substrings. @@ -576,12 +583,12 @@ const ## common regular expressions ## describes an URL when isMainModule: - doAssert match("(a b c)", re"\( .* \)") + doAssert match("(a b c)", rex"\( .* \)") doAssert match("WHiLe", re("while", {reIgnoreCase})) doAssert "0158787".match(re"\d+") doAssert "ABC 0232".match(re"\w+\s+\d+") - doAssert "ABC".match(re"\d+ | \w+") + doAssert "ABC".match(rex"\d+ | \w+") {.push warnings:off.} doAssert matchLen("key", re(reIdentifier)) == 3 diff --git a/lib/js/asyncjs.nim b/lib/js/asyncjs.nim new file mode 100644 index 000000000..ec410ee39 --- /dev/null +++ b/lib/js/asyncjs.nim @@ -0,0 +1,141 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim Authors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. + +## This module implements types and macros for writing asynchronous code +## for the JS backend. It provides tools for interaction with JavaScript async API-s +## and libraries, writing async procedures in Nim and converting callback-based code +## to promises. +## +## A Nim procedure is asynchronous when it includes the ``{.async.}`` pragma. It +## should always have a ``Future[T]`` return type or not have a return type at all. +## A ``Future[void]`` return type is assumed by default. +## +## This is roughly equivalent to the ``async`` keyword in JavaScript code. +## +## .. code-block:: nim +## proc loadGame(name: string): Future[Game] {.async.} = +## # code +## +## should be equivalent to +## +## .. code-block:: javascript +## async function loadGame(name) { +## // code +## } +## +## A call to an asynchronous procedure usually needs ``await`` to wait for +## the completion of the ``Future``. +## +## .. code-block:: nim +## var game = await loadGame(name) +## +## Often, you might work with callback-based API-s. You can wrap them with +## asynchronous procedures using promises and ``newPromise``: +## +## .. code-block:: nim +## proc loadGame(name: string): Future[Game] = +## var promise = newPromise() do (resolve: proc(response: Game)): +## cbBasedLoadGame(name) do (game: Game): +## resolve(game) +## return promise +## +## Forward definitions work properly, you just need to always add the ``{.async.}`` pragma: +## +## .. code-block:: nim +## proc loadGame(name: string): Future[Game] {.async.} +## +## JavaScript compatibility +## ~~~~~~~~~~~~~~~~~~~~~~~~~ +## +## Nim currently generates `async/await` JavaScript code which is supported in modern +## EcmaScript and most modern versions of browsers, Node.js and Electron. +## If you need to use this module with older versions of JavaScript, you can +## use a tool that backports the resulting JavaScript code, as babel. + +import jsffi +import macros + +when not defined(js) and not defined(nimdoc) and not defined(nimsuggest): + {.fatal: "Module asyncjs is designed to be used with the JavaScript backend.".} + +type + Future*[T] = ref object + future*: T + ## Wraps the return type of an asynchronous procedure. + + PromiseJs* {.importcpp: "Promise".} = ref object + ## A JavaScript Promise + +proc replaceReturn(node: var NimNode) = + var z = 0 + for s in node: + var son = node[z] + if son.kind == nnkReturnStmt: + node[z] = nnkReturnStmt.newTree(nnkCall.newTree(ident("jsResolve"), son[0])) + elif son.kind == nnkAsgn and son[0].kind == nnkIdent and $son[0] == "result": + node[z] = nnkAsgn.newTree(son[0], nnkCall.newTree(ident("jsResolve"), son[1])) + else: + replaceReturn(son) + inc z + +proc isFutureVoid(node: NimNode): bool = + result = node.kind == nnkBracketExpr and + node[0].kind == nnkIdent and $node[0] == "Future" and + node[1].kind == nnkIdent and $node[1] == "void" + +proc generateJsasync(arg: NimNode): NimNode = + assert arg.kind == nnkProcDef + result = arg + var isVoid = false + var jsResolveNode = ident("jsResolve") + + if arg.params[0].kind == nnkEmpty: + result.params[0] = nnkBracketExpr.newTree(ident("Future"), ident("void")) + isVoid = true + elif isFutureVoid(arg.params[0]): + isVoid = true + + var code = result.body + replaceReturn(code) + result.body = nnkStmtList.newTree() + + if len(code) > 0: + var awaitFunction = quote: + proc await[T](f: Future[T]): T {.importcpp: "(await #)".} + result.body.add(awaitFunction) + + var resolve: NimNode + if isVoid: + resolve = quote: + var `jsResolveNode` {.importcpp: "undefined".}: Future[void] + else: + resolve = quote: + proc jsResolve[T](a: T): Future[T] {.importcpp: "#".} + result.body.add(resolve) + else: + result.body = newEmptyNode() + for child in code: + result.body.add(child) + + if len(code) > 0 and isVoid: + var voidFix = quote: + return `jsResolveNode` + result.body.add(voidFix) + + result.pragma = quote: + {.codegenDecl: "async function $2($3)".} + + +macro async*(arg: untyped): untyped = + ## Macro which converts normal procedures into + ## javascript-compatible async procedures + generateJsasync(arg) + +proc newPromise*[T](handler: proc(resolve: proc(response: T))): Future[T] {.importcpp: "(new Promise(#))".} + ## A helper for wrapping callback-based functions + ## into promises and async procedures diff --git a/lib/js/dom.nim b/lib/js/dom.nim index cdefc772c..aa7f5d839 100644 --- a/lib/js/dom.nim +++ b/lib/js/dom.nim @@ -134,9 +134,9 @@ type # https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement HtmlElement* = ref object of Element - contentEditable*: string + contentEditable*: cstring isContentEditable*: bool - dir*: string + dir*: cstring offsetHeight*: int offsetWidth*: int offsetLeft*: int diff --git a/lib/js/jsffi.nim b/lib/js/jsffi.nim index 13eb1e759..f34efe9a2 100644 --- a/lib/js/jsffi.nim +++ b/lib/js/jsffi.nim @@ -177,7 +177,7 @@ proc `==`*(x, y: JsRoot): bool {. importcpp: "(# === #)" .} ## and not strings or numbers, this is a *comparison of references*. {. experimental .} -macro `.`*(obj: JsObject, field: static[cstring]): JsObject = +macro `.`*(obj: JsObject, field: untyped): JsObject = ## Experimental dot accessor (get) for type JsObject. ## Returns the value of a property of name `field` from a JsObject `x`. ## @@ -196,14 +196,14 @@ macro `.`*(obj: JsObject, field: static[cstring]): JsObject = helper(`obj`) else: if not mangledNames.hasKey($field): - mangledNames[$field] = $mangleJsName(field) + mangledNames[$field] = $mangleJsName($field) let importString = "#." & mangledNames[$field] result = quote do: proc helper(o: JsObject): JsObject {. importcpp: `importString`, gensym .} helper(`obj`) -macro `.=`*(obj: JsObject, field: static[cstring], value: untyped): untyped = +macro `.=`*(obj: JsObject, field, value: untyped): untyped = ## Experimental dot accessor (set) for type JsObject. ## Sets the value of a property of name `field` in a JsObject `x` to `value`. if validJsName($field): @@ -214,7 +214,7 @@ macro `.=`*(obj: JsObject, field: static[cstring], value: untyped): untyped = helper(`obj`, `value`) else: if not mangledNames.hasKey($field): - mangledNames[$field] = $mangleJsName(field) + mangledNames[$field] = $mangleJsName($field) let importString = "#." & mangledNames[$field] & " = #" result = quote do: proc helper(o: JsObject, v: auto) @@ -222,7 +222,7 @@ macro `.=`*(obj: JsObject, field: static[cstring], value: untyped): untyped = helper(`obj`, `value`) macro `.()`*(obj: JsObject, - field: static[cstring], + field: untyped, args: varargs[JsObject, jsFromAst]): JsObject = ## Experimental "method call" operator for type JsObject. ## Takes the name of a method of the JavaScript object (`field`) and calls @@ -245,7 +245,7 @@ macro `.()`*(obj: JsObject, importString = "#." & $field & "(@)" else: if not mangledNames.hasKey($field): - mangledNames[$field] = $mangleJsName(field) + mangledNames[$field] = $mangleJsName($field) importString = "#." & mangledNames[$field] & "(@)" result = quote: proc helper(o: JsObject): JsObject @@ -257,7 +257,7 @@ macro `.()`*(obj: JsObject, result[1].add args[idx].copyNimTree macro `.`*[K: string | cstring, V](obj: JsAssoc[K, V], - field: static[cstring]): V = + field: untyped): V = ## Experimental dot accessor (get) for type JsAssoc. ## Returns the value of a property of name `field` from a JsObject `x`. var importString: string @@ -265,7 +265,7 @@ macro `.`*[K: string | cstring, V](obj: JsAssoc[K, V], importString = "#." & $field else: if not mangledNames.hasKey($field): - mangledNames[$field] = $mangleJsName(field) + mangledNames[$field] = $mangleJsName($field) importString = "#." & mangledNames[$field] result = quote do: proc helper(o: type(`obj`)): `obj`.V @@ -273,7 +273,7 @@ macro `.`*[K: string | cstring, V](obj: JsAssoc[K, V], helper(`obj`) macro `.=`*[K: string | cstring, V](obj: JsAssoc[K, V], - field: static[cstring], + field: untyped, value: V): untyped = ## Experimental dot accessor (set) for type JsAssoc. ## Sets the value of a property of name `field` in a JsObject `x` to `value`. @@ -282,7 +282,7 @@ macro `.=`*[K: string | cstring, V](obj: JsAssoc[K, V], importString = "#." & $field & " = #" else: if not mangledNames.hasKey($field): - mangledNames[$field] = $mangleJsName(field) + mangledNames[$field] = $mangleJsName($field) importString = "#." & mangledNames[$field] & " = #" result = quote do: proc helper(o: type(`obj`), v: `obj`.V) @@ -290,7 +290,7 @@ macro `.=`*[K: string | cstring, V](obj: JsAssoc[K, V], helper(`obj`, `value`) macro `.()`*[K: string | cstring, V: proc](obj: JsAssoc[K, V], - field: static[cstring], + field: untyped, args: varargs[untyped]): auto = ## Experimental "method call" operator for type JsAssoc. ## Takes the name of a method of the JavaScript object (`field`) and calls diff --git a/lib/nimbase.h b/lib/nimbase.h index 34a2e43e7..31075bbd2 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -70,7 +70,7 @@ __clang__ #if defined(_MSC_VER) # pragma warning(disable: 4005 4100 4101 4189 4191 4200 4244 4293 4296 4309) # pragma warning(disable: 4310 4365 4456 4477 4514 4574 4611 4668 4702 4706) -# pragma warning(disable: 4710 4711 4774 4800 4820 4996 4090) +# pragma warning(disable: 4710 4711 4774 4800 4820 4996 4090 4297) #endif /* ------------------------------------------------------------------------- */ @@ -159,6 +159,7 @@ __clang__ /* ------------------------------------------------------------------- */ #if defined(WIN32) || defined(_WIN32) /* only Windows has this mess... */ +# define N_LIB_PRIVATE # define N_CDECL(rettype, name) rettype __cdecl name # define N_STDCALL(rettype, name) rettype __stdcall name # define N_SYSCALL(rettype, name) rettype __syscall name @@ -178,6 +179,7 @@ __clang__ # endif # define N_LIB_IMPORT extern __declspec(dllimport) #else +# define N_LIB_PRIVATE __attribute__((visibility("hidden"))) # if defined(__GNUC__) # define N_CDECL(rettype, name) rettype name # define N_STDCALL(rettype, name) rettype name @@ -396,15 +398,13 @@ typedef struct TStringDesc* string; #define GenericSeqSize sizeof(TGenericSeq) #define paramCount() cmdCount -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__i386__) -# ifndef NAN -static unsigned long nimNaN[2]={0xffffffff, 0x7fffffff}; -# define NAN (*(double*) nimNaN) -# endif -#endif - +// NAN definition copied from math.h included in the Windows SDK version 10.0.14393.0 #ifndef NAN -# define NAN (0.0 / 0.0) +# ifndef _HUGE_ENUF +# define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow +# endif +# define NAN_INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) +# define NAN ((float)(NAN_INFINITY * 0.0F)) #endif #ifndef INF @@ -482,7 +482,6 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); } On disagreement, your C compiler will say something like: "error: 'Nim_and_C_compiler_disagree_on_target_architecture' declared as an array with a negative size" */ typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1]; -#endif #ifdef __cplusplus # define NIM_EXTERNC extern "C" @@ -509,3 +508,5 @@ extern Libc::Env *genodeEnv; /* Compile with -d:checkAbi and a sufficiently C11:ish compiler to enable */ #define NIM_CHECK_SIZE(typ, sz) \ _Static_assert(sizeof(typ) == sz, "Nim & C disagree on type size") + +#endif /* NIMBASE_H */ diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index 1d396d9e0..2a58854a6 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -31,14 +31,12 @@ type state: TokenClass SourceLanguage* = enum - langNone, langNim, langNimrod, langCpp, langCsharp, langC, langJava, + langNone, langNim, langCpp, langCsharp, langC, langJava, langYaml -{.deprecated: [TSourceLanguage: SourceLanguage, TTokenClass: TokenClass, - TGeneralTokenizer: GeneralTokenizer].} const sourceLanguageToStr*: array[SourceLanguage, string] = ["none", - "Nim", "Nimrod", "C++", "C#", "C", "Java", "Yaml"] + "Nim", "C++", "C#", "C", "Java", "Yaml"] tokenClassToStr*: array[TokenClass, string] = ["Eof", "None", "Whitespace", "DecNumber", "BinNumber", "HexNumber", "OctNumber", "FloatNumber", "Identifier", "Keyword", "StringLit", "LongStringLit", "CharLit", @@ -49,12 +47,12 @@ const # The following list comes from doc/keywords.txt, make sure it is # synchronized with this array by running the module itself as a test case. - nimKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", + nimKeywords = ["addr", "and", "as", "asm", "bind", "block", "break", "case", "cast", "concept", "const", "continue", "converter", "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", "finally", "for", "from", "func", - "generic", "if", "import", "in", "include", + "if", "import", "in", "include", "interface", "is", "isnot", "iterator", "let", "macro", "method", "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "static", @@ -398,7 +396,6 @@ type TokenizerFlag = enum hasPreprocessor, hasNestedComments TokenizerFlags = set[TokenizerFlag] -{.deprecated: [TTokenizerFlag: TokenizerFlag, TTokenizerFlags: TokenizerFlags].} proc clikeNextToken(g: var GeneralTokenizer, keywords: openArray[string], flags: TokenizerFlags) = @@ -888,7 +885,7 @@ proc yamlNextToken(g: var GeneralTokenizer) = proc getNextToken*(g: var GeneralTokenizer, lang: SourceLanguage) = case lang of langNone: assert false - of langNim, langNimrod: nimNextToken(g) + of langNim: nimNextToken(g) of langCpp: cppNextToken(g) of langCsharp: csharpNextToken(g) of langC: cNextToken(g) @@ -901,12 +898,11 @@ when isMainModule: for filename in ["doc/keywords.txt", "../../../doc/keywords.txt"]: try: let input = string(readFile(filename)) - keywords = input.split() + keywords = input.splitWhitespace() break except: echo filename, " not found" doAssert(not keywords.isNil, "Couldn't read any keywords.txt file!") - doAssert keywords.len == nimKeywords.len, "No matching lengths" - for i in 0..keywords.len-1: - #echo keywords[i], " == ", nimKeywords[i] + for i in 0..min(keywords.len, nimKeywords.len)-1: doAssert keywords[i] == nimKeywords[i], "Unexpected keyword" + doAssert keywords.len == nimKeywords.len, "No matching lengths" diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 53699166f..223fc836a 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -45,8 +45,6 @@ type MsgHandler* = proc (filename: string, line, col: int, msgKind: MsgKind, arg: string) {.nimcall.} ## what to do in case of an error FindFileHandler* = proc (filename: string): string {.nimcall.} -{.deprecated: [TRstParseOptions: RstParseOptions, TRstParseOption: RstParseOption, - TMsgKind: MsgKind].} const messages: array[MsgKind, string] = [ @@ -127,8 +125,6 @@ type bufpos*: int line*, col*, baseIndent*: int skipPounds*: bool -{.deprecated: [TTokType: TokType, TToken: Token, TTokenSeq: TokenSeq, - TLexer: Lexer].} proc getThing(L: var Lexer, tok: var Token, s: set[char]) = tok.kind = tkWord @@ -288,10 +284,6 @@ type hasToc*: bool EParseError* = object of ValueError -{.deprecated: [TLevelMap: LevelMap, TSubstitution: Substitution, - TSharedState: SharedState, TRstParser: RstParser, - TMsgHandler: MsgHandler, TFindFileHandler: FindFileHandler, - TMsgClass: MsgClass].} proc whichMsgClass*(k: MsgKind): MsgClass = ## returns which message class `k` belongs to. @@ -341,11 +333,6 @@ proc rstMessage(p: RstParser, msgKind: MsgKind) = p.col + p.tok[p.idx].col, msgKind, p.tok[p.idx].symbol) -when false: - proc corrupt(p: RstParser) = - assert p.indentStack[0] == 0 - for i in 1 .. high(p.indentStack): assert p.indentStack[i] < 1_000 - proc currInd(p: RstParser): int = result = p.indentStack[high(p.indentStack)] diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 13016bfc0..e6c95b59e 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -46,7 +46,7 @@ type target*: OutputTarget config*: StringTableRef splitAfter*: int # split too long entries in the TOC - listingCounter: int + listingCounter*: int tocPart*: seq[TocEntry] hasToc*: bool theIndex: string # Contents of the index file to be dumped at the end. @@ -61,6 +61,9 @@ type seenIndexTerms: Table[string, int] ## \ ## Keeps count of same text index terms to generate different identifiers ## for hyperlinks. See renderIndexTerm proc for details. + id*: int ## A counter useful for generating IDs. + onTestSnippet*: proc (d: var RstGenerator; filename, cmd: string; status: int; + content: string) PDoc = var RstGenerator ## Alias to type less. @@ -69,8 +72,9 @@ type startLine: int ## The starting line of the code block, by default 1. langStr: string ## Input string used to specify the language. lang: SourceLanguage ## Type of highlighting, by default none. -{.deprecated: [TRstGenerator: RstGenerator, TTocEntry: TocEntry, - TOutputTarget: OutputTarget, TMetaEnum: MetaEnum].} + filename: string + testCmd: string + status: int proc init(p: var CodeBlockParams) = ## Default initialisation of CodeBlockParams to sane values. @@ -133,6 +137,7 @@ proc initRstGenerator*(g: var RstGenerator, target: OutputTarget, g.options = options g.findFile = findFile g.currentSection = "" + g.id = 0 let fileParts = filename.splitFile if fileParts.ext == ".nim": g.currentSection = "Module " & fileParts.name @@ -368,7 +373,6 @@ type ## ## The value indexed by this IndexEntry is a sequence with the real index ## entries found in the ``.idx`` file. -{.deprecated: [TIndexEntry: IndexEntry, TIndexedDocs: IndexedDocs].} proc cmp(a, b: IndexEntry): int = ## Sorts two ``IndexEntry`` first by `keyword` field, then by `link`. @@ -798,7 +802,8 @@ proc renderImage(d: PDoc, n: PRstNode, result: var string) = if arg.valid: let htmlOut = if isObject: "<object data=\"$1\" type=\"image/svg+xml\"$2 >" & content & "</object>" - else: "<img src=\"$1\"$2 />" + else: + "<img src=\"$1\"$2 />" dispA(d.target, result, htmlOut, "\\includegraphics$2{$1}", [arg, options]) if len(n) >= 3: renderRstToOut(d, n.sons[2], result) @@ -822,13 +827,20 @@ proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) = var number: int if parseInt(n.getFieldValue, number) > 0: params.startLine = number - of "file": + of "file", "filename": # The ``file`` option is a Nim extension to the official spec, it acts # like it would for other directives like ``raw`` or ``cvs-table``. This # field is dealt with in ``rst.nim`` which replaces the existing block with # the referenced file, so we only need to ignore it here to avoid incorrect # warning messages. - discard + params.filename = n.getFieldValue.strip + of "test": + params.testCmd = n.getFieldValue.strip + if params.testCmd.len == 0: params.testCmd = "nim c -r $1" + of "status": + var status: int + if parseInt(n.getFieldValue, status) > 0: + params.status = status of "default-language": params.langStr = n.getFieldValue.strip params.lang = params.langStr.getSourceLanguage @@ -866,7 +878,7 @@ proc buildLinesHTMLTable(d: PDoc; params: CodeBlockParams, code: string): inc d.listingCounter let id = $d.listingCounter if not params.numberLines: - result = (d.config.getOrDefault"doc.listing_start" % id, + result = (d.config.getOrDefault"doc.listing_start" % [id, $params.lang], d.config.getOrDefault"doc.listing_end" % id) return @@ -879,7 +891,7 @@ proc buildLinesHTMLTable(d: PDoc; params: CodeBlockParams, code: string): line.inc codeLines.dec result.beginTable.add("</pre></td><td>" & ( - d.config.getOrDefault"doc.listing_start" % id)) + d.config.getOrDefault"doc.listing_start" % [id, $params.lang])) result.endTable = (d.config.getOrDefault"doc.listing_end" % id) & "</td></tr></tbody></table>" & ( d.config.getOrDefault"doc.listing_button" % id) @@ -900,6 +912,9 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) = var m = n.sons[2].sons[0] assert m.kind == rnLeaf + if params.testCmd.len > 0 and d.onTestSnippet != nil: + d.onTestSnippet(d, params.filename, params.testCmd, params.status, m.text) + let (blockStart, blockEnd) = buildLinesHTMLTable(d, params, m.text) dispA(d.target, result, blockStart, "\\begin{rstpre}\n", []) diff --git a/lib/posix/epoll.nim b/lib/posix/epoll.nim index 86b977576..c5ed1a873 100644 --- a/lib/posix/epoll.nim +++ b/lib/posix/epoll.nim @@ -35,18 +35,13 @@ const EPOLL_CTL_MOD* = 3 # Change file descriptor epoll_event structure. type - epoll_data* {.importc: "union epoll_data", + EpollData* {.importc: "union epoll_data", header: "<sys/epoll.h>", pure, final.} = object # TODO: This is actually a union. - #thePtr* {.importc: "ptr".}: pointer - fd* {.importc: "fd".}: cint - when defined(linux) and defined(amd64): - u32: uint32 # this field ensures that binary size is right - it cannot be - # used because its offset is wrong - #u64*: uint64 + u64* {.importc: "u64".}: uint64 - epoll_event* {.importc: "struct epoll_event", header: "<sys/epoll.h>", pure, final.} = object + EpollEvent* {.importc: "struct epoll_event", header: "<sys/epoll.h>", pure, final.} = object events*: uint32 # Epoll events - data*: epoll_data # User data variable + data*: EpollData # User data variable proc epoll_create*(size: cint): cint {.importc: "epoll_create", header: "<sys/epoll.h>".} @@ -60,7 +55,7 @@ proc epoll_create1*(flags: cint): cint {.importc: "epoll_create1", ## Same as epoll_create but with an FLAGS parameter. The unused SIZE ## parameter has been dropped. -proc epoll_ctl*(epfd: cint; op: cint; fd: cint | SocketHandle; event: ptr epoll_event): cint {. +proc epoll_ctl*(epfd: cint; op: cint; fd: cint | SocketHandle; event: ptr EpollEvent): cint {. importc: "epoll_ctl", header: "<sys/epoll.h>".} ## Manipulate an epoll instance "epfd". Returns 0 in case of success, ## -1 in case of error ( the "errno" variable will contain the @@ -69,7 +64,7 @@ proc epoll_ctl*(epfd: cint; op: cint; fd: cint | SocketHandle; event: ptr epoll_ ## operation. The "event" parameter describes which events the caller ## is interested in and any associated user data. -proc epoll_wait*(epfd: cint; events: ptr epoll_event; maxevents: cint; +proc epoll_wait*(epfd: cint; events: ptr EpollEvent; maxevents: cint; timeout: cint): cint {.importc: "epoll_wait", header: "<sys/epoll.h>".} ## Wait for events on an epoll instance "epfd". Returns the number of @@ -84,7 +79,7 @@ proc epoll_wait*(epfd: cint; events: ptr epoll_event; maxevents: cint; ## __THROW. -#proc epoll_pwait*(epfd: cint; events: ptr epoll_event; maxevents: cint; +#proc epoll_pwait*(epfd: cint; events: ptr EpollEvent; maxevents: cint; # timeout: cint; ss: ptr sigset_t): cint {. # importc: "epoll_pwait", header: "<sys/epoll.h>".} # Same as epoll_wait, but the thread's signal mask is temporarily diff --git a/lib/posix/linux.nim b/lib/posix/linux.nim index 01d5e57de..8786ab535 100644 --- a/lib/posix/linux.nim +++ b/lib/posix/linux.nim @@ -26,3 +26,5 @@ const proc clone*(fn: pointer; child_stack: pointer; flags: cint; arg: pointer; ptid: ptr Pid; tls: pointer; ctid: ptr Pid): cint {.importc, header: "<sched.h>".} + +proc pipe2*(a: array[0..1, cint], flags: cint): cint {.importc, header: "<unistd.h>".} \ No newline at end of file diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index b635c0b0b..fba35868c 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -609,11 +609,12 @@ proc clock_nanosleep*(a1: ClockId, a2: cint, a3: var Timespec, proc clock_settime*(a1: ClockId, a2: var Timespec): cint {. importc, header: "<time.h>".} +proc `==`*(a, b: Time): bool {.borrow.} +proc `-`*(a, b: Time): Time {.borrow.} proc ctime*(a1: var Time): cstring {.importc, header: "<time.h>".} proc ctime_r*(a1: var Time, a2: cstring): cstring {.importc, header: "<time.h>".} proc difftime*(a1, a2: Time): cdouble {.importc, header: "<time.h>".} proc getdate*(a1: cstring): ptr Tm {.importc, header: "<time.h>".} - proc gmtime*(a1: var Time): ptr Tm {.importc, header: "<time.h>".} proc gmtime_r*(a1: var Time, a2: var Tm): ptr Tm {.importc, header: "<time.h>".} proc localtime*(a1: var Time): ptr Tm {.importc, header: "<time.h>".} diff --git a/lib/posix/posix_linux_amd64.nim b/lib/posix/posix_linux_amd64.nim index c44128b16..9e6211b63 100644 --- a/lib/posix/posix_linux_amd64.nim +++ b/lib/posix/posix_linux_amd64.nim @@ -12,8 +12,6 @@ # To be included from posix.nim! -from times import Time - const hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays hasAioH = defined(linux) @@ -40,13 +38,15 @@ type const SIG_HOLD* = cast[SigHandler](2) type + Time* {.importc: "time_t", header: "<time.h>".} = distinct clong + Timespec* {.importc: "struct timespec", header: "<time.h>", final, pure.} = object ## struct timespec tv_sec*: Time ## Seconds. tv_nsec*: clong ## Nanoseconds. Dirent* {.importc: "struct dirent", - header: "<dirent.h>", final, pure.} = object ## dirent_t struct + header: "<dirent.h>", final, pure.} = object ## dirent_t struct d_ino*: Ino d_off*: Off d_reclen*: cushort diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index 7321889a8..01bc1c1e5 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -9,8 +9,6 @@ {.deadCodeElim:on.} -from times import Time - const hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays hasAioH = defined(linux) @@ -36,6 +34,8 @@ type {.deprecated: [TSocketHandle: SocketHandle].} type + Time* {.importc: "time_t", header: "<time.h>".} = distinct clong + Timespec* {.importc: "struct timespec", header: "<time.h>", final, pure.} = object ## struct timespec tv_sec*: Time ## Seconds. @@ -209,24 +209,24 @@ type st_gid*: Gid ## Group ID of file. st_rdev*: Dev ## Device ID (if file is character or block special). st_size*: Off ## For regular files, the file size in bytes. - ## For symbolic links, the length in bytes of the - ## pathname contained in the symbolic link. - ## For a shared memory object, the length in bytes. - ## For a typed memory object, the length in bytes. - ## For other file types, the use of this field is - ## unspecified. + ## For symbolic links, the length in bytes of the + ## pathname contained in the symbolic link. + ## For a shared memory object, the length in bytes. + ## For a typed memory object, the length in bytes. + ## For other file types, the use of this field is + ## unspecified. when defined(macosx) or defined(android): - st_atime*: Time ## Time of last access. - st_mtime*: Time ## Time of last data modification. - st_ctime*: Time ## Time of last status change. + st_atime*: Time ## Time of last access. + st_mtime*: Time ## Time of last data modification. + st_ctime*: Time ## Time of last status change. else: - st_atim*: Timespec ## Time of last access. - st_mtim*: Timespec ## Time of last data modification. - st_ctim*: Timespec ## Time of last status change. - st_blksize*: Blksize ## A file system-specific preferred I/O block size - ## for this object. In some file system types, this - ## may vary from file to file. - st_blocks*: Blkcnt ## Number of blocks allocated for this object. + st_atim*: Timespec ## Time of last access. + st_mtim*: Timespec ## Time of last data modification. + st_ctim*: Timespec ## Time of last status change. + st_blksize*: Blksize ## A file system-specific preferred I/O block size + ## for this object. In some file system types, this + ## may vary from file to file. + st_blocks*: Blkcnt ## Number of blocks allocated for this object. Statvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>", diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 9eee04404..fdf2d7cbb 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -371,3 +371,126 @@ when isMainModule: for i in 0 .. high(arr1): assert arr1.reversed(0, i) == arr1.reversed()[high(arr1) - i .. high(arr1)] assert arr1.reversed(i, high(arr1)) == arr1.reversed()[0 .. high(arr1) - i] + + +proc rotateInternal[T](arg: var openarray[T]; first, middle, last: int): int = + ## A port of std::rotate from c++. Ported from `this reference <http://www.cplusplus.com/reference/algorithm/rotate/>`_. + result = first + last - middle + + if first == middle or middle == last: + return + + assert first < middle + assert middle < last + + # m prefix for mutable + var + mFirst = first + mMiddle = middle + next = middle + + swap(arg[mFirst], arg[next]) + mFirst += 1 + next += 1 + if mFirst == mMiddle: + mMiddle = next + + while next != last: + swap(arg[mFirst], arg[next]) + mFirst += 1 + next += 1 + if mFirst == mMiddle: + mMiddle = next + + next = mMiddle + while next != last: + swap(arg[mFirst], arg[next]) + mFirst += 1 + next += 1 + if mFirst == mMiddle: + mMiddle = next + elif next == last: + next = mMiddle + +proc rotatedInternal[T](arg: openarray[T]; first, middle, last: int): seq[T] = + result = newSeq[T](arg.len) + for i in 0 ..< first: + result[i] = arg[i] + let N = last - middle + let M = middle - first + for i in 0 ..< N: + result[first+i] = arg[middle+i] + for i in 0 ..< M: + result[first+N+i] = arg[first+i] + for i in last ..< arg.len: + result[i] = arg[i] + +proc rotateLeft*[T](arg: var openarray[T]; slice: HSlice[int, int]; dist: int): int = + ## Performs a left rotation on a range of elements. If you want to rotate right, use a negative ``dist``. + ## Specifically, ``rotateLeft`` rotates the elements at ``slice`` by ``dist`` positions. + ## The element at index ``slice.a + dist`` will be at index ``slice.a``. + ## The element at index ``slice.b`` will be at ``slice.a + dist -1``. + ## The element at index ``slice.a`` will be at ``slice.b + 1 - dist``. + ## The element at index ``slice.a + dist - 1`` will be at ``slice.b``. + # + ## Elements outsize of ``slice`` will be left unchanged. + ## The time complexity is linear to ``slice.b - slice.a + 1``. + ## + ## ``slice`` + ## the indices of the element range that should be rotated. + ## + ## ``dist`` + ## the distance in amount of elements that the data should be rotated. Can be negative, can be any number. + ## + ## .. code-block:: nim + ## var list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ## list.rotateLeft(1 .. 8, 3) + ## doAssert list == [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10] + let sliceLen = slice.b + 1 - slice.a + let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen + arg.rotateInternal(slice.a, slice.a+distLeft, slice.b + 1) + +proc rotateLeft*[T](arg: var openarray[T]; dist: int): int = + ## default arguments for slice, so that this procedure operates on the entire + ## ``arg``, and not just on a part of it. + let arglen = arg.len + let distLeft = ((dist mod arglen) + arglen) mod arglen + arg.rotateInternal(0, distLeft, arglen) + +proc rotatedLeft*[T](arg: openarray[T]; slice: HSlice[int, int], dist: int): seq[T] = + ## same as ``rotateLeft``, just with the difference that it does + ## not modify the argument. It creates a new ``seq`` instead + let sliceLen = slice.b + 1 - slice.a + let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen + arg.rotatedInternal(slice.a, slice.a+distLeft, slice.b+1) + +proc rotatedLeft*[T](arg: openarray[T]; dist: int): seq[T] = + ## same as ``rotateLeft``, just with the difference that it does + ## not modify the argument. It creates a new ``seq`` instead + let arglen = arg.len + let distLeft = ((dist mod arglen) + arglen) mod arglen + arg.rotatedInternal(0, distLeft, arg.len) + +when isMainModule: + var list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + let list2 = list.rotatedLeft(1 ..< 9, 3) + let expected = [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10] + + doAssert list.rotateLeft(1 ..< 9, 3) == 6 + doAssert list == expected + doAssert list2 == @expected + + var s0,s1,s2,s3,s4,s5 = "xxxabcdefgxxx" + + doAssert s0.rotateLeft(3 ..< 10, 3) == 7 + doAssert s0 == "xxxdefgabcxxx" + doAssert s1.rotateLeft(3 ..< 10, 2) == 8 + doAssert s1 == "xxxcdefgabxxx" + doAssert s2.rotateLeft(3 ..< 10, 4) == 6 + doAssert s2 == "xxxefgabcdxxx" + doAssert s3.rotateLeft(3 ..< 10, -3) == 6 + doAssert s3 == "xxxefgabcdxxx" + doAssert s4.rotateLeft(3 ..< 10, -10) == 6 + doAssert s4 == "xxxefgabcdxxx" + doAssert s5.rotateLeft(3 ..< 10, 11) == 6 + doAssert s5 == "xxxefgabcdxxx" diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 281d5b848..42ffa236c 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -9,8 +9,9 @@ include "system/inclrtl" -import os, tables, strutils, times, heapqueue, options, asyncstreams +import os, tables, strutils, times, heapqueue, lists, options, asyncstreams import asyncfutures except callSoon + import nativesockets, net, deques export Port, SocketFlag @@ -58,9 +59,10 @@ export asyncfutures, asyncstreams ## ## .. code-block::nim ## var future = socket.recv(100) -## future.callback = +## future.addCallback( ## proc () = ## echo(future.read) +## ) ## ## All asynchronous functions returning a ``Future`` will not block. They ## will not however return immediately. An asynchronous function will have @@ -136,6 +138,7 @@ export asyncfutures, asyncstreams ## and occasionally the compilation may fail altogether. ## As such it is better to use the former style when possible. ## +## ## Discarding futures ## ------------------ ## @@ -165,18 +168,20 @@ type timers*: HeapQueue[tuple[finishAt: float, fut: Future[void]]] callbacks*: Deque[proc ()] -proc processTimers(p: PDispatcherBase) {.inline.} = +proc processTimers(p: PDispatcherBase; didSomeWork: var bool) {.inline.} = #Process just part if timers at a step var count = p.timers.len let t = epochTime() while count > 0 and t >= p.timers[0].finishAt: p.timers.pop().fut.complete() dec count + didSomeWork = true -proc processPendingCallbacks(p: PDispatcherBase) = +proc processPendingCallbacks(p: PDispatcherBase; didSomeWork: var bool) = while p.callbacks.len > 0: var cb = p.callbacks.popFirst() cb() + didSomeWork = true proc adjustedTimeout(p: PDispatcherBase, timeout: int): int {.inline.} = # If dispatcher has active timers this proc returns the timeout @@ -226,6 +231,12 @@ when defined(windows) or defined(nimdoc): ovl: PCustomOverlapped PostCallbackDataPtr = ptr PostCallbackData + AsyncEventImpl = object + hEvent: Handle + hWaiter: Handle + pcd: PostCallbackDataPtr + AsyncEvent* = ptr AsyncEventImpl + Callback = proc (fd: AsyncFD): bool {.closure,gcsafe.} {.deprecated: [TCompletionKey: CompletionKey, TAsyncFD: AsyncFD, TCustomOverlapped: CustomOverlapped, TCompletionData: CompletionData].} @@ -275,14 +286,13 @@ when defined(windows) or defined(nimdoc): let p = getGlobalDispatcher() p.handles.len != 0 or p.timers.len != 0 or p.callbacks.len != 0 - proc poll*(timeout = 500) = - ## Waits for completion events and processes them. Raises ``ValueError`` - ## if there are no pending operations. + proc runOnce(timeout = 500): bool = let p = getGlobalDispatcher() if p.handles.len == 0 and p.timers.len == 0 and p.callbacks.len == 0: raise newException(ValueError, "No handles or timers registered in dispatcher.") + result = false if p.handles.len != 0: let at = p.adjustedTimeout(timeout) var llTimeout = @@ -295,6 +305,7 @@ when defined(windows) or defined(nimdoc): let res = getQueuedCompletionStatus(p.ioPort, addr lpNumberOfBytesTransferred, addr lpCompletionKey, cast[ptr POVERLAPPED](addr customOverlapped), llTimeout).bool + result = true # http://stackoverflow.com/a/12277264/492186 # TODO: http://www.serverframework.com/handling-multiple-pending-socket-read-and-write-operations.html @@ -324,17 +335,18 @@ when defined(windows) or defined(nimdoc): else: if errCode.int32 == WAIT_TIMEOUT: # Timed out - discard + result = false else: raiseOSError(errCode) # Timer processing. - processTimers(p) + processTimers(p, result) # Callback queue processing - processPendingCallbacks(p) + processPendingCallbacks(p, result) + - var connectExPtr: pointer = nil - var acceptExPtr: pointer = nil - var getAcceptExSockAddrsPtr: pointer = nil + var acceptEx: WSAPROC_ACCEPTEX + var connectEx: WSAPROC_CONNECTEX + var getAcceptExSockAddrs: WSAPROC_GETACCEPTEXSOCKADDRS proc initPointer(s: SocketHandle, fun: var pointer, guid: var GUID): bool = # Ref: https://github.com/powdahound/twisted/blob/master/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c @@ -346,56 +358,19 @@ when defined(windows) or defined(nimdoc): proc initAll() = let dummySock = newNativeSocket() - if not initPointer(dummySock, connectExPtr, WSAID_CONNECTEX): + if dummySock == INVALID_SOCKET: raiseOSError(osLastError()) - if not initPointer(dummySock, acceptExPtr, WSAID_ACCEPTEX): + var fun: pointer = nil + if not initPointer(dummySock, fun, WSAID_CONNECTEX): raiseOSError(osLastError()) - if not initPointer(dummySock, getAcceptExSockAddrsPtr, WSAID_GETACCEPTEXSOCKADDRS): + connectEx = cast[WSAPROC_CONNECTEX](fun) + if not initPointer(dummySock, fun, WSAID_ACCEPTEX): raiseOSError(osLastError()) - - proc connectEx(s: SocketHandle, name: ptr SockAddr, namelen: cint, - lpSendBuffer: pointer, dwSendDataLength: Dword, - lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool = - if connectExPtr.isNil: raise newException(ValueError, "Need to initialise ConnectEx().") - let fun = - cast[proc (s: SocketHandle, name: ptr SockAddr, namelen: cint, - lpSendBuffer: pointer, dwSendDataLength: Dword, - lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](connectExPtr) - - result = fun(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, - lpOverlapped) - - proc acceptEx(listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, - dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: Dword, lpdwBytesReceived: PDword, - lpOverlapped: POVERLAPPED): bool = - if acceptExPtr.isNil: raise newException(ValueError, "Need to initialise AcceptEx().") - let fun = - cast[proc (listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, - dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: Dword, lpdwBytesReceived: PDword, - lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](acceptExPtr) - result = fun(listenSock, acceptSock, lpOutputBuffer, dwReceiveDataLength, - dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived, - lpOverlapped) - - proc getAcceptExSockaddrs(lpOutputBuffer: pointer, - dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: Dword, - LocalSockaddr: ptr ptr SockAddr, LocalSockaddrLength: LPInt, - RemoteSockaddr: ptr ptr SockAddr, RemoteSockaddrLength: LPInt) = - if getAcceptExSockAddrsPtr.isNil: - raise newException(ValueError, "Need to initialise getAcceptExSockAddrs().") - - let fun = - cast[proc (lpOutputBuffer: pointer, - dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: Dword, LocalSockaddr: ptr ptr SockAddr, - LocalSockaddrLength: LPInt, RemoteSockaddr: ptr ptr SockAddr, - RemoteSockaddrLength: LPInt) {.stdcall,gcsafe.}](getAcceptExSockAddrsPtr) - - fun(lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength, LocalSockaddr, LocalSockaddrLength, - RemoteSockaddr, RemoteSockaddrLength) + acceptEx = cast[WSAPROC_ACCEPTEX](fun) + if not initPointer(dummySock, fun, WSAID_GETACCEPTEXSOCKADDRS): + raiseOSError(osLastError()) + getAcceptExSockAddrs = cast[WSAPROC_GETACCEPTEXSOCKADDRS](fun) + close(dummySock) proc recv*(socket: AsyncFD, size: int, flags = {SocketFlag.SafeDisconn}): Future[string] = @@ -506,10 +481,7 @@ when defined(windows) or defined(nimdoc): proc (fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): - if bytesCount == 0 and dataBuf.buf[0] == '\0': - retFuture.complete(0) - else: - retFuture.complete(bytesCount) + retFuture.complete(bytesCount) else: if flags.isDisconnectionError(errcode): retFuture.complete(0) @@ -543,10 +515,11 @@ when defined(windows) or defined(nimdoc): proc send*(socket: AsyncFD, buf: pointer, size: int, flags = {SocketFlag.SafeDisconn}): Future[void] = - ## Sends ``size`` bytes from ``buf`` to ``socket``. The returned future will complete once all - ## data has been sent. - ## **WARNING**: Use it with caution. If ``buf`` refers to GC'ed object, you must use GC_ref/GC_unref calls - ## to avoid early freeing of the buffer + ## Sends ``size`` bytes from ``buf`` to ``socket``. The returned future + ## will complete once all data has been sent. + ## + ## **WARNING**: Use it with caution. If ``buf`` refers to GC'ed object, + ## you must use GC_ref/GC_unref calls to avoid early freeing of the buffer. verifyPresence(socket) var retFuture = newFuture[void]("send") @@ -793,7 +766,7 @@ when defined(windows) or defined(nimdoc): cast[pointer](p.ovl)) {.pop.} - template registerWaitableEvent(mask) = + proc registerWaitableEvent(fd: AsyncFD, cb: Callback; mask: Dword) = let p = getGlobalDispatcher() var flags = (WT_EXECUTEINWAITTHREAD or WT_EXECUTEONLYONCE).Dword var hEvent = wsaCreateEvent() @@ -843,8 +816,8 @@ when defined(windows) or defined(nimdoc): cast[pointer](pcd), INFINITE, flags): # pcd.ovl will be unrefed in poll() let err = osLastError() - discard wsaCloseEvent(hEvent) deallocShared(cast[pointer](pcd)) + discard wsaCloseEvent(hEvent) raiseOSError(err) else: # we incref `pcd.ovl` and `protect` callback one more time, @@ -883,16 +856,17 @@ when defined(windows) or defined(nimdoc): ## ## This is not ``pure`` mechanism for Windows Completion Ports (IOCP), ## so if you can avoid it, please do it. Use `addRead` only if really - ## need it (main usecase is adaptation of `unix like` libraries to be + ## need it (main usecase is adaptation of unix-like libraries to be ## asynchronous on Windows). - ## If you use this function, you dont need to use asyncdispatch.recv() + ## + ## If you use this function, you don't need to use asyncdispatch.recv() ## or asyncdispatch.accept(), because they are using IOCP, please use ## nativesockets.recv() and nativesockets.accept() instead. ## ## Be sure your callback ``cb`` returns ``true``, if you want to remove ## watch of `read` notifications, and ``false``, if you want to continue - ## receiving notifies. - registerWaitableEvent(FD_READ or FD_ACCEPT or FD_OOB or FD_CLOSE) + ## receiving notifications. + registerWaitableEvent(fd, cb, FD_READ or FD_ACCEPT or FD_OOB or FD_CLOSE) proc addWrite*(fd: AsyncFD, cb: Callback) = ## Start watching the file descriptor for write availability and then call @@ -900,43 +874,213 @@ when defined(windows) or defined(nimdoc): ## ## This is not ``pure`` mechanism for Windows Completion Ports (IOCP), ## so if you can avoid it, please do it. Use `addWrite` only if really - ## need it (main usecase is adaptation of `unix like` libraries to be + ## need it (main usecase is adaptation of unix-like libraries to be ## asynchronous on Windows). - ## If you use this function, you dont need to use asyncdispatch.send() + ## + ## If you use this function, you don't need to use asyncdispatch.send() ## or asyncdispatch.connect(), because they are using IOCP, please use ## nativesockets.send() and nativesockets.connect() instead. ## ## Be sure your callback ``cb`` returns ``true``, if you want to remove ## watch of `write` notifications, and ``false``, if you want to continue - ## receiving notifies. - registerWaitableEvent(FD_WRITE or FD_CONNECT or FD_CLOSE) + ## receiving notifications. + registerWaitableEvent(fd, cb, FD_WRITE or FD_CONNECT or FD_CLOSE) + + template registerWaitableHandle(p, hEvent, flags, pcd, timeout, + handleCallback) = + let handleFD = AsyncFD(hEvent) + pcd.ioPort = p.ioPort + pcd.handleFd = handleFD + var ol = PCustomOverlapped() + GC_ref(ol) + ol.data.fd = handleFD + ol.data.cb = handleCallback + # We need to protect our callback environment value, so GC will not free it + # accidentally. + ol.data.cell = system.protect(rawEnv(ol.data.cb)) + + pcd.ovl = ol + if not registerWaitForSingleObject(addr(pcd.waitFd), hEvent, + cast[WAITORTIMERCALLBACK](waitableCallback), + cast[pointer](pcd), timeout.Dword, flags): + let err = osLastError() + GC_unref(ol) + deallocShared(cast[pointer](pcd)) + discard closeHandle(hEvent) + raiseOSError(err) + p.handles.incl(handleFD) + + template closeWaitable(handle: untyped) = + let waitFd = pcd.waitFd + deallocShared(cast[pointer](pcd)) + p.handles.excl(fd) + if unregisterWait(waitFd) == 0: + let err = osLastError() + if err.int32 != ERROR_IO_PENDING: + discard closeHandle(handle) + raiseOSError(err) + if closeHandle(handle) == 0: + raiseOSError(osLastError()) + + proc addTimer*(timeout: int, oneshot: bool, cb: Callback) = + ## Registers callback ``cb`` to be called when timer expired. + ## + ## Parameters: + ## + ## * ``timeout`` - timeout value in milliseconds. + ## * ``oneshot`` + ## * `true` - generate only one timeout event + ## * `false` - generate timeout events periodically + + doAssert(timeout > 0) + let p = getGlobalDispatcher() + + var hEvent = createEvent(nil, 1, 0, nil) + if hEvent == INVALID_HANDLE_VALUE: + raiseOSError(osLastError()) + + var pcd = cast[PostCallbackDataPtr](allocShared0(sizeof(PostCallbackData))) + var flags = WT_EXECUTEINWAITTHREAD.Dword + if oneshot: flags = flags or WT_EXECUTEONLYONCE + + proc timercb(fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + let res = cb(fd) + if res or oneshot: + closeWaitable(hEvent) + else: + # if callback returned `false`, then it wants to be called again, so + # we need to ref and protect `pcd.ovl` again, because it will be + # unrefed and disposed in `poll()`. + GC_ref(pcd.ovl) + pcd.ovl.data.cell = system.protect(rawEnv(pcd.ovl.data.cb)) + + registerWaitableHandle(p, hEvent, flags, pcd, timeout, timercb) + + proc addProcess*(pid: int, cb: Callback) = + ## Registers callback ``cb`` to be called when process with process ID + ## ``pid`` exited. + let p = getGlobalDispatcher() + let procFlags = SYNCHRONIZE + var hProcess = openProcess(procFlags, 0, pid.Dword) + if hProcess == INVALID_HANDLE_VALUE: + raiseOSError(osLastError()) + + var pcd = cast[PostCallbackDataPtr](allocShared0(sizeof(PostCallbackData))) + var flags = WT_EXECUTEINWAITTHREAD.Dword + + proc proccb(fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + closeWaitable(hProcess) + discard cb(fd) + + registerWaitableHandle(p, hProcess, flags, pcd, INFINITE, proccb) + + proc newAsyncEvent*(): AsyncEvent = + ## Creates a new thread-safe ``AsyncEvent`` object. + ## + ## New ``AsyncEvent`` object is not automatically registered with # TODO: Why? -- DP + ## dispatcher like ``AsyncSocket``. + var sa = SECURITY_ATTRIBUTES( + nLength: sizeof(SECURITY_ATTRIBUTES).cint, + bInheritHandle: 1 + ) + var event = createEvent(addr(sa), 0'i32, 0'i32, nil) + if event == INVALID_HANDLE_VALUE: + raiseOSError(osLastError()) + result = cast[AsyncEvent](allocShared0(sizeof(AsyncEventImpl))) + result.hEvent = event + + proc trigger*(ev: AsyncEvent) = + ## Set event ``ev`` to signaled state. + if setEvent(ev.hEvent) == 0: + raiseOSError(osLastError()) + + proc unregister*(ev: AsyncEvent) = + ## Unregisters event ``ev``. + doAssert(ev.hWaiter != 0, "Event is not registered in the queue!") + let p = getGlobalDispatcher() + p.handles.excl(AsyncFD(ev.hEvent)) + if unregisterWait(ev.hWaiter) == 0: + let err = osLastError() + if err.int32 != ERROR_IO_PENDING: + raiseOSError(err) + ev.hWaiter = 0 + + proc close*(ev: AsyncEvent) = + ## Closes event ``ev``. + let res = closeHandle(ev.hEvent) + deallocShared(cast[pointer](ev)) + if res == 0: + raiseOSError(osLastError()) + + proc addEvent*(ev: AsyncEvent, cb: Callback) = + ## Registers callback ``cb`` to be called when ``ev`` will be signaled + doAssert(ev.hWaiter == 0, "Event is already registered in the queue!") + + let p = getGlobalDispatcher() + let hEvent = ev.hEvent + + var pcd = cast[PostCallbackDataPtr](allocShared0(sizeof(PostCallbackData))) + var flags = WT_EXECUTEINWAITTHREAD.Dword + + proc eventcb(fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + if ev.hWaiter != 0: + if cb(fd): + # we need this check to avoid exception, if `unregister(event)` was + # called in callback. + deallocShared(cast[pointer](pcd)) + if ev.hWaiter != 0: + unregister(ev) + else: + # if callback returned `false`, then it wants to be called again, so + # we need to ref and protect `pcd.ovl` again, because it will be + # unrefed and disposed in `poll()`. + GC_ref(pcd.ovl) + pcd.ovl.data.cell = system.protect(rawEnv(pcd.ovl.data.cb)) + else: + # if ev.hWaiter == 0, then event was unregistered before `poll()` call. + deallocShared(cast[pointer](pcd)) + + registerWaitableHandle(p, hEvent, flags, pcd, INFINITE, eventcb) + ev.hWaiter = pcd.waitFd initAll() else: import selectors from posix import EINTR, EAGAIN, EINPROGRESS, EWOULDBLOCK, MSG_PEEK, MSG_NOSIGNAL - + const + InitCallbackListSize = 4 # initial size of callbacks sequence, + # associated with file/socket descriptor. + InitDelayedCallbackListSize = 64 # initial size of delayed callbacks + # queue. type AsyncFD* = distinct cint Callback = proc (fd: AsyncFD): bool {.closure,gcsafe.} - PData* = ref object of RootRef - fd: AsyncFD - readCBs: seq[Callback] - writeCBs: seq[Callback] + AsyncData = object + readList: seq[Callback] + writeList: seq[Callback] + + AsyncEvent* = distinct SelectEvent PDispatcher* = ref object of PDispatcherBase - selector: Selector + selector: Selector[AsyncData] {.deprecated: [TAsyncFD: AsyncFD, TCallback: Callback].} proc `==`*(x, y: AsyncFD): bool {.borrow.} + proc `==`*(x, y: AsyncEvent): bool {.borrow.} + + template newAsyncData(): AsyncData = + AsyncData( + readList: newSeqOfCap[Callback](InitCallbackListSize), + writeList: newSeqOfCap[Callback](InitCallbackListSize) + ) proc newDispatcher*(): PDispatcher = new result - result.selector = newSelector() + result.selector = newSelector[AsyncData]() result.timers.newHeapQueue() - result.callbacks = initDeque[proc ()](64) + result.callbacks = initDeque[proc ()](InitDelayedCallbackListSize) var gDisp{.threadvar.}: PDispatcher ## Global dispatcher @@ -951,15 +1095,10 @@ else: setGlobalDispatcher(newDispatcher()) result = gDisp - proc update(fd: AsyncFD, events: set[Event]) = - let p = getGlobalDispatcher() - assert fd.SocketHandle in p.selector - p.selector.update(fd.SocketHandle, events) - proc register*(fd: AsyncFD) = let p = getGlobalDispatcher() - var data = PData(fd: fd, readCBs: @[], writeCBs: @[]) - p.selector.register(fd.SocketHandle, {}, data.RootRef) + var data = newAsyncData() + p.selector.registerHandle(fd.SocketHandle, {}, data) proc closeSocket*(sock: AsyncFD) = let disp = getGlobalDispatcher() @@ -969,80 +1108,158 @@ else: proc unregister*(fd: AsyncFD) = getGlobalDispatcher().selector.unregister(fd.SocketHandle) + proc unregister*(ev: AsyncEvent) = + getGlobalDispatcher().selector.unregister(SelectEvent(ev)) + proc addRead*(fd: AsyncFD, cb: Callback) = let p = getGlobalDispatcher() - if fd.SocketHandle notin p.selector: + var newEvents = {Event.Read} + withData(p.selector, fd.SocketHandle, adata) do: + adata.readList.add(cb) + newEvents.incl(Event.Read) + if len(adata.writeList) != 0: newEvents.incl(Event.Write) + do: raise newException(ValueError, "File descriptor not registered.") - p.selector[fd.SocketHandle].data.PData.readCBs.add(cb) - update(fd, p.selector[fd.SocketHandle].events + {EvRead}) + p.selector.updateHandle(fd.SocketHandle, newEvents) proc addWrite*(fd: AsyncFD, cb: Callback) = let p = getGlobalDispatcher() - if fd.SocketHandle notin p.selector: + var newEvents = {Event.Write} + withData(p.selector, fd.SocketHandle, adata) do: + adata.writeList.add(cb) + newEvents.incl(Event.Write) + if len(adata.readList) != 0: newEvents.incl(Event.Read) + do: raise newException(ValueError, "File descriptor not registered.") - p.selector[fd.SocketHandle].data.PData.writeCBs.add(cb) - update(fd, p.selector[fd.SocketHandle].events + {EvWrite}) - - template processCallbacks(callbacks: untyped) = - # Callback may add items to ``callbacks`` which causes issues if - # we are iterating over it at the same time. We therefore - # make a copy to iterate over. - let currentCBs = callbacks - callbacks = @[] - # Using another sequence because callbacks themselves can add - # other callbacks. - var newCBs: seq[Callback] = @[] - for cb in currentCBs: - if newCBs.len > 0: - # A callback has already returned with EAGAIN, don't call any - # others until next `poll`. - newCBs.add(cb) - else: - if not cb(data.fd): - # Callback wants to be called again. - newCBs.add(cb) - callbacks = newCBs & callbacks + p.selector.updateHandle(fd.SocketHandle, newEvents) proc hasPendingOperations*(): bool = let p = getGlobalDispatcher() - p.selector.len != 0 or p.timers.len != 0 or p.callbacks.len != 0 - - proc poll*(timeout = 500) = + not p.selector.isEmpty() or p.timers.len != 0 or p.callbacks.len != 0 + + template processBasicCallbacks(ident, rwlist: untyped) = + # Process pending descriptor and AsyncEvent callbacks. + # + # Invoke every callback stored in `rwlist`, until one + # returns `false` (which means callback wants to stay + # alive). In such case all remaining callbacks will be added + # to `rwlist` again, in the order they have been inserted. + # + # `rwlist` associated with file descriptor MUST BE emptied before + # dispatching callback (See https://github.com/nim-lang/Nim/issues/5128), + # or it can be possible to fall into endless cycle. + var curList: seq[Callback] + + withData(p.selector, ident, adata) do: + shallowCopy(curList, adata.rwlist) + adata.rwlist = newSeqOfCap[Callback](InitCallbackListSize) + + let newLength = max(len(curList), InitCallbackListSize) + var newList = newSeqOfCap[Callback](newLength) + + for cb in curList: + if len(newList) > 0: + # A callback has already returned with EAGAIN, don't call any others + # until next `poll`. + newList.add(cb) + else: + if not cb(fd.AsyncFD): + # Callback wants to be called again. + newList.add(cb) + + withData(p.selector, ident, adata) do: + # descriptor still present in queue. + adata.rwlist = newList & adata.rwlist + rLength = len(adata.readList) + wLength = len(adata.writeList) + do: + # descriptor was unregistered in callback via `unregister()`. + rLength = -1 + wLength = -1 + + template processCustomCallbacks(ident: untyped) = + # Process pending custom event callbacks. Custom events are + # {Event.Timer, Event.Signal, Event.Process, Event.Vnode}. + # There can be only one callback registered with one descriptor, + # so there is no need to iterate over list. + var curList: seq[Callback] + + withData(p.selector, ident, adata) do: + shallowCopy(curList, adata.readList) + adata.readList = newSeqOfCap[Callback](InitCallbackListSize) + + let newLength = len(curList) + var newList = newSeqOfCap[Callback](newLength) + + var cb = curList[0] + if not cb(fd.AsyncFD): + newList.add(cb) + + withData(p.selector, ident, adata) do: + # descriptor still present in queue. + adata.readList = newList & adata.readList + if len(adata.readList) == 0: + # if no callbacks registered with descriptor, unregister it. + p.selector.unregister(fd) + do: + # descriptor was unregistered in callback via `unregister()`. + discard + + proc runOnce(timeout = 500): bool = let p = getGlobalDispatcher() - if p.selector.len == 0 and p.timers.len == 0 and p.callbacks.len == 0: + when ioselSupportedPlatform: + let customSet = {Event.Timer, Event.Signal, Event.Process, + Event.Vnode} + + if p.selector.isEmpty() and p.timers.len == 0 and p.callbacks.len == 0: raise newException(ValueError, "No handles or timers registered in dispatcher.") - if p.selector.len > 0: - for info in p.selector.select(p.adjustedTimeout(timeout)): - let data = PData(info.key.data) - assert data.fd == info.key.fd.AsyncFD - #echo("In poll ", data.fd.cint) - # There may be EvError here, but we handle them in callbacks, - # so that exceptions can be raised from `send(...)` and - # `recv(...)` routines. - - if EvRead in info.events or info.events == {EvError}: - processCallbacks(data.readCBs) - - if EvWrite in info.events or info.events == {EvError}: - processCallbacks(data.writeCBs) - - if info.key in p.selector: - var newEvents: set[Event] - if data.readCBs.len != 0: newEvents = {EvRead} - if data.writeCBs.len != 0: newEvents = newEvents + {EvWrite} - if newEvents != info.key.events: - update(data.fd, newEvents) - else: - # FD no longer a part of the selector. Likely been closed - # (e.g. socket disconnected). - discard + result = false + if not p.selector.isEmpty(): + var keys: array[64, ReadyKey] + var count = p.selector.selectInto(p.adjustedTimeout(timeout), keys) + for i in 0..<count: + var custom = false + let fd = keys[i].fd + let events = keys[i].events + var rLength = 0 # len(data.readList) after callback + var wLength = 0 # len(data.writeList) after callback + + if Event.Read in events or events == {Event.Error}: + processBasicCallbacks(fd, readList) + result = true + + if Event.Write in events or events == {Event.Error}: + processBasicCallbacks(fd, writeList) + result = true + + if Event.User in events: + processBasicCallbacks(fd, readList) + custom = true + if rLength == 0: + p.selector.unregister(fd) + result = true + + when ioselSupportedPlatform: + if (customSet * events) != {}: + custom = true + processCustomCallbacks(fd) + result = true + + # because state `data` can be modified in callback we need to update + # descriptor events with currently registered callbacks. + if not custom: + var newEvents: set[Event] = {} + if rLength != -1 and wLength != -1: + if rLength > 0: incl(newEvents, Event.Read) + if wLength > 0: incl(newEvents, Event.Write) + p.selector.updateHandle(SocketHandle(fd), newEvents) # Timer processing. - processTimers(p) + processTimers(p, result) # Callback queue processing - processPendingCallbacks(p) + processPendingCallbacks(p, result) proc recv*(socket: AsyncFD, size: int, flags = {SocketFlag.SafeDisconn}): Future[string] = @@ -1075,7 +1292,7 @@ else: return retFuture proc recvInto*(socket: AsyncFD, buf: pointer, size: int, - flags = {SocketFlag.SafeDisconn}): Future[int] = + flags = {SocketFlag.SafeDisconn}): Future[int] = var retFuture = newFuture[int]("recvInto") proc cb(sock: AsyncFD): bool = @@ -1216,6 +1433,68 @@ else: addRead(socket, cb) return retFuture + when ioselSupportedPlatform: + + proc addTimer*(timeout: int, oneshot: bool, cb: Callback) = + ## Start watching for timeout expiration, and then call the + ## callback ``cb``. + ## ``timeout`` - time in milliseconds, + ## ``oneshot`` - if ``true`` only one event will be dispatched, + ## if ``false`` continuous events every ``timeout`` milliseconds. + let p = getGlobalDispatcher() + var data = newAsyncData() + data.readList.add(cb) + p.selector.registerTimer(timeout, oneshot, data) + + proc addSignal*(signal: int, cb: Callback) = + ## Start watching signal ``signal``, and when signal appears, call the + ## callback ``cb``. + let p = getGlobalDispatcher() + var data = newAsyncData() + data.readList.add(cb) + p.selector.registerSignal(signal, data) + + proc addProcess*(pid: int, cb: Callback) = + ## Start watching for process exit with pid ``pid``, and then call + ## the callback ``cb``. + let p = getGlobalDispatcher() + var data = newAsyncData() + data.readList.add(cb) + p.selector.registerProcess(pid, data) + + proc newAsyncEvent*(): AsyncEvent = + ## Creates new ``AsyncEvent``. + result = AsyncEvent(newSelectEvent()) + + proc trigger*(ev: AsyncEvent) = + ## Sets new ``AsyncEvent`` to signaled state. + trigger(SelectEvent(ev)) + + proc close*(ev: AsyncEvent) = + ## Closes ``AsyncEvent`` + close(SelectEvent(ev)) + + proc addEvent*(ev: AsyncEvent, cb: Callback) = + ## Start watching for event ``ev``, and call callback ``cb``, when + ## ev will be set to signaled state. + let p = getGlobalDispatcher() + var data = newAsyncData() + data.readList.add(cb) + p.selector.registerEvent(SelectEvent(ev), data) + +proc drain*(timeout = 500) = + ## Waits for completion events and processes them. Raises ``ValueError`` + ## if there are no pending operations. In contrast to ``poll`` this + ## processes as many events as are available. + if runOnce(timeout): + while hasPendingOperations() and runOnce(0): discard + +proc poll*(timeout = 500) = + ## Waits for completion events and processes them. Raises ``ValueError`` + ## if there are no pending operations. This runs the underlying OS + ## `epoll`:idx: or `kqueue`:idx: primitive only once. + discard runOnce(timeout) + # Common procedures between current and upcoming asyncdispatch include includes.asynccommon @@ -1269,7 +1548,7 @@ proc send*(socket: AsyncFD, data: string, var copiedData = data GC_ref(copiedData) # we need to protect data until send operation is completed - # or failed. + # or failed. let sendFut = socket.send(addr copiedData[0], data.len, flags) sendFut.callback = @@ -1317,7 +1596,7 @@ proc recvLine*(socket: AsyncFD): Future[string] {.async, deprecated.} = ## ## **Deprecated since version 0.15.0**: Use ``asyncnet.recvLine()`` instead. - template addNLIfEmpty(): untyped = + template addNLIfEmpty(): typed = if result.len == 0: result.add("\c\L") @@ -1353,3 +1632,5 @@ proc waitFor*[T](fut: Future[T]): T = poll() fut.read + +{.deprecated: [setEvent: trigger].} diff --git a/lib/pure/asyncfutures.nim b/lib/pure/asyncfutures.nim index bebd19611..bcc3ab613 100644 --- a/lib/pure/asyncfutures.nim +++ b/lib/pure/asyncfutures.nim @@ -1,4 +1,4 @@ -import os, tables, strutils, times, heapqueue, options, deques +import os, tables, strutils, times, heapqueue, options, deques, cstrutils # TODO: This shouldn't need to be included, but should ideally be exported. type @@ -217,17 +217,78 @@ proc `callback=`*[T](future: Future[T], ## If future has already completed then ``cb`` will be called immediately. future.callback = proc () = cb(future) +proc getHint(entry: StackTraceEntry): string = + ## We try to provide some hints about stack trace entries that the user + ## may not be familiar with, in particular calls inside the stdlib. + result = "" + if entry.procname == "processPendingCallbacks": + if cmpIgnoreStyle(entry.filename, "asyncdispatch.nim") == 0: + return "Executes pending callbacks" + elif entry.procname == "poll": + if cmpIgnoreStyle(entry.filename, "asyncdispatch.nim") == 0: + return "Processes asynchronous completion events" + + if entry.procname.endsWith("_continue"): + if cmpIgnoreStyle(entry.filename, "asyncmacro.nim") == 0: + return "Resumes an async procedure" + +proc `$`*(entries: seq[StackTraceEntry]): string = + result = "" + # Find longest filename & line number combo for alignment purposes. + var longestLeft = 0 + for entry in entries: + if entry.procName.isNil: continue + + let left = $entry.filename & $entry.line + if left.len > longestLeft: + longestLeft = left.len + + var indent = 2 + # Format the entries. + for entry in entries: + if entry.procName.isNil: + if entry.line == -10: + result.add(spaces(indent) & "#[\n") + indent.inc(2) + else: + indent.dec(2) + result.add(spaces(indent)& "]#\n") + continue + + let left = "$#($#)" % [$entry.filename, $entry.line] + result.add((spaces(indent) & "$#$# $#\n") % [ + left, + spaces(longestLeft - left.len + 2), + $entry.procName + ]) + let hint = getHint(entry) + if hint.len > 0: + result.add(spaces(indent+2) & "## " & hint & "\n") + proc injectStacktrace[T](future: Future[T]) = - # TODO: Come up with something better. when not defined(release): - var msg = "" - msg.add("\n " & future.fromProc & "'s lead up to read of failed Future:") + const header = "\nAsync traceback:\n" - if not future.errorStackTrace.isNil and future.errorStackTrace != "": - msg.add("\n" & indent(future.errorStackTrace.strip(), 4)) - else: - msg.add("\n Empty or nil stack trace.") - future.error.msg.add(msg) + var exceptionMsg = future.error.msg + if header in exceptionMsg: + # This is messy: extract the original exception message from the msg + # containing the async traceback. + let start = exceptionMsg.find(header) + exceptionMsg = exceptionMsg[0..<start] + + + var newMsg = exceptionMsg & header + + let entries = getStackTraceEntries(future.error) + newMsg.add($entries) + + newMsg.add("Exception message: " & exceptionMsg & "\n") + newMsg.add("Exception type:") + + # # For debugging purposes + # for entry in getStackTraceEntries(future.error): + # newMsg.add "\n" & $entry + future.error.msg = newMsg proc read*[T](future: Future[T] | FutureVar[T]): T = ## Retrieves the value of ``future``. Future must be finished otherwise @@ -333,7 +394,7 @@ proc all*[T](futs: varargs[Future[T]]): auto = let totalFutures = len(futs) for fut in futs: - fut.callback = proc(f: Future[T]) = + fut.addCallback proc (f: Future[T]) = inc(completedFutures) if not retFuture.finished: if f.failed: @@ -355,7 +416,7 @@ proc all*[T](futs: varargs[Future[T]]): auto = for i, fut in futs: proc setCallback(i: int) = - fut.callback = proc(f: Future[T]) = + fut.addCallback proc (f: Future[T]) = inc(completedFutures) if not retFuture.finished: if f.failed: diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 6d4b85145..ba1615651 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -58,15 +58,18 @@ type socket: AsyncSocket reuseAddr: bool reusePort: bool + maxBody: int ## The maximum content-length that will be read for the body. {.deprecated: [TRequest: Request, PAsyncHttpServer: AsyncHttpServer, THttpCode: HttpCode, THttpVersion: HttpVersion].} -proc newAsyncHttpServer*(reuseAddr = true, reusePort = false): AsyncHttpServer = +proc newAsyncHttpServer*(reuseAddr = true, reusePort = false, + maxBody = 8388608): AsyncHttpServer = ## Creates a new ``AsyncHttpServer`` instance. new result result.reuseAddr = reuseAddr result.reusePort = reusePort + result.maxBody = maxBody proc addHeaders(msg: var string, headers: HttpHeaders) = for k, v in headers: @@ -122,144 +125,157 @@ proc parseProtocol(protocol: string): tuple[orig: string, major, minor: int] = raise newException(ValueError, "Invalid request protocol. Got: " & protocol) result.orig = protocol - i.inc protocol.parseInt(result.major, i) + i.inc protocol.parseSaturatedNatural(result.major, i) i.inc # Skip . - i.inc protocol.parseInt(result.minor, i) + i.inc protocol.parseSaturatedNatural(result.minor, i) proc sendStatus(client: AsyncSocket, status: string): Future[void] = client.send("HTTP/1.1 " & status & "\c\L\c\L") -proc processClient(client: AsyncSocket, address: string, - callback: proc (request: Request): +proc processRequest(server: AsyncHttpServer, req: FutureVar[Request], + client: AsyncSocket, + address: string, lineFut: FutureVar[string], + callback: proc (request: Request): Future[void] {.closure, gcsafe.}) {.async.} = - var request: Request - request.url = initUri() - request.headers = newHttpHeaders() - var lineFut = newFutureVar[string]("asynchttpserver.processClient") - lineFut.mget() = newStringOfCap(80) - var key, value = "" - while not client.isClosed: - # GET /path HTTP/1.1 - # Header: val - # \n - request.headers.clear() - request.body = "" - request.hostname.shallowCopy(address) - assert client != nil - request.client = client - - # We should skip at least one empty line before the request - # https://tools.ietf.org/html/rfc7230#section-3.5 - for i in 0..1: - lineFut.mget().setLen(0) - lineFut.clean() - await client.recvLineInto(lineFut, maxLength=maxLine) # TODO: Timeouts. - - if lineFut.mget == "": - client.close() - return + # Alias `request` to `req.mget()` so we don't have to write `mget` everywhere. + template request(): Request = + req.mget() + + # GET /path HTTP/1.1 + # Header: val + # \n + request.headers.clear() + request.body = "" + request.hostname.shallowCopy(address) + assert client != nil + request.client = client + + # We should skip at least one empty line before the request + # https://tools.ietf.org/html/rfc7230#section-3.5 + for i in 0..1: + lineFut.mget().setLen(0) + lineFut.clean() + await client.recvLineInto(lineFut, maxLength=maxLine) # TODO: Timeouts. + + if lineFut.mget == "": + client.close() + return - if lineFut.mget.len > maxLine: - await request.respondError(Http413) - client.close() + if lineFut.mget.len > maxLine: + await request.respondError(Http413) + client.close() + return + if lineFut.mget != "\c\L": + break + + # First line - GET /path HTTP/1.1 + var i = 0 + for linePart in lineFut.mget.split(' '): + case i + of 0: + try: + # TODO: this is likely slow. + request.reqMethod = parseEnum[HttpMethod]("http" & linePart) + except ValueError: + asyncCheck request.respondError(Http400) return - if lineFut.mget != "\c\L": - break - - # First line - GET /path HTTP/1.1 - var i = 0 - for linePart in lineFut.mget.split(' '): - case i - of 0: - try: - # TODO: this is likely slow. - request.reqMethod = parseEnum[HttpMethod]("http" & linePart) - except ValueError: - asyncCheck request.respondError(Http400) - continue - of 1: - try: - parseUri(linePart, request.url) - except ValueError: - asyncCheck request.respondError(Http400) - continue - of 2: - try: - request.protocol = parseProtocol(linePart) - except ValueError: - asyncCheck request.respondError(Http400) - continue - else: - await request.respondError(Http400) - continue - inc i - - # Headers - while true: - i = 0 - lineFut.mget.setLen(0) - lineFut.clean() - await client.recvLineInto(lineFut, maxLength=maxLine) - - if lineFut.mget == "": - client.close(); return - if lineFut.mget.len > maxLine: - await request.respondError(Http413) - client.close(); return - if lineFut.mget == "\c\L": break - let (key, value) = parseHeader(lineFut.mget) - request.headers[key] = value - # Ensure the client isn't trying to DoS us. - if request.headers.len > headerLimit: - await client.sendStatus("400 Bad Request") - request.client.close() + of 1: + try: + parseUri(linePart, request.url) + except ValueError: + asyncCheck request.respondError(Http400) return + of 2: + try: + request.protocol = parseProtocol(linePart) + except ValueError: + asyncCheck request.respondError(Http400) + return + else: + await request.respondError(Http400) + return + inc i - if request.reqMethod == HttpPost: - # Check for Expect header - if request.headers.hasKey("Expect"): - if "100-continue" in request.headers["Expect"]: - await client.sendStatus("100 Continue") - else: - await client.sendStatus("417 Expectation Failed") - - # Read the body - # - Check for Content-length header - if request.headers.hasKey("Content-Length"): - var contentLength = 0 - if parseInt(request.headers["Content-Length"], - contentLength) == 0: - await request.respond(Http400, "Bad Request. Invalid Content-Length.") - continue - else: - request.body = await client.recv(contentLength) - if request.body.len != contentLength: - await request.respond(Http400, "Bad Request. Content-Length does not match actual.") - continue - elif request.reqMethod == HttpPost: - await request.respond(Http411, "Content-Length required.") - continue - - # Call the user's callback. - await callback(request) - - if "upgrade" in request.headers.getOrDefault("connection"): + # Headers + while true: + i = 0 + lineFut.mget.setLen(0) + lineFut.clean() + await client.recvLineInto(lineFut, maxLength=maxLine) + + if lineFut.mget == "": + client.close(); return + if lineFut.mget.len > maxLine: + await request.respondError(Http413) + client.close(); return + if lineFut.mget == "\c\L": break + let (key, value) = parseHeader(lineFut.mget) + request.headers[key] = value + # Ensure the client isn't trying to DoS us. + if request.headers.len > headerLimit: + await client.sendStatus("400 Bad Request") + request.client.close() return - # Persistent connections - if (request.protocol == HttpVer11 and - request.headers.getOrDefault("connection").normalize != "close") or - (request.protocol == HttpVer10 and - request.headers.getOrDefault("connection").normalize == "keep-alive"): - # In HTTP 1.1 we assume that connection is persistent. Unless connection - # header states otherwise. - # In HTTP 1.0 we assume that the connection should not be persistent. - # Unless the connection header states otherwise. - discard + if request.reqMethod == HttpPost: + # Check for Expect header + if request.headers.hasKey("Expect"): + if "100-continue" in request.headers["Expect"]: + await client.sendStatus("100 Continue") + else: + await client.sendStatus("417 Expectation Failed") + + # Read the body + # - Check for Content-length header + if request.headers.hasKey("Content-Length"): + var contentLength = 0 + if parseSaturatedNatural(request.headers["Content-Length"], contentLength) == 0: + await request.respond(Http400, "Bad Request. Invalid Content-Length.") + return else: - request.client.close() - break + if contentLength > server.maxBody: + await request.respondError(Http413) + return + request.body = await client.recv(contentLength) + if request.body.len != contentLength: + await request.respond(Http400, "Bad Request. Content-Length does not match actual.") + return + elif request.reqMethod == HttpPost: + await request.respond(Http411, "Content-Length required.") + return + + # Call the user's callback. + await callback(request) + + if "upgrade" in request.headers.getOrDefault("connection"): + return + + # Persistent connections + if (request.protocol == HttpVer11 and + cmpIgnoreCase(request.headers.getOrDefault("connection"), "close") != 0) or + (request.protocol == HttpVer10 and + cmpIgnoreCase(request.headers.getOrDefault("connection"), "keep-alive") == 0): + # In HTTP 1.1 we assume that connection is persistent. Unless connection + # header states otherwise. + # In HTTP 1.0 we assume that the connection should not be persistent. + # Unless the connection header states otherwise. + discard + else: + request.client.close() + return + +proc processClient(server: AsyncHttpServer, client: AsyncSocket, address: string, + callback: proc (request: Request): + Future[void] {.closure, gcsafe.}) {.async.} = + var request = newFutureVar[Request]("asynchttpserver.processClient") + request.mget().url = initUri() + request.mget().headers = newHttpHeaders() + var lineFut = newFutureVar[string]("asynchttpserver.processClient") + lineFut.mget() = newStringOfCap(80) + + while not client.isClosed: + await processRequest(server, request, client, address, lineFut, callback) proc serve*(server: AsyncHttpServer, port: Port, callback: proc (request: Request): Future[void] {.closure,gcsafe.}, @@ -280,7 +296,7 @@ proc serve*(server: AsyncHttpServer, port: Port, # TODO: Causes compiler crash. #var (address, client) = await server.socket.acceptAddr() var fut = await server.socket.acceptAddr() - asyncCheck processClient(fut.client, fut.address, callback) + asyncCheck processClient(server, fut.client, fut.address, callback) #echo(f.isNil) #echo(f.repr) diff --git a/lib/pure/asyncmacro.nim b/lib/pure/asyncmacro.nim index 6e7d7993f..8c679929d 100644 --- a/lib/pure/asyncmacro.nim +++ b/lib/pure/asyncmacro.nim @@ -25,10 +25,10 @@ proc skipStmtList(node: NimNode): NimNode {.compileTime.} = result = node[0] template createCb(retFutureSym, iteratorNameSym, - name, futureVarCompletions: untyped) = + strName, identName, futureVarCompletions: untyped) = var nameIterVar = iteratorNameSym #{.push stackTrace: off.} - proc cb0 {.closure.} = + proc identName {.closure.} = try: if not nameIterVar.finished: var next = nameIterVar() @@ -36,11 +36,11 @@ template createCb(retFutureSym, iteratorNameSym, if not retFutureSym.finished: let msg = "Async procedure ($1) yielded `nil`, are you await'ing a " & "`nil` Future?" - raise newException(AssertionError, msg % name) + raise newException(AssertionError, msg % strName) else: {.gcsafe.}: {.push hint[ConvFromXtoItselfNotNeeded]: off.} - next.callback = (proc() {.closure, gcsafe.})(cb0) + next.callback = (proc() {.closure, gcsafe.})(identName) {.pop.} except: futureVarCompletions @@ -52,7 +52,7 @@ template createCb(retFutureSym, iteratorNameSym, else: retFutureSym.fail(getCurrentException()) - cb0() + identName() #{.pop.} proc generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode: NimNode): NimNode {.compileTime.} = @@ -61,14 +61,14 @@ proc generateExceptionCheck(futSym, else: var exceptionChecks: seq[tuple[cond, body: NimNode]] = @[] let errorNode = newDotExpr(futSym, newIdentNode("error")) - for i in 1 .. <tryStmt.len: + for i in 1 ..< tryStmt.len: let exceptBranch = tryStmt[i] if exceptBranch[0].kind == nnkStmtList: exceptionChecks.add((newIdentNode("true"), exceptBranch[0])) else: var exceptIdentCount = 0 var ifCond: NimNode - for i in 0 .. <exceptBranch.len: + for i in 0 ..< exceptBranch.len: let child = exceptBranch[i] if child.kind == nnkIdent: let cond = infix(errorNode, "of", child) @@ -270,7 +270,7 @@ proc processBody(node, retFutureSym: NimNode, return else: discard - for i in 0 .. <result.len: + for i in 0 ..< result.len: result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, futureVarIdents, nil) @@ -287,7 +287,7 @@ proc getName(node: NimNode): string {.compileTime.} = proc getFutureVarIdents(params: NimNode): seq[NimNode] {.compileTime.} = result = @[] - for i in 1 .. <len(params): + for i in 1 ..< len(params): expectKind(params[i], nnkIdentDefs) if params[i][1].kind == nnkBracketExpr and ($params[i][1][0].ident).normalize == "futurevar": @@ -389,9 +389,12 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} = outerProcBody.add(closureIterator) # -> createCb(retFuture) - #var cbName = newIdentNode("cb") + # NOTE: The "_continue" suffix is checked for in asyncfutures.nim to produce + # friendlier stack traces: + var cbName = genSym(nskProc, prcName & "_continue") var procCb = getAst createCb(retFutureSym, iteratorNameSym, newStrLitNode(prcName), + cbName, createFutureVarCompletions(futureVarIdents, nil)) outerProcBody.add procCb @@ -466,33 +469,19 @@ proc stripAwait(node: NimNode): NimNode = node[0][0] = emptyNoopSym else: discard - for i in 0 .. <result.len: + for i in 0 ..< result.len: result[i] = stripAwait(result[i]) proc splitParamType(paramType: NimNode, async: bool): NimNode = result = paramType if paramType.kind == nnkInfix and $paramType[0].ident in ["|", "or"]: - let firstType = paramType[1] - let firstTypeName = $firstType.ident - let secondType = paramType[2] - let secondTypeName = $secondType.ident - - # Make sure that at least one has the name `async`, otherwise we shouldn't - # touch it. - if not ("async" in firstTypeName.normalize or - "async" in secondTypeName.normalize): - return - - if async: - if firstTypeName.normalize.startsWith("async"): - result = paramType[1] - elif secondTypeName.normalize.startsWith("async"): - result = paramType[2] - else: - if not firstTypeName.normalize.startsWith("async"): - result = paramType[1] - elif not secondTypeName.normalize.startsWith("async"): - result = paramType[2] + let firstAsync = "async" in ($paramType[1].ident).normalize + let secondAsync = "async" in ($paramType[2].ident).normalize + + if firstAsync: + result = paramType[if async: 1 else: 2] + elif secondAsync: + result = paramType[if async: 2 else: 1] proc stripReturnType(returnType: NimNode): NimNode = # Strip out the 'Future' from 'Future[T]'. @@ -512,7 +501,7 @@ proc splitProc(prc: NimNode): (NimNode, NimNode) = # Retrieve the `T` inside `Future[T]`. let returnType = stripReturnType(result[0][3][0]) result[0][3][0] = splitParamType(returnType, async=false) - for i in 1 .. <result[0][3].len: + for i in 1 ..< result[0][3].len: # Sync proc (0) -> FormalParams (3) -> IdentDefs, the parameter (i) -> # parameter type (1). result[0][3][i][1] = splitParamType(result[0][3][i][1], async=false) @@ -521,7 +510,7 @@ proc splitProc(prc: NimNode): (NimNode, NimNode) = result[1] = prc.copyNimTree() if result[1][3][0].kind == nnkBracketExpr: result[1][3][0][1] = splitParamType(result[1][3][0][1], async=true) - for i in 1 .. <result[1][3].len: + for i in 1 ..< result[1][3].len: # Async proc (1) -> FormalParams (3) -> IdentDefs, the parameter (i) -> # parameter type (1). result[1][3][i][1] = splitParamType(result[1][3][i][1], async=true) @@ -535,4 +524,4 @@ macro multisync*(prc: untyped): untyped = let (sync, asyncPrc) = splitProc(prc) result = newStmtList() result.add(asyncSingleProc(asyncPrc)) - result.add(sync) \ No newline at end of file + result.add(sync) diff --git a/lib/pure/bitops.nim b/lib/pure/bitops.nim index d1207603d..3f213c5ea 100644 --- a/lib/pure/bitops.nim +++ b/lib/pure/bitops.nim @@ -181,7 +181,7 @@ elif useICC_builtins: proc countSetBits*(x: SomeInteger): int {.inline, nosideeffect.} = - ## Counts the set bits in integer. (also called Hamming weight.) + ## Counts the set bits in integer. (also called `Hamming weight`:idx:.) # TODO: figure out if ICC support _popcnt32/_popcnt64 on platform without POPCNT. # like GCC and MSVC when nimvm: diff --git a/lib/pure/browsers.nim b/lib/pure/browsers.nim index c6a603318..6912b893c 100644 --- a/lib/pure/browsers.nim +++ b/lib/pure/browsers.nim @@ -21,24 +21,18 @@ proc openDefaultBrowser*(url: string) = ## opens `url` with the user's default browser. This does not block. ## ## Under Windows, ``ShellExecute`` is used. Under Mac OS X the ``open`` - ## command is used. Under Unix, it is checked if ``gnome-open`` exists and - ## used if it does. Next attempt is ``kde-open``, then ``xdg-open``. - ## Otherwise the environment variable ``BROWSER`` is used to determine the - ## default browser to use. + ## command is used. Under Unix, it is checked if ``xdg-open`` exists and + ## used if it does. Otherwise the environment variable ``BROWSER`` is + ## used to determine the default browser to use. when defined(windows): - when useWinUnicode: - var o = newWideCString("open") - var u = newWideCString(url) - discard shellExecuteW(0'i32, o, u, nil, nil, SW_SHOWNORMAL) - else: - discard shellExecuteA(0'i32, "open", url, nil, nil, SW_SHOWNORMAL) + var o = newWideCString("open") + var u = newWideCString(url) + discard shellExecuteW(0'i32, o, u, nil, nil, SW_SHOWNORMAL) elif defined(macosx): discard execShellCmd("open " & quoteShell(url)) else: - const attempts = ["gnome-open ", "kde-open ", "xdg-open "] var u = quoteShell(url) - for a in items(attempts): - if execShellCmd(a & u) == 0: return + if execShellCmd("xdg-open " & u) == 0: return for b in getEnv("BROWSER").string.split(PathSep): try: # we use ``startProcess`` here because we don't want to block! diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index 200a4adf1..5de6aa487 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -29,21 +29,8 @@ ## writeLine(stdout, "your password: " & myData["password"]) ## writeLine(stdout, "</body></html>") -import strutils, os, strtabs, cookies - -proc encodeUrl*(s: string): string = - ## Encodes a value to be HTTP safe: This means that characters in the set - ## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result, - ## a space is converted to ``'+'`` and every other character is encoded as - ## ``'%xx'`` where ``xx`` denotes its hexadecimal value. - result = newStringOfCap(s.len + s.len shr 2) # assume 12% non-alnum-chars - for i in 0..s.len-1: - case s[i] - of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(result, s[i]) - of ' ': add(result, '+') - else: - add(result, '%') - add(result, toHex(ord(s[i]), 2)) +import strutils, os, strtabs, cookies, uri +export uri.encodeUrl, uri.decodeUrl proc handleHexChar(c: char, x: var int) {.inline.} = case c @@ -52,30 +39,6 @@ proc handleHexChar(c: char, x: var int) {.inline.} = of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10) else: assert(false) -proc decodeUrl*(s: string): string = - ## Decodes a value from its HTTP representation: This means that a ``'+'`` - ## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal - ## value) is converted to the character with ordinal number ``xx``, and - ## and every other character is carried over. - result = newString(s.len) - var i = 0 - var j = 0 - while i < s.len: - case s[i] - of '%': - var x = 0 - handleHexChar(s[i+1], x) - handleHexChar(s[i+2], x) - inc(i, 2) - result[j] = chr(x) - of '+': result[j] = ' ' - else: result[j] = s[i] - inc(i) - inc(j) - setLen(result, j) - -{.deprecated: [URLDecode: decodeUrl, URLEncode: encodeUrl].} - proc addXmlChar(dest: var string, c: char) {.inline.} = case c of '&': add(dest, "&") @@ -101,8 +64,7 @@ type methodPost, ## query uses the POST method methodGet ## query uses the GET method -{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError, - XMLencode: xmlEncode].} +{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError].} proc cgiError*(msg: string) {.noreturn.} = ## raises an ECgi exception with message `msg`. @@ -393,8 +355,3 @@ proc existsCookie*(name: string): bool = ## Checks if a cookie of `name` exists. if gcookies == nil: gcookies = parseCookies(getHttpCookie()) result = hasKey(gcookies, name) - -when isMainModule: - const test1 = "abc\L+def xyz" - assert encodeUrl(test1) == "abc%0A%2Bdef+xyz" - assert decodeUrl(encodeUrl(test1)) == test1 diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim index f70a12843..34f5c5470 100644 --- a/lib/pure/collections/critbits.nim +++ b/lib/pure/collections/critbits.nim @@ -141,8 +141,8 @@ proc excl*[T](c: var CritBitTree[T], key: string) = proc missingOrExcl*[T](c: var CritBitTree[T], key: string): bool = ## Returns true iff `c` does not contain the given `key`. If the key - ## does exist, c.excl(key) is performed. - let oldCount = c.count + ## does exist, c.excl(key) is performed. + let oldCount = c.count var n = exclImpl(c, key) result = c.count == oldCount @@ -257,7 +257,7 @@ proc allprefixedAux[T](c: CritBitTree[T], key: string; longestMatch: bool): Node p = p.child[dir] if q.byte < key.len: top = p if not longestMatch: - for i in 0 .. <key.len: + for i in 0 ..< key.len: if p.key[i] != key[i]: return result = top @@ -326,7 +326,7 @@ proc `$`*[T](c: CritBitTree[T]): string = result.add($key) when T isnot void: result.add(": ") - result.add($val) + result.addQuoted(val) result.add("}") when isMainModule: diff --git a/lib/pure/collections/deques.nim b/lib/pure/collections/deques.nim index 1bbe9f1ad..328308a9b 100644 --- a/lib/pure/collections/deques.nim +++ b/lib/pure/collections/deques.nim @@ -185,7 +185,7 @@ proc `$`*[T](deq: Deque[T]): string = result = "[" for x in deq: if result.len > 1: result.add(", ") - result.add($x) + result.addQuoted(x) result.add("]") when isMainModule: @@ -207,9 +207,9 @@ when isMainModule: assert($deq == "[4, 56, 6, 789]") assert deq[0] == deq.peekFirst and deq.peekFirst == 4 - assert deq[^1] == deq.peekLast and deq.peekLast == 789 + #assert deq[^1] == deq.peekLast and deq.peekLast == 789 deq[0] = 42 - deq[^1] = 7 + deq[deq.len - 1] = 7 assert 6 in deq and 789 notin deq assert deq.find(6) >= 0 diff --git a/lib/pure/collections/heapqueue.nim b/lib/pure/collections/heapqueue.nim index f86ba1d3f..60869142e 100644 --- a/lib/pure/collections/heapqueue.nim +++ b/lib/pure/collections/heapqueue.nim @@ -1,3 +1,12 @@ + +# +# +# Nim's Runtime Library +# (c) Copyright 2016 Yuriy Glukhov +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. + ##[ Heap queue algorithm (a.k.a. priority queue). Ported from Python heapq. Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim index f847ddd58..e69acc8d9 100644 --- a/lib/pure/collections/lists.nim +++ b/lib/pure/collections/lists.nim @@ -37,6 +37,14 @@ type DoublyLinkedRing*[T] = object ## a doubly linked ring head*: DoublyLinkedNode[T] + SomeLinkedList*[T] = SinglyLinkedList[T] | DoublyLinkedList[T] + + SomeLinkedRing*[T] = SinglyLinkedRing[T] | DoublyLinkedRing[T] + + SomeLinkedCollection*[T] = SomeLinkedList[T] | SomeLinkedRing[T] + + SomeLinkedNode*[T] = SinglyLinkedNode[T] | DoublyLinkedNode[T] + {.deprecated: [TDoublyLinkedNode: DoublyLinkedNodeObj, PDoublyLinkedNode: DoublyLinkedNode, TSinglyLinkedNode: SinglyLinkedNodeObj, @@ -86,137 +94,57 @@ template itemsRingImpl() {.dirty.} = it = it.next if it == L.head: break -template nodesListImpl() {.dirty.} = - var it = L.head - while it != nil: - var nxt = it.next - yield it - it = nxt - -template nodesRingImpl() {.dirty.} = - var it = L.head - if it != nil: - while true: - var nxt = it.next - yield it - it = nxt - if it == L.head: break - -template findImpl() {.dirty.} = - for x in nodes(L): - if x.value == value: return x - -iterator items*[T](L: DoublyLinkedList[T]): T = +iterator items*[T](L: SomeLinkedList[T]): T = ## yields every value of `L`. itemsListImpl() -iterator items*[T](L: SinglyLinkedList[T]): T = - ## yields every value of `L`. - itemsListImpl() - -iterator items*[T](L: SinglyLinkedRing[T]): T = - ## yields every value of `L`. - itemsRingImpl() - -iterator items*[T](L: DoublyLinkedRing[T]): T = +iterator items*[T](L: SomeLinkedRing[T]): T = ## yields every value of `L`. itemsRingImpl() -iterator mitems*[T](L: var DoublyLinkedList[T]): var T = +iterator mitems*[T](L: var SomeLinkedList[T]): var T = ## yields every value of `L` so that you can modify it. itemsListImpl() -iterator mitems*[T](L: var SinglyLinkedList[T]): var T = - ## yields every value of `L` so that you can modify it. - itemsListImpl() - -iterator mitems*[T](L: var SinglyLinkedRing[T]): var T = +iterator mitems*[T](L: var SomeLinkedRing[T]): var T = ## yields every value of `L` so that you can modify it. itemsRingImpl() -iterator mitems*[T](L: var DoublyLinkedRing[T]): var T = - ## yields every value of `L` so that you can modify it. - itemsRingImpl() - -iterator nodes*[T](L: SinglyLinkedList[T]): SinglyLinkedNode[T] = - ## iterates over every node of `x`. Removing the current node from the - ## list during traversal is supported. - nodesListImpl() - -iterator nodes*[T](L: DoublyLinkedList[T]): DoublyLinkedNode[T] = - ## iterates over every node of `x`. Removing the current node from the - ## list during traversal is supported. - nodesListImpl() - -iterator nodes*[T](L: SinglyLinkedRing[T]): SinglyLinkedNode[T] = +iterator nodes*[T](L: SomeLinkedList[T]): SomeLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. - nodesRingImpl() + var it = L.head + while it != nil: + var nxt = it.next + yield it + it = nxt -iterator nodes*[T](L: DoublyLinkedRing[T]): DoublyLinkedNode[T] = +iterator nodes*[T](L: SomeLinkedRing[T]): SomeLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. - nodesRingImpl() + var it = L.head + if it != nil: + while true: + var nxt = it.next + yield it + it = nxt + if it == L.head: break -template dollarImpl() {.dirty.} = +proc `$`*[T](L: SomeLinkedCollection[T]): string = + ## turns a list into its string representation. result = "[" for x in nodes(L): if result.len > 1: result.add(", ") - result.add($x.value) + result.addQuoted(x.value) result.add("]") -proc `$`*[T](L: SinglyLinkedList[T]): string = - ## turns a list into its string representation. - dollarImpl() - -proc `$`*[T](L: DoublyLinkedList[T]): string = - ## turns a list into its string representation. - dollarImpl() - -proc `$`*[T](L: SinglyLinkedRing[T]): string = - ## turns a list into its string representation. - dollarImpl() - -proc `$`*[T](L: DoublyLinkedRing[T]): string = - ## turns a list into its string representation. - dollarImpl() - -proc find*[T](L: SinglyLinkedList[T], value: T): SinglyLinkedNode[T] = - ## searches in the list for a value. Returns nil if the value does not - ## exist. - findImpl() - -proc find*[T](L: DoublyLinkedList[T], value: T): DoublyLinkedNode[T] = +proc find*[T](L: SomeLinkedCollection[T], value: T): SomeLinkedNode[T] = ## searches in the list for a value. Returns nil if the value does not ## exist. - findImpl() - -proc find*[T](L: SinglyLinkedRing[T], value: T): SinglyLinkedNode[T] = - ## searches in the list for a value. Returns nil if the value does not - ## exist. - findImpl() - -proc find*[T](L: DoublyLinkedRing[T], value: T): DoublyLinkedNode[T] = - ## searches in the list for a value. Returns nil if the value does not - ## exist. - findImpl() - -proc contains*[T](L: SinglyLinkedList[T], value: T): bool {.inline.} = - ## searches in the list for a value. Returns false if the value does not - ## exist, true otherwise. - result = find(L, value) != nil - -proc contains*[T](L: DoublyLinkedList[T], value: T): bool {.inline.} = - ## searches in the list for a value. Returns false if the value does not - ## exist, true otherwise. - result = find(L, value) != nil - -proc contains*[T](L: SinglyLinkedRing[T], value: T): bool {.inline.} = - ## searches in the list for a value. Returns false if the value does not - ## exist, true otherwise. - result = find(L, value) != nil + for x in nodes(L): + if x.value == value: return x -proc contains*[T](L: DoublyLinkedRing[T], value: T): bool {.inline.} = +proc contains*[T](L: SomeLinkedCollection[T], value: T): bool {.inline.} = ## searches in the list for a value. Returns false if the value does not ## exist, true otherwise. result = find(L, value) != nil @@ -266,7 +194,6 @@ proc remove*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) = if n.next != nil: n.next.prev = n.prev if n.prev != nil: n.prev.next = n.next - proc append*[T](L: var SinglyLinkedRing[T], n: SinglyLinkedNode[T]) = ## appends a node `n` to `L`. Efficiency: O(1). if L.head != nil: diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim index 401422162..ce792d6da 100644 --- a/lib/pure/collections/queues.nim +++ b/lib/pure/collections/queues.nim @@ -198,9 +198,8 @@ when isMainModule: assert($q == "[4, 56, 6, 789]") assert q[0] == q.front and q.front == 4 - assert q[^1] == q.back and q.back == 789 q[0] = 42 - q[^1] = 7 + q[q.len - 1] = 7 assert 6 in q and 789 notin q assert q.find(6) >= 0 diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index e8e725aa3..06e96ca36 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -13,12 +13,15 @@ ## were inspired by functional programming languages. ## ## For functional style programming you may want to pass `anonymous procs -## <manual.html#anonymous-procs>`_ to procs like ``filter`` to reduce typing. -## Anonymous procs can use `the special do notation <manual.html#do-notation>`_ +## <manual.html#procedures-anonymous-procs>`_ to procs like ``filter`` to +## reduce typing. Anonymous procs can use `the special do notation +## <manual.html#procedures-do-notation>`_ ## which is more convenient in certain situations. include "system/inclrtl" +import macros + when not defined(nimhygiene): {.pragma: dirty.} @@ -43,12 +46,27 @@ proc concat*[T](seqs: varargs[seq[T]]): seq[T] = result[i] = itm inc(i) -proc cycle*[T](s: seq[T], n: Natural): seq[T] = - ## Returns a new sequence with the items of `s` repeated `n` times. +proc count*[T](s: openArray[T], x: T): int = + ## Returns the number of occurrences of the item `x` in the container `s`. + ## + ## Example: + ## + ## .. code-block:: + ## let + ## s = @[1, 2, 2, 3, 2, 4, 2] + ## c = count(s, 2) + ## assert c == 4 + for itm in items(s): + if itm == x: + inc result + +proc cycle*[T](s: openArray[T], n: Natural): seq[T] = + ## Returns a new sequence with the items of the container `s` repeated + ## `n` times. ## ## Example: ## - ## .. code-block: + ## .. code-block:: ## ## let ## s = @[1, 2, 3] @@ -56,7 +74,7 @@ proc cycle*[T](s: seq[T], n: Natural): seq[T] = ## assert total == @[1, 2, 3, 1, 2, 3, 1, 2, 3] result = newSeq[T](n * s.len) var o = 0 - for x in 0..<n: + for x in 0 ..< n: for e in s: result[o] = e inc o @@ -66,18 +84,20 @@ proc repeat*[T](x: T, n: Natural): seq[T] = ## ## Example: ## - ## .. code-block: + ## .. code-block:: ## ## let ## total = repeat(5, 3) ## assert total == @[5, 5, 5] result = newSeq[T](n) - for i in 0..<n: + for i in 0 ..< n: result[i] = x -proc deduplicate*[T](seq1: seq[T]): seq[T] = +proc deduplicate*[T](s: openArray[T]): seq[T] = ## Returns a new sequence without duplicates. ## + ## Example: + ## ## .. code-block:: ## let ## dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4] @@ -87,17 +107,17 @@ proc deduplicate*[T](seq1: seq[T]): seq[T] = ## assert unique1 == @[1, 3, 4, 2, 8] ## assert unique2 == @["a", "c", "d"] result = @[] - for itm in items(seq1): + for itm in items(s): if not result.contains(itm): result.add(itm) -{.deprecated: [distnct: deduplicate].} - -proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] = - ## Returns a new sequence with a combination of the two input sequences. +proc zip*[S, T](s1: openArray[S], s2: openArray[T]): seq[tuple[a: S, b: T]] = + ## Returns a new sequence with a combination of the two input containers. ## ## For convenience you can access the returned tuples through the named - ## fields `a` and `b`. If one sequence is shorter, the remaining items in the - ## longer sequence are discarded. Example: + ## fields `a` and `b`. If one container is shorter, the remaining items in + ## the longer container are discarded. + ## + ## Example: ## ## .. code-block:: ## let @@ -110,15 +130,16 @@ proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] = ## assert zip2 == @[(1, "one"), (2, "two"), (3, "three")] ## assert zip1[2].b == 4 ## assert zip2[2].b == "three" - var m = min(seq1.len, seq2.len) + var m = min(s1.len, s2.len) newSeq(result, m) - for i in 0 .. m-1: result[i] = (seq1[i], seq2[i]) + for i in 0 ..< m: + result[i] = (s1[i], s2[i]) proc distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] = ## Splits and distributes a sequence `s` into `num` sub sequences. ## ## Returns a sequence of `num` sequences. For some input values this is the - ## inverse of the `concat <#concat>`_ proc. The proc will assert in debug + ## inverse of the `concat <#concat>`_ proc. The proc will assert in debug ## builds if `s` is nil or `num` is less than one, and will likely crash on ## release builds. The input sequence `s` can be empty, which will produce ## `num` empty sequences. @@ -159,48 +180,52 @@ proc distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] = # Use an algorithm which overcounts the stride and minimizes reading limits. if extra > 0: inc(stride) - for i in 0 .. <num: + for i in 0 ..< num: result[i] = newSeq[T]() - for g in first .. <min(s.len, first + stride): + for g in first ..< min(s.len, first + stride): result[i].add(s[g]) first += stride else: # Use an undercounting algorithm which *adds* the remainder each iteration. - for i in 0 .. <num: + for i in 0 ..< num: last = first + stride if extra > 0: extra -= 1 inc(last) result[i] = newSeq[T]() - for g in first .. <last: + for g in first ..< last: result[i].add(s[g]) first = last - -proc map*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): +proc map*[T, S](s: openArray[T], op: proc (x: T): S {.closure.}): seq[S]{.inline.} = ## Returns a new sequence with the results of `op` applied to every item in - ## `data`. + ## the container `s`. ## ## Since the input is not modified you can use this version of ``map`` to - ## transform the type of the elements in the input sequence. Example: + ## transform the type of the elements in the input container. + ## + ## Example: ## ## .. code-block:: nim ## let ## a = @[1, 2, 3, 4] ## b = map(a, proc(x: int): string = $x) ## assert b == @["1", "2", "3", "4"] - newSeq(result, data.len) - for i in 0..data.len-1: result[i] = op(data[i]) + newSeq(result, s.len) + for i in 0 ..< s.len: + result[i] = op(s[i]) -proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) +proc map*[T](s: var openArray[T], op: proc (x: var T) {.closure.}) {.deprecated.} = - ## Applies `op` to every item in `data` modifying it directly. + ## Applies `op` to every item in `s` modifying it directly. ## ## Note that this version of ``map`` requires your input and output types to - ## be the same, since they are modified in-place. Example: + ## be the same, since they are modified in-place. + ## + ## Example: ## ## .. code-block:: nim ## var a = @["1", "2", "3", "4"] @@ -210,15 +235,16 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) ## echo repr(a) ## # --> ["142", "242", "342", "442"] ## **Deprecated since version 0.12.0:** Use the ``apply`` proc instead. - for i in 0..data.len-1: op(data[i]) + for i in 0 ..< s.len: op(s[i]) -proc apply*[T](data: var seq[T], op: proc (x: var T) {.closure.}) +proc apply*[T](s: var openArray[T], op: proc (x: var T) {.closure.}) {.inline.} = - ## Applies `op` to every item in `data` modifying it directly. + ## Applies `op` to every item in `s` modifying it directly. ## ## Note that this requires your input and output types to ## be the same, since they are modified in-place. ## The parameter function takes a ``var T`` type parameter. + ## ## Example: ## ## .. code-block:: nim @@ -229,15 +255,16 @@ proc apply*[T](data: var seq[T], op: proc (x: var T) {.closure.}) ## echo repr(a) ## # --> ["142", "242", "342", "442"] ## - for i in 0..data.len-1: op(data[i]) + for i in 0 ..< s.len: op(s[i]) -proc apply*[T](data: var seq[T], op: proc (x: T): T {.closure.}) +proc apply*[T](s: var openArray[T], op: proc (x: T): T {.closure.}) {.inline.} = - ## Applies `op` to every item in `data` modifying it directly. + ## Applies `op` to every item in `s` modifying it directly. ## ## Note that this requires your input and output types to ## be the same, since they are modified in-place. ## The parameter function takes and returns a ``T`` type variable. + ## ## Example: ## ## .. code-block:: nim @@ -248,11 +275,10 @@ proc apply*[T](data: var seq[T], op: proc (x: T): T {.closure.}) ## echo repr(a) ## # --> ["142", "242", "342", "442"] ## - for i in 0..data.len-1: data[i] = op(data[i]) - + for i in 0 ..< s.len: s[i] = op(s[i]) -iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T = - ## Iterates through a sequence and yields every item that fulfills the +iterator filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): T = + ## Iterates through a container and yields every item that fulfills the ## predicate. ## ## Example: @@ -262,11 +288,11 @@ iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T = ## for n in filter(numbers, proc (x: int): bool = x mod 2 == 0): ## echo($n) ## # echoes 4, 8, 4 in separate lines - for i in 0..<seq1.len: - if pred(seq1[i]): - yield seq1[i] + for i in 0 ..< s.len: + if pred(s[i]): + yield s[i] -proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T] +proc filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): seq[T] {.inline.} = ## Returns a new sequence with all the items that fulfilled the predicate. ## @@ -280,11 +306,11 @@ proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T] ## assert f1 == @["red", "black"] ## assert f2 == @["yellow"] result = newSeq[T]() - for i in 0..<seq1.len: - if pred(seq1[i]): - result.add(seq1[i]) + for i in 0 ..< s.len: + if pred(s[i]): + result.add(s[i]) -proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.}) +proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.}) {.inline.} = ## Keeps the items in the passed sequence if they fulfilled the predicate. ## Same as the ``filter`` proc, but modifies the sequence directly. @@ -296,12 +322,12 @@ proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.}) ## keepIf(floats, proc(x: float): bool = x > 10) ## assert floats == @[13.0, 12.5, 10.1] var pos = 0 - for i in 0 .. <len(seq1): - if pred(seq1[i]): + for i in 0 ..< len(s): + if pred(s[i]): if pos != i: - shallowCopy(seq1[pos], seq1[i]) + shallowCopy(s[pos], s[i]) inc(pos) - setLen(seq1, pos) + setLen(s, pos) proc delete*[T](s: var seq[T]; first, last: Natural) = ## Deletes in `s` the items at position `first` .. `last`. This modifies @@ -354,11 +380,12 @@ proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) = inc(j) -template filterIt*(seq1, pred: untyped): untyped = +template filterIt*(s, pred: untyped): untyped = ## Returns a new sequence with all the items that fulfilled the predicate. ## ## Unlike the `proc` version, the predicate needs to be an expression using ## the ``it`` variable for testing, like: ``filterIt("abcxyz", it == 'x')``. + ## ## Example: ## ## .. code-block:: @@ -368,8 +395,8 @@ template filterIt*(seq1, pred: untyped): untyped = ## notAcceptable = filterIt(temperatures, it > 50 or it < -10) ## assert acceptable == @[-2.0, 24.5, 44.31] ## assert notAcceptable == @[-272.15, 99.9, -113.44] - var result = newSeq[type(seq1[0])]() - for it {.inject.} in items(seq1): + var result = newSeq[type(s[0])]() + for it {.inject.} in items(s): if pred: result.add(it) result @@ -378,6 +405,7 @@ template keepItIf*(varSeq: seq, pred: untyped) = ## ## Unlike the `proc` version, the predicate needs to be an expression using ## the ``it`` variable for testing, like: ``keepItIf("abcxyz", it == 'x')``. + ## ## Example: ## ## .. code-block:: @@ -385,7 +413,7 @@ template keepItIf*(varSeq: seq, pred: untyped) = ## keepItIf(candidates, it.len == 3 and it[0] == 'b') ## assert candidates == @["bar", "baz"] var pos = 0 - for i in 0 .. <len(varSeq): + for i in 0 ..< len(varSeq): let it {.inject.} = varSeq[i] if pred: if pos != i: @@ -393,8 +421,8 @@ template keepItIf*(varSeq: seq, pred: untyped) = inc(pos) setLen(varSeq, pos) -proc all*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = - ## Iterates through a sequence and checks if every item fulfills the +proc all*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool = + ## Iterates through a container and checks if every item fulfills the ## predicate. ## ## Example: @@ -403,12 +431,12 @@ proc all*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = ## let numbers = @[1, 4, 5, 8, 9, 7, 4] ## assert all(numbers, proc (x: int): bool = return x < 10) == true ## assert all(numbers, proc (x: int): bool = return x < 9) == false - for i in seq1: + for i in s: if not pred(i): return false return true -template allIt*(seq1, pred: untyped): bool = +template allIt*(s, pred: untyped): bool = ## Checks if every item fulfills the predicate. ## ## Example: @@ -418,14 +446,14 @@ template allIt*(seq1, pred: untyped): bool = ## assert allIt(numbers, it < 10) == true ## assert allIt(numbers, it < 9) == false var result = true - for it {.inject.} in items(seq1): + for it {.inject.} in items(s): if not pred: result = false break result -proc any*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = - ## Iterates through a sequence and checks if some item fulfills the +proc any*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool = + ## Iterates through a container and checks if some item fulfills the ## predicate. ## ## Example: @@ -434,12 +462,12 @@ proc any*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = ## let numbers = @[1, 4, 5, 8, 9, 7, 4] ## assert any(numbers, proc (x: int): bool = return x > 8) == true ## assert any(numbers, proc (x: int): bool = return x > 9) == false - for i in seq1: + for i in s: if pred(i): return true return false -template anyIt*(seq1, pred: untyped): bool = +template anyIt*(s, pred: untyped): bool = ## Checks if some item fulfills the predicate. ## ## Example: @@ -449,7 +477,7 @@ template anyIt*(seq1, pred: untyped): bool = ## assert anyIt(numbers, it > 8) == true ## assert anyIt(numbers, it > 9) == false var result = false - for it {.inject.} in items(seq1): + for it {.inject.} in items(s): if pred: result = true break @@ -493,7 +521,9 @@ template foldl*(sequence, operation: untyped): untyped = ## variables ``a`` and ``b`` for each step of the fold. Since this is a left ## fold, for non associative binary operations like subtraction think that ## the sequence of numbers 1, 2 and 3 will be parenthesized as (((1) - 2) - - ## 3). Example: + ## 3). + ## + ## Example: ## ## .. code-block:: ## let @@ -527,6 +557,7 @@ template foldl*(sequence, operation, first): untyped = ## The ``operation`` parameter should be an expression which uses the variables ## ``a`` and ``b`` for each step of the fold. The ``first`` parameter is the ## start value (the first ``a``) and therefor defines the type of the result. + ## ## Example: ## ## .. code-block:: @@ -555,7 +586,9 @@ template foldr*(sequence, operation: untyped): untyped = ## variables ``a`` and ``b`` for each step of the fold. Since this is a right ## fold, for non associative binary operations like subtraction think that ## the sequence of numbers 1, 2 and 3 will be parenthesized as (1 - (2 - - ## (3))). Example: + ## (3))). + ## + ## Example: ## ## .. code-block:: ## let @@ -580,13 +613,15 @@ template foldr*(sequence, operation: untyped): untyped = result = operation result -template mapIt*(seq1, typ, op: untyped): untyped = +template mapIt*(s, typ, op: untyped): untyped = ## Convenience template around the ``map`` proc to reduce typing. ## ## The template injects the ``it`` variable which you can use directly in an ## expression. You also need to pass as `typ` the type of the expression, ## since the new returned sequence can have a different type than the - ## original. Example: + ## original. + ## + ## Example: ## ## .. code-block:: ## let @@ -596,16 +631,18 @@ template mapIt*(seq1, typ, op: untyped): untyped = ## **Deprecated since version 0.12.0:** Use the ``mapIt(seq1, op)`` ## template instead. var result: seq[typ] = @[] - for it {.inject.} in items(seq1): + for it {.inject.} in items(s): result.add(op) result -template mapIt*(seq1, op: untyped): untyped = +template mapIt*(s, op: untyped): untyped = ## Convenience template around the ``map`` proc to reduce typing. ## ## The template injects the ``it`` variable which you can use directly in an - ## expression. Example: + ## expression. + ## + ## Example: ## ## .. code-block:: ## let @@ -614,19 +651,19 @@ template mapIt*(seq1, op: untyped): untyped = ## assert strings == @["4", "8", "12", "16"] type outType = type(( block: - var it{.inject.}: type(items(seq1)); + var it{.inject.}: type(items(s)); op)) var result: seq[outType] - when compiles(seq1.len): - let s = seq1 + when compiles(s.len): + let t = s var i = 0 result = newSeq[outType](s.len) - for it {.inject.} in s: + for it {.inject.} in t: result[i] = op i += 1 else: result = @[] - for it {.inject.} in seq1: + for it {.inject.} in s: result.add(op) result @@ -635,20 +672,23 @@ template applyIt*(varSeq, op: untyped) = ## ## The template injects the ``it`` variable which you can use directly in an ## expression. The expression has to return the same type as the sequence you - ## are mutating. Example: + ## are mutating. + ## + ## Example: ## ## .. code-block:: ## var nums = @[1, 2, 3, 4] ## nums.applyIt(it * 3) ## assert nums[0] + nums[3] == 15 - for i in 0 .. <varSeq.len: + for i in 0 ..< varSeq.len: let it {.inject.} = varSeq[i] varSeq[i] = op - template newSeqWith*(len: int, init: untyped): untyped = - ## creates a new sequence, calling `init` to initialize each value. Example: + ## creates a new sequence, calling `init` to initialize each value. + ## + ## Example: ## ## .. code-block:: ## var seq2D = newSeqWith(20, newSeq[bool](10)) @@ -660,10 +700,56 @@ template newSeqWith*(len: int, init: untyped): untyped = ## var seqRand = newSeqWith(20, random(10)) ## echo seqRand var result = newSeq[type(init)](len) - for i in 0 .. <len: + for i in 0 ..< len: result[i] = init result +proc mapLitsImpl(constructor: NimNode; op: NimNode; nested: bool; + filter = nnkLiterals): NimNode = + if constructor.kind in filter: + result = newNimNode(nnkCall, lineInfoFrom=constructor) + result.add op + result.add constructor + else: + result = newNimNode(constructor.kind, lineInfoFrom=constructor) + for v in constructor: + if nested or v.kind in filter: + result.add mapLitsImpl(v, op, nested, filter) + else: + result.add v + +macro mapLiterals*(constructor, op: untyped; + nested = true): untyped = + ## applies ``op`` to each of the **atomic** literals like ``3`` + ## or ``"abc"`` in the specified ``constructor`` AST. This can + ## be used to map every array element to some target type: + ## + ## Example: + ## + ## .. code-block:: + ## let x = mapLiterals([0.1, 1.2, 2.3, 3.4], int) + ## doAssert x is array[4, int] + ## + ## Short notation for: + ## + ## .. code-block:: + ## let x = [int(0.1), int(1.2), int(2.3), int(3.4)] + ## + ## If ``nested`` is true, the literals are replaced everywhere + ## in the ``constructor`` AST, otherwise only the first level + ## is considered: + ## + ## .. code-block:: + ## mapLiterals((1, ("abc"), 2), float, nested=false) + ## + ## Produces:: + ## + ## (float(1), ("abc"), float(2)) + ## + ## There are no constraints for the ``constructor`` AST, it + ## works for nested tuples of arrays of sets etc. + result = mapLitsImpl(constructor, op, nested.boolVal) + when isMainModule: import strutils block: # concat test @@ -674,45 +760,178 @@ when isMainModule: total = concat(s1, s2, s3) assert total == @[1, 2, 3, 4, 5, 6, 7] - block: # duplicates test + block: # count test + let + s1 = @[1, 2, 3, 2] + s2 = @['a', 'b', 'x', 'a'] + a1 = [1, 2, 3, 2] + a2 = ['a', 'b', 'x', 'a'] + r0 = count(s1, 0) + r1 = count(s1, 1) + r2 = count(s1, 2) + r3 = count(s2, 'y') + r4 = count(s2, 'x') + r5 = count(s2, 'a') + ar0 = count(a1, 0) + ar1 = count(a1, 1) + ar2 = count(a1, 2) + ar3 = count(a2, 'y') + ar4 = count(a2, 'x') + ar5 = count(a2, 'a') + assert r0 == 0 + assert r1 == 1 + assert r2 == 2 + assert r3 == 0 + assert r4 == 1 + assert r5 == 2 + assert ar0 == 0 + assert ar1 == 1 + assert ar2 == 2 + assert ar3 == 0 + assert ar4 == 1 + assert ar5 == 2 + + block: # cycle tests + let + a = @[1, 2, 3] + b: seq[int] = @[] + c = [1, 2, 3] + + doAssert a.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] + doAssert a.cycle(0) == @[] + #doAssert a.cycle(-1) == @[] # will not compile! + doAssert b.cycle(3) == @[] + doAssert c.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] + doAssert c.cycle(0) == @[] + + block: # repeat tests + assert repeat(10, 5) == @[10, 10, 10, 10, 10] + assert repeat(@[1,2,3], 2) == @[@[1,2,3], @[1,2,3]] + assert repeat([1,2,3], 2) == @[[1,2,3], [1,2,3]] + + block: # deduplicates test let dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4] dup2 = @["a", "a", "c", "d", "d"] + dup3 = [1, 1, 3, 4, 2, 2, 8, 1, 4] + dup4 = ["a", "a", "c", "d", "d"] unique1 = deduplicate(dup1) unique2 = deduplicate(dup2) + unique3 = deduplicate(dup3) + unique4 = deduplicate(dup4) assert unique1 == @[1, 3, 4, 2, 8] assert unique2 == @["a", "c", "d"] + assert unique3 == @[1, 3, 4, 2, 8] + assert unique4 == @["a", "c", "d"] block: # zip test let short = @[1, 2, 3] long = @[6, 5, 4, 3, 2, 1] words = @["one", "two", "three"] + ashort = [1, 2, 3] + along = [6, 5, 4, 3, 2, 1] + awords = ["one", "two", "three"] zip1 = zip(short, long) zip2 = zip(short, words) + zip3 = zip(ashort, along) + zip4 = zip(ashort, awords) + zip5 = zip(ashort, words) assert zip1 == @[(1, 6), (2, 5), (3, 4)] assert zip2 == @[(1, "one"), (2, "two"), (3, "three")] + assert zip3 == @[(1, 6), (2, 5), (3, 4)] + assert zip4 == @[(1, "one"), (2, "two"), (3, "three")] + assert zip5 == @[(1, "one"), (2, "two"), (3, "three")] assert zip1[2].b == 4 assert zip2[2].b == "three" + assert zip3[2].b == 4 + assert zip4[2].b == "three" + assert zip5[2].b == "three" + + block: # distribute tests + let numbers = @[1, 2, 3, 4, 5, 6, 7] + doAssert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]] + doAssert numbers.distribute(6)[0] == @[1, 2] + doAssert numbers.distribute(6)[5] == @[7] + let a = @[1, 2, 3, 4, 5, 6, 7] + doAssert a.distribute(1, true) == @[@[1, 2, 3, 4, 5, 6, 7]] + doAssert a.distribute(1, false) == @[@[1, 2, 3, 4, 5, 6, 7]] + doAssert a.distribute(2, true) == @[@[1, 2, 3, 4], @[5, 6, 7]] + doAssert a.distribute(2, false) == @[@[1, 2, 3, 4], @[5, 6, 7]] + doAssert a.distribute(3, true) == @[@[1, 2, 3], @[4, 5], @[6, 7]] + doAssert a.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]] + doAssert a.distribute(4, true) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] + doAssert a.distribute(4, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] + doAssert a.distribute(5, true) == @[@[1, 2], @[3, 4], @[5], @[6], @[7]] + doAssert a.distribute(5, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]] + doAssert a.distribute(6, true) == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]] + doAssert a.distribute(6, false) == @[ + @[1, 2], @[3, 4], @[5, 6], @[7], @[], @[]] + doAssert a.distribute(8, false) == a.distribute(8, true) + doAssert a.distribute(90, false) == a.distribute(90, true) + var b = @[0] + for f in 1 .. 25: b.add(f) + doAssert b.distribute(5, true)[4].len == 5 + doAssert b.distribute(5, false)[4].len == 2 + + block: # map test + let + numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] + m1 = map(numbers, proc(x: int): int = 2*x) + m2 = map(anumbers, proc(x: int): int = 2*x) + assert m1 == @[2, 8, 10, 16, 18, 14, 8] + assert m2 == @[2, 8, 10, 16, 18, 14, 8] + + block: # apply test + var a = @["1", "2", "3", "4"] + apply(a, proc(x: var string) = x &= "42") + assert a == @["142", "242", "342", "442"] block: # filter proc test let colors = @["red", "yellow", "black"] + acolors = ["red", "yellow", "black"] f1 = filter(colors, proc(x: string): bool = x.len < 6) f2 = filter(colors) do (x: string) -> bool : x.len > 5 + f3 = filter(acolors, proc(x: string): bool = x.len < 6) + f4 = filter(acolors) do (x: string) -> bool : x.len > 5 assert f1 == @["red", "black"] assert f2 == @["yellow"] + assert f3 == @["red", "black"] + assert f4 == @["yellow"] block: # filter iterator test let numbers = @[1, 4, 5, 8, 9, 7, 4] + let anumbers = [1, 4, 5, 8, 9, 7, 4] assert toSeq(filter(numbers, proc (x: int): bool = x mod 2 == 0)) == @[4, 8, 4] + assert toSeq(filter(anumbers, proc (x: int): bool = x mod 2 == 0)) == + @[4, 8, 4] block: # keepIf test var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1] keepIf(floats, proc(x: float): bool = x > 10) assert floats == @[13.0, 12.5, 10.1] + block: # delete tests + let outcome = @[1,1,1,1,1,1,1,1] + var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] + dest.delete(3, 8) + assert outcome == dest, """\ + Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1] + is [1,1,1,1,1,1,1,1]""" + + block: # insert tests + var dest = @[1,1,1,1,1,1,1,1] + let + src = @[2,2,2,2,2,2] + outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] + dest.insert(src, 3) + assert dest == outcome, """\ + Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1] + at 3 is [1,1,1,2,2,2,2,2,2,1,1,1,1,1]""" + block: # filterIt test let temperatures = @[-272.15, -2.0, 24.5, 44.31, 99.9, -113.44] @@ -726,37 +945,49 @@ when isMainModule: keepItIf(candidates, it.len == 3 and it[0] == 'b') assert candidates == @["bar", "baz"] - block: # any - let - numbers = @[1, 4, 5, 8, 9, 7, 4] - len0seq : seq[int] = @[] - assert any(numbers, proc (x: int): bool = return x > 8) == true - assert any(numbers, proc (x: int): bool = return x > 9) == false - assert any(len0seq, proc (x: int): bool = return true) == false - - block: # anyIt - let - numbers = @[1, 4, 5, 8, 9, 7, 4] - len0seq : seq[int] = @[] - assert anyIt(numbers, it > 8) == true - assert anyIt(numbers, it > 9) == false - assert anyIt(len0seq, true) == false - block: # all let numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] len0seq : seq[int] = @[] assert all(numbers, proc (x: int): bool = return x < 10) == true assert all(numbers, proc (x: int): bool = return x < 9) == false assert all(len0seq, proc (x: int): bool = return false) == true + assert all(anumbers, proc (x: int): bool = return x < 10) == true + assert all(anumbers, proc (x: int): bool = return x < 9) == false block: # allIt let numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] len0seq : seq[int] = @[] assert allIt(numbers, it < 10) == true assert allIt(numbers, it < 9) == false assert allIt(len0seq, false) == true + assert allIt(anumbers, it < 10) == true + assert allIt(anumbers, it < 9) == false + + block: # any + let + numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] + len0seq : seq[int] = @[] + assert any(numbers, proc (x: int): bool = return x > 8) == true + assert any(numbers, proc (x: int): bool = return x > 9) == false + assert any(len0seq, proc (x: int): bool = return true) == false + assert any(anumbers, proc (x: int): bool = return x > 8) == true + assert any(anumbers, proc (x: int): bool = return x > 9) == false + + block: # anyIt + let + numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] + len0seq : seq[int] = @[] + assert anyIt(numbers, it > 8) == true + assert anyIt(numbers, it > 9) == false + assert anyIt(len0seq, true) == false + assert anyIt(anumbers, it > 8) == true + assert anyIt(anumbers, it > 9) == false block: # toSeq test let @@ -792,56 +1023,13 @@ when isMainModule: assert multiplication == 495, "Multiplication is (5*(9*(11)))" assert concatenation == "nimiscool" - block: # delete tests - let outcome = @[1,1,1,1,1,1,1,1] - var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] - dest.delete(3, 8) - assert outcome == dest, """\ - Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1] - is [1,1,1,1,1,1,1,1]""" - - block: # insert tests - var dest = @[1,1,1,1,1,1,1,1] - let - src = @[2,2,2,2,2,2] - outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] - dest.insert(src, 3) - assert dest == outcome, """\ - Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1] - at 3 is [1,1,1,2,2,2,2,2,2,1,1,1,1,1]""" - block: # mapIt tests var nums = @[1, 2, 3, 4] strings = nums.mapIt($(4 * it)) nums.applyIt(it * 3) assert nums[0] + nums[3] == 15 - - block: # distribute tests - let numbers = @[1, 2, 3, 4, 5, 6, 7] - doAssert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]] - doAssert numbers.distribute(6)[0] == @[1, 2] - doAssert numbers.distribute(6)[5] == @[7] - let a = @[1, 2, 3, 4, 5, 6, 7] - doAssert a.distribute(1, true) == @[@[1, 2, 3, 4, 5, 6, 7]] - doAssert a.distribute(1, false) == @[@[1, 2, 3, 4, 5, 6, 7]] - doAssert a.distribute(2, true) == @[@[1, 2, 3, 4], @[5, 6, 7]] - doAssert a.distribute(2, false) == @[@[1, 2, 3, 4], @[5, 6, 7]] - doAssert a.distribute(3, true) == @[@[1, 2, 3], @[4, 5], @[6, 7]] - doAssert a.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]] - doAssert a.distribute(4, true) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] - doAssert a.distribute(4, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7]] - doAssert a.distribute(5, true) == @[@[1, 2], @[3, 4], @[5], @[6], @[7]] - doAssert a.distribute(5, false) == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]] - doAssert a.distribute(6, true) == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]] - doAssert a.distribute(6, false) == @[ - @[1, 2], @[3, 4], @[5, 6], @[7], @[], @[]] - doAssert a.distribute(8, false) == a.distribute(8, true) - doAssert a.distribute(90, false) == a.distribute(90, true) - var b = @[0] - for f in 1 .. 25: b.add(f) - doAssert b.distribute(5, true)[4].len == 5 - doAssert b.distribute(5, false)[4].len == 2 + assert strings[2] == "12" block: # newSeqWith tests var seq2D = newSeqWith(4, newSeq[bool](2)) @@ -850,19 +1038,11 @@ when isMainModule: seq2D[0][1] = true doAssert seq2D == @[@[true, true], @[true, false], @[false, false], @[false, false]] - block: # cycle tests - let - a = @[1, 2, 3] - b: seq[int] = @[] - - doAssert a.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3] - doAssert a.cycle(0) == @[] - #doAssert a.cycle(-1) == @[] # will not compile! - doAssert b.cycle(3) == @[] - - block: # repeat tests - assert repeat(10, 5) == @[10, 10, 10, 10, 10] - assert repeat(@[1,2,3], 2) == @[@[1,2,3], @[1,2,3]] + block: # mapLiterals tests + let x = mapLiterals([0.1, 1.2, 2.3, 3.4], int) + doAssert x is array[4, int] + doAssert mapLiterals((1, ("abc"), 2), float, nested=false) == (float(1), "abc", float(2)) + doAssert mapLiterals(([1], ("abc"), 2), `$`, nested=true) == (["1"], "abc", "2") when not defined(testing): echo "Finished doc tests" diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index dbdf17514..9e9152fc8 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -46,7 +46,7 @@ template default[T](t: typedesc[T]): T = var v: T v -proc clear*[A](s: var HashSet[A]) = +proc clear*[A](s: var HashSet[A]) = ## Clears the HashSet back to an empty state, without shrinking ## any of the existing storage. O(n) where n is the size of the hash bucket. s.counter = 0 @@ -406,7 +406,7 @@ template dollarImpl() {.dirty.} = result = "{" for key in items(s): if result.len > 1: result.add(", ") - result.add($key) + result.addQuoted(key) result.add("}") proc `$`*[A](s: HashSet[A]): string = @@ -610,7 +610,7 @@ type {.deprecated: [TOrderedSet: OrderedSet].} -proc clear*[A](s: var OrderedSet[A]) = +proc clear*[A](s: var OrderedSet[A]) = ## Clears the OrderedSet back to an empty state, without shrinking ## any of the existing storage. O(n) where n is the size of the hash bucket. s.counter = 0 @@ -911,13 +911,13 @@ proc `==`*[A](s, t: OrderedSet[A]): bool = ## Equality for ordered sets. if s.counter != t.counter: return false var h = s.first - var g = s.first + var g = t.first var compared = 0 while h >= 0 and g >= 0: var nxh = s.data[h].next var nxg = t.data[g].next - if isFilled(s.data[h].hcode) and isFilled(s.data[g].hcode): - if s.data[h].key == s.data[g].key: + if isFilled(s.data[h].hcode) and isFilled(t.data[g].hcode): + if s.data[h].key == t.data[g].key: inc compared else: return false @@ -1120,6 +1120,22 @@ when isMainModule and not defined(release): assert s.missingOrExcl(4) == true assert s.missingOrExcl(6) == false + block orderedSetEquality: + type pair = tuple[a, b: int] + + var aa = initOrderedSet[pair]() + var bb = initOrderedSet[pair]() + + var x = (a:1,b:2) + var y = (a:3,b:4) + + aa.incl(x) + aa.incl(y) + + bb.incl(x) + bb.incl(y) + assert aa == bb + when not defined(testing): echo "Micro tests run successfully." diff --git a/lib/pure/collections/sharedlist.nim b/lib/pure/collections/sharedlist.nim index e93ceb02f..b3e677b79 100644 --- a/lib/pure/collections/sharedlist.nim +++ b/lib/pure/collections/sharedlist.nim @@ -73,10 +73,10 @@ proc add*[A](x: var SharedList[A]; y: A) = node.d[node.dataLen] = y inc(node.dataLen) -proc initSharedList*[A](): SharedList[A] = - initLock result.lock - result.head = nil - result.tail = nil +proc init*[A](t: var SharedList[A]) = + initLock t.lock + t.head = nil + t.tail = nil proc clear*[A](t: var SharedList[A]) = withLock(t): @@ -92,4 +92,11 @@ proc deinitSharedList*[A](t: var SharedList[A]) = clear(t) deinitLock t.lock +proc initSharedList*[A](): SharedList[A] {.deprecated.} = + ## Deprecated. Use `init` instead. + ## This is not posix compliant, may introduce undefined behavior. + initLock result.lock + result.head = nil + result.tail = nil + {.pop.} diff --git a/lib/pure/collections/sharedstrings.nim b/lib/pure/collections/sharedstrings.nim index a9e194fb4..7e9de4b73 100644 --- a/lib/pure/collections/sharedstrings.nim +++ b/lib/pure/collections/sharedstrings.nim @@ -55,7 +55,7 @@ proc `[]=`*(s: var SharedString; i: Natural; value: char) = if i < s.len: s.buffer.data[i+s.first] = value else: raise newException(IndexError, "index out of bounds") -proc `[]`*(s: SharedString; ab: Slice[int]): SharedString = +proc `[]`*(s: SharedString; ab: HSlice[int, int]): SharedString = #incRef(src.buffer) if ab.a < s.len: result.buffer = s.buffer @@ -87,10 +87,10 @@ proc newSharedString*(s: string): SharedString = result.len = len when declared(atomicLoadN): - template load(x): expr = atomicLoadN(addr x, ATOMIC_SEQ_CST) + template load(x): untyped = atomicLoadN(addr x, ATOMIC_SEQ_CST) else: # XXX Fixme - template load(x): expr = x + template load(x): untyped = x proc add*(s: var SharedString; t: cstring; len: Natural) = if len == 0: return diff --git a/lib/pure/collections/sharedtables.nim b/lib/pure/collections/sharedtables.nim index fc50ea41c..4f311af87 100644 --- a/lib/pure/collections/sharedtables.nim +++ b/lib/pure/collections/sharedtables.nim @@ -183,6 +183,7 @@ proc `[]=`*[A, B](t: var SharedTable[A, B], key: A, val: B) = proc add*[A, B](t: var SharedTable[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. + ## This can introduce duplicate keys into the table! withLock t: addImpl(enlarge) @@ -191,19 +192,29 @@ proc del*[A, B](t: var SharedTable[A, B], key: A) = withLock t: delImpl() -proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] = +proc init*[A, B](t: var SharedTable[A, B], initialSize=64) = ## creates a new hash table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime ## values for this you could use the ``nextPowerOfTwo`` proc from the ## `math <math.html>`_ module or the ``rightSize`` proc from this module. assert isPowerOfTwo(initialSize) - result.counter = 0 - result.dataLen = initialSize - result.data = cast[KeyValuePairSeq[A, B]](allocShared0( + t.counter = 0 + t.dataLen = initialSize + t.data = cast[KeyValuePairSeq[A, B]](allocShared0( sizeof(KeyValuePair[A, B]) * initialSize)) - initLock result.lock + initLock t.lock proc deinitSharedTable*[A, B](t: var SharedTable[A, B]) = deallocShared(t.data) deinitLock t.lock + +proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] {.deprecated.} = + ## Deprecated. Use `init` instead. + ## This is not posix compliant, may introduce undefined behavior. + assert isPowerOfTwo(initialSize) + result.counter = 0 + result.dataLen = initialSize + result.data = cast[KeyValuePairSeq[A, B]](allocShared0( + sizeof(KeyValuePair[A, B]) * initialSize)) + initLock result.lock diff --git a/lib/pure/collections/tableimpl.nim b/lib/pure/collections/tableimpl.nim index eec98fcaf..9a5bffcef 100644 --- a/lib/pure/collections/tableimpl.nim +++ b/lib/pure/collections/tableimpl.nim @@ -149,7 +149,7 @@ template delImpl() {.dirty.} = delImplIdx(t, i) template clearImpl() {.dirty.} = - for i in 0 .. <t.data.len: + for i in 0 ..< t.data.len: when compiles(t.data[i].hcode): # CountTable records don't contain a hcode t.data[i].hcode = 0 t.data[i].key = default(type(t.data[i].key)) diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 01a42efab..777beabc3 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -308,6 +308,7 @@ proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) = proc add*[A, B](t: var Table[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. + ## This can introduce duplicate keys into the table! addImpl(enlarge) proc len*[A, B](t: TableRef[A, B]): int = @@ -337,9 +338,9 @@ template dollarImpl(): untyped {.dirty.} = result = "{" for key, val in pairs(t): if result.len > 1: result.add(", ") - result.add($key) + result.addQuoted(key) result.add(": ") - result.add($val) + result.addQuoted(val) result.add("}") proc `$`*[A, B](t: Table[A, B]): string = @@ -430,6 +431,7 @@ proc `[]=`*[A, B](t: TableRef[A, B], key: A, val: B) = proc add*[A, B](t: TableRef[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. + ## This can introduce duplicate keys into the table! t[].add(key, val) proc del*[A, B](t: TableRef[A, B], key: A) = @@ -604,6 +606,7 @@ proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) = proc add*[A, B](t: var OrderedTable[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. + ## This can introduce duplicate keys into the table! addImpl(enlarge) proc mgetOrPut*[A, B](t: var OrderedTable[A, B], key: A, val: B): var B = @@ -770,6 +773,7 @@ proc `[]=`*[A, B](t: OrderedTableRef[A, B], key: A, val: B) = proc add*[A, B](t: OrderedTableRef[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. + ## This can introduce duplicate keys into the table! t[].add(key, val) proc newOrderedTable*[A, B](initialSize=64): OrderedTableRef[A, B] = @@ -962,9 +966,10 @@ proc initCountTable*[A](initialSize=64): CountTable[A] = newSeq(result.data, initialSize) proc toCountTable*[A](keys: openArray[A]): CountTable[A] = - ## creates a new count table with every key in `keys` having a count of 1. + ## creates a new count table with every key in `keys` having a count + ## of how many times it occurs in `keys`. result = initCountTable[A](rightSize(keys.len)) - for key in items(keys): result[key] = 1 + for key in items(keys): result.inc key proc `$`*[A](t: CountTable[A]): string = ## The `$` operator for count tables. @@ -989,9 +994,10 @@ proc inc*[A](t: var CountTable[A], key: A, val = 1) = proc smallest*[A](t: CountTable[A]): tuple[key: A, val: int] = ## returns the (key,val)-pair with the smallest `val`. Efficiency: O(n) assert t.len > 0 - var minIdx = 0 - for h in 1..high(t.data): - if t.data[h].val > 0 and t.data[minIdx].val > t.data[h].val: minIdx = h + var minIdx = -1 + for h in 0..high(t.data): + if t.data[h].val > 0 and (minIdx == -1 or t.data[minIdx].val > t.data[h].val): + minIdx = h result.key = t.data[minIdx].key result.val = t.data[minIdx].val @@ -1325,3 +1331,7 @@ when isMainModule: assert((a == b) == true) assert((b == a) == true) + block: # CountTable.smallest + var t = initCountTable[int]() + for v in items([0, 0, 5, 5, 5]): t.inc(v) + doAssert t.smallest == (0, 2) diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim index 603fee080..f01488811 100644 --- a/lib/pure/concurrency/cpuinfo.nim +++ b/lib/pure/concurrency/cpuinfo.nim @@ -45,8 +45,25 @@ proc countProcessors*(): int {.rtl, extern: "ncpi$1".} = ## returns the numer of the processors/cores the machine has. ## Returns 0 if it cannot be detected. when defined(windows): - var x = getEnv("NUMBER_OF_PROCESSORS") - if x.len > 0: result = parseInt(x.string) + type + SYSTEM_INFO {.final, pure.} = object + u1: int32 + dwPageSize: int32 + lpMinimumApplicationAddress: pointer + lpMaximumApplicationAddress: pointer + dwActiveProcessorMask: ptr int32 + dwNumberOfProcessors: int32 + dwProcessorType: int32 + dwAllocationGranularity: int32 + wProcessorLevel: int16 + wProcessorRevision: int16 + + proc GetSystemInfo(lpSystemInfo: var SYSTEM_INFO) {.stdcall, dynlib: "kernel32", importc: "GetSystemInfo".} + + var + si: SYSTEM_INFO + GetSystemInfo(si) + result = si.dwNumberOfProcessors elif defined(macosx) or defined(bsd): var mib: array[0..3, cint] diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 0f23b7e85..a5eaec86e 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -149,7 +149,7 @@ proc selectWorker(w: ptr Worker; fn: WorkerProc; data: pointer): bool = proc cleanFlowVars(w: ptr Worker) = let q = addr(w.q) acquire(q.lock) - for i in 0 .. <q.len: + for i in 0 ..< q.len: GC_unref(cast[RootRef](q.data[i])) #echo "GC_unref" q.len = 0 @@ -401,7 +401,7 @@ proc setup() = gCpus = p currentPoolSize = min(p, MaxThreadPoolSize) readyWorker = addr(workersData[0]) - for i in 0.. <currentPoolSize: activateWorkerThread(i) + for i in 0..<currentPoolSize: activateWorkerThread(i) proc preferSpawn*(): bool = ## Use this proc to determine quickly if a 'spawn' or a direct call is @@ -446,7 +446,7 @@ proc nimSpawn3(fn: WorkerProc; data: pointer) {.compilerProc.} = # implementation of 'spawn' that is used by the code generator. while true: if selectWorker(readyWorker, fn, data): return - for i in 0.. <currentPoolSize: + for i in 0..<currentPoolSize: if selectWorker(addr(workersData[i]), fn, data): return # determine what to do, but keep in mind this is expensive too: @@ -543,7 +543,7 @@ proc sync*() = var toRelease = 0 while true: var allReady = true - for i in 0 .. <currentPoolSize: + for i in 0 ..< currentPoolSize: if not allReady: break allReady = allReady and workersData[i].ready if allReady: break diff --git a/lib/pure/cookies.nim b/lib/pure/cookies.nim index 7d850798c..8f16717ac 100644 --- a/lib/pure/cookies.nim +++ b/lib/pure/cookies.nim @@ -13,6 +13,15 @@ import strtabs, times proc parseCookies*(s: string): StringTableRef = ## parses cookies into a string table. + ## + ## The proc is meant to parse the Cookie header set by a client, not the + ## "Set-Cookie" header set by servers. + ## + ## Example: + ## + ## .. code-block::Nim + ## doAssert parseCookies("a=1; foo=bar") == {"a": 1, "foo": "bar"}.newStringTable + result = newStringTable(modeCaseInsensitive) var i = 0 while true: @@ -42,7 +51,7 @@ proc setCookie*(key, value: string, domain = "", path = "", if secure: result.add("; Secure") if httpOnly: result.add("; HttpOnly") -proc setCookie*(key, value: string, expires: TimeInfo, +proc setCookie*(key, value: string, expires: DateTime, domain = "", path = "", noName = false, secure = false, httpOnly = false): string = ## Creates a command in the format of @@ -54,9 +63,9 @@ proc setCookie*(key, value: string, expires: TimeInfo, noname, secure, httpOnly) when isMainModule: - var tim = Time(int(getTime()) + 76 * (60 * 60 * 24)) + var tim = fromUnix(getTime().toUnix + 76 * (60 * 60 * 24)) - let cookie = setCookie("test", "value", tim.getGMTime()) + let cookie = setCookie("test", "value", tim.utc) when not defined(testing): echo cookie let start = "Set-Cookie: test=value; Expires=" diff --git a/lib/pure/cstrutils.nim b/lib/pure/cstrutils.nim new file mode 100644 index 000000000..437140892 --- /dev/null +++ b/lib/pure/cstrutils.nim @@ -0,0 +1,79 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module supports helper routines for working with ``cstring`` +## without having to convert ``cstring`` to ``string`` in order to +## save allocations. + +include "system/inclrtl" + +proc toLowerAscii(c: char): char {.inline.} = + if c in {'A'..'Z'}: + result = chr(ord(c) + (ord('a') - ord('A'))) + else: + result = c + +proc startsWith*(s, prefix: cstring): bool {.noSideEffect, + rtl, extern: "csuStartsWith".} = + ## Returns true iff ``s`` starts with ``prefix``. + ## + ## If ``prefix == ""`` true is returned. + var i = 0 + while true: + if prefix[i] == '\0': return true + if s[i] != prefix[i]: return false + inc(i) + +proc endsWith*(s, suffix: cstring): bool {.noSideEffect, + rtl, extern: "csuEndsWith".} = + ## Returns true iff ``s`` ends with ``suffix``. + ## + ## If ``suffix == ""`` true is returned. + let slen = s.len + var i = 0 + var j = slen - len(suffix) + while i+j <% slen: + if s[i+j] != suffix[i]: return false + inc(i) + if suffix[i] == '\0': return true + +proc cmpIgnoreStyle*(a, b: cstring): int {.noSideEffect, + rtl, extern: "csuCmpIgnoreStyle".} = + ## Compares two strings normalized (i.e. case and + ## underscores do not matter). Returns: + ## + ## | 0 iff a == b + ## | < 0 iff a < b + ## | > 0 iff a > b + var i = 0 + var j = 0 + while true: + while a[i] == '_': inc(i) + while b[j] == '_': inc(j) # BUGFIX: typo + var aa = toLowerAscii(a[i]) + var bb = toLowerAscii(b[j]) + result = ord(aa) - ord(bb) + if result != 0 or aa == '\0': break + inc(i) + inc(j) + +proc cmpIgnoreCase*(a, b: cstring): int {.noSideEffect, + rtl, extern: "csuCmpIgnoreCase".} = + ## Compares two strings in a case insensitive manner. Returns: + ## + ## | 0 iff a == b + ## | < 0 iff a < b + ## | > 0 iff a > b + var i = 0 + while true: + var aa = toLowerAscii(a[i]) + var bb = toLowerAscii(b[i]) + result = ord(aa) - ord(bb) + if result != 0 or aa == '\0': break + inc(i) diff --git a/lib/pure/future.nim b/lib/pure/future.nim index 2a6d29933..1a3ab688d 100644 --- a/lib/pure/future.nim +++ b/lib/pure/future.nim @@ -22,7 +22,7 @@ proc createProcType(p, b: NimNode): NimNode {.compileTime.} = case p.kind of nnkPar: - for i in 0 .. <p.len: + for i in 0 ..< p.len: let ident = p[i] var identDefs = newNimNode(nnkIdentDefs) case ident.kind @@ -77,7 +77,7 @@ macro `=>`*(p, b: untyped): untyped = if c[0].kind == nnkIdent and c[0].ident == !"->": var procTy = createProcType(c[1], c[2]) params[0] = procTy[0][0] - for i in 1 .. <procTy[0].len: + for i in 1 ..< procTy[0].len: params.add(procTy[0][i]) else: error("Expected proc type (->) got (" & $c[0].ident & ").") @@ -96,7 +96,7 @@ macro `=>`*(p, b: untyped): untyped = if p[0].kind == nnkIdent and p[0].ident == !"->": var procTy = createProcType(p[1], p[2]) params[0] = procTy[0][0] - for i in 1 .. <procTy[0].len: + for i in 1 ..< procTy[0].len: params.add(procTy[0][i]) else: error("Expected proc type (->) got (" & $p[0].ident & ").") @@ -197,4 +197,4 @@ macro dump*(x: typed): untyped = let s = x.toStrLit let r = quote do: debugEcho `s`, " = ", `x` - return r \ No newline at end of file + return r diff --git a/lib/pure/gentabs.nim b/lib/pure/gentabs.nim deleted file mode 100644 index 928ff8fe0..000000000 --- a/lib/pure/gentabs.nim +++ /dev/null @@ -1,211 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## The ``gentabs`` module implements an efficient hash table that is a -## key-value mapping. The keys are required to be strings, but the values -## may be any Nim or user defined type. This module supports matching -## of keys in case-sensitive, case-insensitive and style-insensitive modes. -## -## **Warning:** This module is deprecated, new code shouldn't use it! - -{.deprecated.} - -import - os, hashes, strutils - -type - GenTableMode* = enum ## describes the table's key matching mode - modeCaseSensitive, ## case sensitive matching of keys - modeCaseInsensitive, ## case insensitive matching of keys - modeStyleInsensitive ## style sensitive matching of keys - - GenKeyValuePair[T] = tuple[key: string, val: T] - GenKeyValuePairSeq[T] = seq[GenKeyValuePair[T]] - GenTable*[T] = object of RootObj - counter: int - data: GenKeyValuePairSeq[T] - mode: GenTableMode - - PGenTable*[T] = ref GenTable[T] ## use this type to declare hash tables - -{.deprecated: [TGenTableMode: GenTableMode, TGenKeyValuePair: GenKeyValuePair, - TGenKeyValuePairSeq: GenKeyValuePairSeq, TGenTable: GenTable].} - -const - growthFactor = 2 - startSize = 64 - - -proc len*[T](tbl: PGenTable[T]): int {.inline.} = - ## returns the number of keys in `tbl`. - result = tbl.counter - -iterator pairs*[T](tbl: PGenTable[T]): tuple[key: string, value: T] = - ## iterates over any (key, value) pair in the table `tbl`. - for h in 0..high(tbl.data): - if not isNil(tbl.data[h].key): - yield (tbl.data[h].key, tbl.data[h].val) - -proc myhash[T](tbl: PGenTable[T], key: string): Hash = - case tbl.mode - of modeCaseSensitive: result = hashes.hash(key) - of modeCaseInsensitive: result = hashes.hashIgnoreCase(key) - of modeStyleInsensitive: result = hashes.hashIgnoreStyle(key) - -proc myCmp[T](tbl: PGenTable[T], a, b: string): bool = - case tbl.mode - of modeCaseSensitive: result = cmp(a, b) == 0 - of modeCaseInsensitive: result = cmpIgnoreCase(a, b) == 0 - of modeStyleInsensitive: result = cmpIgnoreStyle(a, b) == 0 - -proc mustRehash(length, counter: int): bool = - assert(length > counter) - result = (length * 2 < counter * 3) or (length - counter < 4) - -proc newGenTable*[T](mode: GenTableMode): PGenTable[T] = - ## creates a new generic hash table that is empty. - new(result) - result.mode = mode - result.counter = 0 - newSeq(result.data, startSize) - -proc nextTry(h, maxHash: Hash): Hash {.inline.} = - result = ((5 * h) + 1) and maxHash - -proc rawGet[T](tbl: PGenTable[T], key: string): int = - var h: Hash - h = myhash(tbl, key) and high(tbl.data) # start with real hash value - while not isNil(tbl.data[h].key): - if myCmp(tbl, tbl.data[h].key, key): - return h - h = nextTry(h, high(tbl.data)) - result = - 1 - -proc rawInsert[T](tbl: PGenTable[T], data: var GenKeyValuePairSeq[T], - key: string, val: T) = - var h: Hash - h = myhash(tbl, key) and high(data) - while not isNil(data[h].key): - h = nextTry(h, high(data)) - data[h].key = key - data[h].val = val - -proc enlarge[T](tbl: PGenTable[T]) = - var n: GenKeyValuePairSeq[T] - newSeq(n, len(tbl.data) * growthFactor) - for i in countup(0, high(tbl.data)): - if not isNil(tbl.data[i].key): - rawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val) - swap(tbl.data, n) - -proc hasKey*[T](tbl: PGenTable[T], key: string): bool = - ## returns true iff `key` is in the table `tbl`. - result = rawGet(tbl, key) >= 0 - -proc `[]`*[T](tbl: PGenTable[T], key: string): T = - ## retrieves the value at ``tbl[key]``. If `key` is not in `tbl`, - ## default(T) is returned and no exception is raised. One can check - ## with ``hasKey`` whether the key exists. - var index = rawGet(tbl, key) - if index >= 0: result = tbl.data[index].val - -proc `[]=`*[T](tbl: PGenTable[T], key: string, val: T) = - ## puts a (key, value)-pair into `tbl`. - var index = rawGet(tbl, key) - if index >= 0: - tbl.data[index].val = val - else: - if mustRehash(len(tbl.data), tbl.counter): enlarge(tbl) - rawInsert(tbl, tbl.data, key, val) - inc(tbl.counter) - - -when isMainModule: - # - # Verify tables of integer values (string keys) - # - var x = newGenTable[int](modeCaseInsensitive) - x["one"] = 1 - x["two"] = 2 - x["three"] = 3 - x["four"] = 4 - x["five"] = 5 - assert(len(x) == 5) # length procedure works - assert(x["one"] == 1) # case-sensitive lookup works - assert(x["ONE"] == 1) # case-insensitive should work for this table - assert(x["one"]+x["two"] == 3) # make sure we're getting back ints - assert(x.hasKey("one")) # hasKey should return 'true' for a key - # of "one"... - assert(not x.hasKey("NOPE")) # ...but key "NOPE" is not in the table. - for k,v in pairs(x): # make sure the 'pairs' iterator works - assert(x[k]==v) - - # - # Verify a table of user-defined types - # - type - MyType = tuple[first, second: string] # a pair of strings - {.deprecated: [TMyType: MyType].} - - var y = newGenTable[MyType](modeCaseInsensitive) # hash table where each - # value is MyType tuple - - #var junk: MyType = ("OK", "Here") - - #echo junk.first, " ", junk.second - - y["Hello"] = ("Hello", "World") - y["Goodbye"] = ("Goodbye", "Everyone") - #y["Hello"] = MyType( ("Hello", "World") ) - #y["Goodbye"] = MyType( ("Goodbye", "Everyone") ) - - assert( not isNil(y["Hello"].first) ) - assert( y["Hello"].first == "Hello" ) - assert( y["Hello"].second == "World" ) - - # - # Verify table of tables - # - var z: PGenTable[ PGenTable[int] ] # hash table where each value is - # a hash table of ints - - z = newGenTable[PGenTable[int]](modeCaseInsensitive) - z["first"] = newGenTable[int](modeCaseInsensitive) - z["first"]["one"] = 1 - z["first"]["two"] = 2 - z["first"]["three"] = 3 - - z["second"] = newGenTable[int](modeCaseInsensitive) - z["second"]["red"] = 10 - z["second"]["blue"] = 20 - - assert(len(z) == 2) # length of outer table - assert(len(z["first"]) == 3) # length of "first" table - assert(len(z["second"]) == 2) # length of "second" table - assert( z["first"]["one"] == 1) # retrieve from first inner table - assert( z["second"]["red"] == 10) # retrieve from second inner table - - when false: - # disabled: depends on hash order: - var output = "" - for k, v in pairs(z): - output.add( "$# ($#) ->\L" % [k,$len(v)] ) - for k2,v2 in pairs(v): - output.add( " $# <-> $#\L" % [k2,$v2] ) - - let expected = unindent """ - first (3) -> - two <-> 2 - three <-> 3 - one <-> 1 - second (2) -> - red <-> 10 - blue <-> 20 - """ - assert output == expected diff --git a/lib/pure/htmlgen.nim b/lib/pure/htmlgen.nim index ad199a215..c0934a45b 100644 --- a/lib/pure/htmlgen.nim +++ b/lib/pure/htmlgen.nim @@ -59,8 +59,8 @@ proc xmlCheckedTag*(e: NimNode, tag: string, optAttr = "", reqAttr = "", # copy the attributes; when iterating over them these lists # will be modified, so that each attribute is only given one value - var req = split(reqAttr) - var opt = split(optAttr) + var req = splitWhitespace(reqAttr) + var opt = splitWhitespace(optAttr) result = newNimNode(nnkBracket, e) result.add(newStrLitNode("<")) result.add(newStrLitNode(tag)) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index de1d332a3..54a8498fa 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -469,7 +469,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "", ## **Deprecated since version 0.15.0**: use ``HttpClient.request`` instead. var r = if proxy == nil: parseUri(url) else: proxy.url var hostUrl = if proxy == nil: r else: parseUri(url) - var headers = httpMethod.toUpper() + var headers = httpMethod.toUpperAscii() # TODO: Use generateHeaders further down once it supports proxies. var s = newSocket() @@ -713,10 +713,10 @@ proc downloadFile*(url: string, outputFilename: string, proc generateHeaders(requestUrl: Uri, httpMethod: string, headers: HttpHeaders, body: string, proxy: Proxy): string = # GET - result = httpMethod.toUpper() + result = httpMethod.toUpperAscii() result.add ' ' - if proxy.isNil: + if proxy.isNil or (not proxy.isNil and requestUrl.scheme == "https"): # /path?query if requestUrl.path[0] != '/': result.add '/' result.add(requestUrl.path) @@ -1048,7 +1048,11 @@ proc newConnection(client: HttpClient | AsyncHttpClient, client.currentURL.scheme != url.scheme or client.currentURL.port != url.port or (not client.connected): - let isSsl = url.scheme.toLowerAscii() == "https" + # Connect to proxy if specified + let connectionUrl = + if client.proxy.isNil: url else: client.proxy.url + + let isSsl = connectionUrl.scheme.toLowerAscii() == "https" if isSsl and not defined(ssl): raise newException(HttpRequestError, @@ -1056,31 +1060,55 @@ proc newConnection(client: HttpClient | AsyncHttpClient, if client.connected: client.close() + client.connected = false # TODO: I should be able to write 'net.Port' here... let port = - if url.port == "": + if connectionUrl.port == "": if isSsl: nativesockets.Port(443) else: nativesockets.Port(80) - else: nativesockets.Port(url.port.parseInt) + else: nativesockets.Port(connectionUrl.port.parseInt) when client is HttpClient: - client.socket = await net.dial(url.hostname, port) + client.socket = await net.dial(connectionUrl.hostname, port) elif client is AsyncHttpClient: - client.socket = await asyncnet.dial(url.hostname, port) + client.socket = await asyncnet.dial(connectionUrl.hostname, port) else: {.fatal: "Unsupported client type".} when defined(ssl): if isSsl: try: client.sslContext.wrapConnectedSocket( - client.socket, handshakeAsClient, url.hostname) + client.socket, handshakeAsClient, connectionUrl.hostname) except: client.socket.close() raise getCurrentException() + # If need to CONNECT through proxy + if url.scheme == "https" and not client.proxy.isNil: + when defined(ssl): + # Pass only host:port for CONNECT + var connectUrl = initUri() + connectUrl.hostname = url.hostname + connectUrl.port = if url.port != "": url.port else: "443" + + let proxyHeaderString = generateHeaders(connectUrl, $HttpConnect, newHttpHeaders(), "", client.proxy) + await client.socket.send(proxyHeaderString) + let proxyResp = await parseResponse(client, false) + + if not proxyResp.status.startsWith("200"): + raise newException(HttpRequestError, + "The proxy server rejected a CONNECT request, " & + "so a secure connection could not be established.") + client.sslContext.wrapConnectedSocket( + client.socket, handshakeAsClient, url.hostname) + else: + raise newException(HttpRequestError, + "SSL support is not available. Cannot connect over SSL.") + + # May be connected through proxy but remember actual URL being accessed client.currentURL = url client.connected = true @@ -1100,32 +1128,9 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string, headers: HttpHeaders = nil): Future[Response | AsyncResponse] {.multisync.} = # Helper that actually makes the request. Does not handle redirects. - let connectionUrl = - if client.proxy.isNil: parseUri(url) else: client.proxy.url let requestUrl = parseUri(url) - let savedProxy = client.proxy # client's proxy may be overwritten. - - if requestUrl.scheme == "https" and not client.proxy.isNil: - when defined(ssl): - client.proxy.url = connectionUrl - var connectUrl = requestUrl - connectUrl.scheme = "http" - connectUrl.port = "443" - let proxyResp = await requestAux(client, $connectUrl, $HttpConnect) - - if not proxyResp.status.startsWith("200"): - raise newException(HttpRequestError, - "The proxy server rejected a CONNECT request, " & - "so a secure connection could not be established.") - client.sslContext.wrapConnectedSocket( - client.socket, handshakeAsClient, requestUrl.hostname) - client.proxy = nil - else: - raise newException(HttpRequestError, - "SSL support not available. Cannot connect to https site over proxy.") - else: - await newConnection(client, connectionUrl) + await newConnection(client, requestUrl) let effectiveHeaders = client.headers.override(headers) @@ -1143,9 +1148,6 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string, client.getBody result = await parseResponse(client, getBody) - # Restore the clients proxy in case it was overwritten. - client.proxy = savedProxy - proc request*(client: HttpClient | AsyncHttpClient, url: string, httpMethod: string, body = "", headers: HttpHeaders = nil): Future[Response | AsyncResponse] diff --git a/lib/pure/httpcore.nim b/lib/pure/httpcore.nim index a5ab40ca4..f150fa1c1 100644 --- a/lib/pure/httpcore.nim +++ b/lib/pure/httpcore.nim @@ -113,6 +113,9 @@ proc newHttpHeaders*(keyValuePairs: new result result.table = newTable[string, seq[string]](pairs) +proc `$`*(headers: HttpHeaders): string = + return $headers.table + proc clear*(headers: HttpHeaders) = headers.table.clear() diff --git a/lib/pure/includes/osenv.nim b/lib/pure/includes/osenv.nim index 8d2fc235a..ae62a5c4e 100644 --- a/lib/pure/includes/osenv.nim +++ b/lib/pure/includes/osenv.nim @@ -94,7 +94,7 @@ proc findEnvVar(key: string): int = if startsWith(environment[i], temp): return i return -1 -proc getEnv*(key: string): TaintedString {.tags: [ReadEnvEffect].} = +proc getEnv*(key: string, default = ""): TaintedString {.tags: [ReadEnvEffect].} = ## Returns the value of the `environment variable`:idx: named `key`. ## ## If the variable does not exist, "" is returned. To distinguish @@ -108,7 +108,7 @@ proc getEnv*(key: string): TaintedString {.tags: [ReadEnvEffect].} = return TaintedString(substr(environment[i], find(environment[i], '=')+1)) else: var env = c_getenv(key) - if env == nil: return TaintedString("") + if env == nil: return TaintedString(default) result = TaintedString($env) proc existsEnv*(key: string): bool {.tags: [ReadEnvEffect].} = diff --git a/lib/pure/includes/oserr.nim b/lib/pure/includes/oserr.nim index dbb709f1b..0889d7383 100644 --- a/lib/pure/includes/oserr.nim +++ b/lib/pure/includes/oserr.nim @@ -56,9 +56,6 @@ proc raiseOSError*(msg: string = "") {.noinline, rtl, extern: "nos$1", raise newException(OSError, msg) {.pop.} -when not defined(nimfix): - {.deprecated: [osError: raiseOSError].} - proc `==`*(err1, err2: OSErrorCode): bool {.borrow.} proc `$`*(err: OSErrorCode): string {.borrow.} diff --git a/lib/pure/ioselectors.nim b/lib/pure/ioselectors.nim deleted file mode 100644 index ef8072221..000000000 --- a/lib/pure/ioselectors.nim +++ /dev/null @@ -1,293 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2016 Eugene Kabanov -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module allows high-level and efficient I/O multiplexing. -## -## Supported OS primitives: ``epoll``, ``kqueue``, ``poll`` and -## Windows ``select``. -## -## To use threadsafe version of this module, it needs to be compiled -## with both ``-d:threadsafe`` and ``--threads:on`` options. -## -## Supported features: files, sockets, pipes, timers, processes, signals -## and user events. -## -## Fully supported OS: MacOSX, FreeBSD, OpenBSD, NetBSD, Linux (except -## for Android). -## -## Partially supported OS: Windows (only sockets and user events), -## Solaris (files, sockets, handles and user events). -## Android (files, sockets, handles and user events). -## -## TODO: ``/dev/poll``, ``event ports`` and filesystem events. - -import os - -const hasThreadSupport = compileOption("threads") and defined(threadsafe) - -const ioselSupportedPlatform* = defined(macosx) or defined(freebsd) or - defined(netbsd) or defined(openbsd) or - defined(dragonfly) or - (defined(linux) and not defined(android)) - ## This constant is used to determine whether the destination platform is - ## fully supported by ``ioselectors`` module. - -const bsdPlatform = defined(macosx) or defined(freebsd) or - defined(netbsd) or defined(openbsd) or - defined(dragonfly) - -when defined(nimdoc): - type - Selector*[T] = ref object - ## An object which holds descriptors to be checked for read/write status - - Event* {.pure.} = enum - ## An enum which hold event types - Read, ## Descriptor is available for read - Write, ## Descriptor is available for write - Timer, ## Timer descriptor is completed - Signal, ## Signal is raised - Process, ## Process is finished - Vnode, ## BSD specific file change happens - User, ## User event is raised - Error, ## Error happens while waiting, for descriptor - VnodeWrite, ## NOTE_WRITE (BSD specific, write to file occurred) - VnodeDelete, ## NOTE_DELETE (BSD specific, unlink of file occurred) - VnodeExtend, ## NOTE_EXTEND (BSD specific, file extended) - VnodeAttrib, ## NOTE_ATTRIB (BSD specific, file attributes changed) - VnodeLink, ## NOTE_LINK (BSD specific, file link count changed) - VnodeRename, ## NOTE_RENAME (BSD specific, file renamed) - VnodeRevoke ## NOTE_REVOKE (BSD specific, file revoke occurred) - - ReadyKey* = object - ## An object which holds result for descriptor - fd* : int ## file/socket descriptor - events*: set[Event] ## set of events - - SelectEvent* = object - ## An object which holds user defined event - - proc newSelector*[T](): Selector[T] = - ## Creates a new selector - - proc close*[T](s: Selector[T]) = - ## Closes selector - - proc registerHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event], - data: T) = - ## Registers file/socket descriptor ``fd`` to selector ``s`` - ## with events set in ``events``. The ``data`` is application-defined - ## data, which to be passed when event happens. - - proc updateHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event]) = - ## Update file/socket descriptor ``fd``, registered in selector - ## ``s`` with new events set ``event``. - - proc registerTimer*[T](s: Selector[T], timeout: int, oneshot: bool, - data: T): int {.discardable.} = - ## Registers timer notification with ``timeout`` in milliseconds - ## to selector ``s``. - ## If ``oneshot`` is ``true`` timer will be notified only once. - ## Set ``oneshot`` to ``false`` if your want periodic notifications. - ## The ``data`` is application-defined data, which to be passed, when - ## time limit expired. - - proc registerSignal*[T](s: Selector[T], signal: int, - data: T): int {.discardable.} = - ## Registers Unix signal notification with ``signal`` to selector - ## ``s``. The ``data`` is application-defined data, which to be - ## passed, when signal raises. - ## - ## This function is not supported for ``Windows``. - - proc registerProcess*[T](s: Selector[T], pid: int, - data: T): int {.discardable.} = - ## Registers process id (pid) notification when process has - ## exited to selector ``s``. - ## The ``data`` is application-defined data, which to be passed, when - ## process with ``pid`` has exited. - - proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = - ## Registers selector event ``ev`` to selector ``s``. - ## ``data`` application-defined data, which to be passed, when - ## ``ev`` happens. - - proc registerVnode*[T](s: Selector[T], fd: cint, events: set[Event], - data: T) = - ## Registers selector BSD/MacOSX specific vnode events for file - ## descriptor ``fd`` and events ``events``. - ## ``data`` application-defined data, which to be passed, when - ## vnode event happens. - ## - ## This function is supported only by BSD and MacOSX. - - proc newSelectEvent*(): SelectEvent = - ## Creates new event ``SelectEvent``. - - proc setEvent*(ev: SelectEvent) = - ## Trigger event ``ev``. - - proc close*(ev: SelectEvent) = - ## Closes selector event ``ev``. - - proc unregister*[T](s: Selector[T], ev: SelectEvent) = - ## Unregisters event ``ev`` from selector ``s``. - - proc unregister*[T](s: Selector[T], fd: int|SocketHandle|cint) = - ## Unregisters file/socket descriptor ``fd`` from selector ``s``. - - proc selectInto*[T](s: Selector[T], timeout: int, - results: var openarray[ReadyKey]): int = - ## Process call waiting for events registered in selector ``s``. - ## The ``timeout`` argument specifies the minimum number of milliseconds - ## the function will be blocked, if no events are not ready. Specifying a - ## timeout of ``-1`` causes function to block indefinitely. - ## All available events will be stored in ``results`` array. - ## - ## Function returns number of triggered events. - - proc select*[T](s: Selector[T], timeout: int): seq[ReadyKey] = - ## Process call waiting for events registered in selector ``s``. - ## The ``timeout`` argument specifies the minimum number of milliseconds - ## the function will be blocked, if no events are not ready. Specifying a - ## timeout of -1 causes function to block indefinitely. - ## - ## Function returns sequence of triggered events. - - proc getData*[T](s: Selector[T], fd: SocketHandle|int): T = - ## Retrieves application-defined ``data`` associated with descriptor ``fd``. - ## If specified descriptor ``fd`` is not registered, empty/default value - ## will be returned. - - proc setData*[T](s: Selector[T], fd: SocketHandle|int, data: var T): bool = - ## Associate application-defined ``data`` with descriptor ``fd``. - ## - ## Returns ``true``, if data was succesfully updated, ``false`` otherwise. - - template isEmpty*[T](s: Selector[T]): bool = - ## Returns ``true``, if there no registered events or descriptors - ## in selector. - - template withData*[T](s: Selector[T], fd: SocketHandle|int, value, - body: untyped) = - ## Retrieves the application-data assigned with descriptor ``fd`` - ## to ``value``. This ``value`` can be modified in the scope of - ## the ``withData`` call. - ## - ## .. code-block:: nim - ## - ## s.withData(fd, value) do: - ## # block is executed only if ``fd`` registered in selector ``s`` - ## value.uid = 1000 - ## - - template withData*[T](s: Selector[T], fd: SocketHandle|int, value, - body1, body2: untyped) = - ## Retrieves the application-data assigned with descriptor ``fd`` - ## to ``value``. This ``value`` can be modified in the scope of - ## the ``withData`` call. - ## - ## .. code-block:: nim - ## - ## s.withData(fd, value) do: - ## # block is executed only if ``fd`` registered in selector ``s``. - ## value.uid = 1000 - ## do: - ## # block is executed if ``fd`` not registered in selector ``s``. - ## raise - ## - -else: - when hasThreadSupport: - import locks - - type - SharedArray[T] = UncheckedArray[T] - - proc allocSharedArray[T](nsize: int): ptr SharedArray[T] = - result = cast[ptr SharedArray[T]](allocShared0(sizeof(T) * nsize)) - - proc deallocSharedArray[T](sa: ptr SharedArray[T]) = - deallocShared(cast[pointer](sa)) - type - Event* {.pure.} = enum - Read, Write, Timer, Signal, Process, Vnode, User, Error, Oneshot, - Finished, VnodeWrite, VnodeDelete, VnodeExtend, VnodeAttrib, VnodeLink, - VnodeRename, VnodeRevoke - - type - IOSelectorsException* = object of Exception - - ReadyKey* = object - fd* : int - events*: set[Event] - - SelectorKey[T] = object - ident: int - events: set[Event] - param: int - data: T - - proc raiseIOSelectorsError[T](message: T) = - var msg = "" - when T is string: - msg.add(message) - elif T is OSErrorCode: - msg.add(osErrorMsg(message) & " (code: " & $int(message) & ")") - else: - msg.add("Internal Error\n") - var err = newException(IOSelectorsException, msg) - raise err - - when not defined(windows): - import posix - - proc setNonBlocking(fd: cint) {.inline.} = - var x = fcntl(fd, F_GETFL, 0) - if x == -1: - raiseIOSelectorsError(osLastError()) - else: - var mode = x or O_NONBLOCK - if fcntl(fd, F_SETFL, mode) == -1: - raiseIOSelectorsError(osLastError()) - - template setKey(s, pident, pevents, pparam, pdata: untyped) = - var skey = addr(s.fds[pident]) - skey.ident = pident - skey.events = pevents - skey.param = pparam - skey.data = data - - when ioselSupportedPlatform: - template blockSignals(newmask: var Sigset, oldmask: var Sigset) = - when hasThreadSupport: - if posix.pthread_sigmask(SIG_BLOCK, newmask, oldmask) == -1: - raiseIOSelectorsError(osLastError()) - else: - if posix.sigprocmask(SIG_BLOCK, newmask, oldmask) == -1: - raiseIOSelectorsError(osLastError()) - - template unblockSignals(newmask: var Sigset, oldmask: var Sigset) = - when hasThreadSupport: - if posix.pthread_sigmask(SIG_UNBLOCK, newmask, oldmask) == -1: - raiseIOSelectorsError(osLastError()) - else: - if posix.sigprocmask(SIG_UNBLOCK, newmask, oldmask) == -1: - raiseIOSelectorsError(osLastError()) - - when defined(linux): - include ioselects/ioselectors_epoll - elif bsdPlatform: - include ioselects/ioselectors_kqueue - elif defined(windows): - include ioselects/ioselectors_select - elif defined(solaris): - include ioselects/ioselectors_poll # need to replace it with event ports - else: - include ioselects/ioselectors_poll diff --git a/lib/pure/ioselects/ioselectors_epoll.nim b/lib/pure/ioselects/ioselectors_epoll.nim index 3a5cbc87a..8827f239f 100644 --- a/lib/pure/ioselects/ioselectors_epoll.nim +++ b/lib/pure/ioselects/ioselectors_epoll.nim @@ -9,7 +9,7 @@ # This module implements Linux epoll(). -import posix, times +import posix, times, epoll # Maximum number of events that can be returned const MAX_EPOLL_EVENTS = 64 @@ -36,35 +36,6 @@ when not defined(android): ssi_addr*: uint64 pad* {.importc: "__pad".}: array[0..47, uint8] -type - eventFdData {.importc: "eventfd_t", - header: "<sys/eventfd.h>", pure, final.} = uint64 - epoll_data {.importc: "union epoll_data", header: "<sys/epoll.h>", - pure, final.} = object - u64 {.importc: "u64".}: uint64 - epoll_event {.importc: "struct epoll_event", - header: "<sys/epoll.h>", pure, final.} = object - events: uint32 # Epoll events - data: epoll_data # User data variable - -const - EPOLL_CTL_ADD = 1 # Add a file descriptor to the interface. - EPOLL_CTL_DEL = 2 # Remove a file descriptor from the interface. - EPOLL_CTL_MOD = 3 # Change file descriptor epoll_event structure. - EPOLLIN = 0x00000001 - EPOLLOUT = 0x00000004 - EPOLLERR = 0x00000008 - EPOLLHUP = 0x00000010 - EPOLLRDHUP = 0x00002000 - EPOLLONESHOT = 1 shl 30 - -proc epoll_create(size: cint): cint - {.importc: "epoll_create", header: "<sys/epoll.h>".} -proc epoll_ctl(epfd: cint; op: cint; fd: cint; event: ptr epoll_event): cint - {.importc: "epoll_ctl", header: "<sys/epoll.h>".} -proc epoll_wait(epfd: cint; events: ptr epoll_event; maxevents: cint; - timeout: cint): cint - {.importc: "epoll_wait", header: "<sys/epoll.h>".} proc timerfd_create(clock_id: ClockId, flags: cint): cint {.cdecl, importc: "timerfd_create", header: "<sys/timerfd.h>".} proc timerfd_settime(ufd: cint, flags: cint, @@ -80,26 +51,26 @@ when not defined(android): var RLIMIT_NOFILE {.importc: "RLIMIT_NOFILE", header: "<sys/resource.h>".}: cint type - rlimit {.importc: "struct rlimit", + RLimit {.importc: "struct rlimit", header: "<sys/resource.h>", pure, final.} = object rlim_cur: int rlim_max: int -proc getrlimit(resource: cint, rlp: var rlimit): cint +proc getrlimit(resource: cint, rlp: var RLimit): cint {.importc: "getrlimit",header: "<sys/resource.h>".} when hasThreadSupport: type SelectorImpl[T] = object - epollFD : cint - maxFD : int + epollFD: cint + maxFD: int fds: ptr SharedArray[SelectorKey[T]] count: int Selector*[T] = ptr SelectorImpl[T] else: type SelectorImpl[T] = object - epollFD : cint - maxFD : int + epollFD: cint + maxFD: int fds: seq[SelectorKey[T]] count: int Selector*[T] = ref SelectorImpl[T] @@ -109,7 +80,8 @@ type SelectEvent* = ptr SelectEventImpl proc newSelector*[T](): Selector[T] = - var a = rlimit() + # Retrieve the maximum fd count (for current OS) via getrlimit() + var a = RLimit() if getrlimit(RLIMIT_NOFILE, a) != 0: raiseOsError(osLastError()) var maxFD = int(a.rlim_max) @@ -152,8 +124,8 @@ proc newSelectEvent*(): SelectEvent = result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) result.efd = fdci -proc setEvent*(ev: SelectEvent) = - var data : uint64 = 1 +proc trigger*(ev: SelectEvent) = + var data: uint64 = 1 if posix.write(ev.efd, addr data, sizeof(uint64)) == -1: raiseIOSelectorsError(osLastError()) @@ -164,6 +136,8 @@ proc close*(ev: SelectEvent) = raiseIOSelectorsError(osLastError()) template checkFd(s, f) = + # TODO: I don't see how this can ever happen. You won't be able to create an + # FD if there is too many. -- DP if f >= s.maxFD: raiseIOSelectorsError("Maximum number of descriptors is exhausted!") @@ -171,10 +145,10 @@ proc registerHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event], data: T) = let fdi = int(fd) s.checkFd(fdi) - doAssert(s.fds[fdi].ident == 0) + doAssert(s.fds[fdi].ident == 0, "Descriptor $# already registered" % $fdi) s.setKey(fdi, events, 0, data) if events != {}: - var epv = epoll_event(events: EPOLLRDHUP) + var epv = EpollEvent(events: EPOLLRDHUP) epv.data.u64 = fdi.uint if Event.Read in events: epv.events = epv.events or EPOLLIN if Event.Write in events: epv.events = epv.events or EPOLLOUT @@ -189,10 +163,10 @@ proc updateHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event]) = s.checkFd(fdi) var pkey = addr(s.fds[fdi]) doAssert(pkey.ident != 0, - "Descriptor [" & $fdi & "] is not registered in the queue!") + "Descriptor $# is not registered in the selector!" % $fdi) doAssert(pkey.events * maskEvents == {}) if pkey.events != events: - var epv = epoll_event(events: EPOLLRDHUP) + var epv = EpollEvent(events: EPOLLRDHUP) epv.data.u64 = fdi.uint if Event.Read in events: epv.events = epv.events or EPOLLIN @@ -217,24 +191,25 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) = s.checkFd(fdi) var pkey = addr(s.fds[fdi]) doAssert(pkey.ident != 0, - "Descriptor [" & $fdi & "] is not registered in the queue!") + "Descriptor $# is not registered in the selector!" % $fdi) if pkey.events != {}: when not defined(android): if pkey.events * {Event.Read, Event.Write} != {}: - var epv = epoll_event() + var epv = EpollEvent() + # TODO: Refactor all these EPOLL_CTL_DEL + dec(s.count) into a proc. if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) != 0: raiseIOSelectorsError(osLastError()) dec(s.count) elif Event.Timer in pkey.events: if Event.Finished notin pkey.events: - var epv = epoll_event() + var epv = EpollEvent() if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) != 0: raiseIOSelectorsError(osLastError()) dec(s.count) if posix.close(cint(fdi)) != 0: raiseIOSelectorsError(osLastError()) elif Event.Signal in pkey.events: - var epv = epoll_event() + var epv = EpollEvent() if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) != 0: raiseIOSelectorsError(osLastError()) var nmask, omask: Sigset @@ -247,7 +222,7 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) = raiseIOSelectorsError(osLastError()) elif Event.Process in pkey.events: if Event.Finished notin pkey.events: - var epv = epoll_event() + var epv = EpollEvent() if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) != 0: raiseIOSelectorsError(osLastError()) var nmask, omask: Sigset @@ -260,13 +235,13 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) = raiseIOSelectorsError(osLastError()) else: if pkey.events * {Event.Read, Event.Write} != {}: - var epv = epoll_event() + var epv = EpollEvent() if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) != 0: raiseIOSelectorsError(osLastError()) dec(s.count) elif Event.Timer in pkey.events: if Event.Finished notin pkey.events: - var epv = epoll_event() + var epv = EpollEvent() if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) != 0: raiseIOSelectorsError(osLastError()) dec(s.count) @@ -280,7 +255,7 @@ proc unregister*[T](s: Selector[T], ev: SelectEvent) = var pkey = addr(s.fds[fdi]) doAssert(pkey.ident != 0, "Event is not registered in the queue!") doAssert(Event.User in pkey.events) - var epv = epoll_event() + var epv = EpollEvent() if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) != 0: raiseIOSelectorsError(osLastError()) dec(s.count) @@ -300,17 +275,18 @@ proc registerTimer*[T](s: Selector[T], timeout: int, oneshot: bool, doAssert(s.fds[fdi].ident == 0) var events = {Event.Timer} - var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP) + var epv = EpollEvent(events: EPOLLIN or EPOLLRDHUP) epv.data.u64 = fdi.uint + if oneshot: - new_ts.it_interval.tv_sec = 0.Time + new_ts.it_interval.tv_sec = posix.Time(0) new_ts.it_interval.tv_nsec = 0 - new_ts.it_value.tv_sec = (timeout div 1_000).Time + new_ts.it_value.tv_sec = posix.Time(timeout div 1_000) new_ts.it_value.tv_nsec = (timeout %% 1_000) * 1_000_000 incl(events, Event.Oneshot) epv.events = epv.events or EPOLLONESHOT else: - new_ts.it_interval.tv_sec = (timeout div 1000).Time + new_ts.it_interval.tv_sec = posix.Time(timeout div 1000) new_ts.it_interval.tv_nsec = (timeout %% 1_000) * 1_000_000 new_ts.it_value.tv_sec = new_ts.it_interval.tv_sec new_ts.it_value.tv_nsec = new_ts.it_interval.tv_nsec @@ -343,7 +319,7 @@ when not defined(android): s.checkFd(fdi) doAssert(s.fds[fdi].ident == 0) - var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP) + var epv = EpollEvent(events: EPOLLIN or EPOLLRDHUP) epv.data.u64 = fdi.uint if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) != 0: raiseIOSelectorsError(osLastError()) @@ -370,7 +346,7 @@ when not defined(android): s.checkFd(fdi) doAssert(s.fds[fdi].ident == 0) - var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP) + var epv = EpollEvent(events: EPOLLIN or EPOLLRDHUP) epv.data.u64 = fdi.uint epv.events = EPOLLIN or EPOLLRDHUP if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) != 0: @@ -383,7 +359,7 @@ proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = let fdi = int(ev.efd) doAssert(s.fds[fdi].ident == 0, "Event is already registered in the queue!") s.setKey(fdi, {Event.User}, 0, data) - var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP) + var epv = EpollEvent(events: EPOLLIN or EPOLLRDHUP) epv.data.u64 = ev.efd.uint if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, ev.efd, addr epv) != 0: raiseIOSelectorsError(osLastError()) @@ -392,7 +368,7 @@ proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = proc selectInto*[T](s: Selector[T], timeout: int, results: var openarray[ReadyKey]): int = var - resTable: array[MAX_EPOLL_EVENTS, epoll_event] + resTable: array[MAX_EPOLL_EVENTS, EpollEvent] maxres = MAX_EPOLL_EVENTS i, k: int @@ -482,7 +458,7 @@ proc selectInto*[T](s: Selector[T], timeout: int, rkey.events.incl(Event.User) if Event.Oneshot in pkey.events: - var epv = epoll_event() + var epv = EpollEvent() if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, cint(fdi), addr epv) != 0: raiseIOSelectorsError(osLastError()) # we will not clear key until it will be unregistered, so @@ -505,16 +481,19 @@ proc select*[T](s: Selector[T], timeout: int): seq[ReadyKey] = template isEmpty*[T](s: Selector[T]): bool = (s.count == 0) -proc getData*[T](s: Selector[T], fd: SocketHandle|int): T = +proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = + return s.fds[fd].ident != 0 + +proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T = let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: + if fdi in s: result = s.fds[fdi].data proc setData*[T](s: Selector[T], fd: SocketHandle|int, data: T): bool = let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: + if fdi in s: s.fds[fdi].data = data result = true @@ -523,8 +502,8 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, mixin checkFd let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: - var value = addr(s.fds[fdi].data) + if fdi in s: + var value = addr(s.getData(fdi)) body template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1, @@ -532,8 +511,8 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1, mixin checkFd let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: - var value = addr(s.fds[fdi].data) + if fdi in s: + var value = addr(s.getData(fdi)) body1 else: body2 diff --git a/lib/pure/ioselects/ioselectors_kqueue.nim b/lib/pure/ioselects/ioselectors_kqueue.nim index 7786de46a..af5aa15df 100644 --- a/lib/pure/ioselects/ioselectors_kqueue.nim +++ b/lib/pure/ioselects/ioselectors_kqueue.nim @@ -144,7 +144,7 @@ proc newSelectEvent*(): SelectEvent = result.rfd = fds[0] result.wfd = fds[1] -proc setEvent*(ev: SelectEvent) = +proc trigger*(ev: SelectEvent) = var data: uint64 = 1 if posix.write(ev.wfd, addr data, sizeof(uint64)) != sizeof(uint64): raiseIOSelectorsError(osLastError()) @@ -243,7 +243,7 @@ proc updateHandle*[T](s: Selector[T], fd: SocketHandle, s.checkFd(fdi) var pkey = addr(s.fds[fdi]) doAssert(pkey.ident != 0, - "Descriptor [" & $fdi & "] is not registered in the queue!") + "Descriptor $# is not registered in the queue!" % $fdi) doAssert(pkey.events * maskEvents == {}) if pkey.events != events: @@ -452,10 +452,10 @@ proc selectInto*[T](s: Selector[T], timeout: int, if timeout != -1: if timeout >= 1000: - tv.tv_sec = (timeout div 1_000).Time + tv.tv_sec = posix.Time(timeout div 1_000) tv.tv_nsec = (timeout %% 1_000) * 1_000_000 else: - tv.tv_sec = 0.Time + tv.tv_sec = posix.Time(0) tv.tv_nsec = timeout * 1_000_000 else: ptv = nil @@ -584,16 +584,19 @@ proc select*[T](s: Selector[T], timeout: int): seq[ReadyKey] = template isEmpty*[T](s: Selector[T]): bool = (s.count == 0) -proc getData*[T](s: Selector[T], fd: SocketHandle|int): T = +proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = + return s.fds[fd].ident != 0 + +proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T = let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: + if fdi in s: result = s.fds[fdi].data proc setData*[T](s: Selector[T], fd: SocketHandle|int, data: T): bool = let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: + if fdi in s: s.fds[fdi].data = data result = true @@ -602,8 +605,8 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, mixin checkFd let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: - var value = addr(s.fds[fdi].data) + if fdi in s: + var value = addr(s.getData(fdi)) body template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1, @@ -611,8 +614,8 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1, mixin checkFd let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: - var value = addr(s.fds[fdi].data) + if fdi in s: + var value = addr(s.getData(fdi)) body1 else: body2 diff --git a/lib/pure/ioselects/ioselectors_poll.nim b/lib/pure/ioselects/ioselectors_poll.nim index 1b90e0806..cc06aa592 100644 --- a/lib/pure/ioselects/ioselectors_poll.nim +++ b/lib/pure/ioselects/ioselectors_poll.nim @@ -208,7 +208,7 @@ proc newSelectEvent*(): SelectEvent = result.rfd = fds[0] result.wfd = fds[1] -proc setEvent*(ev: SelectEvent) = +proc trigger*(ev: SelectEvent) = var data: uint64 = 1 if posix.write(ev.wfd, addr data, sizeof(uint64)) != sizeof(uint64): raiseIOSelectorsError(osLastError()) @@ -279,16 +279,19 @@ proc select*[T](s: Selector[T], timeout: int): seq[ReadyKey] = template isEmpty*[T](s: Selector[T]): bool = (s.count == 0) -proc getData*[T](s: Selector[T], fd: SocketHandle|int): T = +proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = + return s.fds[fd].ident != 0 + +proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T = let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: + if fdi in s: result = s.fds[fdi].data proc setData*[T](s: Selector[T], fd: SocketHandle|int, data: T): bool = let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: + if fdi in s: s.fds[fdi].data = data result = true @@ -297,8 +300,8 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, mixin checkFd let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: - var value = addr(s.fds[fdi].data) + if fdi in s: + var value = addr(s.getData(fdi)) body template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1, @@ -306,8 +309,8 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1, mixin checkFd let fdi = int(fd) s.checkFd(fdi) - if s.fds[fdi].ident != 0: - var value = addr(s.fds[fdi].data) + if fdi in s: + var value = addr(s.getData(fdi)) body1 else: body2 diff --git a/lib/pure/ioselects/ioselectors_select.nim b/lib/pure/ioselects/ioselectors_select.nim index dc3451d52..c787f0070 100644 --- a/lib/pure/ioselects/ioselectors_select.nim +++ b/lib/pure/ioselects/ioselectors_select.nim @@ -154,7 +154,7 @@ when defined(windows): result.rsock = rsock result.wsock = wsock - proc setEvent*(ev: SelectEvent) = + proc trigger*(ev: SelectEvent) = var data: uint64 = 1 if winlean.send(ev.wsock, cast[pointer](addr data), cint(sizeof(uint64)), 0) != sizeof(uint64): @@ -178,7 +178,7 @@ else: result.rsock = SocketHandle(fds[0]) result.wsock = SocketHandle(fds[1]) - proc setEvent*(ev: SelectEvent) = + proc trigger*(ev: SelectEvent) = var data: uint64 = 1 if posix.write(cint(ev.wsock), addr data, sizeof(uint64)) != sizeof(uint64): raiseIOSelectorsError(osLastError()) @@ -279,8 +279,9 @@ proc updateHandle*[T](s: Selector[T], fd: SocketHandle, inc(s.count) pkey.events = events -proc unregister*[T](s: Selector[T], fd: SocketHandle) = +proc unregister*[T](s: Selector[T], fd: SocketHandle|int) = s.withSelectLock(): + let fd = fd.SocketHandle var pkey = s.getKey(fd) if Event.Read in pkey.events: IOFD_CLR(fd, addr s.rSet) @@ -379,6 +380,16 @@ proc flush*[T](s: Selector[T]) = discard template isEmpty*[T](s: Selector[T]): bool = (s.count == 0) +proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = + s.withSelectLock(): + result = false + + let fdi = int(fd) + for i in 0..<FD_SETSIZE: + if s.fds[i].ident == fdi: + return true + inc(i) + when hasThreadSupport: template withSelectLock[T](s: Selector[T], body: untyped) = acquire(s.lock) @@ -391,15 +402,12 @@ else: template withSelectLock[T](s: Selector[T], body: untyped) = body -proc getData*[T](s: Selector[T], fd: SocketHandle|int): T = +proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T = s.withSelectLock(): let fdi = int(fd) - var i = 0 - while i < FD_SETSIZE: + for i in 0..<FD_SETSIZE: if s.fds[i].ident == fdi: - result = s.fds[i].data - break - inc(i) + return s.fds[i].data proc setData*[T](s: Selector[T], fd: SocketHandle|int, data: T): bool = s.withSelectLock(): @@ -431,16 +439,17 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1, body2: untyped) = mixin withSelectLock s.withSelectLock(): - var value: ptr T - let fdi = int(fd) - var i = 0 - while i < FD_SETSIZE: - if s.fds[i].ident == fdi: - value = addr(s.fds[i].data) - break - inc(i) - if i != FD_SETSIZE: - body1 - else: - body2 + block: + var value: ptr T + let fdi = int(fd) + var i = 0 + while i < FD_SETSIZE: + if s.fds[i].ident == fdi: + value = addr(s.fds[i].data) + break + inc(i) + if i != FD_SETSIZE: + body1 + else: + body2 diff --git a/lib/pure/json.nim b/lib/pure/json.nim index fd7a3af03..b5b84863a 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -823,13 +823,13 @@ proc toJson(x: NimNode): NimNode {.compiletime.} = of nnkBracket: # array if x.len == 0: return newCall(bindSym"newJArray") result = newNimNode(nnkBracket) - for i in 0 .. <x.len: + for i in 0 ..< x.len: result.add(toJson(x[i])) result = newCall(bindSym"%", result) of nnkTableConstr: # object if x.len == 0: return newCall(bindSym"newJObject") result = newNimNode(nnkTableConstr) - for i in 0 .. <x.len: + for i in 0 ..< x.len: x[i].expectKind nnkExprColonExpr result.add newTree(nnkExprColonExpr, x[i][0], toJson(x[i][1])) result = newCall(bindSym"%", result) @@ -1303,7 +1303,7 @@ else: case getVarType(x) of JArray: result = newJArray() - for i in 0 .. <x.len: + for i in 0 ..< x.len: result.add(x[i].convertObject()) of JObject: result = newJObject() @@ -1346,6 +1346,16 @@ proc createJsonIndexer(jsonNode: NimNode, indexNode ) +proc transformJsonIndexer(jsonNode: NimNode): NimNode = + case jsonNode.kind + of nnkBracketExpr: + result = newNimNode(nnkCurlyExpr) + else: + result = jsonNode.copy() + + for child in jsonNode: + result.add(transformJsonIndexer(child)) + template verifyJsonKind(node: JsonNode, kinds: set[JsonNodeKind], ast: string) = if node.kind notin kinds: @@ -1449,7 +1459,7 @@ proc processElseBranch(recCaseNode, elseBranch, jsonNode, kindType, # We need to build up a list of conditions from each ``of`` branch so that # we can then negate it to get ``else``. var cond = newIdentNode("false") - for i in 1 .. <len(recCaseNode): + for i in 1 ..< len(recCaseNode): if recCaseNode[i].kind == nnkElse: break @@ -1511,7 +1521,7 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] = exprColonExpr.add(getEnumCall) # Iterate through each `of` branch. - for i in 1 .. <field.len: + for i in 1 ..< field.len: case field[i].kind of nnkOfBranch: result.add processOfBranch(field[i], jsonNode, kindType, kindJsonNode) @@ -1524,6 +1534,35 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] = doAssert result.len > 0 +proc processFields(obj: NimNode, + jsonNode: NimNode): seq[NimNode] {.compileTime.} = + ## Process all the fields of an ``ObjectTy`` and any of its + ## parent type's fields (via inheritance). + result = @[] + case obj.kind + of nnkObjectTy: + expectKind(obj[2], nnkRecList) + for field in obj[2]: + let nodes = processObjField(field, jsonNode) + result.add(nodes) + + # process parent type fields + case obj[1].kind + of nnkBracketExpr: + assert $obj[1][0] == "ref" + result.add(processFields(getType(obj[1][1]), jsonNode)) + of nnkSym: + result.add(processFields(getType(obj[1]), jsonNode)) + else: + discard + of nnkTupleTy: + for identDefs in obj: + expectKind(identDefs, nnkIdentDefs) + let nodes = processObjField(identDefs[0], jsonNode) + result.add(nodes) + else: + doAssert false, "Unable to process field type: " & $obj.kind + proc processType(typeName: NimNode, obj: NimNode, jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} = ## Process a type such as ``Sym "float"`` or ``ObjectTy ...``. @@ -1533,20 +1572,21 @@ proc processType(typeName: NimNode, obj: NimNode, ## .. code-block::plain ## ObjectTy ## Empty - ## Empty + ## InheritanceInformation ## RecList ## Sym "events" case obj.kind - of nnkObjectTy: + of nnkObjectTy, nnkTupleTy: # Create object constructor. - result = newNimNode(nnkObjConstr) - result.add(typeName) # Name of the type to construct. + result = + if obj.kind == nnkObjectTy: newNimNode(nnkObjConstr) + else: newNimNode(nnkPar) - # Process each object field and add it as an exprColonExpr - expectKind(obj[2], nnkRecList) - for field in obj[2]: - let nodes = processObjField(field, jsonNode) - result.add(nodes) + if obj.kind == nnkObjectTy: + result.add(typeName) # Name of the type to construct. + + # Process each object/tuple field and add it as an exprColonExpr + result.add(processFields(obj, jsonNode)) # Object might be null. So we need to check for that. if isRef: @@ -1569,25 +1609,14 @@ proc processType(typeName: NimNode, obj: NimNode, `getEnumCall` ) of nnkSym: - case ($typeName).normalize - of "float": - result = quote do: - ( - verifyJsonKind(`jsonNode`, {JFloat, JInt}, astToStr(`jsonNode`)); - if `jsonNode`.kind == JFloat: `jsonNode`.fnum else: `jsonNode`.num.float - ) + let name = ($typeName).normalize + case name of "string": result = quote do: ( verifyJsonKind(`jsonNode`, {JString, JNull}, astToStr(`jsonNode`)); if `jsonNode`.kind == JNull: nil else: `jsonNode`.str ) - of "int": - result = quote do: - ( - verifyJsonKind(`jsonNode`, {JInt}, astToStr(`jsonNode`)); - `jsonNode`.num.int - ) of "biggestint": result = quote do: ( @@ -1601,12 +1630,36 @@ proc processType(typeName: NimNode, obj: NimNode, `jsonNode`.bval ) else: - doAssert false, "Unable to process nnkSym " & $typeName + if name.startsWith("int") or name.startsWith("uint"): + result = quote do: + ( + verifyJsonKind(`jsonNode`, {JInt}, astToStr(`jsonNode`)); + `jsonNode`.num.`obj` + ) + elif name.startsWith("float"): + result = quote do: + ( + verifyJsonKind(`jsonNode`, {JInt, JFloat}, astToStr(`jsonNode`)); + if `jsonNode`.kind == JFloat: `jsonNode`.fnum.`obj` else: `jsonNode`.num.`obj` + ) + else: + doAssert false, "Unable to process nnkSym " & $typeName else: doAssert false, "Unable to process type: " & $obj.kind doAssert(not result.isNil(), "processType not initialised.") +import options +proc workaroundMacroNone[T](): Option[T] = + none(T) + +proc depth(n: NimNode, current = 0): int = + result = 1 + for child in n: + let d = 1 + child.depth(current + 1) + if d > result: + result = d + proc createConstructor(typeSym, jsonNode: NimNode): NimNode = ## Accepts a type description, i.e. "ref Type", "seq[Type]", "Type" etc. ## @@ -1616,10 +1669,50 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode = # echo("--createConsuctor-- \n", treeRepr(typeSym)) # echo() + if depth(jsonNode) > 150: + error("The `to` macro does not support ref objects with cycles.", jsonNode) + case typeSym.kind of nnkBracketExpr: var bracketName = ($typeSym[0]).normalize case bracketName + of "option": + # TODO: Would be good to verify that this is Option[T] from + # options module I suppose. + let lenientJsonNode = transformJsonIndexer(jsonNode) + + let optionGeneric = typeSym[1] + let value = createConstructor(typeSym[1], jsonNode) + let workaround = bindSym("workaroundMacroNone") # TODO: Nim Bug: This shouldn't be necessary. + + result = quote do: + ( + if `lenientJsonNode`.isNil: `workaround`[`optionGeneric`]() else: some[`optionGeneric`](`value`) + ) + of "table", "orderedtable": + let tableKeyType = typeSym[1] + if ($tableKeyType).cmpIgnoreStyle("string") != 0: + error("JSON doesn't support keys of type " & $tableKeyType) + let tableValueType = typeSym[2] + + let forLoopKey = genSym(nskForVar, "key") + let indexerNode = createJsonIndexer(jsonNode, forLoopKey) + let constructorNode = createConstructor(tableValueType, indexerNode) + + let tableInit = + if bracketName == "table": + bindSym("initTable") + else: + bindSym("initOrderedTable") + + # Create a statement expression containing a for loop. + result = quote do: + ( + var map = `tableInit`[`tableKeyType`, `tableValueType`](); + verifyJsonKind(`jsonNode`, {JObject}, astToStr(`jsonNode`)); + for `forLoopKey` in keys(`jsonNode`.fields): map[`forLoopKey`] = `constructorNode`; + map + ) of "ref": # Ref type. var typeName = $typeSym[1] @@ -1640,7 +1733,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode = ( var list: `typeSym` = @[]; verifyJsonKind(`jsonNode`, {JArray}, astToStr(`jsonNode`)); - for `forLoopI` in 0 .. <`jsonNode`.len: list.add(`constructorNode`); + for `forLoopI` in 0 ..< `jsonNode`.len: list.add(`constructorNode`); list ) of "array": @@ -1654,7 +1747,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode = ( var list: `typeSym`; verifyJsonKind(`jsonNode`, {JArray}, astToStr(`jsonNode`)); - for `forLoopI` in 0 .. <`jsonNode`.len: list[`forLoopI`] =`constructorNode`; + for `forLoopI` in 0 ..< `jsonNode`.len: list[`forLoopI`] =`constructorNode`; list ) @@ -1663,12 +1756,23 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode = let obj = getType(typeSym) result = processType(typeSym, obj, jsonNode, false) of nnkSym: + # Handle JsonNode. + if ($typeSym).cmpIgnoreStyle("jsonnode") == 0: + return jsonNode + + # Handle all other types. let obj = getType(typeSym) if obj.kind == nnkBracketExpr: # When `Sym "Foo"` turns out to be a `ref object`. result = createConstructor(obj, jsonNode) else: result = processType(typeSym, obj, jsonNode, false) + of nnkTupleTy: + result = processType(typeSym, typeSym, jsonNode, false) + of nnkPar: + # TODO: The fact that `jsonNode` here works to give a good line number + # is weird. Specifying typeSym should work but doesn't. + error("Use a named tuple instead of: " & $toStrLit(typeSym), jsonNode) else: doAssert false, "Unable to create constructor for: " & $typeSym.kind @@ -1683,7 +1787,7 @@ proc postProcessValue(value: NimNode): NimNode = result = postProcess(value) else: result = value - for i in 0 .. <len(result): + for i in 0 ..< len(result): result[i] = postProcessValue(result[i]) proc postProcessExprColonExpr(exprColonExpr, resIdent: NimNode): NimNode = @@ -1796,10 +1900,18 @@ macro to*(node: JsonNode, T: typedesc): untyped = expectKind(typeNode, nnkBracketExpr) doAssert(($typeNode[0]).normalize == "typedesc") - result = createConstructor(typeNode[1], node) + # Create `temp` variable to store the result in case the user calls this + # on `parseJson` (see bug #6604). + result = newNimNode(nnkStmtListExpr) + let temp = genSym(nskLet, "temp") + result.add quote do: + let `temp` = `node` + + let constructor = createConstructor(typeNode[1], temp) # TODO: Rename postProcessValue and move it (?) - result = postProcessValue(result) + result.add(postProcessValue(constructor)) + # echo(treeRepr(result)) # echo(toStrLit(result)) when false: @@ -1849,8 +1961,8 @@ when isMainModule: discard parseJson"""{ invalid""" except: discard - # memory diff should less than 2M - doAssert(abs(getOccupiedMem() - startMemory) < 2 * 1024 * 1024) + # memory diff should less than 4M + doAssert(abs(getOccupiedMem() - startMemory) < 4 * 1024 * 1024) # test `$` diff --git a/lib/pure/lenientops.nim b/lib/pure/lenientops.nim new file mode 100644 index 000000000..b124a9512 --- /dev/null +++ b/lib/pure/lenientops.nim @@ -0,0 +1,60 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module offers implementations of common binary operations +## like ``+``, ``-``, ``*``, ``/`` and comparison operations, +## which work for mixed float/int operands. +## All operations convert the integer operand into the +## type of the float operand. For numerical expressions, the return +## type is always the type of the float involved in the expresssion, +## i.e., there is no auto conversion from float32 to float64. +## +## Note: In general, auto-converting from int to float loses +## information, which is why these operators live in a separate +## module. Use with care. +## +## Regarding binary comparison, this module only provides unequal operators. +## The equality operator ``==`` is omitted, because depending on the use case +## either casting to float or rounding to int might be preferred, and users +## should make an explicit choice. + +import typetraits + +proc `+`*[I: SomeInteger, F: SomeReal](i: I, f: F): F {.noSideEffect, inline.} = + F(i) + f +proc `+`*[I: SomeInteger, F: SomeReal](f: F, i: I): F {.noSideEffect, inline.} = + f + F(i) + +proc `-`*[I: SomeInteger, F: SomeReal](i: I, f: F): F {.noSideEffect, inline.} = + F(i) - f +proc `-`*[I: SomeInteger, F: SomeReal](f: F, i: I): F {.noSideEffect, inline.} = + f - F(i) + +proc `*`*[I: SomeInteger, F: SomeReal](i: I, f: F): F {.noSideEffect, inline.} = + F(i) * f +proc `*`*[I: SomeInteger, F: SomeReal](f: F, i: I): F {.noSideEffect, inline.} = + f * F(i) + +proc `/`*[I: SomeInteger, F: SomeReal](i: I, f: F): F {.noSideEffect, inline.} = + F(i) / f +proc `/`*[I: SomeInteger, F: SomeReal](f: F, i: I): F {.noSideEffect, inline.} = + f / F(i) + +proc `<`*[I: SomeInteger, F: SomeReal](i: I, f: F): bool {.noSideEffect, inline.} = + F(i) < f +proc `<`*[I: SomeInteger, F: SomeReal](f: F, i: I): bool {.noSideEffect, inline.} = + f < F(i) +proc `<=`*[I: SomeInteger, F: SomeReal](i: I, f: F): bool {.noSideEffect, inline.} = + F(i) <= f +proc `<=`*[I: SomeInteger, F: SomeReal](f: F, i: I): bool {.noSideEffect, inline.} = + f <= F(i) + +# Note that we must not defined `>=` and `>`, because system.nim already has a +# template with signature (x, y: untyped): untyped, which would lead to +# ambigous calls. diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index e2a5bed96..830820fd1 100644 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -202,13 +202,17 @@ when not defined(js): proc countLogLines(logger: RollingFileLogger): int = result = 0 - for line in logger.file.lines(): + let fp = open(logger.baseName, fmRead) + for line in fp.lines(): result.inc() + fp.close() proc countFiles(filename: string): int = # Example: file.log.1 result = 0 - let (dir, name, ext) = splitFile(filename) + var (dir, name, ext) = splitFile(filename) + if dir == "": + dir = "." for kind, path in walkDir(dir): if kind == pcFile: let llfn = name & ext & ExtSep diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim index c4c731acf..6ee830786 100644 --- a/lib/pure/marshal.nim +++ b/lib/pure/marshal.nim @@ -283,7 +283,7 @@ proc to*[T](data: string): T = loadAny(newStringStream(data), toAny(result), tab) when not defined(testing) and isMainModule: - template testit(x: expr) = echo($$to[type(x)]($$x)) + template testit(x: untyped) = echo($$to[type(x)]($$x)) var x: array[0..4, array[0..4, string]] = [ ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim index 7022c21d9..6366fee1a 100644 --- a/lib/pure/matchers.nim +++ b/lib/pure/matchers.nim @@ -48,7 +48,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect, "aero", "jobs", "museum": return true else: return false -proc parseInt*(s: string, value: var int, validRange: Slice[int]) {. +proc parseInt*(s: string, value: var int, validRange: HSlice[int, int]) {. noSideEffect, rtl, extern: "nmatchParseInt".} = ## parses `s` into an integer in the range `validRange`. If successful, ## `value` is modified to contain the result. Otherwise no exception is diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 8037b31b0..cbd04a145 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -184,6 +184,8 @@ when not defined(JS): proc pow*(x, y: float32): float32 {.importc: "powf", header: "<math.h>".} proc pow*(x, y: float64): float64 {.importc: "pow", header: "<math.h>".} ## computes x to power raised of y. + ## + ## To compute power between integers, use `^` e.g. 2 ^ 6 proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".} proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".} @@ -289,6 +291,8 @@ when not defined(JS): ## echo fmod(-2.5, 0.3) ## -0.1 else: + proc trunc*(x: float32): float32 {.importc: "Math.trunc", nodecl.} + proc trunc*(x: float64): float64 {.importc: "Math.trunc", nodecl.} proc floor*(x: float32): float32 {.importc: "Math.floor", nodecl.} proc floor*(x: float64): float64 {.importc: "Math.floor", nodecl.} proc ceil*(x: float32): float32 {.importc: "Math.ceil", nodecl.} @@ -347,15 +351,19 @@ proc round*[T: float32|float64](x: T, places: int = 0): T = result = round0(x*mult)/mult when not defined(JS): - proc frexp*(x: float32, exponent: var int): float32 {. + proc c_frexp*(x: float32, exponent: var int32): float32 {. importc: "frexp", header: "<math.h>".} - proc frexp*(x: float64, exponent: var int): float64 {. + proc c_frexp*(x: float64, exponent: var int32): float64 {. importc: "frexp", header: "<math.h>".} + proc frexp*[T, U](x: T, exponent: var U): T = ## Split a number into mantissa and exponent. ## `frexp` calculates the mantissa m (a float greater than or equal to 0.5 ## and less than 1) and the integer value n such that `x` (the original ## float value) equals m * 2**n. frexp stores n in `exponent` and returns ## m. + var exp: int32 + result = c_frexp(x, exp) + exponent = exp else: proc frexp*[T: float32|float64](x: T, exponent: var int): T = if x == 0.0: @@ -364,9 +372,14 @@ else: elif x < 0.0: result = -frexp(-x, exponent) else: - var ex = floor(log2(x)) - exponent = round(ex) + var ex = trunc(log2(x)) + exponent = int(ex) result = x / pow(2.0, ex) + if abs(result) >= 1: + inc(exponent) + result = result / 2 + if exponent == 1024 and result == 0.0: + result = 0.99999999999999988898 proc splitDecimal*[T: float32|float64](x: T): tuple[intpart: T, floatpart: T] = ## Breaks `x` into an integral and a fractional part. diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index 9b2d25267..5c73381ff 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -257,10 +257,13 @@ proc close*(f: var MemFile) = when defined(windows): if f.wasOpened: error = unmapViewOfFile(f.mem) == 0 - lastErr = osLastError() - error = (closeHandle(f.mapHandle) == 0) or error - if f.fHandle != INVALID_HANDLE_VALUE: - error = (closeHandle(f.fHandle) == 0) or error + if not error: + error = closeHandle(f.mapHandle) == 0 + if not error and f.fHandle != INVALID_HANDLE_VALUE: + discard closeHandle(f.fHandle) + f.fHandle = INVALID_HANDLE_VALUE + if error: + lastErr = osLastError() else: error = munmap(f.mem, f.size) != 0 lastErr = osLastError() diff --git a/lib/pure/mersenne.nim b/lib/pure/mersenne.nim index f18cf5b90..6ac0c4e56 100644 --- a/lib/pure/mersenne.nim +++ b/lib/pure/mersenne.nim @@ -17,7 +17,7 @@ type proc newMersenneTwister*(seed: uint32): MersenneTwister = result.index = 0 result.mt[0] = seed - for i in 1..623'u32: + for i in 1'u32 .. 623'u32: result.mt[i] = (0x6c078965'u32 * (result.mt[i-1] xor (result.mt[i-1] shr 30'u32)) + i) proc generateNumbers(m: var MersenneTwister) = diff --git a/lib/pure/mimetypes.nim b/lib/pure/mimetypes.nim index 1e315afb4..b397ef47b 100644 --- a/lib/pure/mimetypes.nim +++ b/lib/pure/mimetypes.nim @@ -491,6 +491,8 @@ const mimes* = { "vrml": "x-world/x-vrml", "wrl": "x-world/x-vrml"} +from strutils import startsWith + proc newMimetypes*(): MimeDB = ## Creates a new Mimetypes database. The database will contain the most ## common mimetypes. @@ -498,8 +500,11 @@ proc newMimetypes*(): MimeDB = proc getMimetype*(mimedb: MimeDB, ext: string, default = "text/plain"): string = ## Gets mimetype which corresponds to ``ext``. Returns ``default`` if ``ext`` - ## could not be found. - result = mimedb.mimes.getOrDefault(ext) + ## could not be found. ``ext`` can start with an optional dot which is ignored. + if ext.startsWith("."): + result = mimedb.mimes.getOrDefault(ext.substr(1)) + else: + result = mimedb.mimes.getOrDefault(ext) if result == "": return default diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 215a301b6..aad6ab3e8 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -58,7 +58,7 @@ ## You can then begin accepting connections using the ``accept`` procedure. ## ## .. code-block:: Nim -## var client = newSocket() +## var client = new Socket ## var address = "" ## while true: ## socket.acceptAddr(client, address) @@ -145,7 +145,7 @@ type SOBool* = enum ## Boolean socket options. OptAcceptConn, OptBroadcast, OptDebug, OptDontRoute, OptKeepAlive, - OptOOBInline, OptReuseAddr, OptReusePort + OptOOBInline, OptReuseAddr, OptReusePort, OptNoDelay ReadLineResult* = enum ## result for readLineAsync ReadFullLine, ReadPartialLine, ReadDisconnected, ReadNone @@ -857,15 +857,23 @@ proc close*(socket: Socket) = # shutdown i.e not wait for the peers "close notify" alert with a second # call to SSLShutdown let res = SSLShutdown(socket.sslHandle) - SSLFree(socket.sslHandle) - socket.sslHandle = nil if res == 0: discard elif res != 1: socketError(socket, res) finally: + when defineSsl: + if socket.isSSL and socket.sslHandle != nil: + SSLFree(socket.sslHandle) + socket.sslHandle = nil + socket.fd.close() +when defined(posix): + from posix import TCP_NODELAY +else: + from winlean import TCP_NODELAY + proc toCInt*(opt: SOBool): cint = ## Converts a ``SOBool`` into its Socket Option cint representation. case opt @@ -877,6 +885,7 @@ proc toCInt*(opt: SOBool): cint = of OptOOBInline: SO_OOBINLINE of OptReuseAddr: SO_REUSEADDR of OptReusePort: SO_REUSEPORT + of OptNoDelay: TCP_NODELAY proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {. tags: [ReadIOEffect].} = @@ -899,6 +908,12 @@ proc getPeerAddr*(socket: Socket): (string, Port) = proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {. tags: [WriteIOEffect].} = ## Sets option ``opt`` to a boolean value specified by ``value``. + ## + ## .. code-block:: Nim + ## var socket = newSocket() + ## socket.setSockOpt(OptReusePort, true) + ## socket.setSockOpt(OptNoDelay, true, level=IPPROTO_TCP.toInt) + ## var valuei = cint(if value: 1 else: 0) setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei) @@ -1120,11 +1135,11 @@ proc recv*(socket: Socket, data: var string, size: int, timeout = -1, ## ## When 0 is returned the socket's connection has been closed. ## - ## This function will throw an EOS exception when an error occurs. A value + ## This function will throw an OSError exception when an error occurs. A value ## lower than 0 is never returned. ## ## A timeout may be specified in milliseconds, if enough data is not received - ## within the time specified an ETimeout exception will be raised. + ## within the time specified an TimeoutError exception will be raised. ## ## **Note**: ``data`` must be initialised. ## diff --git a/lib/pure/numeric.nim b/lib/pure/numeric.nim deleted file mode 100644 index ccda3a146..000000000 --- a/lib/pure/numeric.nim +++ /dev/null @@ -1,87 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2013 Robert Persson -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## **Warning:** This module will be moved out of the stdlib and into a -## Nimble package, don't use it. - -type OneVarFunction* = proc (x: float): float - -{.deprecated: [TOneVarFunction: OneVarFunction].} - -proc brent*(xmin,xmax:float, function:OneVarFunction, tol:float,maxiter=1000): - tuple[rootx, rooty: float, success: bool]= - ## Searches `function` for a root between `xmin` and `xmax` - ## using brents method. If the function value at `xmin`and `xmax` has the - ## same sign, `rootx`/`rooty` is set too the extrema value closest to x-axis - ## and succes is set to false. - ## Otherwise there exists at least one root and success is set to true. - ## This root is searched for at most `maxiter` iterations. - ## If `tol` tolerance is reached within `maxiter` iterations - ## the root refinement stops and success=true. - - # see http://en.wikipedia.org/wiki/Brent%27s_method - var - a=xmin - b=xmax - c=a - d=1.0e308 - fa=function(a) - fb=function(b) - fc=fa - s=0.0 - fs=0.0 - mflag:bool - i=0 - tmp2:float - - if fa*fb>=0: - if abs(fa)<abs(fb): - return (a,fa,false) - else: - return (b,fb,false) - - if abs(fa)<abs(fb): - swap(fa,fb) - swap(a,b) - - while fb!=0.0 and abs(a-b)>tol: - if fa!=fc and fb!=fc: # inverse quadratic interpolation - s = a * fb * fc / (fa - fb) / (fa - fc) + b * fa * fc / (fb - fa) / (fb - fc) + c * fa * fb / (fc - fa) / (fc - fb) - else: #secant rule - s = b - fb * (b - a) / (fb - fa) - tmp2 = (3.0 * a + b) / 4.0 - if not((s > tmp2 and s < b) or (s < tmp2 and s > b)) or - (mflag and abs(s - b) >= (abs(b - c) / 2.0)) or - (not mflag and abs(s - b) >= abs(c - d) / 2.0): - s=(a+b)/2.0 - mflag=true - else: - if (mflag and (abs(b - c) < tol)) or (not mflag and (abs(c - d) < tol)): - s=(a+b)/2.0 - mflag=true - else: - mflag=false - fs = function(s) - d = c - c = b - fc = fb - if fa * fs<0.0: - b=s - fb=fs - else: - a=s - fa=fs - if abs(fa)<abs(fb): - swap(a,b) - swap(fa,fb) - inc i - if i>maxiter: - break - - return (b,fb,true) diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim index 60b53dbe0..427a68964 100644 --- a/lib/pure/oids.nim +++ b/lib/pure/oids.nim @@ -88,7 +88,7 @@ proc generatedTime*(oid: Oid): Time = var tmp: int32 var dummy = oid.time bigEndian32(addr(tmp), addr(dummy)) - result = Time(tmp) + result = fromUnix(tmp) when not defined(testing) and isMainModule: let xo = genOid() diff --git a/lib/pure/os.nim b/lib/pure/os.nim index a1ae4e250..c18d03289 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -173,33 +173,33 @@ proc findExe*(exe: string, followSymlinks: bool = true; return x result = "" -proc getLastModificationTime*(file: string): Time {.rtl, extern: "nos$1".} = +proc getLastModificationTime*(file: string): times.Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s last modification time. when defined(posix): var res: Stat if stat(file, res) < 0'i32: raiseOSError(osLastError()) - return res.st_mtime + return fromUnix(res.st_mtime.int64) else: var f: WIN32_FIND_DATA var h = findFirstFile(file, f) if h == -1'i32: raiseOSError(osLastError()) - result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime)) + result = fromUnix(winTimeToUnixTime(rdFileTime(f.ftLastWriteTime)).int64) findClose(h) -proc getLastAccessTime*(file: string): Time {.rtl, extern: "nos$1".} = +proc getLastAccessTime*(file: string): times.Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s last read or write access time. when defined(posix): var res: Stat if stat(file, res) < 0'i32: raiseOSError(osLastError()) - return res.st_atime + return fromUnix(res.st_atime.int64) else: var f: WIN32_FIND_DATA var h = findFirstFile(file, f) if h == -1'i32: raiseOSError(osLastError()) - result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime)) + result = fromUnix(winTimeToUnixTime(rdFileTime(f.ftLastAccessTime)).int64) findClose(h) -proc getCreationTime*(file: string): Time {.rtl, extern: "nos$1".} = +proc getCreationTime*(file: string): times.Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s creation time. ## ## **Note:** Under POSIX OS's, the returned time may actually be the time at @@ -208,12 +208,12 @@ proc getCreationTime*(file: string): Time {.rtl, extern: "nos$1".} = when defined(posix): var res: Stat if stat(file, res) < 0'i32: raiseOSError(osLastError()) - return res.st_ctime + return fromUnix(res.st_ctime.int64) else: var f: WIN32_FIND_DATA var h = findFirstFile(file, f) if h == -1'i32: raiseOSError(osLastError()) - result = winTimeToUnixTime(rdFileTime(f.ftCreationTime)) + result = fromUnix(winTimeToUnixTime(rdFileTime(f.ftCreationTime)).int64) findClose(h) proc fileNewer*(a, b: string): bool {.rtl, extern: "nos$1".} = @@ -630,7 +630,7 @@ proc execShellCmd*(command: string): int {.rtl, extern: "nos$1", ## the process has finished. To execute a program without having a ## shell involved, use the `execProcess` proc of the `osproc` ## module. - when defined(linux): + when defined(posix): result = c_system(command) shr 8 else: result = c_system(command) @@ -816,32 +816,40 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path: k = getSymlinkFileKind(y) yield (k, y) -iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {. - tags: [ReadDirEffect].} = - ## Recursively walks over the directory `dir` and yields for each file in `dir`. - ## The full path for each file is returned. Directories are not returned. +iterator walkDirRec*(dir: string, yieldFilter = {pcFile}, + followFilter = {pcDir}): string {.tags: [ReadDirEffect].} = + ## Recursively walks over the directory `dir` and yields for each file + ## or directory in `dir`. + ## The full path for each file or directory is returned. ## **Warning**: ## Modifying the directory structure while the iterator ## is traversing may result in undefined behavior! ## - ## Walking is recursive. `filter` controls the behaviour of the iterator: + ## Walking is recursive. `filters` controls the behaviour of the iterator: ## ## --------------------- --------------------------------------------- - ## filter meaning + ## yieldFilter meaning ## --------------------- --------------------------------------------- ## ``pcFile`` yield real files ## ``pcLinkToFile`` yield symbolic links to files + ## ``pcDir`` yield real directories + ## ``pcLinkToDir`` yield symbolic links to directories + ## --------------------- --------------------------------------------- + ## + ## --------------------- --------------------------------------------- + ## followFilter meaning + ## --------------------- --------------------------------------------- ## ``pcDir`` follow real directories ## ``pcLinkToDir`` follow symbolic links to directories ## --------------------- --------------------------------------------- ## var stack = @[dir] while stack.len > 0: - for k,p in walkDir(stack.pop()): - if k in filter: - case k - of pcFile, pcLinkToFile: yield p - of pcDir, pcLinkToDir: stack.add(p) + for k, p in walkDir(stack.pop()): + if k in {pcDir, pcLinkToDir} and k in followFilter: + stack.add(p) + if k in yieldFilter: + yield p proc rawRemoveDir(dir: string) = when defined(windows): @@ -1195,14 +1203,15 @@ when defined(nimdoc): ## Returns the number of `command line arguments`:idx: given to the ## application. ## - ## If your binary was called without parameters this will return zero. You - ## can later query each individual paramater with `paramStr() <#paramStr>`_ + ## Unlike `argc`:idx: in C, if your binary was called without parameters this + ## will return zero. + ## You can query each individual paramater with `paramStr() <#paramStr>`_ ## or retrieve all of them in one go with `commandLineParams() ## <#commandLineParams>`_. ## - ## **Availability**: On Posix there is no portable way to get the command - ## line from a DLL and thus the proc isn't defined in this environment. You - ## can test for its availability with `declared() <system.html#declared>`_. + ## **Availability**: When generating a dynamic library (see --app:lib) on + ## Posix this proc is not defined. + ## Test for availability using `declared() <system.html#declared>`_. ## Example: ## ## .. code-block:: nim @@ -1219,13 +1228,14 @@ when defined(nimdoc): ## `paramCount() <#paramCount>`_ with this proc you can call the ## convenience `commandLineParams() <#commandLineParams>`_. ## - ## It is possible to call ``paramStr(0)`` but this will return OS specific + ## Similarly to `argv`:idx: in C, + ## it is possible to call ``paramStr(0)`` but this will return OS specific ## contents (usually the name of the invoked executable). You should avoid ## this and call `getAppFilename() <#getAppFilename>`_ instead. ## - ## **Availability**: On Posix there is no portable way to get the command - ## line from a DLL and thus the proc isn't defined in this environment. You - ## can test for its availability with `declared() <system.html#declared>`_. + ## **Availability**: When generating a dynamic library (see --app:lib) on + ## Posix this proc is not defined. + ## Test for availability using `declared() <system.html#declared>`_. ## Example: ## ## .. code-block:: nim @@ -1441,7 +1451,7 @@ proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [TimeEffect].} = winlean.sleep(int32(milsecs)) else: var a, b: Timespec - a.tv_sec = Time(milsecs div 1000) + a.tv_sec = posix.Time(milsecs div 1000) a.tv_nsec = (milsecs mod 1000) * 1000 * 1000 discard posix.nanosleep(a, b) @@ -1479,16 +1489,17 @@ type size*: BiggestInt # Size of file. permissions*: set[FilePermission] # File permissions linkCount*: BiggestInt # Number of hard links the file object has. - lastAccessTime*: Time # Time file was last accessed. - lastWriteTime*: Time # Time file was last modified/written to. - creationTime*: Time # Time file was created. Not supported on all systems! + lastAccessTime*: times.Time # Time file was last accessed. + lastWriteTime*: times.Time # Time file was last modified/written to. + creationTime*: times.Time # Time file was created. Not supported on all systems! template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped = ## Transforms the native file info structure into the one nim uses. ## 'rawInfo' is either a 'TBY_HANDLE_FILE_INFORMATION' structure on Windows, ## or a 'Stat' structure on posix when defined(Windows): - template toTime(e: FILETIME): untyped {.gensym.} = winTimeToUnixTime(rdFileTime(e)) # local templates default to bind semantics + template toTime(e: FILETIME): untyped {.gensym.} = + fromUnix(winTimeToUnixTime(rdFileTime(e)).int64) # local templates default to bind semantics template merge(a, b): untyped = a or (b shl 32) formalInfo.id.device = rawInfo.dwVolumeSerialNumber formalInfo.id.file = merge(rawInfo.nFileIndexLow, rawInfo.nFileIndexHigh) @@ -1520,9 +1531,9 @@ template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped = formalInfo.id = (rawInfo.st_dev, rawInfo.st_ino) formalInfo.size = rawInfo.st_size formalInfo.linkCount = rawInfo.st_Nlink.BiggestInt - formalInfo.lastAccessTime = rawInfo.st_atime - formalInfo.lastWriteTime = rawInfo.st_mtime - formalInfo.creationTime = rawInfo.st_ctime + formalInfo.lastAccessTime = fromUnix(rawInfo.st_atime.int64) + formalInfo.lastWriteTime = fromUnix(rawInfo.st_mtime.int64) + formalInfo.creationTime = fromUnix(rawInfo.st_ctime.int64) result.permissions = {} checkAndIncludeMode(S_IRUSR, fpUserRead) diff --git a/lib/pure/ospaths.nim b/lib/pure/ospaths.nim index dcb785c83..0d638abb9 100644 --- a/lib/pure/ospaths.nim +++ b/lib/pure/ospaths.nim @@ -558,3 +558,67 @@ proc expandTilde*(path: string): string {. result = getHomeDir() / path.substr(2) else: result = path + +proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = + ## Quote s, so it can be safely passed to Windows API. + ## Based on Python's subprocess.list2cmdline + ## See http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + let needQuote = {' ', '\t'} in s or s.len == 0 + + result = "" + var backslashBuff = "" + if needQuote: + result.add("\"") + + for c in s: + if c == '\\': + backslashBuff.add(c) + elif c == '\"': + result.add(backslashBuff) + result.add(backslashBuff) + backslashBuff.setLen(0) + result.add("\\\"") + else: + if backslashBuff.len != 0: + result.add(backslashBuff) + backslashBuff.setLen(0) + result.add(c) + + if needQuote: + result.add("\"") + +proc quoteShellPosix*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = + ## Quote ``s``, so it can be safely passed to POSIX shell. + ## Based on Python's pipes.quote + const safeUnixChars = {'%', '+', '-', '.', '/', '_', ':', '=', '@', + '0'..'9', 'A'..'Z', 'a'..'z'} + if s.len == 0: + return "''" + + let safe = s.allCharsInSet(safeUnixChars) + + if safe: + return s + else: + return "'" & s.replace("'", "'\"'\"'") & "'" + +when defined(windows) or defined(posix): + proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = + ## Quote ``s``, so it can be safely passed to shell. + when defined(windows): + return quoteShellWindows(s) + else: + return quoteShellPosix(s) + +when isMainModule: + assert quoteShellWindows("aaa") == "aaa" + assert quoteShellWindows("aaa\"") == "aaa\\\"" + assert quoteShellWindows("") == "\"\"" + + assert quoteShellPosix("aaa") == "aaa" + assert quoteShellPosix("aaa a") == "'aaa a'" + assert quoteShellPosix("") == "''" + assert quoteShellPosix("a'a") == "'a'\"'\"'a'" + + when defined(posix): + assert quoteShell("") == "''" diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 07429b9a9..1625845d1 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -15,6 +15,9 @@ include "system/inclrtl" import strutils, os, strtabs, streams, cpuinfo +from ospaths import quoteShell, quoteShellWindows, quoteShellPosix +export quoteShell, quoteShellWindows, quoteShellPosix + when defined(windows): import winlean else: @@ -38,10 +41,13 @@ type ## Windows: Named pipes are used so that you can peek ## at the process' output streams. poDemon ## Windows: The program creates no Window. + ## Unix: Start the program as a demon. This is still + ## work in progress! ProcessObj = object of RootObj when defined(windows): fProcessHandle: Handle + fThreadHandle: Handle inHandle, outHandle, errHandle: FileHandle id: Handle else: @@ -49,6 +55,7 @@ type inStream, outStream, errStream: Stream id: Pid exitStatus: cint + exitFlag: bool options: set[ProcessOption] Process* = ref ProcessObj ## represents an operating system process @@ -60,58 +67,6 @@ type const poUseShell* {.deprecated.} = poUsePath ## Deprecated alias for poUsePath. -proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = - ## Quote s, so it can be safely passed to Windows API. - ## Based on Python's subprocess.list2cmdline - ## See http://msdn.microsoft.com/en-us/library/17w5ykft.aspx - let needQuote = {' ', '\t'} in s or s.len == 0 - - result = "" - var backslashBuff = "" - if needQuote: - result.add("\"") - - for c in s: - if c == '\\': - backslashBuff.add(c) - elif c == '\"': - result.add(backslashBuff) - result.add(backslashBuff) - backslashBuff.setLen(0) - result.add("\\\"") - else: - if backslashBuff.len != 0: - result.add(backslashBuff) - backslashBuff.setLen(0) - result.add(c) - - if needQuote: - result.add("\"") - -proc quoteShellPosix*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = - ## Quote ``s``, so it can be safely passed to POSIX shell. - ## Based on Python's pipes.quote - const safeUnixChars = {'%', '+', '-', '.', '/', '_', ':', '=', '@', - '0'..'9', 'A'..'Z', 'a'..'z'} - if s.len == 0: - return "''" - - let safe = s.allCharsInSet(safeUnixChars) - - if safe: - return s - else: - return "'" & s.replace("'", "'\"'\"'") & "'" - -proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = - ## Quote ``s``, so it can be safely passed to shell. - when defined(Windows): - return quoteShellWindows(s) - elif defined(posix): - return quoteShellPosix(s) - else: - {.error:"quoteShell is not supported on your system".} - proc execProcess*(command: string, args: openArray[string] = [], env: StringTableRef = nil, @@ -216,8 +171,7 @@ proc waitForExit*(p: Process, timeout: int = -1): int {.rtl, ## On posix, if the process has exited because of a signal, 128 + signal ## number will be returned. - -proc peekExitCode*(p: Process): int {.tags: [].} +proc peekExitCode*(p: Process): int {.rtl, extern: "nosp$1", tags: [].} ## return -1 if the process is still running. Otherwise the process' exit code ## ## On posix, if the process has exited because of a signal, 128 + signal @@ -280,55 +234,98 @@ proc execProcesses*(cmds: openArray[string], ## executes the commands `cmds` in parallel. Creates `n` processes ## that execute in parallel. The highest return value of all processes ## is returned. Runs `beforeRunEvent` before running each command. - when defined(posix): - # poParentStreams causes problems on Posix, so we simply disable it: - var options = options - {poParentStreams} assert n > 0 if n > 1: - var q: seq[Process] - newSeq(q, n) - var m = min(n, cmds.len) - for i in 0..m-1: + var i = 0 + var q = newSeq[Process](n) + + when defined(windows): + var w: WOHandleArray + var m = min(min(n, MAXIMUM_WAIT_OBJECTS), cmds.len) + var wcount = m + else: + var m = min(n, cmds.len) + + while i < m: if beforeRunEvent != nil: beforeRunEvent(i) - q[i] = startProcess(cmds[i], options=options + {poEvalCommand}) - when defined(noBusyWaiting): - var r = 0 - for i in m..high(cmds): - when defined(debugExecProcesses): - var err = "" - var outp = outputStream(q[r]) - while running(q[r]) or not atEnd(outp): - err.add(outp.readLine()) - err.add("\n") - echo(err) - result = max(waitForExit(q[r]), result) - if afterRunEvent != nil: afterRunEvent(r, q[r]) - if q[r] != nil: close(q[r]) - if beforeRunEvent != nil: - beforeRunEvent(i) - q[r] = startProcess(cmds[i], options=options + {poEvalCommand}) - r = (r + 1) mod n - else: - var i = m - while i <= high(cmds): - sleep(50) - for r in 0..n-1: - if not running(q[r]): - #echo(outputStream(q[r]).readLine()) - result = max(waitForExit(q[r]), result) - if afterRunEvent != nil: afterRunEvent(r, q[r]) - if q[r] != nil: close(q[r]) - if beforeRunEvent != nil: - beforeRunEvent(i) - q[r] = startProcess(cmds[i], options=options + {poEvalCommand}) - inc(i) - if i > high(cmds): break - for j in 0..m-1: - result = max(waitForExit(q[j]), result) - if afterRunEvent != nil: afterRunEvent(j, q[j]) - if q[j] != nil: close(q[j]) + q[i] = startProcess(cmds[i], options = options + {poEvalCommand}) + when defined(windows): + w[i] = q[i].fProcessHandle + inc(i) + + var ecount = len(cmds) + while ecount > 0: + var rexit = -1 + when defined(windows): + # waiting for all children, get result if any child exits + var ret = waitForMultipleObjects(int32(wcount), addr(w), 0'i32, + INFINITE) + if ret == WAIT_TIMEOUT: + # must not be happen + discard + elif ret == WAIT_FAILED: + raiseOSError(osLastError()) + else: + var status: int32 + for r in 0..m-1: + if not isNil(q[r]) and q[r].fProcessHandle == w[ret]: + discard getExitCodeProcess(q[r].fProcessHandle, status) + q[r].exitFlag = true + q[r].exitStatus = status + rexit = r + break + else: + var status: cint = 1 + # waiting for all children, get result if any child exits + let res = waitpid(-1, status, 0) + if res > 0: + for r in 0..m-1: + if not isNil(q[r]) and q[r].id == res: + if WIFEXITED(status) or WIFSIGNALED(status): + q[r].exitFlag = true + q[r].exitStatus = status + rexit = r + break + else: + let err = osLastError() + if err == OSErrorCode(ECHILD): + # some child exits, we need to check our childs exit codes + for r in 0..m-1: + if (not isNil(q[r])) and (not running(q[r])): + q[r].exitFlag = true + q[r].exitStatus = status + rexit = r + break + elif err == OSErrorCode(EINTR): + # signal interrupted our syscall, lets repeat it + continue + else: + # all other errors are exceptions + raiseOSError(err) + + if rexit >= 0: + result = max(result, q[rexit].peekExitCode()) + if afterRunEvent != nil: afterRunEvent(rexit, q[rexit]) + close(q[rexit]) + if i < len(cmds): + if beforeRunEvent != nil: beforeRunEvent(i) + q[rexit] = startProcess(cmds[i], + options = options + {poEvalCommand}) + when defined(windows): + w[rexit] = q[rexit].fProcessHandle + inc(i) + else: + when defined(windows): + for k in 0..wcount - 1: + if w[k] == q[rexit].fProcessHandle: + w[k] = w[wcount - 1] + w[wcount - 1] = 0 + dec(wcount) + break + q[rexit] = nil + dec(ecount) else: for i in 0..high(cmds): if beforeRunEvent != nil: @@ -370,6 +367,8 @@ when not defined(useNimRtl): elif not running(p): break close(p) +template streamAccess(p) = + assert poParentStreams notin p.options, "API usage error: stream access not allowed when you use poParentStreams" when defined(Windows) and not defined(useNimRtl): # We need to implement a handle stream for Windows: @@ -513,6 +512,7 @@ when defined(Windows) and not defined(useNimRtl): hi, ho, he: Handle new(result) result.options = options + result.exitFlag = true si.cb = sizeof(si).cint if poParentStreams notin options: si.dwFlags = STARTF_USESTDHANDLES # STARTF_USESHOWWINDOW or @@ -581,28 +581,31 @@ when defined(Windows) and not defined(useNimRtl): "Requested command not found: '$1'. OS error:" % command) else: raiseOSError(lastError, command) - # Close the handle now so anyone waiting is woken: - discard closeHandle(procInfo.hThread) result.fProcessHandle = procInfo.hProcess + result.fThreadHandle = procInfo.hThread result.id = procInfo.dwProcessId + result.exitFlag = false proc close(p: Process) = - if poInteractive in p.options: - # somehow this is not always required on Windows: + if poParentStreams notin p.options: discard closeHandle(p.inHandle) discard closeHandle(p.outHandle) discard closeHandle(p.errHandle) - #discard closeHandle(p.FProcessHandle) + discard closeHandle(p.fThreadHandle) + discard closeHandle(p.fProcessHandle) proc suspend(p: Process) = - discard suspendThread(p.fProcessHandle) + discard suspendThread(p.fThreadHandle) proc resume(p: Process) = - discard resumeThread(p.fProcessHandle) + discard resumeThread(p.fThreadHandle) proc running(p: Process): bool = - var x = waitForSingleObject(p.fProcessHandle, 50) - return x == WAIT_TIMEOUT + if p.exitFlag: + return false + else: + var x = waitForSingleObject(p.fProcessHandle, 0) + return x == WAIT_TIMEOUT proc terminate(p: Process) = if running(p): @@ -612,28 +615,48 @@ when defined(Windows) and not defined(useNimRtl): terminate(p) proc waitForExit(p: Process, timeout: int = -1): int = - discard waitForSingleObject(p.fProcessHandle, timeout.int32) - - var res: int32 - discard getExitCodeProcess(p.fProcessHandle, res) - result = res - discard closeHandle(p.fProcessHandle) + if p.exitFlag: + return p.exitStatus + + let res = waitForSingleObject(p.fProcessHandle, timeout.int32) + if res == WAIT_TIMEOUT: + terminate(p) + var status: int32 + discard getExitCodeProcess(p.fProcessHandle, status) + if status != STILL_ACTIVE: + p.exitFlag = true + p.exitStatus = status + discard closeHandle(p.fThreadHandle) + discard closeHandle(p.fProcessHandle) + result = status + else: + result = -1 proc peekExitCode(p: Process): int = - var b = waitForSingleObject(p.fProcessHandle, 50) == WAIT_TIMEOUT - if b: result = -1 - else: - var res: int32 - discard getExitCodeProcess(p.fProcessHandle, res) - return res + if p.exitFlag: + return p.exitStatus + + result = -1 + var b = waitForSingleObject(p.fProcessHandle, 0) == WAIT_TIMEOUT + if not b: + var status: int32 + discard getExitCodeProcess(p.fProcessHandle, status) + p.exitFlag = true + p.exitStatus = status + discard closeHandle(p.fThreadHandle) + discard closeHandle(p.fProcessHandle) + result = status proc inputStream(p: Process): Stream = + streamAccess(p) result = newFileHandleStream(p.inHandle) proc outputStream(p: Process): Stream = + streamAccess(p) result = newFileHandleStream(p.outHandle) proc errorStream(p: Process): Stream = + streamAccess(p) result = newFileHandleStream(p.errHandle) proc execCmd(command: string): int = @@ -729,9 +752,7 @@ elif not defined(useNimRtl): sysEnv: cstringArray workingDir: cstring pStdin, pStdout, pStderr, pErrorPipe: array[0..1, cint] - optionPoUsePath: bool - optionPoParentStreams: bool - optionPoStdErrToStdOut: bool + options: set[ProcessOption] {.deprecated: [TStartProcessData: StartProcessData].} const useProcessAuxSpawn = declared(posix_spawn) and not defined(useFork) and @@ -756,7 +777,8 @@ elif not defined(useNimRtl): pStdin, pStdout, pStderr: array[0..1, cint] new(result) result.options = options - result.exitStatus = -3 # for ``waitForExit`` + result.exitFlag = true + if poParentStreams notin options: if pipe(pStdin) != 0'i32 or pipe(pStdout) != 0'i32 or pipe(pStderr) != 0'i32: @@ -765,7 +787,9 @@ elif not defined(useNimRtl): var sysCommand: string var sysArgsRaw: seq[string] if poEvalCommand in options: - const useShPath {.strdefine.} = "/bin/sh" + const useShPath {.strdefine.} = + when not defined(android): "/bin/sh" + else: "/system/bin/sh" sysCommand = useShPath sysArgsRaw = @[sysCommand, "-c", command] assert args.len == 0, "`args` has to be empty when using poEvalCommand." @@ -794,10 +818,8 @@ elif not defined(useNimRtl): data.pStdin = pStdin data.pStdout = pStdout data.pStderr = pStderr - data.optionPoParentStreams = poParentStreams in options - data.optionPoUsePath = poUsePath in options - data.optionPoStdErrToStdOut = poStdErrToStdOut in options data.workingDir = workingDir + data.options = options when useProcessAuxSpawn: var currentDir = getCurrentDir() @@ -811,6 +833,7 @@ elif not defined(useNimRtl): if poEchoCmd in options: echo(command, " ", join(args, " ")) result.id = pid + result.exitFlag = false if poParentStreams in options: # does not make much sense, but better than nothing: @@ -837,7 +860,7 @@ elif not defined(useNimRtl): var attr: Tposix_spawnattr var fops: Tposix_spawn_file_actions - template chck(e: expr) = + template chck(e: untyped) = if e != 0'i32: raiseOSError(osLastError()) chck posix_spawn_file_actions_init(fops) @@ -846,19 +869,22 @@ elif not defined(useNimRtl): var mask: Sigset chck sigemptyset(mask) chck posix_spawnattr_setsigmask(attr, mask) - chck posix_spawnattr_setpgroup(attr, 0'i32) + if poDemon in data.options: + chck posix_spawnattr_setpgroup(attr, 0'i32) - chck posix_spawnattr_setflags(attr, POSIX_SPAWN_USEVFORK or - POSIX_SPAWN_SETSIGMASK or - POSIX_SPAWN_SETPGROUP) + var flags = POSIX_SPAWN_USEVFORK or + POSIX_SPAWN_SETSIGMASK + if poDemon in data.options: + flags = flags or POSIX_SPAWN_SETPGROUP + chck posix_spawnattr_setflags(attr, flags) - if not data.optionPoParentStreams: + if not (poParentStreams in data.options): chck posix_spawn_file_actions_addclose(fops, data.pStdin[writeIdx]) chck posix_spawn_file_actions_adddup2(fops, data.pStdin[readIdx], readIdx) chck posix_spawn_file_actions_addclose(fops, data.pStdout[readIdx]) chck posix_spawn_file_actions_adddup2(fops, data.pStdout[writeIdx], writeIdx) chck posix_spawn_file_actions_addclose(fops, data.pStderr[readIdx]) - if data.optionPoStdErrToStdOut: + if (poStdErrToStdOut in data.options): chck posix_spawn_file_actions_adddup2(fops, data.pStdout[writeIdx], 2) else: chck posix_spawn_file_actions_adddup2(fops, data.pStderr[writeIdx], 2) @@ -868,7 +894,7 @@ elif not defined(useNimRtl): setCurrentDir($data.workingDir) var pid: Pid - if data.optionPoUsePath: + if (poUsePath in data.options): res = posix_spawnp(pid, data.sysCommand, fops, attr, data.sysArgs, data.sysEnv) else: res = posix_spawn(pid, data.sysCommand, fops, attr, data.sysArgs, data.sysEnv) @@ -930,7 +956,7 @@ elif not defined(useNimRtl): # Warning: no GC here! # Or anything that touches global structures - all called nim procs # must be marked with stackTrace:off. Inspect C code after making changes. - if not data.optionPoParentStreams: + if not (poParentStreams in data.options): discard close(data.pStdin[writeIdx]) if dup2(data.pStdin[readIdx], readIdx) < 0: startProcessFail(data) @@ -938,7 +964,7 @@ elif not defined(useNimRtl): if dup2(data.pStdout[writeIdx], writeIdx) < 0: startProcessFail(data) discard close(data.pStderr[readIdx]) - if data.optionPoStdErrToStdOut: + if (poStdErrToStdOut in data.options): if dup2(data.pStdout[writeIdx], 2) < 0: startProcessFail(data) else: @@ -952,7 +978,7 @@ elif not defined(useNimRtl): discard close(data.pErrorPipe[readIdx]) discard fcntl(data.pErrorPipe[writeIdx], F_SETFD, FD_CLOEXEC) - if data.optionPoUsePath: + if (poUsePath in data.options): when defined(uClibc) or defined(linux): # uClibc environment (OpenWrt included) doesn't have the full execvpe let exe = findExe(data.sysCommand) @@ -984,19 +1010,22 @@ elif not defined(useNimRtl): if kill(p.id, SIGCONT) != 0'i32: raiseOsError(osLastError()) proc running(p: Process): bool = - var ret : int - var status : cint = 1 - ret = waitpid(p.id, status, WNOHANG) - if ret == int(p.id): - if isExitStatus(status): - p.exitStatus = status - return false - else: - return true - elif ret == 0: - return true # Can't establish status. Assume running. - else: + if p.exitFlag: return false + else: + var status: cint = 1 + let ret = waitpid(p.id, status, WNOHANG) + if ret == int(p.id): + if isExitStatus(status): + p.exitFlag = true + p.exitStatus = status + return false + else: + return true + elif ret == 0: + return true # Can't establish status. Assume running. + else: + raiseOSError(osLastError()) proc terminate(p: Process) = if kill(p.id, SIGTERM) != 0'i32: @@ -1011,13 +1040,14 @@ elif not defined(useNimRtl): import kqueue, times proc waitForExit(p: Process, timeout: int = -1): int = - if p.exitStatus != -3: + if p.exitFlag: return exitStatus(p.exitStatus) if timeout == -1: - var status : cint = 1 + var status: cint = 1 if waitpid(p.id, status, 0) < 0: raiseOSError(osLastError()) + p.exitFlag = true p.exitStatus = status else: var kqFD = kqueue() @@ -1030,15 +1060,15 @@ elif not defined(useNimRtl): var tmspec: Timespec if timeout >= 1000: - tmspec.tv_sec = (timeout div 1_000).Time + tmspec.tv_sec = posix.Time(timeout div 1_000) tmspec.tv_nsec = (timeout %% 1_000) * 1_000_000 else: - tmspec.tv_sec = 0.Time + tmspec.tv_sec = posix.Time(0) tmspec.tv_nsec = (timeout * 1_000_000) try: while true: - var status : cint = 1 + var status: cint = 1 var count = kevent(kqFD, addr(kevIn), 1, addr(kevOut), 1, addr(tmspec)) if count < 0: @@ -1051,12 +1081,14 @@ elif not defined(useNimRtl): raiseOSError(osLastError()) if waitpid(p.id, status, 0) < 0: raiseOSError(osLastError()) + p.exitFlag = true p.exitStatus = status break else: if kevOut.ident == p.id.uint and kevOut.filter == EVFILT_PROC: if waitpid(p.id, status, 0) < 0: raiseOSError(osLastError()) + p.exitFlag = true p.exitStatus = status break else: @@ -1077,36 +1109,33 @@ elif not defined(useNimRtl): var b: Timespec b.tv_sec = e.tv_sec b.tv_nsec = e.tv_nsec - e.tv_sec = (e.tv_sec - s.tv_sec).Time + e.tv_sec = e.tv_sec - s.tv_sec if e.tv_nsec >= s.tv_nsec: e.tv_nsec -= s.tv_nsec else: - if e.tv_sec == 0.Time: + if e.tv_sec == posix.Time(0): raise newException(ValueError, "System time was modified") else: diff = s.tv_nsec - e.tv_nsec e.tv_nsec = 1_000_000_000 - diff - t.tv_sec = (t.tv_sec - e.tv_sec).Time + t.tv_sec = t.tv_sec - e.tv_sec if t.tv_nsec >= e.tv_nsec: t.tv_nsec -= e.tv_nsec else: - t.tv_sec = (int(t.tv_sec) - 1).Time + t.tv_sec = t.tv_sec - posix.Time(1) diff = e.tv_nsec - t.tv_nsec t.tv_nsec = 1_000_000_000 - diff s.tv_sec = b.tv_sec s.tv_nsec = b.tv_nsec - #if waitPid(p.id, p.exitStatus, 0) == int(p.id): - # ``waitPid`` fails if the process is not running anymore. But then - # ``running`` probably set ``p.exitStatus`` for us. Since ``p.exitStatus`` is - # initialized with -3, wrong success exit codes are prevented. - if p.exitStatus != -3: + if p.exitFlag: return exitStatus(p.exitStatus) if timeout == -1: - var status : cint = 1 + var status: cint = 1 if waitpid(p.id, status, 0) < 0: raiseOSError(osLastError()) + p.exitFlag = true p.exitStatus = status else: var nmask, omask: Sigset @@ -1125,10 +1154,10 @@ elif not defined(useNimRtl): raiseOSError(osLastError()) if timeout >= 1000: - tmspec.tv_sec = (timeout div 1_000).Time + tmspec.tv_sec = posix.Time(timeout div 1_000) tmspec.tv_nsec = (timeout %% 1_000) * 1_000_000 else: - tmspec.tv_sec = 0.Time + tmspec.tv_sec = posix.Time(0) tmspec.tv_nsec = (timeout * 1_000_000) try: @@ -1138,9 +1167,10 @@ elif not defined(useNimRtl): let res = sigtimedwait(nmask, sinfo, tmspec) if res == SIGCHLD: if sinfo.si_pid == p.id: - var status : cint = 1 + var status: cint = 1 if waitpid(p.id, status, 0) < 0: raiseOSError(osLastError()) + p.exitFlag = true p.exitStatus = status break else: @@ -1161,9 +1191,10 @@ elif not defined(useNimRtl): # timeout expired, so we trying to kill process if posix.kill(p.id, SIGKILL) == -1: raiseOSError(osLastError()) - var status : cint = 1 + var status: cint = 1 if waitpid(p.id, status, 0) < 0: raiseOSError(osLastError()) + p.exitFlag = true p.exitStatus = status break else: @@ -1181,12 +1212,13 @@ elif not defined(useNimRtl): proc peekExitCode(p: Process): int = var status = cint(0) result = -1 - if p.exitStatus != -3: + if p.exitFlag: return exitStatus(p.exitStatus) var ret = waitpid(p.id, status, WNOHANG) if ret > 0: if isExitStatus(status): + p.exitFlag = true p.exitStatus = status result = exitStatus(status) @@ -1197,16 +1229,19 @@ elif not defined(useNimRtl): stream = newFileStream(f) proc inputStream(p: Process): Stream = + streamAccess(p) if p.inStream == nil: createStream(p.inStream, p.inHandle, fmWrite) return p.inStream proc outputStream(p: Process): Stream = + streamAccess(p) if p.outStream == nil: createStream(p.outStream, p.outHandle, fmRead) return p.outStream proc errorStream(p: Process): Stream = + streamAccess(p) if p.errStream == nil: createStream(p.errStream, p.errHandle, fmRead) return p.errStream @@ -1287,16 +1322,3 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = { result[1] = peekExitCode(p) if result[1] != -1: break close(p) - -when isMainModule: - assert quoteShellWindows("aaa") == "aaa" - assert quoteShellWindows("aaa\"") == "aaa\\\"" - assert quoteShellWindows("") == "\"\"" - - assert quoteShellPosix("aaa") == "aaa" - assert quoteShellPosix("aaa a") == "'aaa a'" - assert quoteShellPosix("") == "''" - assert quoteShellPosix("a'a") == "'a'\"'\"'a'" - - when defined(posix): - assert quoteShell("") == "''" diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim index 77b145a73..071858b7c 100644 --- a/lib/pure/parsecsv.nim +++ b/lib/pure/parsecsv.nim @@ -32,7 +32,7 @@ ## import parsecsv ## import os ## # Prepare a file -## var csv_content = """One,Two,Three,Four +## var content = """One,Two,Three,Four ## 1,2,3,4 ## 10,20,30,40 ## 100,200,300,400 @@ -72,7 +72,10 @@ proc raiseEInvalidCsv(filename: string, line, col: int, msg: string) {.noreturn.} = var e: ref CsvError new(e) - e.msg = filename & "(" & $line & ", " & $col & ") Error: " & msg + if filename.len == 0: + e.msg = "Error: " & msg + else: + e.msg = filename & "(" & $line & ", " & $col & ") Error: " & msg raise e proc error(my: CsvParser, pos: int, msg: string) = diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim index 2e8dbe140..a2ff9bf0c 100644 --- a/lib/pure/parseopt2.nim +++ b/lib/pure/parseopt2.nim @@ -35,7 +35,7 @@ type cmd: seq[string] pos: int remainingShortOptions: string - kind*: CmdLineKind ## the dected command line token + kind*: CmdLineKind ## the detected command line token key*, val*: TaintedString ## key and value pair; ``key`` is the option ## or the argument, ``value`` is not "" if ## the option was given a value diff --git a/lib/pure/parsesql.nim b/lib/pure/parsesql.nim index 00d007d01..ae192ab9a 100644 --- a/lib/pure/parsesql.nim +++ b/lib/pure/parsesql.nim @@ -55,6 +55,13 @@ const ";", ":", ",", "(", ")", "[", "]", "." ] + reservedKeywords = @[ + # statements + "select", "from", "where", "group", "limit", "having", + # functions + "count", + ] + proc open(L: var SqlLexer, input: Stream, filename: string) = lexbase.open(L, input) L.filename = filename @@ -274,16 +281,16 @@ proc getSymbol(c: var SqlLexer, tok: var Token) = c.bufpos = pos tok.kind = tkIdentifier -proc getQuotedIdentifier(c: var SqlLexer, tok: var Token) = +proc getQuotedIdentifier(c: var SqlLexer, tok: var Token, quote='\"') = var pos = c.bufpos + 1 var buf = c.buf tok.kind = tkQuotedIdentifier while true: var ch = buf[pos] - if ch == '\"': - if buf[pos+1] == '\"': + if ch == quote: + if buf[pos+1] == quote: inc(pos, 2) - add(tok.literal, '\"') + add(tok.literal, quote) else: inc(pos) break @@ -442,7 +449,8 @@ proc getTok(c: var SqlLexer, tok: var Token) = add(tok.literal, '.') of '0'..'9': getNumeric(c, tok) of '\'': getString(c, tok, tkStringConstant) - of '"': getQuotedIdentifier(c, tok) + of '"': getQuotedIdentifier(c, tok, '"') + of '`': getQuotedIdentifier(c, tok, '`') of lexbase.EndOfFile: tok.kind = tkEof tok.literal = "[EOF]" @@ -450,7 +458,7 @@ proc getTok(c: var SqlLexer, tok: var Token) = '\128'..'\255': getSymbol(c, tok) of '+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%', - '^', '&', '|', '`', '?': + '^', '&', '|', '?': getOperator(c, tok) else: add(tok.literal, c.buf[c.bufpos]) @@ -462,27 +470,27 @@ proc errorStr(L: SqlLexer, msg: string): string = # ----------------------------- parser ---------------------------------------- -# Operator/Element Associativity Description -# . left table/column name separator -# :: left PostgreSQL-style typecast -# [ ] left array element selection -# - right unary minus -# ^ left exponentiation -# * / % left multiplication, division, modulo -# + - left addition, subtraction -# IS IS TRUE, IS FALSE, IS UNKNOWN, IS NULL -# ISNULL test for null -# NOTNULL test for not null -# (any other) left all other native and user-defined oprs -# IN set membership -# BETWEEN range containment -# OVERLAPS time interval overlap -# LIKE ILIKE SIMILAR string pattern matching -# < > less than, greater than -# = right equality, assignment -# NOT right logical negation -# AND left logical conjunction -# OR left logical disjunction +# Operator/Element Associativity Description +# . left table/column name separator +# :: left PostgreSQL-style typecast +# [ ] left array element selection +# - right unary minus +# ^ left exponentiation +# * / % left multiplication, division, modulo +# + - left addition, subtraction +# IS IS TRUE, IS FALSE, IS UNKNOWN, IS NULL +# ISNULL test for null +# NOTNULL test for not null +# (any other) left all other native and user-defined oprs +# IN set membership +# BETWEEN range containment +# OVERLAPS time interval overlap +# LIKE ILIKE SIMILAR string pattern matching +# < > less than, greater than +# = right equality, assignment +# NOT right logical negation +# AND left logical conjunction +# OR left logical disjunction type SqlNodeKind* = enum ## kind of SQL abstract syntax tree @@ -504,6 +512,7 @@ type nkPrefix, nkInfix, nkCall, + nkPrGroup, nkColumnReference, nkReferences, nkDefault, @@ -518,11 +527,15 @@ type nkSelect, nkSelectDistinct, nkSelectColumns, + nkSelectPair, nkAsgn, nkFrom, + nkFromItemPair, nkGroup, + nkLimit, nkHaving, nkOrder, + nkJoin, nkDesc, nkUnion, nkIntersect, @@ -658,10 +671,12 @@ proc getPrecedence(p: SqlParser): int = elif isOpr(p, "=") or isOpr(p, "<") or isOpr(p, ">") or isOpr(p, ">=") or isOpr(p, "<=") or isOpr(p, "<>") or isOpr(p, "!=") or isKeyw(p, "is") or isKeyw(p, "like"): - result = 3 + result = 4 elif isKeyw(p, "and"): - result = 2 + result = 3 elif isKeyw(p, "or"): + result = 2 + elif isKeyw(p, "between"): result = 1 elif p.tok.kind == tkOperator: # user-defined operator: @@ -670,6 +685,7 @@ proc getPrecedence(p: SqlParser): int = result = - 1 proc parseExpr(p: var SqlParser): SqlNode +proc parseSelect(p: var SqlParser): SqlNode proc identOrLiteral(p: var SqlParser): SqlNode = case p.tok.kind @@ -693,7 +709,8 @@ proc identOrLiteral(p: var SqlParser): SqlNode = getTok(p) of tkParLe: getTok(p) - result = parseExpr(p) + result = newNode(nkPrGroup) + result.add(parseExpr(p)) eat(p, tkParRi) else: sqlError(p, "expression expected") @@ -745,7 +762,7 @@ proc lowestExprAux(p: var SqlParser, v: var SqlNode, limit: int): int = result = opPred while opPred > limit: node = newNode(nkInfix) - opNode = newNode(nkIdent, p.tok.literal) + opNode = newNode(nkIdent, p.tok.literal.toLower()) getTok(p) result = lowestExprAux(p, v2, opPred) node.add(opNode) @@ -921,6 +938,19 @@ proc parseWhere(p: var SqlParser): SqlNode = result = newNode(nkWhere) result.add(parseExpr(p)) +proc parseFromItem(p: var SqlParser): SqlNode = + result = newNode(nkFromItemPair) + if p.tok.kind == tkParLe: + getTok(p) + var select = parseSelect(p) + result.add(select) + eat(p, tkParRi) + else: + result.add(parseExpr(p)) + if isKeyw(p, "as"): + getTok(p) + result.add(parseExpr(p)) + proc parseIndexDef(p: var SqlParser): SqlNode = result = parseIfNotExists(p, nkCreateIndex) if isKeyw(p, "primary"): @@ -956,6 +986,7 @@ proc parseInsert(p: var SqlParser): SqlNode = if p.tok.kind == tkParLe: var n = newNode(nkColumnList) parseParIdentList(p, n) + result.add n else: result.add(nil) if isKeyw(p, "default"): @@ -996,6 +1027,8 @@ proc parseUpdate(p: var SqlParser): SqlNode = proc parseDelete(p: var SqlParser): SqlNode = getTok(p) + if isOpr(p, "*"): + getTok(p) result = newNode(nkDelete) eat(p, "from") result.add(primary(p)) @@ -1018,7 +1051,12 @@ proc parseSelect(p: var SqlParser): SqlNode = a.add(newNode(nkIdent, "*")) getTok(p) else: - a.add(parseExpr(p)) + var pair = newNode(nkSelectPair) + pair.add(parseExpr(p)) + a.add(pair) + if isKeyw(p, "as"): + getTok(p) + pair.add(parseExpr(p)) if p.tok.kind != tkComma: break getTok(p) result.add(a) @@ -1026,7 +1064,7 @@ proc parseSelect(p: var SqlParser): SqlNode = var f = newNode(nkFrom) while true: getTok(p) - f.add(parseExpr(p)) + f.add(parseFromItem(p)) if p.tok.kind != tkComma: break result.add(f) if isKeyw(p, "where"): @@ -1040,6 +1078,11 @@ proc parseSelect(p: var SqlParser): SqlNode = if p.tok.kind != tkComma: break getTok(p) result.add(g) + if isKeyw(p, "limit"): + getTok(p) + var l = newNode(nkLimit) + l.add(parseExpr(p)) + result.add(l) if isKeyw(p, "having"): var h = newNode(nkHaving) while true: @@ -1072,6 +1115,19 @@ proc parseSelect(p: var SqlParser): SqlNode = if p.tok.kind != tkComma: break getTok(p) result.add(n) + if isKeyw(p, "join") or isKeyw(p, "inner") or isKeyw(p, "outer") or isKeyw(p, "cross"): + var join = newNode(nkJoin) + result.add(join) + if isKeyw(p, "join"): + join.add(newNode(nkIdent, "")) + getTok(p) + else: + join.add(newNode(nkIdent, p.tok.literal.toLower())) + getTok(p) + eat(p, "join") + join.add(parseFromItem(p)) + eat(p, "on") + join.add(parseExpr(p)) proc parseStmt(p: var SqlParser; parent: SqlNode) = if isKeyw(p, "create"): @@ -1103,7 +1159,7 @@ proc parseStmt(p: var SqlParser; parent: SqlNode) = elif isKeyw(p, "begin"): getTok(p) else: - sqlError(p, "CREATE expected") + sqlError(p, "SELECT, CREATE, UPDATE or DELETE expected") proc open(p: var SqlParser, input: Stream, filename: string) = ## opens the parser `p` and assigns the input stream `input` to it. @@ -1115,13 +1171,13 @@ proc open(p: var SqlParser, input: Stream, filename: string) = proc parse(p: var SqlParser): SqlNode = ## parses the content of `p`'s input stream and returns the SQL AST. - ## Syntax errors raise an `EInvalidSql` exception. + ## Syntax errors raise an `SqlParseError` exception. result = newNode(nkStmtList) while p.tok.kind != tkEof: parseStmt(p, result) + if p.tok.kind == tkEof: + break eat(p, tkSemicolon) - if result.len == 1: - result = result.sons[0] proc close(p: var SqlParser) = ## closes the parser `p`. The associated input stream is closed too. @@ -1130,7 +1186,7 @@ proc close(p: var SqlParser) = proc parseSQL*(input: Stream, filename: string): SqlNode = ## parses the SQL from `input` into an AST and returns the AST. ## `filename` is only used for error messages. - ## Syntax errors raise an `EInvalidSql` exception. + ## Syntax errors raise an `SqlParseError` exception. var p: SqlParser open(p, input, filename) try: @@ -1138,29 +1194,74 @@ proc parseSQL*(input: Stream, filename: string): SqlNode = finally: close(p) -proc ra(n: SqlNode, s: var string, indent: int) +proc parseSQL*(input: string, filename=""): SqlNode = + ## parses the SQL from `input` into an AST and returns the AST. + ## `filename` is only used for error messages. + ## Syntax errors raise an `SqlParseError` exception. + parseSQL(newStringStream(input), "") + + +type + SqlWriter = object + indent: int + upperCase: bool + buffer: string + +proc add(s: var SqlWriter, thing: char) = + s.buffer.add(thing) + +proc add(s: var SqlWriter, thing: string) = + if s.buffer.len > 0 and s.buffer[^1] notin {' ', '\L', '(', '.'}: + s.buffer.add(" ") + s.buffer.add(thing) + +proc addKeyw(s: var SqlWriter, thing: string) = + var keyw = thing + if s.upperCase: + keyw = keyw.toUpper() + s.add(keyw) + +proc addIden(s: var SqlWriter, thing: string) = + var iden = thing + if iden.toLower() in reservedKeywords: + iden = '"' & iden & '"' + s.add(iden) + +proc ra(n: SqlNode, s: var SqlWriter) + +proc rs(n: SqlNode, s: var SqlWriter, prefix = "(", suffix = ")", sep = ", ") = + if n.len > 0: + s.add(prefix) + for i in 0 .. n.len-1: + if i > 0: s.add(sep) + ra(n.sons[i], s) + s.add(suffix) + +proc addMulti(s: var SqlWriter, n: SqlNode, sep = ',') = + if n.len > 0: + for i in 0 .. n.len-1: + if i > 0: s.add(sep) + ra(n.sons[i], s) -proc rs(n: SqlNode, s: var string, indent: int, - prefix = "(", suffix = ")", - sep = ", ") = +proc addMulti(s: var SqlWriter, n: SqlNode, sep = ',', prefix, suffix: char) = if n.len > 0: s.add(prefix) for i in 0 .. n.len-1: if i > 0: s.add(sep) - ra(n.sons[i], s, indent) + ra(n.sons[i], s) s.add(suffix) -proc ra(n: SqlNode, s: var string, indent: int) = +proc ra(n: SqlNode, s: var SqlWriter) = if n == nil: return case n.kind of nkNone: discard of nkIdent: - if allCharsInSet(n.strVal, {'\33'..'\127'}): + if allCharsInSet(n.strVal, {'\33'..'\127'}) and n.strVal.toLower() notin reservedKeywords: s.add(n.strVal) else: s.add("\"" & replace(n.strVal, "\"", "\"\"") & "\"") of nkStringLit: - s.add(escape(n.strVal, "e'", "'")) + s.add(escape(n.strVal, "'", "'")) of nkBitStringLit: s.add("b'" & n.strVal & "'") of nkHexStringLit: @@ -1168,217 +1269,206 @@ proc ra(n: SqlNode, s: var string, indent: int) = of nkIntegerLit, nkNumericLit: s.add(n.strVal) of nkPrimaryKey: - s.add(" primary key") - rs(n, s, indent) + s.addKeyw("primary key") + rs(n, s) of nkForeignKey: - s.add(" foreign key") - rs(n, s, indent) + s.addKeyw("foreign key") + rs(n, s) of nkNotNull: - s.add(" not null") + s.addKeyw("not null") of nkNull: - s.add(" null") + s.addKeyw("null") of nkDot: - ra(n.sons[0], s, indent) - s.add(".") - ra(n.sons[1], s, indent) + ra(n.sons[0], s) + s.add('.') + ra(n.sons[1], s) of nkDotDot: - ra(n.sons[0], s, indent) + ra(n.sons[0], s) s.add(". .") - ra(n.sons[1], s, indent) + ra(n.sons[1], s) of nkPrefix: - s.add('(') - ra(n.sons[0], s, indent) + ra(n.sons[0], s) s.add(' ') - ra(n.sons[1], s, indent) - s.add(')') + ra(n.sons[1], s) of nkInfix: - s.add('(') - ra(n.sons[1], s, indent) + ra(n.sons[1], s) s.add(' ') - ra(n.sons[0], s, indent) + ra(n.sons[0], s) s.add(' ') - ra(n.sons[2], s, indent) - s.add(')') + ra(n.sons[2], s) of nkCall, nkColumnReference: - ra(n.sons[0], s, indent) + ra(n.sons[0], s) s.add('(') for i in 1..n.len-1: - if i > 1: s.add(", ") - ra(n.sons[i], s, indent) + if i > 1: s.add(',') + ra(n.sons[i], s) + s.add(')') + of nkPrGroup: + s.add('(') + s.addMulti(n) s.add(')') of nkReferences: - s.add(" references ") - ra(n.sons[0], s, indent) + s.addKeyw("references") + ra(n.sons[0], s) of nkDefault: - s.add(" default ") - ra(n.sons[0], s, indent) + s.addKeyw("default") + ra(n.sons[0], s) of nkCheck: - s.add(" check ") - ra(n.sons[0], s, indent) + s.addKeyw("check") + ra(n.sons[0], s) of nkConstraint: - s.add(" constraint ") - ra(n.sons[0], s, indent) - s.add(" check ") - ra(n.sons[1], s, indent) + s.addKeyw("constraint") + ra(n.sons[0], s) + s.addKeyw("check") + ra(n.sons[1], s) of nkUnique: - s.add(" unique") - rs(n, s, indent) + s.addKeyw("unique") + rs(n, s) of nkIdentity: - s.add(" identity") + s.addKeyw("identity") of nkColumnDef: - s.add("\n ") - rs(n, s, indent, "", "", " ") + rs(n, s, "", "", " ") of nkStmtList: for i in 0..n.len-1: - ra(n.sons[i], s, indent) - s.add("\n") + ra(n.sons[i], s) + s.add(';') of nkInsert: assert n.len == 3 - s.add("insert into ") - ra(n.sons[0], s, indent) - ra(n.sons[1], s, indent) + s.addKeyw("insert into") + ra(n.sons[0], s) + s.add(' ') + ra(n.sons[1], s) if n.sons[2].kind == nkDefault: - s.add("default values") + s.addKeyw("default values") else: - s.add("\nvalues ") - ra(n.sons[2], s, indent) - s.add(';') + ra(n.sons[2], s) of nkUpdate: - s.add("update ") - ra(n.sons[0], s, indent) - s.add(" set ") + s.addKeyw("update") + ra(n.sons[0], s) + s.addKeyw("set") var L = n.len for i in 1 .. L-2: if i > 1: s.add(", ") var it = n.sons[i] assert it.kind == nkAsgn - ra(it, s, indent) - ra(n.sons[L-1], s, indent) - s.add(';') + ra(it, s) + ra(n.sons[L-1], s) of nkDelete: - s.add("delete from ") - ra(n.sons[0], s, indent) - ra(n.sons[1], s, indent) - s.add(';') + s.addKeyw("delete from") + ra(n.sons[0], s) + ra(n.sons[1], s) of nkSelect, nkSelectDistinct: - s.add("select ") + s.addKeyw("select") if n.kind == nkSelectDistinct: - s.add("distinct ") - rs(n.sons[0], s, indent, "", "", ", ") - for i in 1 .. n.len-1: ra(n.sons[i], s, indent) - s.add(';') + s.addKeyw("distinct") + s.addMulti(n.sons[0]) + for i in 1 .. n.len-1: + ra(n.sons[i], s) of nkSelectColumns: assert(false) + of nkSelectPair: + ra(n.sons[0], s) + if n.sons.len == 2: + s.addKeyw("as") + ra(n.sons[1], s) + of nkFromItemPair: + if n.sons[0].kind == nkIdent: + ra(n.sons[0], s) + else: + assert n.sons[0].kind == nkSelect + s.add('(') + ra(n.sons[0], s) + s.add(')') + if n.sons.len == 2: + s.addKeyw("as") + ra(n.sons[1], s) of nkAsgn: - ra(n.sons[0], s, indent) + ra(n.sons[0], s) s.add(" = ") - ra(n.sons[1], s, indent) + ra(n.sons[1], s) of nkFrom: - s.add("\nfrom ") - rs(n, s, indent, "", "", ", ") + s.addKeyw("from") + s.addMulti(n) of nkGroup: - s.add("\ngroup by") - rs(n, s, indent, "", "", ", ") + s.addKeyw("group by") + s.addMulti(n) + of nkLimit: + s.addKeyw("limit") + s.addMulti(n) of nkHaving: - s.add("\nhaving") - rs(n, s, indent, "", "", ", ") + s.addKeyw("having") + s.addMulti(n) of nkOrder: - s.add("\norder by ") - rs(n, s, indent, "", "", ", ") + s.addKeyw("order by") + s.addMulti(n) + of nkJoin: + var joinType = n.sons[0].strVal + if joinType == "": + joinType = "join" + else: + joinType &= " " & "join" + s.addKeyw(joinType) + ra(n.sons[1], s) + s.addKeyw("on") + ra(n.sons[2], s) of nkDesc: - ra(n.sons[0], s, indent) - s.add(" desc") + ra(n.sons[0], s) + s.addKeyw("desc") of nkUnion: - s.add(" union") + s.addKeyw("union") of nkIntersect: - s.add(" intersect") + s.addKeyw("intersect") of nkExcept: - s.add(" except") + s.addKeyw("except") of nkColumnList: - rs(n, s, indent) + rs(n, s) of nkValueList: - s.add("values ") - rs(n, s, indent) + s.addKeyw("values") + rs(n, s) of nkWhere: - s.add("\nwhere ") - ra(n.sons[0], s, indent) + s.addKeyw("where") + ra(n.sons[0], s) of nkCreateTable, nkCreateTableIfNotExists: - s.add("create table ") + s.addKeyw("create table") if n.kind == nkCreateTableIfNotExists: - s.add("if not exists ") - ra(n.sons[0], s, indent) + s.addKeyw("if not exists") + ra(n.sons[0], s) s.add('(') for i in 1..n.len-1: - if i > 1: s.add(", ") - ra(n.sons[i], s, indent) + if i > 1: s.add(',') + ra(n.sons[i], s) s.add(");") of nkCreateType, nkCreateTypeIfNotExists: - s.add("create type ") + s.addKeyw("create type") if n.kind == nkCreateTypeIfNotExists: - s.add("if not exists ") - ra(n.sons[0], s, indent) - s.add(" as ") - ra(n.sons[1], s, indent) - s.add(';') + s.addKeyw("if not exists") + ra(n.sons[0], s) + s.addKeyw("as") + ra(n.sons[1], s) of nkCreateIndex, nkCreateIndexIfNotExists: - s.add("create index ") + s.addKeyw("create index") if n.kind == nkCreateIndexIfNotExists: - s.add("if not exists ") - ra(n.sons[0], s, indent) - s.add(" on ") - ra(n.sons[1], s, indent) + s.addKeyw("if not exists") + ra(n.sons[0], s) + s.addKeyw("on") + ra(n.sons[1], s) s.add('(') for i in 2..n.len-1: if i > 2: s.add(", ") - ra(n.sons[i], s, indent) + ra(n.sons[i], s) s.add(");") of nkEnumDef: - s.add("enum ") - rs(n, s, indent) + s.addKeyw("enum") + rs(n, s) -# What I want: -# -#select(columns = [T1.all, T2.name], -# fromm = [T1, T2], -# where = T1.name ==. T2.name, -# orderby = [name]): -# -#for row in dbQuery(db, """select x, y, z -# from a, b -# where a.name = b.name"""): -# - -#select x, y, z: -# fromm: Table1, Table2 -# where: x.name == y.name -#db.select(fromm = [t1, t2], where = t1.name == t2.name): -#for x, y, z in db.select(fromm = a, b where = a.name == b.name): -# writeLine x, y, z - -proc renderSQL*(n: SqlNode): string = +proc renderSQL*(n: SqlNode, upperCase=false): string = ## Converts an SQL abstract syntax tree to its string representation. - result = "" - ra(n, result, 0) + var s: SqlWriter + s.buffer = "" + s.upperCase = upperCase + ra(n, s) + return s.buffer proc `$`*(n: SqlNode): string = ## an alias for `renderSQL`. renderSQL(n) - -when not defined(testing) and isMainModule: - echo(renderSQL(parseSQL(newStringStream(""" - CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic'); - CREATE TABLE holidays ( - num_weeks int, - happiness happiness - ); - CREATE INDEX table1_attr1 ON table1(attr1); - - SELECT * FROM myTab WHERE col1 = 'happy'; - """), "stdin"))) - -# CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic'); -# CREATE TABLE holidays ( -# num_weeks int, -# happiness happiness -# ); -# CREATE INDEX table1_attr1 ON table1(attr1) diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index b78e8d000..57387e62e 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -8,6 +8,8 @@ # ## This module contains helpers for parsing tokens, numbers, identifiers, etc. +## +## To unpack raw bytes look at the `streams <streams.html>`_ module. {.deadCodeElim: on.} @@ -85,6 +87,23 @@ proc parseOct*(s: string, number: var int, start = 0): int {. inc(i) if foundDigit: result = i-start +proc parseBin*(s: string, number: var int, start = 0): int {. + rtl, extern: "npuParseBin", noSideEffect.} = + ## parses an binary number and stores its value in ``number``. Returns + ## the number of the parsed characters or 0 in case of an error. + var i = start + var foundDigit = false + if s[i] == '0' and (s[i+1] == 'b' or s[i+1] == 'B'): inc(i, 2) + while true: + case s[i] + of '_': discard + of '0'..'1': + number = number shl 1 or (ord(s[i]) - ord('0')) + foundDigit = true + else: break + inc(i) + if foundDigit: result = i-start + proc parseIdent*(s: string, ident: var string, start = 0): int = ## parses an identifier and stores it in ``ident``. Returns ## the number of the parsed characters or 0 in case of an error. @@ -250,6 +269,31 @@ proc parseInt*(s: string, number: var int, start = 0): int {. elif result != 0: number = int(res) +proc parseSaturatedNatural*(s: string, b: var int, start = 0): int = + ## parses a natural number into ``b``. This cannot raise an overflow + ## error. Instead of an ``Overflow`` exception ``high(int)`` is returned. + ## The number of processed character is returned. + ## This is usually what you really want to use instead of `parseInt`:idx:. + ## Example: + ## + ## .. code-block:: nim + ## var res = 0 + ## discard parseSaturatedNatural("848", res) + ## doAssert res == 848 + var i = start + if s[i] == '+': inc(i) + if s[i] in {'0'..'9'}: + b = 0 + while s[i] in {'0'..'9'}: + let c = ord(s[i]) - ord('0') + if b <= (high(int) - c) div 10: + b = b * 10 + c + else: + b = high(int) + inc(i) + while s[i] == '_': inc(i) # underscores are allowed and ignored + result = i - start + # overflowChecks doesn't work with BiggestUInt proc rawParseUInt(s: string, b: var BiggestUInt, start = 0): int = var @@ -391,16 +435,43 @@ when isMainModule: let input = "$test{} $this is ${an{ example}} " let expected = @[(ikVar, "test"), (ikStr, "{} "), (ikVar, "this"), (ikStr, " is "), (ikExpr, "an{ example}"), (ikStr, " ")] - assert toSeq(interpolatedFragments(input)) == expected + doAssert toSeq(interpolatedFragments(input)) == expected var value = 0 discard parseHex("0x38", value) - assert value == 56 + doAssert value == 56 discard parseHex("0x34", value) - assert value == 56 * 256 + 52 + doAssert value == 56 * 256 + 52 value = -1 discard parseHex("0x38", value) - assert value == -200 + doAssert value == -200 + + value = -1 + doAssert(parseSaturatedNatural("848", value) == 3) + doAssert value == 848 + + value = -1 + discard parseSaturatedNatural("84899999999999999999324234243143142342135435342532453", value) + doAssert value == high(int) + value = -1 + discard parseSaturatedNatural("9223372036854775808", value) + doAssert value == high(int) + + value = -1 + discard parseSaturatedNatural("9223372036854775807", value) + doAssert value == high(int) + + value = -1 + discard parseSaturatedNatural("18446744073709551616", value) + doAssert value == high(int) + + value = -1 + discard parseSaturatedNatural("18446744073709551615", value) + doAssert value == high(int) + + value = -1 + doAssert(parseSaturatedNatural("1_000_000", value) == 9) + doAssert value == 1_000_000 {.pop.} diff --git a/lib/pure/poly.nim b/lib/pure/poly.nim deleted file mode 100644 index e286c5d17..000000000 --- a/lib/pure/poly.nim +++ /dev/null @@ -1,371 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2013 Robert Persson -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## **Warning:** This module will be moved out of the stdlib and into a -## Nimble package, don't use it. - -import math -import strutils -import numeric - -type - Poly* = object - cofs:seq[float] - -{.deprecated: [TPoly: Poly].} - -proc degree*(p:Poly):int= - ## Returns the degree of the polynomial, - ## that is the number of coefficients-1 - return p.cofs.len-1 - - -proc eval*(p:Poly,x:float):float= - ## Evaluates a polynomial function value for `x` - ## quickly using Horners method - var n=p.degree - result=p.cofs[n] - dec n - while n>=0: - result = result*x+p.cofs[n] - dec n - -proc `[]` *(p:Poly;idx:int):float= - ## Gets a coefficient of the polynomial. - ## p[2] will returns the quadric term, p[3] the cubic etc. - ## Out of bounds index will return 0.0. - if idx<0 or idx>p.degree: - return 0.0 - return p.cofs[idx] - -proc `[]=` *(p:var Poly;idx:int,v:float)= - ## Sets an coefficient of the polynomial by index. - ## p[2] set the quadric term, p[3] the cubic etc. - ## If index is out of range for the coefficients, - ## the polynomial grows to the smallest needed degree. - assert(idx>=0) - - if idx>p.degree: #polynomial must grow - var oldlen=p.cofs.len - p.cofs.setLen(idx+1) - for q in oldlen.. <high(p.cofs): - p.cofs[q]=0.0 #new-grown coefficients set to zero - - p.cofs[idx]=v - - -iterator items*(p:Poly):float= - ## Iterates through the coefficients of the polynomial. - var i=p.degree - while i>=0: - yield p[i] - dec i - -proc clean*(p:var Poly;zerotol=0.0)= - ## Removes leading zero coefficients of the polynomial. - ## An optional tolerance can be given for what's considered zero. - var n=p.degree - var relen=false - - while n>0 and abs(p[n])<=zerotol: # >0 => keep at least one coefficient - dec n - relen=true - - if relen: p.cofs.setLen(n+1) - - -proc `$` *(p:Poly):string = - ## Gets a somewhat reasonable string representation of the polynomial - ## The format should be compatible with most online function plotters, - ## for example directly in google search - result="" - var first=true #might skip + sign if first coefficient - - for idx in countdown(p.degree,0): - let a=p[idx] - - if a==0.0: - continue - - if a>= 0.0 and not first: - result.add('+') - first=false - - if a!=1.0 or idx==0: - result.add(formatFloat(a,ffDefault,0)) - if idx>=2: - result.add("x^" & $idx) - elif idx==1: - result.add("x") - - if result=="": - result="0" - - -proc derivative*(p: Poly): Poly= - ## Returns a new polynomial, which is the derivative of `p` - newSeq[float](result.cofs,p.degree) - for idx in 0..high(result.cofs): - result.cofs[idx]=p.cofs[idx+1]*float(idx+1) - -proc diff*(p:Poly,x:float):float= - ## Evaluates the differentiation of a polynomial with - ## respect to `x` quickly using a modifed Horners method - var n=p.degree - result=p[n]*float(n) - dec n - while n>=1: - result = result*x+p[n]*float(n) - dec n - -proc integral*(p:Poly):Poly= - ## Returns a new polynomial which is the indefinite - ## integral of `p`. The constant term is set to 0.0 - newSeq(result.cofs,p.cofs.len+1) - result.cofs[0]=0.0 #constant arbitrary term, use 0.0 - for i in 1..high(result.cofs): - result.cofs[i]=p.cofs[i-1]/float(i) - - -proc integrate*(p:Poly;xmin,xmax:float):float= - ## Computes the definite integral of `p` between `xmin` and `xmax` - ## quickly using a modified version of Horners method - var - n=p.degree - s1=p[n]/float(n+1) - s2=s1 - fac:float - - dec n - while n>=0: - fac=p[n]/float(n+1) - s1 = s1*xmin+fac - s2 = s2*xmax+fac - dec n - - result=s2*xmax-s1*xmin - -proc initPoly*(cofs:varargs[float]):Poly= - ## Initializes a polynomial with given coefficients. - ## The most significant coefficient is first, so to create x^2-2x+3: - ## intiPoly(1.0,-2.0,3.0) - if len(cofs)<=0: - result.cofs= @[0.0] #need at least one coefficient - else: - # reverse order of coefficients so indexing matches degree of - # coefficient... - result.cofs= @[] - for idx in countdown(cofs.len-1,0): - result.cofs.add(cofs[idx]) - - result.clean #remove leading zero terms - - -proc divMod*(p,d:Poly;q,r:var Poly)= - ## Divides `p` with `d`, and stores the quotinent in `q` and - ## the remainder in `d` - var - pdeg=p.degree - ddeg=d.degree - power=p.degree-d.degree - ratio:float - - r.cofs = p.cofs #initial remainder=numerator - if power<0: #denominator is larger than numerator - q.cofs= @ [0.0] #quotinent is 0.0 - return # keep remainder as numerator - - q.cofs=newSeq[float](power+1) - - for i in countdown(pdeg,ddeg): - ratio=r.cofs[i]/d.cofs[ddeg] - - q.cofs[i-ddeg]=ratio - r.cofs[i]=0.0 - - for j in countup(0,<ddeg): - var idx=i-ddeg+j - r.cofs[idx] = r.cofs[idx] - d.cofs[j]*ratio - - r.clean # drop zero coefficients in remainder - -proc `+` *(p1:Poly,p2:Poly):Poly= - ## Adds two polynomials - var n=max(p1.cofs.len,p2.cofs.len) - newSeq(result.cofs,n) - - for idx in countup(0,n-1): - result[idx]=p1[idx]+p2[idx] - - result.clean # drop zero coefficients in remainder - -proc `*` *(p1:Poly,p2:Poly):Poly= - ## Multiplies the polynomial `p1` with `p2` - var - d1=p1.degree - d2=p2.degree - n=d1+d2 - idx:int - - newSeq(result.cofs,n) - - for i1 in countup(0,d1): - for i2 in countup(0,d2): - idx=i1+i2 - result[idx]=result[idx]+p1[i1]*p2[i2] - - result.clean - -proc `*` *(p:Poly,f:float):Poly= - ## Multiplies the polynomial `p` with a real number - newSeq(result.cofs,p.cofs.len) - for i in 0..high(p.cofs): - result[i]=p.cofs[i]*f - result.clean - -proc `*` *(f:float,p:Poly):Poly= - ## Multiplies a real number with a polynomial - return p*f - -proc `-`*(p:Poly):Poly= - ## Negates a polynomial - result=p - for i in countup(0,<result.cofs.len): - result.cofs[i]= -result.cofs[i] - -proc `-` *(p1:Poly,p2:Poly):Poly= - ## Subtract `p1` with `p2` - var n=max(p1.cofs.len,p2.cofs.len) - newSeq(result.cofs,n) - - for idx in countup(0,n-1): - result[idx]=p1[idx]-p2[idx] - - result.clean # drop zero coefficients in remainder - -proc `/`*(p:Poly,f:float):Poly= - ## Divides polynomial `p` with a real number `f` - newSeq(result.cofs,p.cofs.len) - for i in 0..high(p.cofs): - result[i]=p.cofs[i]/f - result.clean - -proc `/` *(p,q:Poly):Poly= - ## Divides polynomial `p` with polynomial `q` - var dummy:Poly - p.divMod(q,result,dummy) - -proc `mod` *(p,q:Poly):Poly= - ## Computes the polynomial modulo operation, - ## that is the remainder of `p`/`q` - var dummy:Poly - p.divMod(q,dummy,result) - - -proc normalize*(p:var Poly)= - ## Multiplies the polynomial inplace by a term so that - ## the leading term is 1.0. - ## This might lead to an unstable polynomial - ## if the leading term is zero. - p=p/p[p.degree] - - -proc solveQuadric*(a,b,c:float;zerotol=0.0):seq[float]= - ## Solves the quadric equation `ax^2+bx+c`, with a possible - ## tolerance `zerotol` to find roots of curves just 'touching' - ## the x axis. Returns sequence with 0,1 or 2 solutions. - - var p,q,d:float - - p=b/(2.0*a) - - if p==Inf or p==NegInf: #linear equation.. - var linrt= -c/b - if linrt==Inf or linrt==NegInf: #constant only - return @[] - return @[linrt] - - q=c/a - d=p*p-q - - if d<0.0: - #check for inside zerotol range for neg. roots - var err=a*p*p-b*p+c #evaluate error at parabola center axis - if(err<=zerotol): return @[-p] - return @[] - else: - var sr=sqrt(d) - result= @[-sr-p,sr-p] - -proc getRangeForRoots(p:Poly):tuple[xmin,xmax:float]= - ## helper function for `roots` function - ## quickly computes a range, guaranteed to contain - ## all the real roots of the polynomial - # see http://www.mathsisfun.com/algebra/polynomials-bounds-zeros.html - - var deg=p.degree - var d=p[deg] - var bound1,bound2:float - - for i in countup(0,deg): - var c=abs(p.cofs[i]/d) - bound1=max(bound1,c+1.0) - bound2=bound2+c - - bound2=max(1.0,bound2) - result.xmax=min(bound1,bound2) - result.xmin= -result.xmax - - -proc addRoot(p:Poly,res:var seq[float],xp0,xp1,tol,zerotol,mergetol:float,maxiter:int)= - ## helper function for `roots` function - ## try to do a numeric search for a single root in range xp0-xp1, - ## adding it to `res` (allocating `res` if nil) - var br=brent(xp0,xp1, proc(x:float):float=p.eval(x),tol) - if br.success: - if res.len==0 or br.rootx>=res[high(res)]+mergetol: #dont add equal roots. - res.add(br.rootx) - else: - #this might be a 'touching' case, check function value against - #zero tolerance - if abs(br.rooty)<=zerotol: - if res.len==0 or br.rootx>=res[high(res)]+mergetol: #dont add equal roots. - res.add(br.rootx) - - -proc roots*(p:Poly,tol=1.0e-9,zerotol=1.0e-6,mergetol=1.0e-12,maxiter=1000):seq[float]= - ## Computes the real roots of the polynomial `p` - ## `tol` is the tolerance used to break searching for each root when reached. - ## `zerotol` is the tolerance, which is 'close enough' to zero to be considered a root - ## and is used to find roots for curves that only 'touch' the x-axis. - ## `mergetol` is the tolerance, of which two x-values are considered being the same root. - ## `maxiter` can be used to limit the number of iterations for each root. - ## Returns a (possibly empty) sorted sequence with the solutions. - var deg=p.degree - if deg<=0: #constant only => no roots - return @[] - elif p.degree==1: #linear - var linrt= -p.cofs[0]/p.cofs[1] - if linrt==Inf or linrt==NegInf: - return @[] #constant only => no roots - return @[linrt] - elif p.degree==2: - return solveQuadric(p.cofs[2],p.cofs[1],p.cofs[0],zerotol) - else: - # degree >=3 , find min/max points of polynomial with recursive - # derivative and do a numerical search for root between each min/max - var range=p.getRangeForRoots() - var minmax=p.derivative.roots(tol,zerotol,mergetol) - result= @[] - if minmax!=nil: #ie. we have minimas/maximas in this function - for x in minmax.items: - addRoot(p,result,range.xmin,x,tol,zerotol,mergetol,maxiter) - range.xmin=x - addRoot(p,result,range.xmin,range.xmax,tol,zerotol,mergetol,maxiter) - diff --git a/lib/pure/random.nim b/lib/pure/random.nim index 27fbfad45..de419b9fb 100644 --- a/lib/pure/random.nim +++ b/lib/pure/random.nim @@ -7,16 +7,16 @@ # distribution, for details about the copyright. # -## Nim's standard random number generator. Based on the ``xoroshiro128+`` (xor/rotate/shift/rotate) library. +## Nim's standard random number generator. Based on +## the ``xoroshiro128+`` (xor/rotate/shift/rotate) library. ## * More information: http://xoroshiro.di.unimi.it/ ## * C implementation: http://xoroshiro.di.unimi.it/xoroshiro128plus.c ## -## Do not use this module for cryptographic use! +## **Do not use this module for cryptographic purposes!** include "system/inclrtl" {.push debugger:off.} -# XXX Expose RandomGenState when defined(JS): type ui = uint32 @@ -27,31 +27,34 @@ else: const randMax = 18_446_744_073_709_551_615u64 type - RandomGenState = object + Rand* = object ## State of the random number generator. + ## The procs that use the default state + ## are **not** thread-safe! a0, a1: ui when defined(JS): - var state = RandomGenState( + var state = Rand( a0: 0x69B4C98Cu32, a1: 0xFED1DD30u32) # global for backwards compatibility else: # racy for multi-threading but good enough for now: - var state = RandomGenState( + var state = Rand( a0: 0x69B4C98CB8530805u64, a1: 0xFED1DD3004688D67CAu64) # global for backwards compatibility proc rotl(x, k: ui): ui = result = (x shl k) or (x shr (ui(64) - k)) -proc next(s: var RandomGenState): uint64 = - let s0 = s.a0 - var s1 = s.a1 +proc next*(r: var Rand): uint64 = + ## Uses the state to compute a new ``uint64`` random number. + let s0 = r.a0 + var s1 = r.a1 result = s0 + s1 s1 = s1 xor s0 - s.a0 = rotl(s0, 55) xor s1 xor (s1 shl 14) # a, b - s.a1 = rotl(s1, 36) # c + r.a0 = rotl(s0, 55) xor s1 xor (s1 shl 14) # a, b + r.a1 = rotl(s1, 36) # c -proc skipRandomNumbers(s: var RandomGenState) = +proc skipRandomNumbers*(s: var Rand) = ## This is the jump function for the generator. It is equivalent ## to 2^64 calls to next(); it can be used to generate 2^64 ## non-overlapping subsequences for parallel computations. @@ -71,21 +74,23 @@ proc skipRandomNumbers(s: var RandomGenState) = s.a0 = s0 s.a1 = s1 -proc random*(max: int): int {.benign.} = +proc random*(max: int): int {.benign, deprecated.} = ## Returns a random number in the range 0..max-1. The sequence of ## random number is always the same, unless `randomize` is called ## which initializes the random number generator with a "random" - ## number, i.e. a tickcount. + ## number, i.e. a tickcount. **Deprecated since version 0.18.0**. + ## Use ``rand`` instead. while true: let x = next(state) if x < randMax - (randMax mod ui(max)): return int(x mod uint64(max)) -proc random*(max: float): float {.benign.} = +proc random*(max: float): float {.benign, deprecated.} = ## Returns a random number in the range 0..<max. The sequence of ## random number is always the same, unless `randomize` is called ## which initializes the random number generator with a "random" - ## number, i.e. a tickcount. + ## number, i.e. a tickcount. **Deprecated since version 0.18.0**. + ## Use ``rand`` instead. let x = next(state) when defined(JS): result = (float(x) / float(high(uint32))) * max @@ -93,38 +98,100 @@ proc random*(max: float): float {.benign.} = let u = (0x3FFu64 shl 52u64) or (x shr 12u64) result = (cast[float](u) - 1.0) * max -proc random*[T](x: Slice[T]): T = +proc random*[T](x: HSlice[T, T]): T {.deprecated.} = ## For a slice `a .. b` returns a value in the range `a .. b-1`. + ## **Deprecated since version 0.18.0**. + ## Use ``rand`` instead. result = T(random(x.b - x.a)) + x.a -proc random*[T](a: openArray[T]): T = +proc random*[T](a: openArray[T]): T {.deprecated.} = ## returns a random element from the openarray `a`. + ## **Deprecated since version 0.18.0**. + ## Use ``rand`` instead. result = a[random(a.low..a.len)] +proc rand*(r: var Rand; max: int): int {.benign.} = + ## Returns a random number in the range 0..max. The sequence of + ## random number is always the same, unless `randomize` is called + ## which initializes the random number generator with a "random" + ## number, i.e. a tickcount. + while true: + let x = next(r) + if x <= randMax - (randMax mod ui(max)): + return int(x mod (uint64(max)+1u64)) + +proc rand*(max: int): int {.benign.} = + ## Returns a random number in the range 0..max. The sequence of + ## random number is always the same, unless `randomize` is called + ## which initializes the random number generator with a "random" + ## number, i.e. a tickcount. + rand(state, max) + +proc rand*(r: var Rand; max: float): float {.benign.} = + ## Returns a random number in the range 0..max. The sequence of + ## random number is always the same, unless `randomize` is called + ## which initializes the random number generator with a "random" + ## number, i.e. a tickcount. + let x = next(r) + when defined(JS): + result = (float(x) / float(high(uint32))) * max + else: + let u = (0x3FFu64 shl 52u64) or (x shr 12u64) + result = (cast[float](u) - 1.0) * max + +proc rand*(max: float): float {.benign.} = + ## Returns a random number in the range 0..max. The sequence of + ## random number is always the same, unless `randomize` is called + ## which initializes the random number generator with a "random" + ## number, i.e. a tickcount. + rand(state, max) + +proc rand*[T](r: var Rand; x: HSlice[T, T]): T = + ## For a slice `a .. b` returns a value in the range `a .. b`. + result = T(rand(r, x.b - x.a)) + x.a + +proc rand*[T](x: HSlice[T, T]): T = + ## For a slice `a .. b` returns a value in the range `a .. b`. + result = rand(state, x) + +proc rand*[T](r: var Rand; a: openArray[T]): T = + ## returns a random element from the openarray `a`. + result = a[rand(r, a.low..a.high)] + +proc rand*[T](a: openArray[T]): T = + ## returns a random element from the openarray `a`. + result = a[rand(a.low..a.high)] + + +proc initRand*(seed: int64): Rand = + ## Creates a new ``Rand`` state from ``seed``. + result.a0 = ui(seed shr 16) + result.a1 = ui(seed and 0xffff) + discard next(result) + proc randomize*(seed: int64) {.benign.} = - ## Initializes the random number generator with a specific seed. - state.a0 = ui(seed shr 16) - state.a1 = ui(seed and 0xffff) - discard next(state) + ## Initializes the default random number generator + ## with a specific seed. + state = initRand(seed) -proc shuffle*[T](x: var openArray[T]) = - ## Will randomly swap the positions of elements in a sequence. +proc shuffle*[T](r: var Rand; x: var openArray[T]) = + ## Swaps the positions of elements in a sequence randomly. for i in countdown(x.high, 1): - let j = random(i + 1) + let j = r.rand(i) swap(x[i], x[j]) +proc shuffle*[T](x: var openArray[T]) = + ## Swaps the positions of elements in a sequence randomly. + shuffle(state, x) + when not defined(nimscript): import times proc randomize*() {.benign.} = ## Initializes the random number generator with a "random" ## number, i.e. a tickcount. Note: Does not work for NimScript. - when defined(JS): - proc getMil(t: Time): int {.importcpp: "getTime", nodecl.} - randomize(getMil times.getTime()) - else: - let time = int64(times.epochTime() * 1_000_000_000) - randomize(time) + let time = int64(times.epochTime() * 1_000_000_000) + randomize(time) {.pop.} @@ -134,12 +201,12 @@ when isMainModule: var x = 8234 for i in 0..100_000: - x = random(len(occur)) # myrand(x) + x = rand(high(occur)) inc occur[x] for i, oc in occur: if oc < 69: doAssert false, "too few occurrences of " & $i - elif oc > 130: + elif oc > 150: doAssert false, "too many occurrences of " & $i var a = [0, 1] diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim index c2ba2b1f3..7907b4e6c 100644 --- a/lib/pure/rationals.nim +++ b/lib/pure/rationals.nim @@ -39,47 +39,13 @@ proc toRational*[T:SomeInteger](x: T): Rational[T] = result.num = x result.den = 1 -proc toRationalSub(x: float, n: int): Rational[int] = - var - a = 0'i64 - b, c, d = 1'i64 - result = 0 // 1 # rational 0 - while b <= n and d <= n: - let ac = (a+c) - let bd = (b+d) - # scale by 1000 so not overflow for high precision - let mediant = (ac.float/1000) / (bd.float/1000) - if x == mediant: - if bd <= n: - result.num = ac.int - result.den = bd.int - return result - elif d > b: - result.num = c.int - result.den = d.int - return result - else: - result.num = a.int - result.den = b.int - return result - elif x > mediant: - a = ac - b = bd - else: - c = ac - d = bd - if (b > n): - return initRational(c.int, d.int) - return initRational(a.int, b.int) - -proc toRational*(x: float, n: int = high(int)): Rational[int] = - ## Calculate the best rational numerator and denominator +proc toRational*(x: float, n: int = high(int) shr (sizeof(int) div 2 * 8)): Rational[int] = + ## Calculates the best rational numerator and denominator ## that approximates to `x`, where the denominator is ## smaller than `n` (default is the largest possible - ## int to give maximum resolution) + ## int to give maximum resolution). ## - ## The algorithm is based on the Farey sequence named - ## after John Farey + ## The algorithm is based on the theory of continued fractions. ## ## .. code-block:: Nim ## import math, rationals @@ -88,13 +54,24 @@ proc toRational*(x: float, n: int = high(int)): Rational[int] = ## let x = toRational(PI, t) ## let newPI = x.num / x.den ## echo x, " ", newPI, " error: ", PI - newPI, " ", t - if x > 1: - result = toRationalSub(1.0/x, n) - swap(result.num, result.den) - elif x == 1.0: - result = 1 // 1 - else: - result = toRationalSub(x, n) + + # David Eppstein / UC Irvine / 8 Aug 1993 + # With corrections from Arno Formella, May 2008 + var + m11, m22 = 1 + m12, m21 = 0 + ai = int(x) + x = x + while m21 * ai + m22 <= n: + swap m12, m11 + swap m22, m21 + m11 = m12 * ai + m11 + m21 = m22 * ai + m21 + if x == float(ai): break # division by zero + x = 1/(x - float(ai)) + if x > float(high(int32)): break # representation failure + ai = int(x) + result = m11 // m21 proc toFloat*[T](x: Rational[T]): float = ## Convert a rational number `x` to a float. @@ -346,7 +323,19 @@ when isMainModule: assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7 assert toInt(z) == 0 - assert toRational(0.98765432) == 12345679 // 12500000 - assert toRational(0.1, 1000000) == 1 // 10 - assert toRational(0.9, 1000000) == 9 // 10 - #assert toRational(PI) == 80143857 // 25510582 + when sizeof(int) == 8: + assert toRational(0.98765432) == 2111111029 // 2137499919 + assert toRational(PI) == 817696623 // 260280919 + when sizeof(int) == 4: + assert toRational(0.98765432) == 80 // 81 + assert toRational(PI) == 355 // 113 + + assert toRational(0.1) == 1 // 10 + assert toRational(0.9) == 9 // 10 + + assert toRational(0.0) == 0 // 1 + assert toRational(-0.25) == 1 // -4 + assert toRational(3.2) == 16 // 5 + assert toRational(0.33) == 33 // 100 + assert toRational(0.22) == 11 // 50 + assert toRational(10.0) == 10 // 1 diff --git a/lib/pure/romans.nim b/lib/pure/romans.nim deleted file mode 100644 index aa047d1cc..000000000 --- a/lib/pure/romans.nim +++ /dev/null @@ -1,59 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2011 Philippe Lhoste -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## Module for converting an integer to a Roman numeral. -## See http://en.wikipedia.org/wiki/Roman_numerals for reference. -## -## **Warning:** This module will be moved out of the stdlib and into a -## Nimble package, don't use it. - -const - RomanNumeralDigits* = {'I', 'i', 'V', 'v', 'X', 'x', 'L', 'l', 'C', 'c', - 'D', 'd', 'M', 'm'} ## set of all characters a Roman numeral may consist of - -proc romanToDecimal*(romanVal: string): int = - ## Converts a Roman numeral to its int representation. - result = 0 - var prevVal = 0 - for i in countdown(romanVal.len - 1, 0): - var val = 0 - case romanVal[i] - of 'I', 'i': val = 1 - of 'V', 'v': val = 5 - of 'X', 'x': val = 10 - of 'L', 'l': val = 50 - of 'C', 'c': val = 100 - of 'D', 'd': val = 500 - of 'M', 'm': val = 1000 - else: - raise newException(EInvalidValue, "invalid roman numeral: " & $romanVal) - if val >= prevVal: - inc(result, val) - else: - dec(result, val) - prevVal = val - -proc decimalToRoman*(number: range[1..3_999]): string = - ## Converts a number to a Roman numeral. - const romanComposites = [ - ("M", 1000), ("CM", 900), - ("D", 500), ("CD", 400), ("C", 100), - ("XC", 90), ("L", 50), ("XL", 40), ("X", 10), ("IX", 9), - ("V", 5), ("IV", 4), ("I", 1)] - result = "" - var decVal: int = number - for key, val in items(romanComposites): - while decVal >= val: - dec(decVal, val) - result.add(key) - -when isMainModule: - for i in 1 .. 3_999: - assert i == i.decimalToRoman.romanToDecimal - diff --git a/lib/pure/ropes.nim b/lib/pure/ropes.nim index 6e97237e0..6ddd61afa 100644 --- a/lib/pure/ropes.nim +++ b/lib/pure/ropes.nim @@ -17,6 +17,7 @@ ## runtime efficiency. include "system/inclrtl" +import streams {.deadCodeElim: on.} @@ -130,7 +131,7 @@ proc insertInCache(s: string, tree: Rope): Rope = result.left = t t.right = nil -proc rope*(s: string): Rope {.rtl, extern: "nro$1Str".} = +proc rope*(s: string = nil): Rope {.rtl, extern: "nro$1Str".} = ## Converts a string to a rope. if s.len == 0: result = nil @@ -242,10 +243,13 @@ proc write*(f: File, r: Rope) {.rtl, extern: "nro$1".} = ## writes a rope to a file. for s in leaves(r): write(f, s) +proc write*(s: Stream, r: Rope) {.rtl, extern: "nroWriteStream".} = + ## writes a rope to a stream. + for rs in leaves(r): write(s, rs) + proc `$`*(r: Rope): string {.rtl, extern: "nroToString".}= ## converts a rope back to a string. - result = newString(r.len) - setLen(result, 0) + result = newStringOfCap(r.len) for s in leaves(r): add(result, s) when false: diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim index 711e4a897..1ff26954e 100644 --- a/lib/pure/scgi.nim +++ b/lib/pure/scgi.nim @@ -95,7 +95,7 @@ type AsyncScgiState* = ref AsyncScgiStateObj {.deprecated: [EScgi: ScgiError, TScgiState: ScgiState, - PAsyncScgiState: AsyncScgiState, scgiError: raiseScgiError].} + PAsyncScgiState: AsyncScgiState].} proc recvBuffer(s: var ScgiState, L: int) = if L > s.bufLen: diff --git a/lib/pure/securehash.nim b/lib/pure/securehash.nim index c19146669..57c1f3631 100644 --- a/lib/pure/securehash.nim +++ b/lib/pure/securehash.nim @@ -181,7 +181,7 @@ proc `$`*(self: SecureHash): string = result.add(toHex(int(v), 2)) proc parseSecureHash*(hash: string): SecureHash = - for i in 0.. <Sha1DigestSize: + for i in 0 ..< Sha1DigestSize: Sha1Digest(result)[i] = uint8(parseHexInt(hash[i*2] & hash[i*2 + 1])) proc `==`*(a, b: SecureHash): bool = diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index 506b2cec0..518cc4bd5 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -1,420 +1,313 @@ # # # Nim's Runtime Library -# (c) Copyright 2015 Dominik Picheta +# (c) Copyright 2016 Eugene Kabanov # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# TODO: Docs. - -import os, hashes - -when defined(linux): - import posix, epoll -elif defined(macosx) or defined(freebsd) or defined(openbsd) or defined(netbsd): - import posix, kqueue, times -elif defined(windows): - import winlean -else: - import posix - -const MultiThreaded = defined(useStdlibThreading) - -when MultiThreaded: - import sharedtables - - type SelectorData = pointer -else: - import tables - - type SelectorData = RootRef - -proc hash*(x: SocketHandle): Hash {.borrow.} -proc `$`*(x: SocketHandle): string {.borrow.} - -type - Event* = enum - EvRead, EvWrite, EvError - - SelectorKey* = object - fd*: SocketHandle - events*: set[Event] ## The events which ``fd`` listens for. - data*: SelectorData ## User object. - - ReadyInfo* = tuple[key: SelectorKey, events: set[Event]] +## This module allows high-level and efficient I/O multiplexing. +## +## Supported OS primitives: ``epoll``, ``kqueue``, ``poll`` and +## Windows ``select``. +## +## To use threadsafe version of this module, it needs to be compiled +## with both ``-d:threadsafe`` and ``--threads:on`` options. +## +## Supported features: files, sockets, pipes, timers, processes, signals +## and user events. +## +## Fully supported OS: MacOSX, FreeBSD, OpenBSD, NetBSD, Linux (except +## for Android). +## +## Partially supported OS: Windows (only sockets and user events), +## Solaris (files, sockets, handles and user events). +## Android (files, sockets, handles and user events). +## +## TODO: ``/dev/poll``, ``event ports`` and filesystem events. + +import os, strutils, nativesockets + +const hasThreadSupport = compileOption("threads") and defined(threadsafe) + +const ioselSupportedPlatform* = defined(macosx) or defined(freebsd) or + defined(netbsd) or defined(openbsd) or + defined(dragonfly) or + (defined(linux) and not defined(android)) + ## This constant is used to determine whether the destination platform is + ## fully supported by ``ioselectors`` module. + +const bsdPlatform = defined(macosx) or defined(freebsd) or + defined(netbsd) or defined(openbsd) or + defined(dragonfly) when defined(nimdoc): type - Selector* = ref object - ## An object which holds file descriptors to be checked for read/write - ## status. - - proc register*(s: Selector, fd: SocketHandle, events: set[Event], - data: SelectorData): SelectorKey {.discardable.} = - ## Registers file descriptor ``fd`` to selector ``s`` with a set of Event - ## ``events``. - - proc update*(s: Selector, fd: SocketHandle, - events: set[Event]): SelectorKey {.discardable.} = - ## Updates the events which ``fd`` wants notifications for. - - proc unregister*(s: Selector, fd: SocketHandle): SelectorKey {.discardable.} = - ## Unregisters file descriptor ``fd`` from selector ``s``. - - proc close*(s: Selector) = - ## Closes the selector - - proc select*(s: Selector, timeout: int): seq[ReadyInfo] = - ## The ``events`` field of the returned ``key`` contains the original events - ## for which the ``fd`` was bound. This is contrary to the ``events`` field - ## of the ``ReadyInfo`` tuple which determines which events are ready - ## on the ``fd``. - - proc newSelector*(): Selector = + Selector*[T] = ref object + ## An object which holds descriptors to be checked for read/write status + + Event* {.pure.} = enum + ## An enum which hold event types + Read, ## Descriptor is available for read + Write, ## Descriptor is available for write + Timer, ## Timer descriptor is completed + Signal, ## Signal is raised + Process, ## Process is finished + Vnode, ## BSD specific file change happens + User, ## User event is raised + Error, ## Error happens while waiting, for descriptor + VnodeWrite, ## NOTE_WRITE (BSD specific, write to file occurred) + VnodeDelete, ## NOTE_DELETE (BSD specific, unlink of file occurred) + VnodeExtend, ## NOTE_EXTEND (BSD specific, file extended) + VnodeAttrib, ## NOTE_ATTRIB (BSD specific, file attributes changed) + VnodeLink, ## NOTE_LINK (BSD specific, file link count changed) + VnodeRename, ## NOTE_RENAME (BSD specific, file renamed) + VnodeRevoke ## NOTE_REVOKE (BSD specific, file revoke occurred) + + ReadyKey* = object + ## An object which holds result for descriptor + fd* : int ## file/socket descriptor + events*: set[Event] ## set of events + + SelectEvent* = object + ## An object which holds user defined event + + proc newSelector*[T](): Selector[T] = ## Creates a new selector - proc contains*(s: Selector, fd: SocketHandle): bool = + proc close*[T](s: Selector[T]) = + ## Closes the selector. + + proc registerHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event], + data: T) = + ## Registers file/socket descriptor ``fd`` to selector ``s`` + ## with events set in ``events``. The ``data`` is application-defined + ## data, which will be passed when an event is triggered. + + proc updateHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event]) = + ## Update file/socket descriptor ``fd``, registered in selector + ## ``s`` with new events set ``event``. + + proc registerTimer*[T](s: Selector[T], timeout: int, oneshot: bool, + data: T): int {.discardable.} = + ## Registers timer notification with ``timeout`` (in milliseconds) + ## to selector ``s``. + ## + ## If ``oneshot`` is ``true``, timer will be notified only once. + ## + ## Set ``oneshot`` to ``false`` if you want periodic notifications. + ## + ## The ``data`` is application-defined data, which will be passed, when + ## the timer is triggered. + ## + ## Returns the file descriptor for the registered timer. + + proc registerSignal*[T](s: Selector[T], signal: int, + data: T): int {.discardable.} = + ## Registers Unix signal notification with ``signal`` to selector + ## ``s``. + ## + ## The ``data`` is application-defined data, which will be + ## passed when signal raises. + ## + ## Returns the file descriptor for the registered signal. + ## + ## **Note:** This function is not supported on ``Windows``. + + proc registerProcess*[T](s: Selector[T], pid: int, + data: T): int {.discardable.} = + ## Registers a process id (pid) notification (when process has + ## exited) in selector ``s``. + ## + ## The ``data`` is application-defined data, which will be passed when + ## process with ``pid`` has exited. + ## + ## Returns the file descriptor for the registered signal. + + proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = + ## Registers selector event ``ev`` in selector ``s``. + ## + ## The ``data`` is application-defined data, which will be passed when + ## ``ev`` happens. + + proc registerVnode*[T](s: Selector[T], fd: cint, events: set[Event], + data: T) = + ## Registers selector BSD/MacOSX specific vnode events for file + ## descriptor ``fd`` and events ``events``. + ## ``data`` application-defined data, which to be passed, when + ## vnode event happens. + ## + ## **Note:** This function is supported only by BSD and MacOSX. + + proc newSelectEvent*(): SelectEvent = + ## Creates a new user-defined event. + + proc trigger*(ev: SelectEvent) = + ## Trigger event ``ev``. + + proc close*(ev: SelectEvent) = + ## Closes user-defined event ``ev``. + + proc unregister*[T](s: Selector[T], ev: SelectEvent) = + ## Unregisters user-defined event ``ev`` from selector ``s``. + + proc unregister*[T](s: Selector[T], fd: int|SocketHandle|cint) = + ## Unregisters file/socket descriptor ``fd`` from selector ``s``. + + proc selectInto*[T](s: Selector[T], timeout: int, + results: var openarray[ReadyKey]): int = + ## Waits for events registered in selector ``s``. + ## + ## The ``timeout`` argument specifies the maximum number of milliseconds + ## the function will be blocked for if no events are ready. Specifying a + ## timeout of ``-1`` causes the function to block indefinitely. + ## All available events will be stored in ``results`` array. + ## + ## Returns number of triggered events. + + proc select*[T](s: Selector[T], timeout: int): seq[ReadyKey] = + ## Waits for events registered in selector ``s``. + ## + ## The ``timeout`` argument specifies the maximum number of milliseconds + ## the function will be blocked for if no events are ready. Specifying a + ## timeout of ``-1`` causes the function to block indefinitely. + ## + ## Returns a list of triggered events. + + proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T = + ## Retrieves application-defined ``data`` associated with descriptor ``fd``. + ## If specified descriptor ``fd`` is not registered, empty/default value + ## will be returned. + + proc setData*[T](s: Selector[T], fd: SocketHandle|int, data: var T): bool = + ## Associate application-defined ``data`` with descriptor ``fd``. + ## + ## Returns ``true``, if data was succesfully updated, ``false`` otherwise. + + template isEmpty*[T](s: Selector[T]): bool = # TODO: Why is this a template? + ## Returns ``true``, if there are no registered events or descriptors + ## in selector. + + template withData*[T](s: Selector[T], fd: SocketHandle|int, value, + body: untyped) = + ## Retrieves the application-data assigned with descriptor ``fd`` + ## to ``value``. This ``value`` can be modified in the scope of + ## the ``withData`` call. + ## + ## .. code-block:: nim + ## + ## s.withData(fd, value) do: + ## # block is executed only if ``fd`` registered in selector ``s`` + ## value.uid = 1000 + ## + + template withData*[T](s: Selector[T], fd: SocketHandle|int, value, + body1, body2: untyped) = + ## Retrieves the application-data assigned with descriptor ``fd`` + ## to ``value``. This ``value`` can be modified in the scope of + ## the ``withData`` call. + ## + ## .. code-block:: nim + ## + ## s.withData(fd, value) do: + ## # block is executed only if ``fd`` registered in selector ``s``. + ## value.uid = 1000 + ## do: + ## # block is executed if ``fd`` not registered in selector ``s``. + ## raise + ## + + proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = ## Determines whether selector contains a file descriptor. - proc `[]`*(s: Selector, fd: SocketHandle): SelectorKey = - ## Retrieves the selector key for ``fd``. - -elif defined(linux): - type - Selector* = object - epollFD: cint - events: array[64, epoll_event] - when MultiThreaded: - fds: SharedTable[SocketHandle, SelectorKey] - else: - fds: Table[SocketHandle, SelectorKey] - - proc createEventStruct(events: set[Event], fd: SocketHandle): epoll_event = - if EvRead in events: - result.events = EPOLLIN - if EvWrite in events: - result.events = result.events or EPOLLOUT - result.events = result.events or EPOLLRDHUP - result.data.fd = fd.cint - - proc register*(s: var Selector, fd: SocketHandle, events: set[Event], - data: SelectorData) = - var event = createEventStruct(events, fd) - if events != {}: - if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0: - raiseOSError(osLastError()) - - s.fds[fd] = SelectorKey(fd: fd, events: events, data: data) - - proc update*(s: var Selector, fd: SocketHandle, events: set[Event]) = - if s.fds[fd].events != events: - if events == {}: - # This fd is idle -- it should not be registered to epoll. - # But it should remain a part of this selector instance. - # This is to prevent epoll_wait from returning immediately - # because its got fds which are waiting for no events and - # are therefore constantly ready. (leading to 100% CPU usage). - if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0: - raiseOSError(osLastError()) - s.fds[fd].events = events - else: - var event = createEventStruct(events, fd) - if s.fds[fd].events == {}: - # This fd is idle. It's not a member of this epoll instance and must - # be re-registered. - if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0: - raiseOSError(osLastError()) - else: - if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0: - raiseOSError(osLastError()) - s.fds[fd].events = events - - proc unregister*(s: var Selector, fd: SocketHandle) = - if s.fds[fd].events != {}: - if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0: - let err = osLastError() - if err.cint notin {ENOENT, EBADF}: - # TODO: Why do we sometimes get an EBADF? Is this normal? - raiseOSError(err) - s.fds.del(fd) - - proc close*(s: var Selector) = - when MultiThreaded: deinitSharedTable(s.fds) - if s.epollFD.close() != 0: raiseOSError(osLastError()) - - proc epollHasFd(s: Selector, fd: SocketHandle): bool = - result = true - var event = createEventStruct(s.fds[fd].events, fd) - if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0: - let err = osLastError() - if err.cint in {ENOENT, EBADF}: - return false - raiseOSError(err) - - proc select*(s: var Selector, timeout: int): seq[ReadyInfo] = - result = @[] - let evNum = epoll_wait(s.epollFD, addr s.events[0], 64.cint, timeout.cint) - if evNum < 0: - let err = osLastError() - if err.cint == EINTR: - return @[] - raiseOSError(err) - if evNum == 0: return @[] - for i in 0 .. <evNum: - let fd = s.events[i].data.fd.SocketHandle - - var evSet: set[Event] = {} - if (s.events[i].events and EPOLLERR) != 0 or (s.events[i].events and EPOLLHUP) != 0: evSet = evSet + {EvError} - if (s.events[i].events and EPOLLIN) != 0: evSet = evSet + {EvRead} - if (s.events[i].events and EPOLLOUT) != 0: evSet = evSet + {EvWrite} - let selectorKey = s.fds[fd] - assert selectorKey.fd != 0.SocketHandle - result.add((selectorKey, evSet)) - - #echo("Epoll: ", result[i].key.fd, " ", result[i].events, " ", result[i].key.events) - - proc newSelector*(): Selector = - result.epollFD = epoll_create(64) - if result.epollFD < 0: - raiseOSError(osLastError()) - when MultiThreaded: - result.fds = initSharedTable[SocketHandle, SelectorKey]() - else: - result.fds = initTable[SocketHandle, SelectorKey]() - - proc contains*(s: Selector, fd: SocketHandle): bool = - ## Determines whether selector contains a file descriptor. - if s.fds.hasKey(fd): - # Ensure the underlying epoll instance still contains this fd. - if s.fds[fd].events != {}: - result = epollHasFd(s, fd) - else: - result = true - else: - return false +else: + when hasThreadSupport: + import locks - proc `[]`*(s: Selector, fd: SocketHandle): SelectorKey = - ## Retrieves the selector key for ``fd``. - return s.fds[fd] -elif defined(macosx) or defined(freebsd) or defined(openbsd) or defined(netbsd): - type - Selector* = object - kqFD: cint - events: array[64, KEvent] - when MultiThreaded: - fds: SharedTable[SocketHandle, SelectorKey] - else: - fds: Table[SocketHandle, SelectorKey] - - template modifyKQueue(kqFD: cint, fd: SocketHandle, event: Event, - op: cushort) = - var kev = KEvent(ident: fd.cuint, - filter: if event == EvRead: EVFILT_READ else: EVFILT_WRITE, - flags: op) - if kevent(kqFD, addr kev, 1, nil, 0, nil) == -1: - raiseOSError(osLastError()) - - proc register*(s: var Selector, fd: SocketHandle, events: set[Event], - data: SelectorData) = - for event in events: - modifyKQueue(s.kqFD, fd, event, EV_ADD) - s.fds[fd] = SelectorKey(fd: fd, events: events, data: data) - - proc update*(s: var Selector, fd: SocketHandle, events: set[Event]) = - let previousEvents = s.fds[fd].events - if previousEvents != events: - for event in events-previousEvents: - modifyKQueue(s.kqFD, fd, event, EV_ADD) - for event in previousEvents-events: - modifyKQueue(s.kqFD, fd, event, EV_DELETE) - s.fds[fd].events = events - - proc unregister*(s: var Selector, fd: SocketHandle) = - for event in s.fds[fd].events: - modifyKQueue(s.kqFD, fd, event, EV_DELETE) - s.fds.del(fd) - - proc close*(s: var Selector) = - when MultiThreaded: deinitSharedTable(s.fds) - if s.kqFD.close() != 0: raiseOSError(osLastError()) - - proc select*(s: var Selector, timeout: int): seq[ReadyInfo] = - result = @[] - var tv = - if timeout >= 1000: Timespec(tv_sec: (timeout div 1000).Time, tv_nsec: 0) - else: Timespec(tv_sec: 0.Time, tv_nsec: timeout * 1000000) - let evNum = kevent(s.kqFD, nil, 0, addr s.events[0], 64.cint, addr tv) - if evNum < 0: - let err = osLastError() - if err.cint == EINTR: - return @[] - raiseOSError(err) - if evNum == 0: return @[] - for i in 0 .. <evNum: - let fd = s.events[i].ident.SocketHandle - - var evSet: set[Event] = {} - if (s.events[i].flags and EV_EOF) != 0: evSet = evSet + {EvError} - if s.events[i].filter == EVFILT_READ: evSet = evSet + {EvRead} - elif s.events[i].filter == EVFILT_WRITE: evSet = evSet + {EvWrite} - let selectorKey = s.fds[fd] - assert selectorKey.fd != 0.SocketHandle - result.add((selectorKey, evSet)) - - proc newSelector*(): Selector = - result.kqFD = kqueue() - if result.kqFD < 0: - raiseOSError(osLastError()) - when MultiThreaded: - result.fds = initSharedTable[SocketHandle, SelectorKey]() - else: - result.fds = initTable[SocketHandle, SelectorKey]() + type + SharedArray[T] = UncheckedArray[T] - proc contains*(s: Selector, fd: SocketHandle): bool = - ## Determines whether selector contains a file descriptor. - s.fds.hasKey(fd) # and s.fds[fd].events != {} + proc allocSharedArray[T](nsize: int): ptr SharedArray[T] = + result = cast[ptr SharedArray[T]](allocShared0(sizeof(T) * nsize)) - proc `[]`*(s: Selector, fd: SocketHandle): SelectorKey = - ## Retrieves the selector key for ``fd``. - return s.fds[fd] + proc deallocSharedArray[T](sa: ptr SharedArray[T]) = + deallocShared(cast[pointer](sa)) -elif not defined(nimdoc): - # TODO: kqueue for bsd/mac os x. type - Selector* = object - when MultiThreaded: - fds: SharedTable[SocketHandle, SelectorKey] - else: - fds: Table[SocketHandle, SelectorKey] - - proc register*(s: var Selector, fd: SocketHandle, events: set[Event], - data: SelectorData) = - let result = SelectorKey(fd: fd, events: events, data: data) - if s.fds.hasKeyOrPut(fd, result): - raise newException(ValueError, "File descriptor already exists.") - - proc update*(s: var Selector, fd: SocketHandle, events: set[Event]) = - #if not s.fds.hasKey(fd): - # raise newException(ValueError, "File descriptor not found.") - s.fds[fd].events = events - - proc unregister*(s: var Selector, fd: SocketHandle) = - s.fds.del(fd) - - proc close*(s: var Selector) = - when MultiThreaded: deinitSharedTable(s.fds) - - proc timeValFromMilliseconds(timeout: int): TimeVal = - if timeout != -1: - var seconds = timeout div 1000 - result.tv_sec = seconds.int32 - result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 - - proc createFdSet(rd, wr: var TFdSet, s: Selector, m: var int) = - FD_ZERO(rd); FD_ZERO(wr) - for k, v in pairs(s.fds): - if EvRead in v.events: - m = max(m, int(k)) - FD_SET(k, rd) - if EvWrite in v.events: - m = max(m, int(k)) - FD_SET(k, wr) - - proc getReadyFDs(rd, wr: var TFdSet, - s: var Selector): seq[ReadyInfo] = - result = @[] - for k, v in pairs(s.fds): - var events: set[Event] = {} - if FD_ISSET(k, rd) != 0'i32: - events = events + {EvRead} - if FD_ISSET(k, wr) != 0'i32: - events = events + {EvWrite} - result.add((v, events)) - - proc select*(s: var Selector, timeout: int): seq[ReadyInfo] = - var tv {.noInit.}: TimeVal = timeValFromMilliseconds(timeout) - - var rd, wr: TFdSet - var m = 0 - createFdSet(rd, wr, s, m) - - var retCode = 0 - if timeout != -1: - retCode = int(select(cint(m+1), addr(rd), addr(wr), nil, addr(tv))) - else: - retCode = int(select(cint(m+1), addr(rd), addr(wr), nil, nil)) - - if retCode < 0: - raiseOSError(osLastError()) - elif retCode == 0: - return @[] - else: - return getReadyFDs(rd, wr, s) + Event* {.pure.} = enum + Read, Write, Timer, Signal, Process, Vnode, User, Error, Oneshot, + Finished, VnodeWrite, VnodeDelete, VnodeExtend, VnodeAttrib, VnodeLink, + VnodeRename, VnodeRevoke - proc newSelector*(): Selector = - when MultiThreaded: - result.fds = initSharedTable[SocketHandle, SelectorKey]() + type + IOSelectorsException* = object of Exception + + ReadyKey* = object + fd* : int + events*: set[Event] + + SelectorKey[T] = object + ident: int + events: set[Event] + param: int + data: T + + proc raiseIOSelectorsError[T](message: T) = + var msg = "" + when T is string: + msg.add(message) + elif T is OSErrorCode: + msg.add(osErrorMsg(message) & " (code: " & $int(message) & ")") else: - result.fds = initTable[SocketHandle, SelectorKey]() - - proc contains*(s: Selector, fd: SocketHandle): bool = - return s.fds.hasKey(fd) - - proc `[]`*(s: Selector, fd: SocketHandle): SelectorKey = - return s.fds[fd] - -proc contains*(s: Selector, key: SelectorKey): bool = - ## Determines whether selector contains this selector key. More accurate - ## than checking if the file descriptor is in the selector because it - ## ensures that the keys are equal. File descriptors may not always be - ## unique especially when an fd is closed and then a new one is opened, - ## the new one may have the same value. - when not defined(nimdoc): - return key.fd in s and s.fds[key.fd] == key - -proc len*(s: Selector): int = - ## Retrieves the number of registered file descriptors in this Selector. - when not defined(nimdoc): - return s.fds.len - -{.deprecated: [TEvent: Event, PSelectorKey: SelectorKey, - TReadyInfo: ReadyInfo, PSelector: Selector].} - - -when not defined(testing) and isMainModule and not defined(nimdoc): - # Select() - import sockets + msg.add("Internal Error\n") + var err = newException(IOSelectorsException, msg) + raise err + + proc setNonBlocking(fd: cint) {.inline.} = + setBlocking(fd.SocketHandle, false) + + when not defined(windows): + import posix + + template setKey(s, pident, pevents, pparam, pdata: untyped) = + var skey = addr(s.fds[pident]) + skey.ident = pident + skey.events = pevents + skey.param = pparam + skey.data = data + + when ioselSupportedPlatform: + template blockSignals(newmask: var Sigset, oldmask: var Sigset) = + when hasThreadSupport: + if posix.pthread_sigmask(SIG_BLOCK, newmask, oldmask) == -1: + raiseIOSelectorsError(osLastError()) + else: + if posix.sigprocmask(SIG_BLOCK, newmask, oldmask) == -1: + raiseIOSelectorsError(osLastError()) - when MultiThreaded: - type - SockWrapper = object - sock: Socket - else: - type - SockWrapper = ref object of RootObj - sock: Socket - - var sock = socket() - if sock == sockets.invalidSocket: raiseOSError(osLastError()) - #sock.setBlocking(false) - sock.connect("irc.freenode.net", Port(6667)) - - var selector = newSelector() - var data = SockWrapper(sock: sock) - when MultiThreaded: - selector.register(sock.getFD, {EvWrite}, addr data) + template unblockSignals(newmask: var Sigset, oldmask: var Sigset) = + when hasThreadSupport: + if posix.pthread_sigmask(SIG_UNBLOCK, newmask, oldmask) == -1: + raiseIOSelectorsError(osLastError()) + else: + if posix.sigprocmask(SIG_UNBLOCK, newmask, oldmask) == -1: + raiseIOSelectorsError(osLastError()) + + when defined(linux): + include ioselects/ioselectors_epoll + elif bsdPlatform: + include ioselects/ioselectors_kqueue + elif defined(windows): + include ioselects/ioselectors_select + elif defined(solaris): + include ioselects/ioselectors_poll # need to replace it with event ports + elif defined(genode): + include ioselects/ioselectors_select # TODO: use the native VFS layer else: - selector.register(sock.getFD, {EvWrite}, data) - var i = 0 - while true: - let ready = selector.select(1000) - echo ready.len - if ready.len > 0: echo ready[0].events - i.inc - if i == 6: - selector.unregister(sock.getFD) - selector.close() - break + include ioselects/ioselectors_poll + +{.deprecated: [setEvent: trigger].} +{.deprecated: [register: registerHandle].} +{.deprecated: [update: updateHandle].} diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 69f673990..354e07da3 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -224,6 +224,38 @@ proc peekInt64*(s: Stream): int64 = ## peeks an int64 from the stream `s`. Raises `EIO` if an error occurred. peek(s, result) +proc readUint8*(s: Stream): uint8 = + ## reads an uint8 from the stream `s`. Raises `EIO` if an error occurred. + read(s, result) + +proc peekUint8*(s: Stream): uint8 = + ## peeks an uint8 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + +proc readUint16*(s: Stream): uint16 = + ## reads an uint16 from the stream `s`. Raises `EIO` if an error occurred. + read(s, result) + +proc peekUint16*(s: Stream): uint16 = + ## peeks an uint16 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + +proc readUint32*(s: Stream): uint32 = + ## reads an uint32 from the stream `s`. Raises `EIO` if an error occurred. + read(s, result) + +proc peekUint32*(s: Stream): uint32 = + ## peeks an uint32 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + +proc readUint64*(s: Stream): uint64 = + ## reads an uint64 from the stream `s`. Raises `EIO` if an error occurred. + read(s, result) + +proc peekUint64*(s: Stream): uint64 = + ## peeks an uint64 from the stream `s`. Raises `EIO` if an error occurred. + peek(s, result) + proc readFloat32*(s: Stream): float32 = ## reads a float32 from the stream `s`. Raises `EIO` if an error occurred. read(s, result) diff --git a/lib/pure/strformat.nim b/lib/pure/strformat.nim new file mode 100644 index 000000000..180cbcbec --- /dev/null +++ b/lib/pure/strformat.nim @@ -0,0 +1,619 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +##[ +String `interpolation`:idx: / `format`:idx: inspired by +Python's ``f``-strings. + +Examples: + +.. code-block:: nim + + doAssert fmt"""{"abc":>4}""" == " abc" + doAssert fmt"""{"abc":<4}""" == "abc " + + doAssert fmt"{-12345:08}" == "-0012345" + doAssert fmt"{-1:3}" == " -1" + doAssert fmt"{-1:03}" == "-01" + doAssert fmt"{16:#X}" == "0x10" + + doAssert fmt"{123.456}" == "123.456" + doAssert fmt"{123.456:>9.3f}" == " 123.456" + doAssert fmt"{123.456:9.3f}" == " 123.456" + doAssert fmt"{123.456:9.4f}" == " 123.4560" + doAssert fmt"{123.456:>9.0f}" == " 123." + doAssert fmt"{123.456:<9.4f}" == "123.4560 " + + doAssert fmt"{123.456:e}" == "1.234560e+02" + doAssert fmt"{123.456:>13e}" == " 1.234560e+02" + doAssert fmt"{123.456:13e}" == " 1.234560e+02" + + +An expression like ``fmt"{key} is {value:arg} {{z}}"`` is transformed into: + +.. code-block:: nim + var temp = newStringOfCap(educatedCapGuess) + format(key, temp) + format(" is ", temp) + format(value, arg, temp) + format(" {z}", temp) + temp + +Parts of the string that are enclosed in the curly braces are interpreted +as Nim code, to escape an ``{`` or ``}`` double it. + +``fmt`` delegates most of the work to an open overloaded set +of ``format`` procs. The required signature for a type ``T`` that supports +formatting is usually ``proc format(x: T; result: var string)`` for efficiency +but can also be ``proc format(x: T): string``. ``add`` and ``$`` procs are +used as the fallback implementation. + +This is the concrete lookup algorithm that ``fmt`` uses: + +.. code-block:: nim + + when compiles(format(arg, res)): + format(arg, res) + elif compiles(format(arg)): + res.add format(arg) + elif compiles(add(res, arg)): + res.add(arg) + else: + res.add($arg) + + +The subexpression after the colon +(``arg`` in ``fmt"{key} is {value:arg} {{z}}"``) is an optional argument +passed to ``format``. + +If an optional argument is present the following lookup algorithm is used: + +.. code-block:: nim + + when compiles(format(arg, option, res)): + format(arg, option, res) + else: + res.add format(arg, option) + + +For strings and numeric types the optional argument is a so-called +"standard format specifier". + + +Standard format specifier +========================= + + +The general form of a standard format specifier is:: + + [[fill]align][sign][#][0][minimumwidth][.precision][type] + +The square brackets ``[]`` indicate an optional element. + +The optional align flag can be one of the following: + +'<' + Forces the field to be left-aligned within the available + space. (This is the default for strings.) + +'>' + Forces the field to be right-aligned within the available space. + (This is the default for numbers.) + +'^' + Forces the field to be centered within the available space. + +Note that unless a minimum field width is defined, the field width +will always be the same size as the data to fill it, so that the alignment +option has no meaning in this case. + +The optional 'fill' character defines the character to be used to pad +the field to the minimum width. The fill character, if present, must be +followed by an alignment flag. + +The 'sign' option is only valid for numeric types, and can be one of the following: + +================= ==================================================== + Sign Meaning +================= ==================================================== +``+`` Indicates that a sign should be used for both + positive as well as negative numbers. +``-`` Indicates that a sign should be used only for + negative numbers (this is the default behavior). +(space) Indicates that a leading space should be used on + positive numbers. +================= ==================================================== + +If the '#' character is present, integers use the 'alternate form' for formatting. +This means that binary, octal, and hexadecimal output will be prefixed +with '0b', '0o', and '0x', respectively. + +'width' is a decimal integer defining the minimum field width. If not specified, +then the field width will be determined by the content. + +If the width field is preceded by a zero ('0') character, this enables +zero-padding. + +The 'precision' is a decimal number indicating how many digits should be displayed +after the decimal point in a floating point conversion. For non-numeric types the +field indicates the maximum field size - in other words, how many characters will +be used from the field content. The precision is ignored for integer conversions. + +Finally, the 'type' determines how the data should be presented. + +The available integer presentation types are: + + +================= ==================================================== + Type Result +================= ==================================================== +``b`` Binary. Outputs the number in base 2. +``d`` Decimal Integer. Outputs the number in base 10. +``o`` Octal format. Outputs the number in base 8. +``x`` Hex format. Outputs the number in base 16, using + lower-case letters for the digits above 9. +``X`` Hex format. Outputs the number in base 16, using + uppercase letters for the digits above 9. +(None) the same as 'd' +================= ==================================================== + + +The available floating point presentation types are: + +================= ==================================================== + Type Result +================= ==================================================== +``e`` Exponent notation. Prints the number in scientific + notation using the letter 'e' to indicate the + exponent. +``E`` Exponent notation. Same as 'e' except it converts + the number to uppercase. +``f`` Fixed point. Displays the number as a fixed-point + number. +``F`` Fixed point. Same as 'f' except it converts the + number to uppercase. +``g`` General format. This prints the number as a + fixed-point number, unless the number is too + large, in which case it switches to 'e' + exponent notation. +``G`` General format. Same as 'g' except switches to 'E' + if the number gets to large. +(None) similar to 'g', except that it prints at least one + digit after the decimal point. +================= ==================================================== + + +Future directions +================= + +A curly expression with commas in it like ``{x, argA, argB}`` could be +transformed to ``format(x, argA, argB, res)`` in order to support +formatters that do not need to parse a custom language within a custom +language but instead prefer to use Nim's existing syntax. This also +helps in readability since there is only so much you can cram into +single letter DSLs. + +]## + +import macros, parseutils, unicode +import strutils + +template callFormat(res, arg) {.dirty.} = + when arg is string: + # workaround in order to circumvent 'strutils.format' which matches + # too but doesn't adhere to our protocol. + res.add arg + elif compiles(format(arg, res)): + format(arg, res) + elif compiles(format(arg)): + res.add format(arg) + elif compiles(add(res, arg)): + res.add(arg) + else: + res.add($arg) + +template callFormatOption(res, arg, option) {.dirty.} = + when compiles(format(arg, option, res)): + format(arg, option, res) + else: + res.add format(arg, option) + +macro fmt*(pattern: string): untyped = + ## For a specification of the ``fmt`` macro, see the module level documentation. + runnableExamples: + template check(actual, expected: string) = + doAssert actual == expected + + from strutils import toUpperAscii, repeat + + # Basic tests + let s = "string" + check fmt"{0} {s}", "0 string" + check fmt"{s[0..2].toUpperAscii}", "STR" + check fmt"{-10:04}", "-010" + check fmt"{-10:<04}", "-010" + check fmt"{-10:>04}", "-010" + check fmt"0x{10:02X}", "0x0A" + + check fmt"{10:#04X}", "0x0A" + + check fmt"""{"test":#>5}""", "#test" + check fmt"""{"test":>5}""", " test" + + check fmt"""{"test":#^7}""", "#test##" + + check fmt"""{"test": <5}""", "test " + check fmt"""{"test":<5}""", "test " + check fmt"{1f:.3f}", "1.000" + check fmt"Hello, {s}!", "Hello, string!" + + # Tests for identifers without parenthesis + check fmt"{s} works{s}", "string worksstring" + check fmt"{s:>7}", " string" + doAssert(not compiles(fmt"{s_works}")) # parsed as identifier `s_works` + + # Misc general tests + check fmt"{{}}", "{}" + check fmt"{0}%", "0%" + check fmt"{0}%asdf", "0%asdf" + check fmt("\n{\"\\n\"}\n"), "\n\n\n" + check fmt"""{"abc"}s""", "abcs" + + # String tests + check fmt"""{"abc"}""", "abc" + check fmt"""{"abc":>4}""", " abc" + check fmt"""{"abc":<4}""", "abc " + check fmt"""{"":>4}""", " " + check fmt"""{"":<4}""", " " + + # Int tests + check fmt"{12345}", "12345" + check fmt"{ - 12345}", "-12345" + check fmt"{12345:6}", " 12345" + check fmt"{12345:>6}", " 12345" + check fmt"{12345:4}", "12345" + check fmt"{12345:08}", "00012345" + check fmt"{-12345:08}", "-0012345" + check fmt"{0:0}", "0" + check fmt"{0:02}", "00" + check fmt"{-1:3}", " -1" + check fmt"{-1:03}", "-01" + check fmt"{10}", "10" + check fmt"{16:#X}", "0x10" + check fmt"{16:^#7X}", " 0x10 " + check fmt"{16:^+#7X}", " +0x10 " + + # Hex tests + check fmt"{0:x}", "0" + check fmt"{-0:x}", "0" + check fmt"{255:x}", "ff" + check fmt"{255:X}", "FF" + check fmt"{-255:x}", "-ff" + check fmt"{-255:X}", "-FF" + check fmt"{255:x} uNaffeCteD CaSe", "ff uNaffeCteD CaSe" + check fmt"{255:X} uNaffeCteD CaSe", "FF uNaffeCteD CaSe" + check fmt"{255:4x}", " ff" + check fmt"{255:04x}", "00ff" + check fmt"{-255:4x}", " -ff" + check fmt"{-255:04x}", "-0ff" + + # Float tests + check fmt"{123.456}", "123.456" + check fmt"{-123.456}", "-123.456" + check fmt"{123.456:.3f}", "123.456" + check fmt"{123.456:+.3f}", "+123.456" + check fmt"{-123.456:+.3f}", "-123.456" + check fmt"{-123.456:.3f}", "-123.456" + check fmt"{123.456:1g}", "123.456" + check fmt"{123.456:.1f}", "123.5" + check fmt"{123.456:.0f}", "123." + #check fmt"{123.456:.0f}", "123." + check fmt"{123.456:>9.3f}", " 123.456" + check fmt"{123.456:9.3f}", " 123.456" + check fmt"{123.456:>9.4f}", " 123.4560" + check fmt"{123.456:>9.0f}", " 123." + check fmt"{123.456:<9.4f}", "123.4560 " + + # Float (scientific) tests + check fmt"{123.456:e}", "1.234560e+02" + check fmt"{123.456:>13e}", " 1.234560e+02" + check fmt"{123.456:<13e}", "1.234560e+02 " + check fmt"{123.456:.1e}", "1.2e+02" + check fmt"{123.456:.2e}", "1.23e+02" + check fmt"{123.456:.3e}", "1.235e+02" + + # Note: times.format adheres to the format protocol. Test that this + # works: + import times + + var nullTime: TimeInfo + check fmt"{nullTime:yyyy-mm-dd}", "0000-00-00" + + # Unicode string tests + check fmt"""{"αβγ"}""", "αβγ" + check fmt"""{"αβγ":>5}""", " αβγ" + check fmt"""{"αβγ":<5}""", "αβγ " + check fmt"""a{"a"}α{"α"}€{"€"}ðˆ{"ðˆ"}""", "aaαα€€ðˆðˆ" + check fmt"""a{"a":2}α{"α":2}€{"€":2}ðˆ{"ðˆ":2}""", "aa αα €€ ðˆðˆ " + # Invalid unicode sequences should be handled as plain strings. + # Invalid examples taken from: https://stackoverflow.com/a/3886015/1804173 + let invalidUtf8 = [ + "\xc3\x28", "\xa0\xa1", + "\xe2\x28\xa1", "\xe2\x82\x28", + "\xf0\x28\x8c\xbc", "\xf0\x90\x28\xbc", "\xf0\x28\x8c\x28" + ] + for s in invalidUtf8: + check fmt"{s:>5}", repeat(" ", 5-s.len) & s + + if pattern.kind notin {nnkStrLit..nnkTripleStrLit}: + error "fmt only works with string literals", pattern + let f = pattern.strVal + var i = 0 + let res = genSym(nskVar, "fmtRes") + result = newNimNode(nnkStmtListExpr, lineInfoFrom=pattern) + result.add newVarStmt(res, newCall(bindSym"newStringOfCap", newLit(f.len + count(f, '{')*10))) + var strlit = "" + while i < f.len: + if f[i] == '{': + inc i + if f[i] == '{': + inc i + strlit.add '{' + else: + if strlit.len > 0: + result.add newCall(bindSym"add", res, newLit(strlit)) + strlit = "" + + var subexpr = "" + while i < f.len and f[i] != '}' and f[i] != ':': + subexpr.add f[i] + inc i + let x = parseExpr(subexpr) + + if f[i] == ':': + inc i + var options = "" + while i < f.len and f[i] != '}': + options.add f[i] + inc i + result.add getAst(callFormatOption(res, x, newLit(options))) + else: + result.add getAst(callFormat(res, x)) + if f[i] == '}': + inc i + else: + doAssert false, "invalid format string: missing '}'" + elif f[i] == '}': + if f[i+1] == '}': + strlit.add '}' + inc i, 2 + else: + doAssert false, "invalid format string: '}' instead of '}}'" + inc i + else: + strlit.add f[i] + inc i + if strlit.len > 0: + result.add newCall(bindSym"add", res, newLit(strlit)) + result.add res + when defined(debugFmtDsl): + echo repr result + +proc mkDigit(v: int, typ: char): string {.inline.} = + assert(v < 26) + if v < 10: + result = $chr(ord('0') + v) + else: + result = $chr(ord(if typ == 'x': 'a' else: 'A') + v - 10) + +proc alignString*(s: string, minimumWidth: int; align = '\0'; fill = ' '): string = + ## Aligns ``s`` using ``fill`` char. + ## This is only of interest if you want to write a custom ``format`` proc that + ## should support the standard format specifiers. + if minimumWidth == 0: + result = s + else: + let sRuneLen = if s.validateUtf8 == -1: s.runeLen else: s.len + let toFill = minimumWidth - sRuneLen + if toFill <= 0: + result = s + elif align == '<' or align == '\0': + result = s & repeat(fill, toFill) + elif align == '^': + let half = toFill div 2 + result = repeat(fill, half) & s & repeat(fill, toFill - half) + else: + result = repeat(fill, toFill) & s + +type + StandardFormatSpecifier* = object ## Type that describes "standard format specifiers". + fill*, align*: char ## Desired fill and alignment. + sign*: char ## Desired sign. + alternateForm*: bool ## Whether to prefix binary, octal and hex numbers + ## with ``0b``, ``0o``, ``0x``. + padWithZero*: bool ## Whether to pad with zeros rather than spaces. + minimumWidth*, precision*: int ## Desired minium width and precision. + typ*: char ## Type like 'f', 'g' or 'd'. + endPosition*: int ## End position in the format specifier after + ## ``parseStandardFormatSpecifier`` returned. + +proc formatInt(n: SomeNumber; radix: int; spec: StandardFormatSpecifier): string = + ## Converts ``n`` to string. If ``n`` is `SomeReal`, it casts to `int64`. + ## Conversion is done using ``radix``. If result's length is lesser than + ## ``minimumWidth``, it aligns result to the right or left (depending on ``a``) + ## with ``fill`` char. + when n is SomeUnsignedInt: + var v = n.uint64 + let negative = false + else: + var v = n.int64 + let negative = v.int64 < 0 + if negative: + # FIXME: overflow error for low(int64) + v = v * -1 + + var xx = "" + if spec.alternateForm: + case spec.typ + of 'X': xx = "0x" + of 'x': xx = "0x" + of 'b': xx = "0b" + of 'o': xx = "0o" + else: discard + + if v == 0: + result = "0" + else: + result = "" + while v > type(v)(0): + let d = v mod type(v)(radix) + v = v div type(v)(radix) + result.add(mkDigit(d.int, spec.typ)) + for idx in 0..<(result.len div 2): + swap result[idx], result[result.len - idx - 1] + if spec.padWithZero: + let sign = negative or spec.sign != '-' + let toFill = spec.minimumWidth - result.len - xx.len - ord(sign) + if toFill > 0: + result = repeat('0', toFill) & result + + if negative: + result = "-" & xx & result + elif spec.sign != '-': + result = spec.sign & xx & result + else: + result = xx & result + + if spec.align == '<': + for i in result.len..<spec.minimumWidth: + result.add(spec.fill) + else: + let toFill = spec.minimumWidth - result.len + if spec.align == '^': + let half = toFill div 2 + result = repeat(spec.fill, half) & result & repeat(spec.fill, toFill - half) + else: + if toFill > 0: + result = repeat(spec.fill, toFill) & result + +proc parseStandardFormatSpecifier*(s: string; start = 0; + ignoreUnknownSuffix = false): StandardFormatSpecifier = + ## An exported helper proc that parses the "standard format specifiers", + ## as specified by the grammar:: + ## + ## [[fill]align][sign][#][0][minimumwidth][.precision][type] + ## + ## This is only of interest if you want to write a custom ``format`` proc that + ## should support the standard format specifiers. If ``ignoreUnknownSuffix`` is true, + ## an unknown suffix after the ``type`` field is not an error. + const alignChars = {'<', '>', '^'} + result.fill = ' ' + result.align = '\0' + result.sign = '-' + var i = start + if i + 1 < s.len and s[i+1] in alignChars: + result.fill = s[i] + result.align = s[i+1] + inc i, 2 + elif i < s.len and s[i] in alignChars: + result.align = s[i] + inc i + + if i < s.len and s[i] in {'-', '+', ' '}: + result.sign = s[i] + inc i + + if i < s.len and s[i] == '#': + result.alternateForm = true + inc i + + if i+1 < s.len and s[i] == '0' and s[i+1] in {'0'..'9'}: + result.padWithZero = true + inc i + + let parsedLength = parseSaturatedNatural(s, result.minimumWidth, i) + inc i, parsedLength + if i < s.len and s[i] == '.': + inc i + let parsedLengthB = parseSaturatedNatural(s, result.precision, i) + inc i, parsedLengthB + else: + result.precision = -1 + + if i < s.len and s[i] in {'A'..'Z', 'a'..'z'}: + result.typ = s[i] + inc i + result.endPosition = i + if i != s.len and not ignoreUnknownSuffix: + raise newException(ValueError, + "invalid format string, cannot parse: " & s[i..^1]) + + +proc format*(value: SomeInteger; specifier: string; res: var string) = + ## Standard format implementation for ``SomeInteger``. It makes little + ## sense to call this directly, but it is required to exist + ## by the ``fmt`` macro. + let spec = parseStandardFormatSpecifier(specifier) + var radix = 10 + case spec.typ + of 'x', 'X': radix = 16 + of 'd', '\0': discard + of 'b': radix = 2 + of 'o': radix = 8 + else: + raise newException(ValueError, + "invalid type in format string for number, expected one " & + " of 'x', 'X', 'b', 'd', 'o' but got: " & spec.typ) + res.add formatInt(value, radix, spec) + +proc format*(value: SomeReal; specifier: string; res: var string) = + ## Standard format implementation for ``SomeReal``. It makes little + ## sense to call this directly, but it is required to exist + ## by the ``fmt`` macro. + let spec = parseStandardFormatSpecifier(specifier) + + var fmode = ffDefault + case spec.typ + of 'e', 'E': + fmode = ffScientific + of 'f', 'F': + fmode = ffDecimal + of 'g', 'G': + fmode = ffDefault + of '\0': discard + else: + raise newException(ValueError, + "invalid type in format string for number, expected one " & + " of 'e', 'E', 'f', 'F', 'g', 'G' but got: " & spec.typ) + + var f = formatBiggestFloat(value, fmode, spec.precision) + if value >= 0.0 and spec.sign != '-': + f = spec.sign & f + # the default for numbers is right-alignment: + let align = if spec.align == '\0': '>' else: spec.align + let result = alignString(f, spec.minimumWidth, + align, spec.fill) + if spec.typ in {'A'..'Z'}: + res.add toUpperAscii(result) + else: + res.add result + +proc format*(value: string; specifier: string; res: var string) = + ## Standard format implementation for ``string``. It makes little + ## sense to call this directly, but it is required to exist + ## by the ``fmt`` macro. + let spec = parseStandardFormatSpecifier(specifier) + var fmode = ffDefault + case spec.typ + of 's', '\0': discard + else: + raise newException(ValueError, + "invalid type in format string for string, expected 's', but got " & + spec.typ) + res.add alignString(value, spec.minimumWidth, spec.align, spec.fill) diff --git a/lib/pure/strscans.nim b/lib/pure/strscans.nim index a54556915..2bd87837f 100644 --- a/lib/pure/strscans.nim +++ b/lib/pure/strscans.nim @@ -31,7 +31,10 @@ As can be seen from the examples, strings are matched verbatim except for substrings starting with ``$``. These constructions are available: ================= ======================================================== -``$i`` Matches an integer. This uses ``parseutils.parseInt``. +``$b`` Matches a binary integer. This uses ``parseutils.parseBin``. +``$o`` Matches an octal integer. This uses ``parseutils.parseOct``. +``$i`` Matches a decimal integer. This uses ``parseutils.parseInt``. +``$h`` Matches a hex integer. This uses ``parseutils.parseHex``. ``$f`` Matches a floating pointer number. Uses ``parseFloat``. ``$w`` Matches an ASCII identifier: ``[A-Z-a-z_][A-Za-z_0-9]*``. ``$s`` Skips optional whitespace. @@ -330,19 +333,37 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b conds.add resLen.notZero conds.add resLen of 'w': - if i < results.len or getType(results[i]).typeKind != ntyString: + if i < results.len and getType(results[i]).typeKind == ntyString: matchBind "parseIdent" else: error("no string var given for $w") inc i + of 'b': + if i < results.len and getType(results[i]).typeKind == ntyInt: + matchBind "parseBin" + else: + error("no int var given for $b") + inc i + of 'o': + if i < results.len and getType(results[i]).typeKind == ntyInt: + matchBind "parseOct" + else: + error("no int var given for $o") + inc i of 'i': - if i < results.len or getType(results[i]).typeKind != ntyInt: + if i < results.len and getType(results[i]).typeKind == ntyInt: matchBind "parseInt" else: - error("no int var given for $d") + error("no int var given for $i") + inc i + of 'h': + if i < results.len and getType(results[i]).typeKind == ntyInt: + matchBind "parseHex" + else: + error("no int var given for $h") inc i of 'f': - if i < results.len or getType(results[i]).typeKind != ntyFloat: + if i < results.len and getType(results[i]).typeKind == ntyFloat: matchBind "parseFloat" else: error("no float var given for $f") @@ -357,7 +378,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b else: error("invalid format string") of '*', '+': - if i < results.len or getType(results[i]).typeKind != ntyString: + if i < results.len and getType(results[i]).typeKind == ntyString: var min = ord(pattern[p] == '+') var q=p+1 var token = "" @@ -441,7 +462,7 @@ template success*(x: int): bool = x != 0 template nxt*(input: string; idx, step: int = 1) = inc(idx, step) macro scanp*(input, idx: typed; pattern: varargs[untyped]): bool = - ## See top level documentation of his module of how ``scanp`` works. + ## ``scanp`` is currently undocumented. type StmtTriple = tuple[init, cond, action: NimNode] template interf(x): untyped = bindSym(x, brForceOpen) @@ -563,12 +584,12 @@ macro scanp*(input, idx: typed; pattern: varargs[untyped]): bool = of nnkCurlyExpr: if it.len == 3 and it[1].kind == nnkIntLit and it[2].kind == nnkIntLit: var h = newTree(nnkPar, it[0]) - for count in 2..it[1].intVal: h.add(it[0]) + for count in 2i64 .. it[1].intVal: h.add(it[0]) for count in it[1].intVal .. it[2].intVal-1: h.add(newTree(nnkPrefix, ident"?", it[0])) result = atm(h, input, idx, attached) elif it.len == 2 and it[1].kind == nnkIntLit: var h = newTree(nnkPar, it[0]) - for count in 2..it[1].intVal: h.add(it[0]) + for count in 2i64 .. it[1].intVal: h.add(it[0]) result = atm(h, input, idx, attached) else: error("invalid pattern") @@ -645,6 +666,14 @@ when isMainModule: doAssert intval == 89 doAssert floatVal == 33.25 + var binval: int + var octval: int + var hexval: int + doAssert scanf("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval) + doAssert binval == 0b0101 + doAssert octval == 0o1234 + doAssert hexval == 0xabcd + let xx = scanf("$abc", "$$$i", intval) doAssert xx == false diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index cc0f474f4..dbb4db781 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -32,10 +32,6 @@ when defined(nimOldSplit): else: {.pragma: deprecatedSplit.} -type - CharSet* {.deprecated.} = set[char] # for compatibility with Nim -{.deprecated: [TCharSet: CharSet].} - const Whitespace* = {' ', '\t', '\v', '\r', '\l', '\f'} ## All the characters that count as whitespace. @@ -78,40 +74,40 @@ proc isAlphaAscii*(c: char): bool {.noSideEffect, procvar, return c in Letters proc isAlphaNumeric*(c: char): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsAlphaNumericChar".}= + rtl, extern: "nsuIsAlphaNumericChar".} = ## Checks whether or not `c` is alphanumeric. ## ## This checks a-z, A-Z, 0-9 ASCII characters only. - return c in Letters or c in Digits + return c in Letters+Digits proc isDigit*(c: char): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsDigitChar".}= + rtl, extern: "nsuIsDigitChar".} = ## Checks whether or not `c` is a number. ## ## This checks 0-9 ASCII characters only. return c in Digits proc isSpaceAscii*(c: char): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsSpaceAsciiChar".}= + rtl, extern: "nsuIsSpaceAsciiChar".} = ## Checks whether or not `c` is a whitespace character. return c in Whitespace proc isLowerAscii*(c: char): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsLowerAsciiChar".}= + rtl, extern: "nsuIsLowerAsciiChar".} = ## Checks whether or not `c` is a lower case character. ## ## This checks ASCII characters only. return c in {'a'..'z'} proc isUpperAscii*(c: char): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsUpperAsciiChar".}= + rtl, extern: "nsuIsUpperAsciiChar".} = ## Checks whether or not `c` is an upper case character. ## ## This checks ASCII characters only. return c in {'A'..'Z'} proc isAlphaAscii*(s: string): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsAlphaAsciiStr".}= + rtl, extern: "nsuIsAlphaAsciiStr".} = ## Checks whether or not `s` is alphabetical. ## ## This checks a-z, A-Z ASCII characters only. @@ -123,10 +119,10 @@ proc isAlphaAscii*(s: string): bool {.noSideEffect, procvar, result = true for c in s: - result = c.isAlphaAscii() and result + if not c.isAlphaAscii(): return false proc isAlphaNumeric*(s: string): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsAlphaNumericStr".}= + rtl, extern: "nsuIsAlphaNumericStr".} = ## Checks whether or not `s` is alphanumeric. ## ## This checks a-z, A-Z, 0-9 ASCII characters only. @@ -138,10 +134,11 @@ proc isAlphaNumeric*(s: string): bool {.noSideEffect, procvar, result = true for c in s: - result = c.isAlphaNumeric() and result + if not c.isAlphaNumeric(): + return false proc isDigit*(s: string): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsDigitStr".}= + rtl, extern: "nsuIsDigitStr".} = ## Checks whether or not `s` is a numeric value. ## ## This checks 0-9 ASCII characters only. @@ -153,10 +150,11 @@ proc isDigit*(s: string): bool {.noSideEffect, procvar, result = true for c in s: - result = c.isDigit() and result + if not c.isDigit(): + return false proc isSpaceAscii*(s: string): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsSpaceAsciiStr".}= + rtl, extern: "nsuIsSpaceAsciiStr".} = ## Checks whether or not `s` is completely whitespace. ## ## Returns true if all characters in `s` are whitespace @@ -170,7 +168,7 @@ proc isSpaceAscii*(s: string): bool {.noSideEffect, procvar, return false proc isLowerAscii*(s: string): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsLowerAsciiStr".}= + rtl, extern: "nsuIsLowerAsciiStr".} = ## Checks whether or not `s` contains all lower case characters. ## ## This checks ASCII characters only. @@ -185,7 +183,7 @@ proc isLowerAscii*(s: string): bool {.noSideEffect, procvar, true proc isUpperAscii*(s: string): bool {.noSideEffect, procvar, - rtl, extern: "nsuIsUpperAsciiStr".}= + rtl, extern: "nsuIsUpperAsciiStr".} = ## Checks whether or not `s` contains all upper case characters. ## ## This checks ASCII characters only. @@ -504,16 +502,15 @@ template splitCommon(s, sep, maxsplit, sepLen) = var last = 0 var splits = maxsplit - if len(s) > 0: - while last <= len(s): - var first = last - while last < len(s) and not stringHasSep(s, last, sep): - inc(last) - if splits == 0: last = len(s) - yield substr(s, first, last-1) - if splits == 0: break - dec(splits) - inc(last, sepLen) + while last <= len(s): + var first = last + while last < len(s) and not stringHasSep(s, last, sep): + inc(last) + if splits == 0: last = len(s) + yield substr(s, first, last-1) + if splits == 0: break + dec(splits) + inc(last, sepLen) template oldSplit(s, seps, maxsplit) = var last = 0 @@ -576,15 +573,46 @@ iterator split*(s: string, seps: set[char] = Whitespace, else: splitCommon(s, seps, maxsplit, 1) -iterator splitWhitespace*(s: string): string = - ## Splits at whitespace. - oldSplit(s, Whitespace, -1) +iterator splitWhitespace*(s: string, maxsplit: int = -1): string = + ## Splits the string ``s`` at whitespace stripping leading and trailing + ## whitespace if necessary. If ``maxsplit`` is specified and is positive, + ## no more than ``maxsplit`` splits is made. + ## + ## The following code: + ## + ## .. code-block:: nim + ## let s = " foo \t bar baz " + ## for ms in [-1, 1, 2, 3]: + ## echo "------ maxsplit = ", ms, ":" + ## for item in s.splitWhitespace(maxsplit=ms): + ## echo '"', item, '"' + ## + ## ...results in: + ## + ## .. code-block:: + ## ------ maxsplit = -1: + ## "foo" + ## "bar" + ## "baz" + ## ------ maxsplit = 1: + ## "foo" + ## "bar baz " + ## ------ maxsplit = 2: + ## "foo" + ## "bar" + ## "baz " + ## ------ maxsplit = 3: + ## "foo" + ## "bar" + ## "baz" + ## + oldSplit(s, Whitespace, maxsplit) -proc splitWhitespace*(s: string): seq[string] {.noSideEffect, +proc splitWhitespace*(s: string, maxsplit: int = -1): seq[string] {.noSideEffect, rtl, extern: "nsuSplitWhitespace".} = - ## The same as the `splitWhitespace <#splitWhitespace.i,string>`_ + ## The same as the `splitWhitespace <#splitWhitespace.i,string,int>`_ ## iterator, but is a proc that returns a sequence of substrings. - accumulateResult(splitWhitespace(s)) + accumulateResult(splitWhitespace(s, maxsplit)) iterator split*(s: string, sep: char, maxsplit: int = -1): string = ## Splits the string `s` into substrings using a single separator. @@ -640,36 +668,35 @@ template rsplitCommon(s, sep, maxsplit, sepLen) = splits = maxsplit startPos = 0 - if len(s) > 0: - # go to -1 in order to get separators at the beginning - while first >= -1: - while first >= 0 and not stringHasSep(s, first, sep): - dec(first) + # go to -1 in order to get separators at the beginning + while first >= -1: + while first >= 0 and not stringHasSep(s, first, sep): + dec(first) - if splits == 0: - # No more splits means set first to the beginning - first = -1 + if splits == 0: + # No more splits means set first to the beginning + first = -1 - if first == -1: - startPos = 0 - else: - startPos = first + sepLen + if first == -1: + startPos = 0 + else: + startPos = first + sepLen - yield substr(s, startPos, last) + yield substr(s, startPos, last) - if splits == 0: - break + if splits == 0: + break - dec(splits) - dec(first) + dec(splits) + dec(first) - last = first + last = first iterator rsplit*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): string = ## Splits the string `s` into substrings from the right using a ## string separator. Works exactly the same as `split iterator - ## <#split.i,string,char>`_ except in reverse order. + ## <#split.i,string,char,int>`_ except in reverse order. ## ## .. code-block:: nim ## for piece in "foo bar".rsplit(WhiteSpace): @@ -689,7 +716,7 @@ iterator rsplit*(s: string, sep: char, maxsplit: int = -1): string = ## Splits the string `s` into substrings from the right using a ## string separator. Works exactly the same as `split iterator - ## <#split.i,string,char>`_ except in reverse order. + ## <#split.i,string,char,int>`_ except in reverse order. ## ## .. code-block:: nim ## for piece in "foo:bar".rsplit(':'): @@ -708,7 +735,7 @@ iterator rsplit*(s: string, sep: string, maxsplit: int = -1, keepSeparators: bool = false): string = ## Splits the string `s` into substrings from the right using a ## string separator. Works exactly the same as `split iterator - ## <#split.i,string,string>`_ except in reverse order. + ## <#split.i,string,string,int>`_ except in reverse order. ## ## .. code-block:: nim ## for piece in "foothebar".rsplit("the"): @@ -789,14 +816,20 @@ proc countLines*(s: string): int {.noSideEffect, proc split*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): seq[string] {. noSideEffect, rtl, extern: "nsuSplitCharSet".} = - ## The same as the `split iterator <#split.i,string,set[char]>`_, but is a + ## The same as the `split iterator <#split.i,string,set[char],int>`_, but is a ## proc that returns a sequence of substrings. + runnableExamples: + doAssert "a,b;c".split({',', ';'}) == @["a", "b", "c"] + doAssert "".split({' '}) == @[""] accumulateResult(split(s, seps, maxsplit)) proc split*(s: string, sep: char, maxsplit: int = -1): seq[string] {.noSideEffect, rtl, extern: "nsuSplitChar".} = - ## The same as the `split iterator <#split.i,string,char>`_, but is a proc + ## The same as the `split iterator <#split.i,string,char,int>`_, but is a proc ## that returns a sequence of substrings. + runnableExamples: + doAssert "a,b,c".split(',') == @["a", "b", "c"] + doAssert "".split(' ') == @[""] accumulateResult(split(s, sep, maxsplit)) proc split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEffect, @@ -804,7 +837,14 @@ proc split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEff ## Splits the string `s` into substrings using a string separator. ## ## Substrings are separated by the string `sep`. This is a wrapper around the - ## `split iterator <#split.i,string,string>`_. + ## `split iterator <#split.i,string,string,int>`_. + runnableExamples: + doAssert "a,b,c".split(",") == @["a", "b", "c"] + doAssert "a man a plan a canal panama".split("a ") == @["", "man ", "plan ", "canal panama"] + doAssert "".split("Elon Musk") == @[""] + doAssert "a largely spaced sentence".split(" ") == @["a", "", "largely", "", "", "", "spaced", "sentence"] + + doAssert "a largely spaced sentence".split(" ", maxsplit=1) == @["a", " largely spaced sentence"] doAssert(sep.len > 0) accumulateResult(split(s, sep, maxsplit)) @@ -812,7 +852,7 @@ proc split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEff proc rsplit*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): seq[string] {.noSideEffect, rtl, extern: "nsuRSplitCharSet".} = - ## The same as the `rsplit iterator <#rsplit.i,string,set[char]>`_, but is a + ## The same as the `rsplit iterator <#rsplit.i,string,set[char],int>`_, but is a ## proc that returns a sequence of substrings. ## ## A possible common use case for `rsplit` is path manipulation, @@ -834,7 +874,7 @@ proc rsplit*(s: string, seps: set[char] = Whitespace, proc rsplit*(s: string, sep: char, maxsplit: int = -1): seq[string] {.noSideEffect, rtl, extern: "nsuRSplitChar".} = - ## The same as the `split iterator <#rsplit.i,string,char>`_, but is a proc + ## The same as the `rsplit iterator <#rsplit.i,string,char,int>`_, but is a proc ## that returns a sequence of substrings. ## ## A possible common use case for `rsplit` is path manipulation, @@ -856,7 +896,7 @@ proc rsplit*(s: string, sep: char, maxsplit: int = -1): seq[string] proc rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEffect, rtl, extern: "nsuRSplitString".} = - ## The same as the `split iterator <#rsplit.i,string,string>`_, but is a proc + ## The same as the `rsplit iterator <#rsplit.i,string,string,int>`_, but is a proc ## that returns a sequence of substrings. ## ## A possible common use case for `rsplit` is path manipulation, @@ -873,6 +913,13 @@ proc rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string] ## .. code-block:: nim ## @["Root#Object#Method", "Index"] ## + runnableExamples: + doAssert "a largely spaced sentence".rsplit(" ", maxsplit=1) == @["a largely spaced", "sentence"] + + doAssert "a,b,c".rsplit(",") == @["a", "b", "c"] + doAssert "a man a plan a canal panama".rsplit("a ") == @["", "man ", "plan ", "canal panama"] + doAssert "".rsplit("Elon Musk") == @[""] + doAssert "a largely spaced sentence".rsplit(" ") == @["a", "", "largely", "", "", "", "spaced", "sentence"] accumulateResult(rsplit(s, sep, maxsplit)) result.reverse() @@ -1062,8 +1109,8 @@ proc align*(s: string, count: Natural, padding = ' '): string {. ## ## `padding` characters (by default spaces) are added before `s` resulting in ## right alignment. If ``s.len >= count``, no spaces are added and `s` is - ## returned unchanged. If you need to left align a string use the `repeatChar - ## proc <#repeatChar>`_. Example: + ## returned unchanged. If you need to left align a string use the `alignLeft + ## proc <#alignLeft>`_. Example: ## ## .. code-block:: nim ## assert align("abc", 4) == " abc" @@ -1078,6 +1125,28 @@ proc align*(s: string, count: Natural, padding = ' '): string {. else: result = s +proc alignLeft*(s: string, count: Natural, padding = ' '): string {.noSideEffect.} = + ## Left-Aligns a string `s` with `padding`, so that it is of length `count`. + ## + ## `padding` characters (by default spaces) are added after `s` resulting in + ## left alignment. If ``s.len >= count``, no spaces are added and `s` is + ## returned unchanged. If you need to right align a string use the `align + ## proc <#align>`_. Example: + ## + ## .. code-block:: nim + ## assert alignLeft("abc", 4) == "abc " + ## assert alignLeft("a", 0) == "a" + ## assert alignLeft("1232", 6) == "1232 " + ## assert alignLeft("1232", 6, '#') == "1232##" + if s.len < count: + result = newString(count) + if s.len > 0: + result[0 .. (s.len - 1)] = s + for i in s.len ..< count: + result[i] = padding + else: + result = s + iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ token: string, isSep: bool] = ## Tokenizes the string `s` into substrings. @@ -1175,7 +1244,7 @@ proc unindent*(s: string, count: Natural, padding: string = " "): string var indentCount = 0 for j in 0..<count.int: indentCount.inc - if line[j .. j + <padding.len] != padding: + if line[j .. j + padding.len-1] != padding: indentCount = j break result.add(line[indentCount*padding.len .. ^1]) @@ -1250,14 +1319,13 @@ proc addSep*(dest: var string, sep = ", ", startLen: Natural = 0) ## This is often useful for generating some code where the items need to ## be *separated* by `sep`. `sep` is only added if `dest` is longer than ## `startLen`. The following example creates a string describing - ## an array of integers: - ## - ## .. code-block:: nim - ## var arr = "[" - ## for x in items([2, 3, 5, 7, 11]): - ## addSep(arr, startLen=len("[")) - ## add(arr, $x) - ## add(arr, "]") + ## an array of integers. + runnableExamples: + var arr = "[" + for x in items([2, 3, 5, 7, 11]): + addSep(arr, startLen=len("[")) + add(arr, $x) + add(arr, "]") if dest.len > startLen: add(dest, sep) proc allCharsInSet*(s: string, theSet: set[char]): bool = @@ -1306,18 +1374,36 @@ proc join*[T: not string](a: openArray[T], sep: string = ""): string {. add(result, $x) type - SkipTable = array[char, int] - -{.push profiler: off.} -proc preprocessSub(sub: string, a: var SkipTable) = - var m = len(sub) - for i in 0..0xff: a[chr(i)] = m+1 - for i in 0..m-1: a[sub[i]] = m-i -{.pop.} + SkipTable* = array[char, int] -proc findAux(s, sub: string, start, last: int, a: SkipTable): int = - # Fast "quick search" algorithm: - var +proc initSkipTable*(a: var SkipTable, sub: string) + {.noSideEffect, rtl, extern: "nsuInitSkipTable".} = + ## Preprocess table `a` for `sub`. + let m = len(sub) + let m1 = m + 1 + var i = 0 + while i <= 0xff-7: + a[chr(i + 0)] = m1 + a[chr(i + 1)] = m1 + a[chr(i + 2)] = m1 + a[chr(i + 3)] = m1 + a[chr(i + 4)] = m1 + a[chr(i + 5)] = m1 + a[chr(i + 6)] = m1 + a[chr(i + 7)] = m1 + i += 8 + + for i in 0..m-1: + a[sub[i]] = m-i + +proc find*(a: SkipTable, s, sub: string, start: Natural = 0, last: Natural = 0): int + {.noSideEffect, rtl, extern: "nsuFindStrA".} = + ## Searches for `sub` in `s` inside range `start`..`last` using preprocessed table `a`. + ## If `last` is unspecified, it defaults to `s.high`. + ## + ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. + let + last = if last==0: s.high else: last m = len(sub) n = last + 1 # search: @@ -1337,17 +1423,6 @@ when not (defined(js) or defined(nimdoc) or defined(nimscript)): else: const hasCStringBuiltin = false -proc find*(s, sub: string, start: Natural = 0, last: Natural = 0): int {.noSideEffect, - rtl, extern: "nsuFindStr".} = - ## Searches for `sub` in `s` inside range `start`..`last`. - ## If `last` is unspecified, it defaults to `s.high`. - ## - ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. - var a {.noinit.}: SkipTable - let last = if last==0: s.high else: last - preprocessSub(sub, a) - result = findAux(s, sub, start, last, a) - proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.noSideEffect, rtl, extern: "nsuFindChar".} = ## Searches for `sub` in `s` inside range `start`..`last`. @@ -1366,9 +1441,24 @@ proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.n else: for i in start..last: if sub == s[i]: return i - return -1 +proc find*(s, sub: string, start: Natural = 0, last: Natural = 0): int {.noSideEffect, + rtl, extern: "nsuFindStr".} = + ## Searches for `sub` in `s` inside range `start`..`last`. + ## If `last` is unspecified, it defaults to `s.high`. + ## + ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. + if sub.len > s.len: + return -1 + + if sub.len == 1: + return find(s, sub[0], start, last) + + var a {.noinit.}: SkipTable + initSkipTable(a, sub) + result = find(a, s, sub, start, last) + proc find*(s: string, chars: set[char], start: Natural = 0, last: Natural = 0): int {.noSideEffect, rtl, extern: "nsuFindCharSet".} = ## Searches for `chars` in `s` inside range `start`..`last`. @@ -1500,11 +1590,11 @@ proc replace*(s, sub: string, by = ""): string {.noSideEffect, ## Replaces `sub` in `s` by the string `by`. var a {.noinit.}: SkipTable result = "" - preprocessSub(sub, a) + initSkipTable(a, sub) let last = s.high var i = 0 while true: - var j = findAux(s, sub, i, last, a) + var j = find(a, s, sub, i, last) if j < 0: break add result, substr(s, i, j - 1) add result, by @@ -1534,11 +1624,11 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} var a {.noinit.}: SkipTable result = "" - preprocessSub(sub, a) + initSkipTable(a, sub) var i = 0 let last = s.high while true: - var j = findAux(s, sub, i, last, a) + var j = find(a, s, sub, i, last) if j < 0: break # word boundary? if (j == 0 or s[j-1] notin wordChars) and @@ -1653,7 +1743,9 @@ proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect, ## ## Even though the algorithm works with any string `s`, it is only useful ## if `s` contains a number. - ## Example: ``insertSep("1000000") == "1_000_000"`` + runnableExamples: + doAssert insertSep("1000000") == "1_000_000" + var L = (s.len-1) div digits + s.len result = newString(L) var j = 0 @@ -1669,29 +1761,15 @@ proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect, proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, rtl, extern: "nsuEscape".} = - ## Escapes a string `s`. - ## - ## This does these operations (at the same time): - ## * replaces any ``\`` by ``\\`` - ## * replaces any ``'`` by ``\'`` - ## * replaces any ``"`` by ``\"`` - ## * replaces any other character in the set ``{'\0'..'\31', '\127'..'\255'}`` - ## by ``\xHH`` where ``HH`` is its hexadecimal value. - ## The procedure has been designed so that its output is usable for many - ## different common syntaxes. The resulting string is prefixed with - ## `prefix` and suffixed with `suffix`. Both may be empty strings. - ## **Note**: This is not correct for producing Ansi C code! + ## Escapes a string `s`. See `system.addEscapedChar <system.html#addEscapedChar>`_ + ## for the escaping scheme. + ## + ## The resulting string is prefixed with `prefix` and suffixed with `suffix`. + ## Both may be empty strings. result = newStringOfCap(s.len + s.len shr 2) result.add(prefix) for c in items(s): - case c - of '\0'..'\31', '\127'..'\255': - add(result, "\\x") - add(result, toHex(ord(c), 2)) - of '\\': add(result, "\\\\") - of '\'': add(result, "\\'") - of '\"': add(result, "\\\"") - else: add(result, c) + result.addEscapedChar(c) add(result, suffix) proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, @@ -1741,6 +1819,8 @@ proc validIdentifier*(s: string): bool {.noSideEffect, ## ## A valid identifier starts with a character of the set `IdentStartChars` ## and is followed by any number of characters of the set `IdentChars`. + runnableExamples: + doAssert "abc_def08".validIdentifier if s[0] in IdentStartChars: for i in 1..s.len-1: if s[i] notin IdentChars: return false @@ -1751,7 +1831,7 @@ proc editDistance*(a, b: string): int {.noSideEffect, ## Returns the edit distance between `a` and `b`. ## ## This uses the `Levenshtein`:idx: distance algorithm with only a linear - ## memory overhead. This implementation is highly optimized! + ## memory overhead. var len1 = a.len var len2 = b.len if len1 > len2: @@ -1850,7 +1930,7 @@ type {.deprecated: [TFloatFormat: FloatFormatMode].} proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, - precision: range[0..32] = 16; + precision: range[-1..32] = 16; decimalSep = '.'): string {. noSideEffect, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. @@ -1862,7 +1942,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, ## `precision`'s default value is the maximum number of meaningful digits ## after the decimal point for Nim's ``biggestFloat`` type. ## - ## If ``precision == 0``, it tries to format it nicely. + ## If ``precision == -1``, it tries to format it nicely. when defined(js): var res: cstring case format @@ -1884,7 +1964,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, buf {.noinit.}: array[0..2500, char] L: cint frmtstr[0] = '%' - if precision > 0: + if precision >= 0: frmtstr[1] = '#' frmtstr[2] = '.' frmtstr[3] = '*' @@ -1907,9 +1987,18 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, # but nothing else is possible: if buf[i] in {'.', ','}: result[i] = decimalsep else: result[i] = buf[i] + when defined(windows): + # VS pre 2015 violates the C standard: "The exponent always contains at + # least two digits, and only as many more digits as necessary to + # represent the exponent." [C11 §7.21.6.1] + # The following post-processing fixes this behavior. + if result.len > 4 and result[^4] == '+' and result[^3] == '0': + result[^3] = result[^2] + result[^2] = result[^1] + result.setLen(result.len - 1) proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, - precision: range[0..32] = 16; decimalSep = '.'): string {. + precision: range[-1..32] = 16; decimalSep = '.'): string {. noSideEffect, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. ## @@ -1920,7 +2009,12 @@ proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, ## `precision`'s default value is the maximum number of meaningful digits ## after the decimal point for Nim's ``float`` type. ## - ## If ``precision == 0``, it tries to format it nicely. + ## If ``precision == -1``, it tries to format it nicely. + runnableExamples: + let x = 123.456 + doAssert x.formatFloat() == "123.4560000000000" + doAssert x.formatFloat(ffDecimal, 4) == "123.4560" + doAssert x.formatFloat(ffScientific, 2) == "1.23e+02" result = formatBiggestFloat(f, format, precision, decimalSep) proc trimZeros*(x: var string) {.noSideEffect.} = @@ -1955,18 +2049,13 @@ proc formatSize*(bytes: int64, ## ## `includeSpace` can be set to true to include the (SI preferred) space ## between the number and the unit (e.g. 1 KiB). - ## - ## Examples: - ## - ## .. code-block:: nim - ## - ## formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" - ## formatSize((2.234*1024*1024).int) == "2.234MiB" - ## formatSize(4096, includeSpace=true) == "4 KiB" - ## formatSize(4096, prefix=bpColloquial, includeSpace=true) == "4 kB" - ## formatSize(4096) == "4KiB" - ## formatSize(5_378_934, prefix=bpColloquial, decimalSep=',') == "5,13MB" - ## + runnableExamples: + doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" + doAssert formatSize((2.234*1024*1024).int) == "2.234MiB" + doAssert formatSize(4096, includeSpace=true) == "4 KiB" + doAssert formatSize(4096, prefix=bpColloquial, includeSpace=true) == "4 kB" + doAssert formatSize(4096) == "4KiB" + doAssert formatSize(5_378_934, prefix=bpColloquial, decimalSep=',') == "5,13MB" const iecPrefixes = ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"] const collPrefixes = ["", "k", "M", "G", "T", "P", "E", "Z", "Y"] var @@ -2060,7 +2149,7 @@ proc formatEng*(f: BiggestFloat, ## formatEng(4100, unit="V") == "4.1e3 V" ## formatEng(4100, unit="") == "4.1e3 " # Space with unit="" ## - ## `decimalSep` is used as the decimal separator + ## `decimalSep` is used as the decimal separator. var absolute: BiggestFloat significand: BiggestFloat @@ -2271,69 +2360,116 @@ proc format*(formatstr: string, a: varargs[string, `$`]): string {.noSideEffect, proc removeSuffix*(s: var string, chars: set[char] = Newlines) {. rtl, extern: "nsuRemoveSuffixCharSet".} = - ## Removes the first matching character from the string (in-place) given a - ## set of characters. If the set of characters is only equal to `Newlines` - ## then it will remove both the newline and return feed. - ## .. code-block:: nim - ## var - ## userInput = "Hello World!\r\n" - ## otherInput = "Hello!?!" - ## userInput.removeSuffix - ## userInput == "Hello World!" - ## userInput.removeSuffix({'!', '?'}) - ## userInput == "Hello World" - ## otherInput.removeSuffix({'!', '?'}) - ## otherInput == "Hello!?" + ## Removes all characters from `chars` from the end of the string `s` + ## (in-place). + runnableExamples: + var userInput = "Hello World!*~\r\n" + userInput.removeSuffix + doAssert userInput == "Hello World!*~" + userInput.removeSuffix({'~', '*'}) + doAssert userInput == "Hello World!" + + var otherInput = "Hello!?!" + otherInput.removeSuffix({'!', '?'}) + doAssert otherInput == "Hello" if s.len == 0: return - var last = len(s) - 1 - if chars == Newlines: - if s[last] == '\10': - last -= 1 - if s[last] == '\13': - last -= 1 - else: - if s[last] in chars: - last -= 1 + var last = s.high + while last > -1 and s[last] in chars: last -= 1 s.setLen(last + 1) proc removeSuffix*(s: var string, c: char) {. rtl, extern: "nsuRemoveSuffixChar".} = - ## Removes a single character (in-place) from a string. - ## .. code-block:: nim - ## var - ## table = "users" - ## table.removeSuffix('s') - ## table == "user" + ## Removes all occurrences of a single character (in-place) from the end + ## of a string. + ## + runnableExamples: + var table = "users" + table.removeSuffix('s') + doAssert table == "user" + + var dots = "Trailing dots......." + dots.removeSuffix('.') + doAssert dots == "Trailing dots" removeSuffix(s, chars = {c}) proc removeSuffix*(s: var string, suffix: string) {. rtl, extern: "nsuRemoveSuffixString".} = ## Remove the first matching suffix (in-place) from a string. - ## .. code-block:: nim - ## var - ## answers = "yeses" - ## answers.removeSuffix("es") - ## answers == "yes" + runnableExamples: + var answers = "yeses" + answers.removeSuffix("es") + doAssert answers == "yes" var newLen = s.len if s.endsWith(suffix): newLen -= len(suffix) s.setLen(newLen) +proc removePrefix*(s: var string, chars: set[char] = Newlines) {. + rtl, extern: "nsuRemovePrefixCharSet".} = + ## Removes all characters from `chars` from the start of the string `s` + ## (in-place). + ## + runnableExamples: + var userInput = "\r\n*~Hello World!" + userInput.removePrefix + doAssert userInput == "*~Hello World!" + userInput.removePrefix({'~', '*'}) + doAssert userInput == "Hello World!" + + var otherInput = "?!?Hello!?!" + otherInput.removePrefix({'!', '?'}) + doAssert otherInput == "Hello!?!" + var start = 0 + while start < s.len and s[start] in chars: start += 1 + if start > 0: s.delete(0, start - 1) + +proc removePrefix*(s: var string, c: char) {. + rtl, extern: "nsuRemovePrefixChar".} = + ## Removes all occurrences of a single character (in-place) from the start + ## of a string. + ## + runnableExamples: + var ident = "pControl" + ident.removePrefix('p') + doAssert ident == "Control" + removePrefix(s, chars = {c}) + +proc removePrefix*(s: var string, prefix: string) {. + rtl, extern: "nsuRemovePrefixString".} = + ## Remove the first matching prefix (in-place) from a string. + ## + runnableExamples: + var answers = "yesyes" + answers.removePrefix("yes") + doAssert answers == "yes" + if s.startsWith(prefix): + s.delete(0, prefix.len - 1) + when isMainModule: doAssert align("abc", 4) == " abc" doAssert align("a", 0) == "a" doAssert align("1232", 6) == " 1232" doAssert align("1232", 6, '#') == "##1232" + doAssert alignLeft("abc", 4) == "abc " + doAssert alignLeft("a", 0) == "a" + doAssert alignLeft("1232", 6) == "1232 " + doAssert alignLeft("1232", 6, '#') == "1232##" + let inp = """ this is a long text -- muchlongerthan10chars and here it goes""" outp = " this is a\nlong text\n--\nmuchlongerthan10chars\nand here\nit goes" doAssert wordWrap(inp, 10, false) == outp + doAssert formatBiggestFloat(1234.567, ffDecimal, -1) == "1234.567000" + doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235." + doAssert formatBiggestFloat(1234.567, ffDecimal, 1) == "1234.6" doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in ["1,0e-11", "1,0e-011"] + # bug #6589 + doAssert formatFloat(123.456, ffScientific, precision = -1) == "1.234560e+02" doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c" doAssert "${1}12 ${-1}$2" % ["a", "b"] == "a12 bb" @@ -2497,6 +2633,12 @@ bar doAssert s.split(' ', maxsplit=1) == @["", "this is an example "] doAssert s.split(" ", maxsplit=4) == @["", "this", "is", "an", "example "] + doAssert s.splitWhitespace() == @["this", "is", "an", "example"] + doAssert s.splitWhitespace(maxsplit=1) == @["this", "is an example "] + doAssert s.splitWhitespace(maxsplit=2) == @["this", "is", "an example "] + doAssert s.splitWhitespace(maxsplit=3) == @["this", "is", "an", "example "] + doAssert s.splitWhitespace(maxsplit=4) == @["this", "is", "an", "example"] + block: # formatEng tests doAssert formatEng(0, 2, trim=false) == "0.00" doAssert formatEng(0, 2) == "0" diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 871ac5d39..f15cee66a 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -391,8 +391,8 @@ proc eraseLine*(f: File) = origin.X = 0'i16 if setConsoleCursorPosition(h, origin) == 0: raiseOSError(osLastError()) - var ht = scrbuf.dwSize.Y - origin.Y - var wt = scrbuf.dwSize.X - origin.X + var ht: DWORD = scrbuf.dwSize.Y - origin.Y + var wt: DWORD = scrbuf.dwSize.X - origin.X if fillConsoleOutputCharacter(h, ' ', ht*wt, origin, addr(numwrote)) == 0: raiseOSError(osLastError()) @@ -634,7 +634,10 @@ proc getch*(): char = doAssert(readConsoleInput(fd, addr(keyEvent), 1, addr(numRead)) != 0) if numRead == 0 or keyEvent.eventType != 1 or keyEvent.bKeyDown == 0: continue - return char(keyEvent.uChar) + if keyEvent.uChar == 0: + return char(keyEvent.wVirtualKeyCode) + else: + return char(keyEvent.uChar) else: let fd = getFileHandle(stdin) var oldMode: Termios @@ -650,10 +653,10 @@ template setCursorPos*(x, y: int) = setCursorPos(stdout, x, y) template setCursorXPos*(x: int) = setCursorXPos(stdout, x) when defined(windows): template setCursorYPos(x: int) = setCursorYPos(stdout, x) -template cursorUp*(count=1) = cursorUp(stdout, f) -template cursorDown*(count=1) = cursorDown(stdout, f) -template cursorForward*(count=1) = cursorForward(stdout, f) -template cursorBackward*(count=1) = cursorBackward(stdout, f) +template cursorUp*(count=1) = cursorUp(stdout, count) +template cursorDown*(count=1) = cursorDown(stdout, count) +template cursorForward*(count=1) = cursorForward(stdout, count) +template cursorBackward*(count=1) = cursorBackward(stdout, count) template eraseLine*() = eraseLine(stdout) template eraseScreen*() = eraseScreen(stdout) template setStyle*(style: set[Style]) = diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 96668c4f8..42e89e7ce 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -10,27 +10,25 @@ ## This module contains routines and types for dealing with time. ## This module is available for the `JavaScript target -## <backends.html#the-javascript-target>`_. +## <backends.html#the-javascript-target>`_. The proleptic Gregorian calendar is the only calendar supported. ## ## Examples: ## ## .. code-block:: nim ## ## import times, os -## var -## t = cpuTime() +## let time = cpuTime() ## ## sleep(100) # replace this with something to be timed -## echo "Time taken: ",cpuTime() - t +## echo "Time taken: ",cpuTime() - time ## -## echo "My formatted time: ", format(getLocalTime(getTime()), "d MMMM yyyy HH:mm") +## echo "My formatted time: ", format(now(), "d MMMM yyyy HH:mm") ## echo "Using predefined formats: ", getClockStr(), " ", getDateStr() ## ## echo "epochTime() float value: ", epochTime() -## echo "getTime() float value: ", toSeconds(getTime()) ## echo "cpuTime() float value: ", cpuTime() -## echo "An hour from now : ", getLocalTime(getTime()) + 1.hours -## echo "An hour from (UTC) now: ", getGmTime(getTime()) + initInterval(0,0,0,1) +## echo "An hour from now : ", now() + 1.hours +## echo "An hour from (UTC) now: ", getTime().utc + initInterval(0,0,0,1) {.push debugger:off.} # the user does not want to trace a part # of the standard library! @@ -40,132 +38,85 @@ import include "system/inclrtl" -type - Month* = enum ## represents a month - mJan, mFeb, mMar, mApr, mMay, mJun, mJul, mAug, mSep, mOct, mNov, mDec - WeekDay* = enum ## represents a weekday - dMon, dTue, dWed, dThu, dFri, dSat, dSun - -when defined(posix) and not defined(JS): - when defined(linux) and defined(amd64): - type - TimeImpl {.importc: "time_t", header: "<time.h>".} = clong - Time* = distinct TimeImpl ## distinct type that represents a time - ## measured as number of seconds since the epoch - - Timeval {.importc: "struct timeval", - header: "<sys/select.h>".} = object ## struct timeval - tv_sec: clong ## Seconds. - tv_usec: clong ## Microseconds. - else: - type - TimeImpl {.importc: "time_t", header: "<time.h>".} = int - Time* = distinct TimeImpl ## distinct type that represents a time - ## measured as number of seconds since the epoch - - Timeval {.importc: "struct timeval", - header: "<sys/select.h>".} = object ## struct timeval - tv_sec: int ## Seconds. - tv_usec: int ## Microseconds. +when defined(posix): + import posix - # we cannot import posix.nim here, because posix.nim depends on times.nim. - # Ok, we could, but I don't want circular dependencies. - # And gettimeofday() is not defined in the posix module anyway. Sigh. + type CTime = posix.Time proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {. importc: "gettimeofday", header: "<sys/time.h>".} when not defined(freebsd) and not defined(netbsd) and not defined(openbsd): var timezone {.importc, header: "<time.h>".}: int - proc tzset(): void {.importc, header: "<time.h>".} tzset() elif defined(windows): import winlean # newest version of Visual C++ defines time_t to be of 64 bits - type TimeImpl {.importc: "time_t", header: "<time.h>".} = int64 + type CTime {.importc: "time_t", header: "<time.h>".} = distinct int64 # visual c's c runtime exposes these under a different name - var - timezone {.importc: "_timezone", header: "<time.h>".}: int - - type - Time* = distinct TimeImpl + var timezone {.importc: "_timezone", header: "<time.h>".}: int +type + Month* = enum ## Represents a month. Note that the enum starts at ``1``, so ``ord(month)`` will give + ## the month number in the range ``[1..12]``. + mJan = 1, mFeb, mMar, mApr, mMay, mJun, mJul, mAug, mSep, mOct, mNov, mDec -elif defined(JS): - type - TimeBase = float - Time* = distinct TimeBase - - proc getDay(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getFullYear(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getHours(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getMilliseconds(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getMinutes(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getMonth(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getSeconds(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getTime(t: Time): int {.tags: [], raises: [], noSideEffect, benign, importcpp.} - proc getTimezoneOffset(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getDate(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getUTCDate(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getUTCFullYear(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getUTCHours(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getUTCMilliseconds(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getUTCMinutes(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getUTCMonth(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getUTCSeconds(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getUTCDay(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc getYear(t: Time): int {.tags: [], raises: [], benign, importcpp.} - proc parse(t: Time; s: cstring): Time {.tags: [], raises: [], benign, importcpp.} - proc setDate(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setFullYear(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setHours(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setMilliseconds(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setMinutes(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setMonth(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setSeconds(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setTime(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setUTCDate(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setUTCFullYear(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setUTCHours(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setUTCMilliseconds(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setUTCMinutes(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setUTCMonth(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setUTCSeconds(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc setYear(t: Time; x: int) {.tags: [], raises: [], benign, importcpp.} - proc toGMTString(t: Time): cstring {.tags: [], raises: [], benign, importcpp.} - proc toLocaleString(t: Time): cstring {.tags: [], raises: [], benign, importcpp.} + WeekDay* = enum ## Represents a weekday. + dMon, dTue, dWed, dThu, dFri, dSat, dSun -type - TimeInfo* = object of RootObj ## represents a time in different parts - second*: range[0..61] ## The number of seconds after the minute, + MonthdayRange* = range[1..31] + HourRange* = range[0..23] + MinuteRange* = range[0..59] + SecondRange* = range[0..60] + YeardayRange* = range[0..365] + + TimeImpl = int64 + + Time* = distinct TimeImpl ## Represents a point in time. + ## This is currently implemented as a ``int64`` representing + ## seconds since ``1970-01-01T00:00:00Z``, but don't + ## rely on this knowledge because it might change + ## in the future to allow for higher precision. + ## Use the procs ``toUnix`` and ``fromUnix`` to + ## work with unix timestamps instead. + + DateTime* = object of RootObj ## Represents a time in different parts. + ## Although this type can represent leap + ## seconds, they are generally not supported + ## in this module. They are not ignored, + ## but the ``DateTime``'s returned by + ## procedures in this module will never have + ## a leap second. + second*: SecondRange ## The number of seconds after the minute, ## normally in the range 0 to 59, but can - ## be up to 61 to allow for leap seconds. - minute*: range[0..59] ## The number of minutes after the hour, + ## be up to 60 to allow for a leap second. + minute*: MinuteRange ## The number of minutes after the hour, ## in the range 0 to 59. - hour*: range[0..23] ## The number of hours past midnight, + hour*: HourRange ## The number of hours past midnight, ## in the range 0 to 23. - monthday*: range[1..31] ## The day of the month, in the range 1 to 31. + monthday*: MonthdayRange ## The day of the month, in the range 1 to 31. month*: Month ## The current month. - year*: int ## The current year. + year*: int ## The current year, using astronomical year numbering + ## (meaning that before year 1 is year 0, then year -1 and so on). weekday*: WeekDay ## The current day of the week. - yearday*: range[0..365] ## The number of days since January 1, + yearday*: YeardayRange ## The number of days since January 1, ## in the range 0 to 365. - ## Always 0 if the target is JS. - isDST*: bool ## Determines whether DST is in effect. - ## Semantically, this adds another negative hour - ## offset to the time in addition to the timezone. - timezone*: int ## The offset of the (non-DST) timezone in seconds - ## west of UTC. Note that the sign of this number - ## is the opposite of the one in a formatted - ## timezone string like ``+01:00`` (which would be - ## parsed into the timezone ``-3600``). - - ## I make some assumptions about the data in here. Either - ## everything should be positive or everything negative. Zero is - ## fine too. Mixed signs will lead to unexpected results. - TimeInterval* = object ## a time interval + isDst*: bool ## Determines whether DST is in effect. + ## Always false for the JavaScript backend. + timezone*: Timezone ## The timezone represented as an implementation of ``Timezone``. + utcOffset*: int ## The offset in seconds west of UTC, including any offset due to DST. + ## Note that the sign of this number is the opposite + ## of the one in a formatted offset string like ``+01:00`` + ## (which would be parsed into the UTC offset ``-3600``). + + TimeInterval* = object ## Represents a duration of time. Can be used to add and subtract + ## from a ``DateTime`` or ``Time``. + ## Note that a ``TimeInterval`` doesn't represent a fixed duration of time, + ## since the duration of some units depend on the context (e.g a year + ## can be either 365 or 366 days long). The non-fixed time units are years, + ## months and days. milliseconds*: int ## The number of milliseconds seconds*: int ## The number of seconds minutes*: int ## The number of minutes @@ -174,92 +125,394 @@ type months*: int ## The number of months years*: int ## The number of years + Timezone* = object ## Timezone interface for supporting ``DateTime``'s of arbritary timezones. + ## The ``times`` module only supplies implementations for the systems local time and UTC. + ## The members ``zoneInfoFromUtc`` and ``zoneInfoFromTz`` should not be accessed directly + ## and are only exported so that ``Timezone`` can be implemented by other modules. + zoneInfoFromUtc*: proc (time: Time): ZonedTime {.nimcall, tags: [], raises: [], benign .} + zoneInfoFromTz*: proc (adjTime: Time): ZonedTime {.nimcall, tags: [], raises: [], benign .} + name*: string ## The name of the timezone, f.ex 'Europe/Stockholm' or 'Etc/UTC'. Used for checking equality. + ## Se also: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + ZonedTime* = object ## Represents a zooned instant in time that is not associated with any calendar. + ## This type is only used for implementing timezones. + adjTime*: Time ## Time adjusted to a timezone. + utcOffset*: int + isDst*: bool + {.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time, - TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].} + TTimeInterval: TimeInterval, TTimeInfo: DateTime, TimeInfo: DateTime].} -proc getTime*(): Time {.tags: [TimeEffect], benign.} - ## gets the current calendar time as a UNIX epoch value (number of seconds - ## elapsed since 1970) with integer precission. Use epochTime for higher - ## resolution. -proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], benign.} - ## converts the calendar time `t` to broken-time representation, - ## expressed relative to the user's specified time zone. -proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], benign.} - ## converts the calendar time `t` to broken-down time representation, - ## expressed in Coordinated Universal Time (UTC). - -proc timeInfoToTime*(timeInfo: TimeInfo): Time - {.tags: [TimeEffect], benign, deprecated.} - ## converts a broken-down time structure to - ## calendar time representation. The function ignores the specified - ## contents of the structure members `weekday` and `yearday` and recomputes - ## them from the other information in the broken-down time structure. - ## - ## **Warning:** This procedure is deprecated since version 0.14.0. - ## Use ``toTime`` instead. +const + secondsInMin = 60 + secondsInHour = 60*60 + secondsInDay = 60*60*24 + minutesInHour = 60 -proc toTime*(timeInfo: TimeInfo): Time {.tags: [TimeEffect], benign.} - ## converts a broken-down time structure to - ## calendar time representation. The function ignores the specified - ## contents of the structure members `weekday` and `yearday` and recomputes - ## them from the other information in the broken-down time structure. +proc fromUnix*(unix: int64): Time {.benign, tags: [], raises: [], noSideEffect.} = + ## Convert a unix timestamp (seconds since ``1970-01-01T00:00:00Z``) to a ``Time``. + Time(unix) -proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], benign.} - ## Takes a float which contains the number of seconds since the unix epoch and - ## returns a time object. +proc toUnix*(t: Time): int64 {.benign, tags: [], raises: [], noSideEffect.} = + ## Convert ``t`` to a unix timestamp (seconds since ``1970-01-01T00:00:00Z``). + t.int64 -proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign.} = - ## Takes an int which contains the number of seconds since the unix epoch and - ## returns a time object. - fromSeconds(float(since1970)) +proc isLeapYear*(year: int): bool = + ## Returns true if ``year`` is a leap year. + year mod 4 == 0 and (year mod 100 != 0 or year mod 400 == 0) -proc toSeconds*(time: Time): float {.tags: [], raises: [], benign.} - ## Returns the time in seconds since the unix epoch. +proc getDaysInMonth*(month: Month, year: int): int = + ## Get the number of days in a ``month`` of a ``year``. + # http://www.dispersiondesign.com/articles/time/number_of_days_in_a_month + case month + of mFeb: result = if isLeapYear(year): 29 else: 28 + of mApr, mJun, mSep, mNov: result = 30 + else: result = 31 + +proc getDaysInYear*(year: int): int = + ## Get the number of days in a ``year`` + result = 365 + (if isLeapYear(year): 1 else: 0) + +proc assertValidDate(monthday: MonthdayRange, month: Month, year: int) {.inline.} = + assert monthday <= getDaysInMonth(month, year), + $year & "-" & $ord(month) & "-" & $monthday & " is not a valid date" + +proc toEpochDay(monthday: MonthdayRange, month: Month, year: int): int64 = + ## Get the epoch day from a year/month/day date. + ## The epoch day is the number of days since 1970/01/01 (it might be negative). + assertValidDate monthday, month, year + # Based on http://howardhinnant.github.io/date_algorithms.html + var (y, m, d) = (year, ord(month), monthday.int) + if m <= 2: + y.dec + + let era = (if y >= 0: y else: y-399) div 400 + let yoe = y - era * 400 + let doy = (153 * (m + (if m > 2: -3 else: 9)) + 2) div 5 + d-1 + let doe = yoe * 365 + yoe div 4 - yoe div 100 + doy + return era * 146097 + doe - 719468 + +proc fromEpochDay(epochday: int64): tuple[monthday: MonthdayRange, month: Month, year: int] = + ## Get the year/month/day date from a epoch day. + ## The epoch day is the number of days since 1970/01/01 (it might be negative). + # Based on http://howardhinnant.github.io/date_algorithms.html + var z = epochday + z.inc 719468 + let era = (if z >= 0: z else: z - 146096) div 146097 + let doe = z - era * 146097 + let yoe = (doe - doe div 1460 + doe div 36524 - doe div 146096) div 365 + let y = yoe + era * 400; + let doy = doe - (365 * yoe + yoe div 4 - yoe div 100) + let mp = (5 * doy + 2) div 153 + let d = doy - (153 * mp + 2) div 5 + 1 + let m = mp + (if mp < 10: 3 else: -9) + return (d.MonthdayRange, m.Month, (y + ord(m <= 2)).int) + +proc getDayOfYear*(monthday: MonthdayRange, month: Month, year: int): YeardayRange {.tags: [], raises: [], benign .} = + ## Returns the day of the year. + ## Equivalent with ``initDateTime(day, month, year).yearday``. + assertValidDate monthday, month, year + const daysUntilMonth: array[Month, int] = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334] + const daysUntilMonthLeap: array[Month, int] = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335] + + if isLeapYear(year): + result = daysUntilMonthLeap[month] + monthday - 1 + else: + result = daysUntilMonth[month] + monthday - 1 + +proc getDayOfWeek*(monthday: MonthdayRange, month: Month, year: int): WeekDay {.tags: [], raises: [], benign .} = + ## Returns the day of the week enum from day, month and year. + ## Equivalent with ``initDateTime(day, month, year).weekday``. + assertValidDate monthday, month, year + # 1970-01-01 is a Thursday, we adjust to the previous Monday + let days = toEpochday(monthday, month, year) - 3 + let weeks = (if days >= 0: days else: days - 6) div 7 + let wd = days - weeks * 7 + # The value of d is 0 for a Sunday, 1 for a Monday, 2 for a Tuesday, etc. + # so we must correct for the WeekDay type. + result = if wd == 0: dSun else: WeekDay(wd - 1) + +# Forward declarations +proc utcZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .} +proc utcZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .} +proc localZoneInfoFromUtc(time: Time): ZonedTime {.tags: [], raises: [], benign .} +proc localZoneInfoFromTz(adjTime: Time): ZonedTime {.tags: [], raises: [], benign .} proc `-`*(a, b: Time): int64 {. - rtl, extern: "ntDiffTime", tags: [], raises: [], noSideEffect, benign.} - ## computes the difference of two calendar times. Result is in seconds. + rtl, extern: "ntDiffTime", tags: [], raises: [], noSideEffect, benign, deprecated.} = + ## Computes the difference of two calendar times. Result is in seconds. + ## This is deprecated because it will need to change when sub second time resolution is implemented. + ## Use ``a.toUnix - b.toUnix`` instead. ## ## .. code-block:: nim ## let a = fromSeconds(1_000_000_000) ## let b = fromSeconds(1_500_000_000) ## echo initInterval(seconds=int(b - a)) - ## # (milliseconds: 0, seconds: 20, minutes: 53, hours: 0, days: 5787, months: 0, years: 0) + ## # (milliseconds: 0, seconds: 20, minutes: 53, hours: 0, days: 5787, months: 0, years: 0) + a.toUnix - b.toUnix proc `<`*(a, b: Time): bool {. - rtl, extern: "ntLtTime", tags: [], raises: [], noSideEffect.} = - ## returns true iff ``a < b``, that is iff a happened before b. - when defined(js): - result = TimeBase(a) < TimeBase(b) - else: - result = a - b < 0 + rtl, extern: "ntLtTime", tags: [], raises: [], noSideEffect, borrow.} + ## Returns true iff ``a < b``, that is iff a happened before b. proc `<=` * (a, b: Time): bool {. - rtl, extern: "ntLeTime", tags: [], raises: [], noSideEffect.}= - ## returns true iff ``a <= b``. - when defined(js): - result = TimeBase(a) <= TimeBase(b) - else: - result = a - b <= 0 + rtl, extern: "ntLeTime", tags: [], raises: [], noSideEffect, borrow.} + ## Returns true iff ``a <= b``. proc `==`*(a, b: Time): bool {. - rtl, extern: "ntEqTime", tags: [], raises: [], noSideEffect.} = - ## returns true if ``a == b``, that is if both times represent the same value - when defined(js): - result = TimeBase(a) == TimeBase(b) + rtl, extern: "ntEqTime", tags: [], raises: [], noSideEffect, borrow.} + ## Returns true if ``a == b``, that is if both times represent the same point in time. + +proc toTime*(dt: DateTime): Time {.tags: [], raises: [], benign.} = + ## Converts a broken-down time structure to + ## calendar time representation. + let epochDay = toEpochday(dt.monthday, dt.month, dt.year) + result = Time(epochDay * secondsInDay) + result.inc dt.hour * secondsInHour + result.inc dt.minute * 60 + result.inc dt.second + # The code above ignores the UTC offset of `timeInfo`, + # so we need to compensate for that here. + result.inc dt.utcOffset + +proc initDateTime(zt: ZonedTime, zone: Timezone): DateTime = + let adjTime = zt.adjTime.int64 + let epochday = (if adjTime >= 0: adjTime else: adjTime - (secondsInDay - 1)) div secondsInDay + var rem = zt.adjTime.int64 - epochday * secondsInDay + let hour = rem div secondsInHour + rem = rem - hour * secondsInHour + let minute = rem div secondsInMin + rem = rem - minute * secondsInMin + let second = rem + + let (d, m, y) = fromEpochday(epochday) + + DateTime( + year: y, + month: m, + monthday: d, + hour: hour, + minute: minute, + second: second, + weekday: getDayOfWeek(d, m, y), + yearday: getDayOfYear(d, m, y), + isDst: zt.isDst, + timezone: zone, + utcOffset: zt.utcOffset + ) + +proc inZone*(time: Time, zone: Timezone): DateTime {.tags: [], raises: [], benign.} = + ## Break down ``time`` into a ``DateTime`` using ``zone`` as the timezone. + let zoneInfo = zone.zoneInfoFromUtc(time) + result = initDateTime(zoneInfo, zone) + +proc inZone*(dt: DateTime, zone: Timezone): DateTime {.tags: [], raises: [], benign.} = + ## Convert ``dt`` into a ``DateTime`` using ``zone`` as the timezone. + dt.toTime.inZone(zone) + +proc `$`*(zone: Timezone): string = + ## Returns the name of the timezone. + zone.name + +proc `==`*(zone1, zone2: Timezone): bool = + ## Two ``Timezone``'s are considered equal if their name is equal. + zone1.name == zone2.name + +proc toAdjTime(dt: DateTime): Time = + let epochDay = toEpochday(dt.monthday, dt.month, dt.year) + result = Time(epochDay * secondsInDay) + result.inc dt.hour * secondsInHour + result.inc dt.minute * secondsInMin + result.inc dt.second + +when defined(JS): + type JsDate = object + proc newDate(year, month, date, hours, minutes, seconds, milliseconds: int): JsDate {.tags: [], raises: [], importc: "new Date".} + proc newDate(): JsDate {.importc: "new Date".} + proc newDate(value: float): JsDate {.importc: "new Date".} + proc getTimezoneOffset(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getDay(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getFullYear(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getHours(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getMilliseconds(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getMinutes(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getMonth(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getSeconds(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getTime(js: JsDate): int {.tags: [], raises: [], noSideEffect, benign, importcpp.} + proc getDate(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getUTCDate(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getUTCFullYear(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getUTCHours(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getUTCMilliseconds(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getUTCMinutes(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getUTCMonth(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getUTCSeconds(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getUTCDay(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc getYear(js: JsDate): int {.tags: [], raises: [], benign, importcpp.} + proc setFullYear(js: JsDate, year: int): void {.tags: [], raises: [], benign, importcpp.} + + proc localZoneInfoFromUtc(time: Time): ZonedTime = + let jsDate = newDate(time.float * 1000) + let offset = jsDate.getTimezoneOffset() * secondsInMin + result.adjTime = Time(time.int64 - offset) + result.utcOffset = offset + result.isDst = false + + proc localZoneInfoFromTz(adjTime: Time): ZonedTime = + let utcDate = newDate(adjTime.float * 1000) + let localDate = newDate(utcDate.getUTCFullYear(), utcDate.getUTCMonth(), utcDate.getUTCDate(), + utcDate.getUTCHours(), utcDate.getUTCMinutes(), utcDate.getUTCSeconds(), 0) + + # This is as dumb as it looks - JS doesn't support years in the range 0-99 in the constructor + # because they are assumed to be 19xx... + # Because JS doesn't support timezone history, it doesn't really matter in practice. + if utcDate.getUTCFullYear() in 0 .. 99: + localDate.setFullYear(utcDate.getUTCFullYear()) + + result.adjTime = adjTime + result.utcOffset = localDate.getTimezoneOffset() * secondsInMin + result.isDst = false + +else: + when defined(freebsd) or defined(netbsd) or defined(openbsd) or + defined(macosx): + type + StructTm {.importc: "struct tm".} = object + second {.importc: "tm_sec".}, + minute {.importc: "tm_min".}, + hour {.importc: "tm_hour".}, + monthday {.importc: "tm_mday".}, + month {.importc: "tm_mon".}, + year {.importc: "tm_year".}, + weekday {.importc: "tm_wday".}, + yearday {.importc: "tm_yday".}, + isdst {.importc: "tm_isdst".}: cint + gmtoff {.importc: "tm_gmtoff".}: clong else: - result = a - b == 0 + type + StructTm {.importc: "struct tm".} = object + second {.importc: "tm_sec".}, + minute {.importc: "tm_min".}, + hour {.importc: "tm_hour".}, + monthday {.importc: "tm_mday".}, + month {.importc: "tm_mon".}, + year {.importc: "tm_year".}, + weekday {.importc: "tm_wday".}, + yearday {.importc: "tm_yday".}, + isdst {.importc: "tm_isdst".}: cint + when defined(linux) and defined(amd64): + gmtoff {.importc: "tm_gmtoff".}: clong + zone {.importc: "tm_zone".}: cstring + type + StructTmPtr = ptr StructTm + + proc localtime(timer: ptr CTime): StructTmPtr {. importc: "localtime", header: "<time.h>", tags: [].} + + proc toAdjTime(tm: StructTm): Time = + let epochDay = toEpochday(tm.monthday, (tm.month + 1).Month, tm.year.int + 1900) + result = Time(epochDay * secondsInDay) + result.inc tm.hour * secondsInHour + result.inc tm.minute * 60 + result.inc tm.second + + proc getStructTm(time: Time | int64): StructTm = + let timei64 = time.int64 + var a = + if timei64 < low(CTime): + CTime(low(CTime)) + elif timei64 > high(CTime): + CTime(high(CTime)) + else: + CTime(timei64) + result = localtime(addr(a))[] + + proc localZoneInfoFromUtc(time: Time): ZonedTime = + let tm = getStructTm(time) + let adjTime = tm.toAdjTime + result.adjTime = adjTime + result.utcOffset = (time.toUnix - adjTime.toUnix).int + result.isDst = tm.isdst > 0 + + proc localZoneInfoFromTz(adjTime: Time): ZonedTime = + var adjTimei64 = adjTime.int64 + let past = adjTimei64 - secondsInDay + var tm = getStructTm(past) + let pastOffset = past - tm.toAdjTime.int64 + + let future = adjTimei64 + secondsInDay + tm = getStructTm(future) + let futureOffset = future - tm.toAdjTime.int64 + + var utcOffset: int + if pastOffset == futureOffset: + utcOffset = pastOffset.int + else: + if pastOffset > futureOffset: + adjTimei64 -= secondsInHour + + adjTimei64 += pastOffset + utcOffset = (adjTimei64 - getStructTm(adjTimei64).toAdjTime.int64).int + + # This extra roundtrip is needed to normalize any impossible datetimes + # as a result of offset changes (normally due to dst) + let utcTime = adjTime.int64 + utcOffset + tm = getStructTm(utcTime) + result.adjTime = tm.toAdjTime + result.utcOffset = (utcTime - result.adjTime.int64).int + result.isDst = tm.isdst > 0 + +proc utcZoneInfoFromUtc(time: Time): ZonedTime = + result.adjTime = time + result.utcOffset = 0 + result.isDst = false + +proc utcZoneInfoFromTz(adjTime: Time): ZonedTime = + utcZoneInfoFromUtc(adjTime) # adjTime == time since we are in UTC + +proc utc*(): TimeZone = + ## Get the ``Timezone`` implementation for the UTC timezone. + ## + ## .. code-block:: nim + ## doAssert now().utc.timezone == utc() + ## doAssert utc().name == "Etc/UTC" + Timezone(zoneInfoFromUtc: utcZoneInfoFromUtc, zoneInfoFromTz: utcZoneInfoFromTz, name: "Etc/UTC") + +proc local*(): TimeZone = + ## Get the ``Timezone`` implementation for the local timezone. + ## + ## .. code-block:: nim + ## doAssert now().timezone == local() + ## doAssert local().name == "LOCAL" + Timezone(zoneInfoFromUtc: localZoneInfoFromUtc, zoneInfoFromTz: localZoneInfoFromTz, name: "LOCAL") -proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign.} - ## returns the offset of the local (non-DST) timezone in seconds west of UTC. +proc utc*(dt: DateTime): DateTime = + ## Shorthand for ``dt.inZone(utc())``. + dt.inZone(utc()) -proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} - ## get the milliseconds from the start of the program. **Deprecated since - ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead. +proc local*(dt: DateTime): DateTime = + ## Shorthand for ``dt.inZone(local())``. + dt.inZone(local()) + +proc utc*(t: Time): DateTime = + ## Shorthand for ``t.inZone(utc())``. + t.inZone(utc()) + +proc local*(t: Time): DateTime = + ## Shorthand for ``t.inZone(local())``. + t.inZone(local()) + +proc getTime*(): Time {.tags: [TimeEffect], benign.} + ## Gets the current time as a ``Time`` with second resolution. Use epochTime for higher + ## resolution. + +proc now*(): DateTime {.tags: [TimeEffect], benign.} = + ## Get the current time as a ``DateTime`` in the local timezone. + ## + ## Shorthand for ``getTime().local``. + getTime().local proc initInterval*(milliseconds, seconds, minutes, hours, days, months, years: int = 0): TimeInterval = - ## creates a new ``TimeInterval``. + ## Creates a new ``TimeInterval``. ## ## You can also use the convenience procedures called ``milliseconds``, ## ``seconds``, ``minutes``, ``hours``, ``days``, ``months``, and ``years``. @@ -269,46 +522,33 @@ proc initInterval*(milliseconds, seconds, minutes, hours, days, months, ## .. code-block:: nim ## ## let day = initInterval(hours=24) - ## let tomorrow = getTime() + day - ## echo(tomorrow) - var carryO = 0 - result.milliseconds = `mod`(milliseconds, 1000) - carryO = `div`(milliseconds, 1000) - result.seconds = `mod`(carryO + seconds, 60) - carryO = `div`(carryO + seconds, 60) - result.minutes = `mod`(carryO + minutes, 60) - carryO = `div`(carryO + minutes, 60) - result.hours = `mod`(carryO + hours, 24) - carryO = `div`(carryO + hours, 24) - result.days = carryO + days - - result.months = `mod`(months, 12) - carryO = `div`(months, 12) - result.years = carryO + years + ## let dt = initDateTime(01, mJan, 2000, 12, 00, 00, utc()) + ## doAssert $(dt + day) == "2000-01-02T12-00-00+00:00" + result.milliseconds = milliseconds + result.seconds = seconds + result.minutes = minutes + result.hours = hours + result.days = days + result.months = months + result.years = years proc `+`*(ti1, ti2: TimeInterval): TimeInterval = ## Adds two ``TimeInterval`` objects together. - var carryO = 0 - result.milliseconds = `mod`(ti1.milliseconds + ti2.milliseconds, 1000) - carryO = `div`(ti1.milliseconds + ti2.milliseconds, 1000) - result.seconds = `mod`(carryO + ti1.seconds + ti2.seconds, 60) - carryO = `div`(carryO + ti1.seconds + ti2.seconds, 60) - result.minutes = `mod`(carryO + ti1.minutes + ti2.minutes, 60) - carryO = `div`(carryO + ti1.minutes + ti2.minutes, 60) - result.hours = `mod`(carryO + ti1.hours + ti2.hours, 24) - carryO = `div`(carryO + ti1.hours + ti2.hours, 24) - result.days = carryO + ti1.days + ti2.days - - result.months = `mod`(ti1.months + ti2.months, 12) - carryO = `div`(ti1.months + ti2.months, 12) - result.years = carryO + ti1.years + ti2.years + result.milliseconds = ti1.milliseconds + ti2.milliseconds + result.seconds = ti1.seconds + ti2.seconds + result.minutes = ti1.minutes + ti2.minutes + result.hours = ti1.hours + ti2.hours + result.days = ti1.days + ti2.days + result.months = ti1.months + ti2.months + result.years = ti1.years + ti2.years proc `-`*(ti: TimeInterval): TimeInterval = ## Reverses a time interval + ## ## .. code-block:: nim ## ## let day = -initInterval(hours=24) - ## echo day # -> (milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: -1, months: 0, years: 0) + ## echo day # -> (milliseconds: 0, seconds: 0, minutes: 0, hours: -24, days: 0, months: 0, years: 0) result = TimeInterval( milliseconds: -ti.milliseconds, seconds: -ti.seconds, @@ -325,123 +565,100 @@ proc `-`*(ti1, ti2: TimeInterval): TimeInterval = ## Time components are compared one-by-one, see output: ## ## .. code-block:: nim - ## let a = fromSeconds(1_000_000_000) - ## let b = fromSeconds(1_500_000_000) + ## let a = fromUnix(1_000_000_000) + ## let b = fromUnix(1_500_000_000) ## echo b.toTimeInterval - a.toTimeInterval - ## # (milliseconds: 0, seconds: -40, minutes: -6, hours: 1, days: -2, months: -2, years: 16) + ## # (milliseconds: 0, seconds: -40, minutes: -6, hours: 1, days: 5, months: -2, years: 16) result = ti1 + (-ti2) -proc isLeapYear*(year: int): bool = - ## returns true if ``year`` is a leap year - - if year mod 400 == 0: - return true - elif year mod 100 == 0: - return false - elif year mod 4 == 0: - return true - else: - return false - -proc getDaysInMonth*(month: Month, year: int): int = - ## Get the number of days in a ``month`` of a ``year`` +proc evaluateInterval(dt: DateTime, interval: TimeInterval): tuple[adjDiff, absDiff: int64] = + ## Evaluates how many seconds the interval is worth + ## in the context of ``dt``. + ## The result in split into an adjusted diff and an absolute diff. - # http://www.dispersiondesign.com/articles/time/number_of_days_in_a_month - case month - of mFeb: result = if isLeapYear(year): 29 else: 28 - of mApr, mJun, mSep, mNov: result = 30 - else: result = 31 - -proc getDaysInYear*(year: int): int = - ## Get the number of days in a ``year`` - result = 365 + (if isLeapYear(year): 1 else: 0) - -proc toSeconds(a: TimeInfo, interval: TimeInterval): float = - ## Calculates how many seconds the interval is worth by adding up - ## all the fields - - var anew = a + var anew = dt var newinterv = interval - result = 0 newinterv.months += interval.years * 12 var curMonth = anew.month - if newinterv.months < 0: # subtracting + # Subtracting + if newinterv.months < 0: for mth in countDown(-1 * newinterv.months, 1): - result -= float(getDaysInMonth(curMonth, anew.year) * 24 * 60 * 60) if curMonth == mJan: curMonth = mDec anew.year.dec() else: curMonth.dec() - else: # adding + result.adjDiff -= getDaysInMonth(curMonth, anew.year) * secondsInDay + # Adding + else: for mth in 1 .. newinterv.months: - result += float(getDaysInMonth(curMonth, anew.year) * 24 * 60 * 60) + result.adjDiff += getDaysInMonth(curMonth, anew.year) * secondsInDay if curMonth == mDec: curMonth = mJan anew.year.inc() else: curMonth.inc() - result += float(newinterv.days * 24 * 60 * 60) - result += float(newinterv.hours * 60 * 60) - result += float(newinterv.minutes * 60) - result += float(newinterv.seconds) - result += newinterv.milliseconds / 1000 - -proc `+`*(a: TimeInfo, interval: TimeInterval): TimeInfo = - ## adds ``interval`` time from TimeInfo ``a``. + result.adjDiff += newinterv.days * secondsInDay + result.absDiff += newinterv.hours * secondsInHour + result.absDiff += newinterv.minutes * secondsInMin + result.absDiff += newinterv.seconds + result.absDiff += newinterv.milliseconds div 1000 + +proc `+`*(dt: DateTime, interval: TimeInterval): DateTime = + ## Adds ``interval`` to ``dt``. Components from ``interval`` are added + ## in the order of their size, i.e first the ``years`` component, then the ``months`` + ## component and so on. The returned ``DateTime`` will have the same timezone as the input. ## - ## **Note:** This has been only briefly tested and it may not be - ## very accurate. - let t = toSeconds(toTime(a)) - let secs = toSeconds(a, interval) - if a.timezone == 0: - result = getGMTime(fromSeconds(t + secs)) - else: - result = getLocalTime(fromSeconds(t + secs)) - -proc `-`*(a: TimeInfo, interval: TimeInterval): TimeInfo = - ## subtracts ``interval`` time from TimeInfo ``a``. + ## Note that when adding months, monthday overflow is allowed. This means that if the resulting + ## month doesn't have enough days it, the month will be incremented and the monthday will be + ## set to the number of days overflowed. So adding one month to `31 October` will result in `31 November`, + ## which will overflow and result in `1 December`. ## - ## **Note:** This has been only briefly tested, it is inaccurate especially - ## when you subtract so much that you reach the Julian calendar. - let - t = toSeconds(toTime(a)) - secs = toSeconds(a, -interval) - if a.timezone == 0: - result = getGMTime(fromSeconds(t + secs)) + ## .. code-block:: nim + ## let dt = initDateTime(30, mMar, 2017, 00, 00, 00, utc()) + ## doAssert $(dt + 1.months) == "2017-04-30T00:00:00+00:00" + ## # This is correct and happens due to monthday overflow. + ## doAssert $(dt - 1.months) == "2017-03-02T00:00:00+00:00" + let (adjDiff, absDiff) = evaluateInterval(dt, interval) + + if adjDiff.int64 != 0: + let zInfo = dt.timezone.zoneInfoFromTz(Time(dt.toAdjTime.int64 + adjDiff)) + + if absDiff != 0: + let time = Time(zInfo.adjTime.int64 + zInfo.utcOffset + absDiff) + result = initDateTime(dt.timezone.zoneInfoFromUtc(time), dt.timezone) + else: + result = initDateTime(zInfo, dt.timezone) else: - result = getLocalTime(fromSeconds(t + secs)) + result = initDateTime(dt.timezone.zoneInfoFromUtc(Time(dt.toTime.int64 + absDiff)), dt.timezone) -proc miliseconds*(t: TimeInterval): int {.deprecated.} = t.milliseconds - -proc `miliseconds=`*(t: var TimeInterval, milliseconds: int) {.deprecated.} = - ## An alias for a misspelled field in ``TimeInterval``. - ## - ## **Warning:** This should not be used! It will be removed in the next - ## version. - t.milliseconds = milliseconds +proc `-`*(dt: DateTime, interval: TimeInterval): DateTime = + ## Subtract ``interval`` from ``dt``. Components from ``interval`` are subtracted + ## in the order of their size, i.e first the ``years`` component, then the ``months`` + ## component and so on. The returned ``DateTime`` will have the same timezone as the input. + dt + (-interval) proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} = - ## gets the current date as a string of the format ``YYYY-MM-DD``. - var ti = getLocalTime(getTime()) - result = $ti.year & '-' & intToStr(ord(ti.month)+1, 2) & + ## Gets the current date as a string of the format ``YYYY-MM-DD``. + var ti = now() + result = $ti.year & '-' & intToStr(ord(ti.month), 2) & '-' & intToStr(ti.monthday, 2) proc getClockStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} = - ## gets the current clock time as a string of the format ``HH:MM:SS``. - var ti = getLocalTime(getTime()) + ## Gets the current clock time as a string of the format ``HH:MM:SS``. + var ti = now() result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) & ':' & intToStr(ti.second, 2) proc `$`*(day: WeekDay): string = - ## stingify operator for ``WeekDay``. + ## Stringify operator for ``WeekDay``. const lookup: array[WeekDay, string] = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] return lookup[day] proc `$`*(m: Month): string = - ## stingify operator for ``Month``. + ## Stringify operator for ``Month``. const lookup: array[Month, string] = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] @@ -450,74 +667,68 @@ proc `$`*(m: Month): string = proc milliseconds*(ms: int): TimeInterval {.inline.} = ## TimeInterval of `ms` milliseconds ## - ## Note: not all time functions have millisecond resolution - initInterval(`mod`(ms,1000), `div`(ms,1000)) + ## Note: not all time procedures have millisecond resolution + initInterval(milliseconds = ms) proc seconds*(s: int): TimeInterval {.inline.} = ## TimeInterval of `s` seconds ## ## ``echo getTime() + 5.second`` - initInterval(0,`mod`(s,60), `div`(s,60)) + initInterval(seconds = s) proc minutes*(m: int): TimeInterval {.inline.} = ## TimeInterval of `m` minutes ## ## ``echo getTime() + 5.minutes`` - initInterval(0,0,`mod`(m,60), `div`(m,60)) + initInterval(minutes = m) proc hours*(h: int): TimeInterval {.inline.} = ## TimeInterval of `h` hours ## ## ``echo getTime() + 2.hours`` - initInterval(0,0,0,`mod`(h,24),`div`(h,24)) + initInterval(hours = h) proc days*(d: int): TimeInterval {.inline.} = ## TimeInterval of `d` days ## ## ``echo getTime() + 2.days`` - initInterval(0,0,0,0,d) + initInterval(days = d) proc months*(m: int): TimeInterval {.inline.} = ## TimeInterval of `m` months ## ## ``echo getTime() + 2.months`` - initInterval(0,0,0,0,0,`mod`(m,12),`div`(m,12)) + initInterval(months = m) proc years*(y: int): TimeInterval {.inline.} = ## TimeInterval of `y` years ## ## ``echo getTime() + 2.years`` - initInterval(0,0,0,0,0,0,y) + initInterval(years = y) -proc `+=`*(t: var Time, ti: TimeInterval) = - ## modifies `t` by adding the interval `ti` - t = toTime(getLocalTime(t) + ti) +proc `+=`*(time: var Time, interval: TimeInterval) = + ## Modifies `time` by adding `interval`. + time = toTime(time.local + interval) -proc `+`*(t: Time, ti: TimeInterval): Time = - ## adds the interval `ti` to Time `t` - ## by converting to localTime, adding the interval, and converting back +proc `+`*(time: Time, interval: TimeInterval): Time = + ## Adds `interval` to `time` + ## by converting to a ``DateTime`` in the local timezone, + ## adding the interval, and converting back to ``Time``. ## ## ``echo getTime() + 1.day`` - result = toTime(getLocalTime(t) + ti) + result = toTime(time.local + interval) -proc `-=`*(t: var Time, ti: TimeInterval) = - ## modifies `t` by subtracting the interval `ti` - t = toTime(getLocalTime(t) - ti) +proc `-=`*(time: var Time, interval: TimeInterval) = + ## Modifies `time` by subtracting `interval`. + time = toTime(time.local - interval) -proc `-`*(t: Time, ti: TimeInterval): Time = - ## subtracts the interval `ti` from Time `t` +proc `-`*(time: Time, interval: TimeInterval): Time = + ## Subtracts `interval` from Time `time`. ## ## ``echo getTime() - 1.day`` - result = toTime(getLocalTime(t) - ti) + result = toTime(time.local - interval) -const - secondsInMin = 60 - secondsInHour = 60*60 - secondsInDay = 60*60*24 - minutesInHour = 60 - epochStartYear = 1970 - -proc formatToken(info: TimeInfo, token: string, buf: var string) = +proc formatToken(dt: DateTime, token: string, buf: var string) = ## Helper of the format proc to parse individual tokens. ## ## Pass the found token in the user input string, and the buffer where the @@ -525,96 +736,96 @@ proc formatToken(info: TimeInfo, token: string, buf: var string) = ## formatting tokens require modifying the previous characters. case token of "d": - buf.add($info.monthday) + buf.add($dt.monthday) of "dd": - if info.monthday < 10: + if dt.monthday < 10: buf.add("0") - buf.add($info.monthday) + buf.add($dt.monthday) of "ddd": - buf.add(($info.weekday)[0 .. 2]) + buf.add(($dt.weekday)[0 .. 2]) of "dddd": - buf.add($info.weekday) + buf.add($dt.weekday) of "h": - buf.add($(if info.hour > 12: info.hour - 12 else: info.hour)) + buf.add($(if dt.hour > 12: dt.hour - 12 else: dt.hour)) of "hh": - let amerHour = if info.hour > 12: info.hour - 12 else: info.hour + let amerHour = if dt.hour > 12: dt.hour - 12 else: dt.hour if amerHour < 10: buf.add('0') buf.add($amerHour) of "H": - buf.add($info.hour) + buf.add($dt.hour) of "HH": - if info.hour < 10: + if dt.hour < 10: buf.add('0') - buf.add($info.hour) + buf.add($dt.hour) of "m": - buf.add($info.minute) + buf.add($dt.minute) of "mm": - if info.minute < 10: + if dt.minute < 10: buf.add('0') - buf.add($info.minute) + buf.add($dt.minute) of "M": - buf.add($(int(info.month)+1)) + buf.add($ord(dt.month)) of "MM": - if info.month < mOct: + if dt.month < mOct: buf.add('0') - buf.add($(int(info.month)+1)) + buf.add($ord(dt.month)) of "MMM": - buf.add(($info.month)[0..2]) + buf.add(($dt.month)[0..2]) of "MMMM": - buf.add($info.month) + buf.add($dt.month) of "s": - buf.add($info.second) + buf.add($dt.second) of "ss": - if info.second < 10: + if dt.second < 10: buf.add('0') - buf.add($info.second) + buf.add($dt.second) of "t": - if info.hour >= 12: + if dt.hour >= 12: buf.add('P') else: buf.add('A') of "tt": - if info.hour >= 12: + if dt.hour >= 12: buf.add("PM") else: buf.add("AM") of "y": - var fr = ($info.year).len()-1 + var fr = ($dt.year).len()-1 if fr < 0: fr = 0 - buf.add(($info.year)[fr .. ($info.year).len()-1]) + buf.add(($dt.year)[fr .. ($dt.year).len()-1]) of "yy": - var fr = ($info.year).len()-2 + var fr = ($dt.year).len()-2 if fr < 0: fr = 0 - var fyear = ($info.year)[fr .. ($info.year).len()-1] + var fyear = ($dt.year)[fr .. ($dt.year).len()-1] if fyear.len != 2: fyear = repeat('0', 2-fyear.len()) & fyear buf.add(fyear) of "yyy": - var fr = ($info.year).len()-3 + var fr = ($dt.year).len()-3 if fr < 0: fr = 0 - var fyear = ($info.year)[fr .. ($info.year).len()-1] + var fyear = ($dt.year)[fr .. ($dt.year).len()-1] if fyear.len != 3: fyear = repeat('0', 3-fyear.len()) & fyear buf.add(fyear) of "yyyy": - var fr = ($info.year).len()-4 + var fr = ($dt.year).len()-4 if fr < 0: fr = 0 - var fyear = ($info.year)[fr .. ($info.year).len()-1] + var fyear = ($dt.year)[fr .. ($dt.year).len()-1] if fyear.len != 4: fyear = repeat('0', 4-fyear.len()) & fyear buf.add(fyear) of "yyyyy": - var fr = ($info.year).len()-5 + var fr = ($dt.year).len()-5 if fr < 0: fr = 0 - var fyear = ($info.year)[fr .. ($info.year).len()-1] + var fyear = ($dt.year)[fr .. ($dt.year).len()-1] if fyear.len != 5: fyear = repeat('0', 5-fyear.len()) & fyear buf.add(fyear) of "z": let - nonDstTz = info.timezone - int(info.isDst) * secondsInHour + nonDstTz = dt.utcOffset hours = abs(nonDstTz) div secondsInHour if nonDstTz <= 0: buf.add('+') else: buf.add('-') buf.add($hours) of "zz": let - nonDstTz = info.timezone - int(info.isDst) * secondsInHour + nonDstTz = dt.utcOffset hours = abs(nonDstTz) div secondsInHour if nonDstTz <= 0: buf.add('+') else: buf.add('-') @@ -622,7 +833,7 @@ proc formatToken(info: TimeInfo, token: string, buf: var string) = buf.add($hours) of "zzz": let - nonDstTz = info.timezone - int(info.isDst) * secondsInHour + nonDstTz = dt.utcOffset hours = abs(nonDstTz) div secondsInHour minutes = (abs(nonDstTz) div secondsInMin) mod minutesInHour if nonDstTz <= 0: buf.add('+') @@ -638,8 +849,8 @@ proc formatToken(info: TimeInfo, token: string, buf: var string) = raise newException(ValueError, "Invalid format string: " & token) -proc format*(info: TimeInfo, f: string): string = - ## This function formats `info` as specified by `f`. The following format +proc format*(dt: DateTime, f: string): string {.tags: [].}= + ## This procedure formats `dt` as specified by `f`. The following format ## specifiers are available: ## ## ========== ================================================================================= ================================================ @@ -683,7 +894,7 @@ proc format*(info: TimeInfo, f: string): string = while true: case f[i] of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': - formatToken(info, currentF, result) + formatToken(dt, currentF, result) currentF = "" if f[i] == '\0': break @@ -700,187 +911,187 @@ proc format*(info: TimeInfo, f: string): string = if currentF.len < 1 or currentF[high(currentF)] == f[i]: currentF.add(f[i]) else: - formatToken(info, currentF, result) + formatToken(dt, currentF, result) dec(i) # Move position back to re-process the character separately. currentF = "" inc(i) -proc `$`*(timeInfo: TimeInfo): string {.tags: [], raises: [], benign.} = - ## converts a `TimeInfo` object to a string representation. +proc `$`*(dt: DateTime): string {.tags: [], raises: [], benign.} = + ## Converts a `DateTime` object to a string representation. ## It uses the format ``yyyy-MM-dd'T'HH-mm-sszzz``. try: - result = format(timeInfo, "yyyy-MM-dd'T'HH:mm:sszzz") # todo: optimize this + result = format(dt, "yyyy-MM-dd'T'HH:mm:sszzz") # todo: optimize this except ValueError: assert false # cannot happen because format string is valid -proc `$`*(time: Time): string {.tags: [TimeEffect], raises: [], benign.} = +proc `$`*(time: Time): string {.tags: [], raises: [], benign.} = ## converts a `Time` value to a string representation. It will use the local ## time zone and use the format ``yyyy-MM-dd'T'HH-mm-sszzz``. - $getLocalTime(time) + $time.local {.pop.} -proc parseToken(info: var TimeInfo; token, value: string; j: var int) = +proc parseToken(dt: var DateTime; token, value: string; j: var int) = ## Helper of the parse proc to parse individual tokens. var sv: int case token of "d": var pd = parseInt(value[j..j+1], sv) - info.monthday = sv + dt.monthday = sv j += pd of "dd": - info.monthday = value[j..j+1].parseInt() + dt.monthday = value[j..j+1].parseInt() j += 2 of "ddd": case value[j..j+2].toLowerAscii() - of "sun": info.weekday = dSun - of "mon": info.weekday = dMon - of "tue": info.weekday = dTue - of "wed": info.weekday = dWed - of "thu": info.weekday = dThu - of "fri": info.weekday = dFri - of "sat": info.weekday = dSat + of "sun": dt.weekday = dSun + of "mon": dt.weekday = dMon + of "tue": dt.weekday = dTue + of "wed": dt.weekday = dWed + of "thu": dt.weekday = dThu + of "fri": dt.weekday = dFri + of "sat": dt.weekday = dSat else: raise newException(ValueError, "Couldn't parse day of week (ddd), got: " & value[j..j+2]) j += 3 of "dddd": if value.len >= j+6 and value[j..j+5].cmpIgnoreCase("sunday") == 0: - info.weekday = dSun + dt.weekday = dSun j += 6 elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("monday") == 0: - info.weekday = dMon + dt.weekday = dMon j += 6 elif value.len >= j+7 and value[j..j+6].cmpIgnoreCase("tuesday") == 0: - info.weekday = dTue + dt.weekday = dTue j += 7 elif value.len >= j+9 and value[j..j+8].cmpIgnoreCase("wednesday") == 0: - info.weekday = dWed + dt.weekday = dWed j += 9 elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("thursday") == 0: - info.weekday = dThu + dt.weekday = dThu j += 8 elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("friday") == 0: - info.weekday = dFri + dt.weekday = dFri j += 6 elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("saturday") == 0: - info.weekday = dSat + dt.weekday = dSat j += 8 else: raise newException(ValueError, "Couldn't parse day of week (dddd), got: " & value) of "h", "H": var pd = parseInt(value[j..j+1], sv) - info.hour = sv + dt.hour = sv j += pd of "hh", "HH": - info.hour = value[j..j+1].parseInt() + dt.hour = value[j..j+1].parseInt() j += 2 of "m": var pd = parseInt(value[j..j+1], sv) - info.minute = sv + dt.minute = sv j += pd of "mm": - info.minute = value[j..j+1].parseInt() + dt.minute = value[j..j+1].parseInt() j += 2 of "M": var pd = parseInt(value[j..j+1], sv) - info.month = Month(sv-1) + dt.month = sv.Month j += pd of "MM": var month = value[j..j+1].parseInt() j += 2 - info.month = Month(month-1) + dt.month = month.Month of "MMM": case value[j..j+2].toLowerAscii(): - of "jan": info.month = mJan - of "feb": info.month = mFeb - of "mar": info.month = mMar - of "apr": info.month = mApr - of "may": info.month = mMay - of "jun": info.month = mJun - of "jul": info.month = mJul - of "aug": info.month = mAug - of "sep": info.month = mSep - of "oct": info.month = mOct - of "nov": info.month = mNov - of "dec": info.month = mDec + of "jan": dt.month = mJan + of "feb": dt.month = mFeb + of "mar": dt.month = mMar + of "apr": dt.month = mApr + of "may": dt.month = mMay + of "jun": dt.month = mJun + of "jul": dt.month = mJul + of "aug": dt.month = mAug + of "sep": dt.month = mSep + of "oct": dt.month = mOct + of "nov": dt.month = mNov + of "dec": dt.month = mDec else: raise newException(ValueError, "Couldn't parse month (MMM), got: " & value) j += 3 of "MMMM": if value.len >= j+7 and value[j..j+6].cmpIgnoreCase("january") == 0: - info.month = mJan + dt.month = mJan j += 7 elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("february") == 0: - info.month = mFeb + dt.month = mFeb j += 8 elif value.len >= j+5 and value[j..j+4].cmpIgnoreCase("march") == 0: - info.month = mMar + dt.month = mMar j += 5 elif value.len >= j+5 and value[j..j+4].cmpIgnoreCase("april") == 0: - info.month = mApr + dt.month = mApr j += 5 elif value.len >= j+3 and value[j..j+2].cmpIgnoreCase("may") == 0: - info.month = mMay + dt.month = mMay j += 3 elif value.len >= j+4 and value[j..j+3].cmpIgnoreCase("june") == 0: - info.month = mJun + dt.month = mJun j += 4 elif value.len >= j+4 and value[j..j+3].cmpIgnoreCase("july") == 0: - info.month = mJul + dt.month = mJul j += 4 elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("august") == 0: - info.month = mAug + dt.month = mAug j += 6 elif value.len >= j+9 and value[j..j+8].cmpIgnoreCase("september") == 0: - info.month = mSep + dt.month = mSep j += 9 elif value.len >= j+7 and value[j..j+6].cmpIgnoreCase("october") == 0: - info.month = mOct + dt.month = mOct j += 7 elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("november") == 0: - info.month = mNov + dt.month = mNov j += 8 elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("december") == 0: - info.month = mDec + dt.month = mDec j += 8 else: raise newException(ValueError, "Couldn't parse month (MMMM), got: " & value) of "s": var pd = parseInt(value[j..j+1], sv) - info.second = sv + dt.second = sv j += pd of "ss": - info.second = value[j..j+1].parseInt() + dt.second = value[j..j+1].parseInt() j += 2 of "t": - if value[j] == 'P' and info.hour > 0 and info.hour < 12: - info.hour += 12 + if value[j] == 'P' and dt.hour > 0 and dt.hour < 12: + dt.hour += 12 j += 1 of "tt": - if value[j..j+1] == "PM" and info.hour > 0 and info.hour < 12: - info.hour += 12 + if value[j..j+1] == "PM" and dt.hour > 0 and dt.hour < 12: + dt.hour += 12 j += 2 of "yy": # Assumes current century var year = value[j..j+1].parseInt() - var thisCen = getLocalTime(getTime()).year div 100 - info.year = thisCen*100 + year + var thisCen = now().year div 100 + dt.year = thisCen*100 + year j += 2 of "yyyy": - info.year = value[j..j+3].parseInt() + dt.year = value[j..j+3].parseInt() j += 4 of "z": - info.isDST = false + dt.isDst = false if value[j] == '+': - info.timezone = 0 - parseInt($value[j+1]) * secondsInHour + dt.utcOffset = 0 - parseInt($value[j+1]) * secondsInHour elif value[j] == '-': - info.timezone = parseInt($value[j+1]) * secondsInHour + dt.utcOffset = parseInt($value[j+1]) * secondsInHour elif value[j] == 'Z': - info.timezone = 0 + dt.utcOffset = 0 j += 1 return else: @@ -888,13 +1099,13 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = "Couldn't parse timezone offset (z), got: " & value[j]) j += 2 of "zz": - info.isDST = false + dt.isDst = false if value[j] == '+': - info.timezone = 0 - value[j+1..j+2].parseInt() * secondsInHour + dt.utcOffset = 0 - value[j+1..j+2].parseInt() * secondsInHour elif value[j] == '-': - info.timezone = value[j+1..j+2].parseInt() * secondsInHour + dt.utcOffset = value[j+1..j+2].parseInt() * secondsInHour elif value[j] == 'Z': - info.timezone = 0 + dt.utcOffset = 0 j += 1 return else: @@ -902,31 +1113,33 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = "Couldn't parse timezone offset (zz), got: " & value[j]) j += 3 of "zzz": - info.isDST = false + dt.isDst = false var factor = 0 if value[j] == '+': factor = -1 elif value[j] == '-': factor = 1 elif value[j] == 'Z': - info.timezone = 0 + dt.utcOffset = 0 j += 1 return else: raise newException(ValueError, "Couldn't parse timezone offset (zzz), got: " & value[j]) - info.timezone = factor * value[j+1..j+2].parseInt() * secondsInHour + dt.utcOffset = factor * value[j+1..j+2].parseInt() * secondsInHour j += 4 - info.timezone += factor * value[j..j+1].parseInt() * 60 + dt.utcOffset += factor * value[j..j+1].parseInt() * 60 j += 2 else: # Ignore the token and move forward in the value string by the same length j += token.len -proc parse*(value, layout: string): TimeInfo = - ## This function parses a date/time string using the standard format - ## identifiers as listed below. The function defaults information not provided - ## in the format string from the running program (timezone, month, year, etc). - ## Daylight saving time is only set if no timezone is given and the given date - ## lies within the DST period of the current locale. +proc parse*(value, layout: string, zone: Timezone = local()): DateTime = + ## This procedure parses a date/time string using the standard format + ## identifiers as listed below. The procedure defaults information not provided + ## in the format string from the running program (month, year, etc). + ## + ## The return value will always be in the `zone` timezone. If no UTC offset was + ## parsed, then the input will be assumed to be specified in the `zone` timezone + ## already, so no timezone conversion will be done in that case. ## ## ========== ================================================================================= ================================================ ## Specifier Description Example @@ -965,17 +1178,17 @@ proc parse*(value, layout: string): TimeInfo = var j = 0 # pointer for value string var token = "" # Assumes current day of month, month and year, but time is reset to 00:00:00. Weekday will be reset after parsing. - var info = getLocalTime(getTime()) - info.hour = 0 - info.minute = 0 - info.second = 0 - info.isDST = true # using this is flag for checking whether a timezone has \ + var dt = now() + dt.hour = 0 + dt.minute = 0 + dt.second = 0 + dt.isDst = true # using this is flag for checking whether a timezone has \ # been read (because DST is always false when a tz is parsed) while true: case layout[i] of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': if token.len > 0: - parseToken(info, token, value, j) + parseToken(dt, token, value, j) # Reset token token = "" # Break if at end of line @@ -997,26 +1210,15 @@ proc parse*(value, layout: string): TimeInfo = token.add(layout[i]) inc(i) else: - parseToken(info, token, value, j) + parseToken(dt, token, value, j) token = "" - if info.isDST: - # means that no timezone has been parsed. In this case, we need to check - # whether the date is within DST of the local time. - let tmp = getLocalTime(toTime(info)) - # correctly set isDST so that the following step works on the correct time - info.isDST = tmp.isDST - - # Correct weekday and yearday; transform timestamp to local time. - # There currently is no way of returning this with the original (parsed) - # timezone while also setting weekday and yearday (we are depending on stdlib - # to provide this calculation). - return getLocalTime(toTime(info)) - -# Leap year calculations are adapted from: -# http://www.codeproject.com/Articles/7358/Ultra-fast-Algorithms-for-Working-with-Leap-Years -# The dayOfTheWeek procs are adapated from: -# http://stason.org/TULARC/society/calendars/2-5-What-day-of-the-week-was-2-August-1953.html + if dt.isDst: + # No timezone parsed - assume timezone is `zone` + result = initDateTime(zone.zoneInfoFromTz(dt.toAdjTime), zone) + else: + # Otherwise convert to `zone` + result = dt.toTime.inZone(zone) proc countLeapYears*(yearSpan: int): int = ## Returns the number of leap years spanned by a given number of years. @@ -1025,7 +1227,7 @@ proc countLeapYears*(yearSpan: int): int = ## counts the number of leap years up to January 1st of a given year. ## Keep in mind that if specified year is a leap year, the leap day ## has not happened before January 1st of that year. - (((yearSpan - 1) / 4) - ((yearSpan - 1) / 100) + ((yearSpan - 1) / 400)).int + (yearSpan - 1) div 4 - (yearSpan - 1) div 100 + (yearSpan - 1) div 400 proc countDays*(yearSpan: int): int = ## Returns the number of days spanned by a given number of years. @@ -1042,75 +1244,7 @@ proc countYearsAndDays*(daySpan: int): tuple[years: int, days: int] = result.years = days div 365 result.days = days mod 365 -proc getDayOfWeek*(day, month, year: int): WeekDay = - ## Returns the day of the week enum from day, month and year. - # Day & month start from one. - let - a = (14 - month) div 12 - y = year - a - m = month + (12*a) - 2 - d = (day + y + (y div 4) - (y div 100) + (y div 400) + (31*m) div 12) mod 7 - # The value of d is 0 for a Sunday, 1 for a Monday, 2 for a Tuesday, etc. - # so we must correct for the WeekDay type. - if d == 0: return dSun - result = (d-1).WeekDay - -proc getDayOfWeekJulian*(day, month, year: int): WeekDay = - ## Returns the day of the week enum from day, month and year, - ## according to the Julian calendar. - # Day & month start from one. - let - a = (14 - month) div 12 - y = year - a - m = month + (12*a) - 2 - d = (5 + day + y + (y div 4) + (31*m) div 12) mod 7 - result = d.WeekDay - -proc timeToTimeInfo*(t: Time): TimeInfo {.deprecated.} = - ## Converts a Time to TimeInfo. - ## - ## **Warning:** This procedure is deprecated since version 0.14.0. - ## Use ``getLocalTime`` or ``getGMTime`` instead. - let - secs = t.toSeconds().int - daysSinceEpoch = secs div secondsInDay - (yearsSinceEpoch, daysRemaining) = countYearsAndDays(daysSinceEpoch) - daySeconds = secs mod secondsInDay - - y = yearsSinceEpoch + epochStartYear - - var - mon = mJan - days = daysRemaining - daysInMonth = getDaysInMonth(mon, y) - - # calculate month and day remainder - while days > daysInMonth and mon <= mDec: - days -= daysInMonth - mon.inc - daysInMonth = getDaysInMonth(mon, y) - - let - yd = daysRemaining - m = mon # month is zero indexed enum - md = days - # NB: month is zero indexed but dayOfWeek expects 1 indexed. - wd = getDayOfWeek(days, mon.int + 1, y).Weekday - h = daySeconds div secondsInHour + 1 - mi = (daySeconds mod secondsInHour) div secondsInMin - s = daySeconds mod secondsInMin - result = TimeInfo(year: y, yearday: yd, month: m, monthday: md, weekday: wd, hour: h, minute: mi, second: s) - -proc timeToTimeInterval*(t: Time): TimeInterval {.deprecated.} = - ## Converts a Time to a TimeInterval. - ## - ## **Warning:** This procedure is deprecated since version 0.14.0. - ## Use ``toTimeInterval`` instead. - # Milliseconds not available from Time - var tInfo = t.getLocalTime() - initInterval(0, tInfo.second, tInfo.minute, tInfo.hour, tInfo.weekday.ord, tInfo.month.ord, tInfo.year) - -proc toTimeInterval*(t: Time): TimeInterval = +proc toTimeInterval*(time: Time): TimeInterval = ## Converts a Time to a TimeInterval. ## ## To be used when diffing times. @@ -1121,10 +1255,25 @@ proc toTimeInterval*(t: Time): TimeInterval = ## echo a, " ", b # real dates ## echo a.toTimeInterval # meaningless value, don't use it by itself ## echo b.toTimeInterval - a.toTimeInterval - ## # (milliseconds: 0, seconds: -40, minutes: -6, hours: 1, days: -2, months: -2, years: 16) + ## # (milliseconds: 0, seconds: -40, minutes: -6, hours: 1, days: 5, months: -2, years: 16) # Milliseconds not available from Time - var tInfo = t.getLocalTime() - initInterval(0, tInfo.second, tInfo.minute, tInfo.hour, tInfo.weekday.ord, tInfo.month.ord, tInfo.year) + var dt = time.local + initInterval(0, dt.second, dt.minute, dt.hour, dt.monthday, dt.month.ord - 1, dt.year) + +proc initDateTime*(monthday: MonthdayRange, month: Month, year: int, + hour: HourRange, minute: MinuteRange, second: SecondRange, zone: Timezone = local()): DateTime = + ## Create a new ``DateTime`` in the specified timezone. + assertValidDate monthday, month, year + doAssert monthday <= getDaysInMonth(month, year), "Invalid date: " & $month & " " & $monthday & ", " & $year + let dt = DateTime( + monthday: monthday, + year: year, + month: month, + hour: hour, + minute: minute, + second: second + ) + result = initDateTime(zone.zoneInfoFromTz(dt.toAdjTime), zone) when not defined(JS): proc epochTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].} @@ -1145,160 +1294,39 @@ when not defined(JS): ## doWork() ## echo "CPU time [s] ", cpuTime() - t0 -when not defined(JS): - # C wrapper: - when defined(freebsd) or defined(netbsd) or defined(openbsd) or - defined(macosx): - type - StructTM {.importc: "struct tm".} = object - second {.importc: "tm_sec".}, - minute {.importc: "tm_min".}, - hour {.importc: "tm_hour".}, - monthday {.importc: "tm_mday".}, - month {.importc: "tm_mon".}, - year {.importc: "tm_year".}, - weekday {.importc: "tm_wday".}, - yearday {.importc: "tm_yday".}, - isdst {.importc: "tm_isdst".}: cint - gmtoff {.importc: "tm_gmtoff".}: clong - else: - type - StructTM {.importc: "struct tm".} = object - second {.importc: "tm_sec".}, - minute {.importc: "tm_min".}, - hour {.importc: "tm_hour".}, - monthday {.importc: "tm_mday".}, - month {.importc: "tm_mon".}, - year {.importc: "tm_year".}, - weekday {.importc: "tm_wday".}, - yearday {.importc: "tm_yday".}, - isdst {.importc: "tm_isdst".}: cint - when defined(linux) and defined(amd64): - gmtoff {.importc: "tm_gmtoff".}: clong - zone {.importc: "tm_zone".}: cstring +when defined(JS): + proc getTime(): Time = + (newDate().getTime() div 1000).Time + + proc epochTime*(): float {.tags: [TimeEffect].} = + newDate().getTime() / 1000 + +else: type - TimeInfoPtr = ptr StructTM Clock {.importc: "clock_t".} = distinct int - when not defined(windows): - # This is not ANSI C, but common enough - proc timegm(t: StructTM): Time {. - importc: "timegm", header: "<time.h>", tags: [].} - - proc localtime(timer: ptr Time): TimeInfoPtr {. - importc: "localtime", header: "<time.h>", tags: [].} - proc gmtime(timer: ptr Time): TimeInfoPtr {. - importc: "gmtime", header: "<time.h>", tags: [].} - proc timec(timer: ptr Time): Time {. + proc timec(timer: ptr CTime): CTime {. importc: "time", header: "<time.h>", tags: [].} - proc mktime(t: StructTM): Time {. - importc: "mktime", header: "<time.h>", tags: [].} + proc getClock(): Clock {.importc: "clock", header: "<time.h>", tags: [TimeEffect].} - proc difftime(a, b: Time): float {.importc: "difftime", header: "<time.h>", - tags: [].} var clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int - # our own procs on top of that: - proc tmToTimeInfo(tm: StructTM, local: bool): TimeInfo = - const - weekDays: array[0..6, WeekDay] = [ - dSun, dMon, dTue, dWed, dThu, dFri, dSat] - TimeInfo(second: int(tm.second), - minute: int(tm.minute), - hour: int(tm.hour), - monthday: int(tm.monthday), - month: Month(tm.month), - year: tm.year + 1900'i32, - weekday: weekDays[int(tm.weekday)], - yearday: int(tm.yearday), - isDST: tm.isdst > 0, - timezone: if local: getTimezone() else: 0 - ) - - - proc timeInfoToTM(t: TimeInfo): StructTM = - const - weekDays: array[WeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8] - result.second = t.second - result.minute = t.minute - result.hour = t.hour - result.monthday = t.monthday - result.month = ord(t.month) - result.year = cint(t.year - 1900) - result.weekday = weekDays[t.weekday] - result.yearday = t.yearday - result.isdst = if t.isDST: 1 else: 0 - - when not defined(useNimRtl): - proc `-` (a, b: Time): int64 = - return toBiggestInt(difftime(a, b)) - - proc getStartMilsecs(): int = - #echo "clocks per sec: ", clocksPerSec, "clock: ", int(getClock()) - #return getClock() div (clocksPerSec div 1000) - when defined(macosx): - result = toInt(toFloat(int(getClock())) / (toFloat(clocksPerSec) / 1000.0)) - else: - result = int(getClock()) div (clocksPerSec div 1000) - when false: - var a: Timeval - posix_gettimeofday(a) - result = a.tv_sec * 1000'i64 + a.tv_usec div 1000'i64 - #echo "result: ", result - - proc getTime(): Time = return timec(nil) - proc getLocalTime(t: Time): TimeInfo = - var a = t - let lt = localtime(addr(a)) - assert(not lt.isNil) - result = tmToTimeInfo(lt[], true) - # copying is needed anyway to provide reentrancity; thus - # the conversion is not expensive - - proc getGMTime(t: Time): TimeInfo = - var a = t - result = tmToTimeInfo(gmtime(addr(a))[], false) - # copying is needed anyway to provide reentrancity; thus - # the conversion is not expensive - - proc toTime(timeInfo: TimeInfo): Time = - var cTimeInfo = timeInfo # for C++ we have to make a copy - # because the header of mktime is broken in my version of libc - - result = mktime(timeInfoToTM(cTimeInfo)) - # mktime is defined to interpret the input as local time. As timeInfoToTM - # does ignore the timezone, we need to adjust this here. - result = Time(TimeImpl(result) - getTimezone() + timeInfo.timezone) - - proc timeInfoToTime(timeInfo: TimeInfo): Time = toTime(timeInfo) + proc getTime(): Time = + timec(nil).Time const epochDiff = 116444736000000000'i64 rateDiff = 10000000'i64 # 100 nsecs - proc unixTimeToWinTime*(t: Time): int64 = + proc unixTimeToWinTime*(time: CTime): int64 = ## converts a UNIX `Time` (``time_t``) to a Windows file time - result = int64(t) * rateDiff + epochDiff + result = int64(time) * rateDiff + epochDiff - proc winTimeToUnixTime*(t: int64): Time = + proc winTimeToUnixTime*(time: int64): CTime = ## converts a Windows time to a UNIX `Time` (``time_t``) - result = Time((t - epochDiff) div rateDiff) - - proc getTimezone(): int = - when defined(freebsd) or defined(netbsd) or defined(openbsd): - var a = timec(nil) - let lt = localtime(addr(a)) - # BSD stores in `gmtoff` offset east of UTC in seconds, - # but posix systems using west of UTC in seconds - return -(lt.gmtoff) - else: - return timezone - - proc fromSeconds(since1970: float): Time = Time(since1970) - - proc toSeconds(time: Time): float = float(time) + result = CTime((time - epochDiff) div rateDiff) when not defined(useNimRtl): proc epochTime(): float = @@ -1319,83 +1347,138 @@ when not defined(JS): proc cpuTime(): float = result = toFloat(int(getClock())) / toFloat(clocksPerSec) -elif defined(JS): - proc newDate(): Time {.importc: "new Date".} - proc internGetTime(): Time {.importc: "new Date", tags: [].} +# Deprecated procs - proc newDate(value: float): Time {.importc: "new Date".} - proc newDate(value: cstring): Time {.importc: "new Date".} - proc getTime(): Time = - # Warning: This is something different in JS. - return newDate() +proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], benign, deprecated.} = + ## Takes a float which contains the number of seconds since the unix epoch and + ## returns a time object. + ## + ## **Deprecated since v0.18.0:** use ``fromUnix`` instead + Time(since1970) - const - weekDays: array[0..6, WeekDay] = [ - dSun, dMon, dTue, dWed, dThu, dFri, dSat] - - proc getLocalTime(t: Time): TimeInfo = - result.second = t.getSeconds() - result.minute = t.getMinutes() - result.hour = t.getHours() - result.monthday = t.getDate() - result.month = Month(t.getMonth()) - result.year = t.getFullYear() - result.weekday = weekDays[t.getDay()] - result.timezone = getTimezone() - - result.yearday = result.monthday - 1 - for month in mJan..<result.month: - result.yearday += getDaysInMonth(month, result.year) - - proc getGMTime(t: Time): TimeInfo = - result.second = t.getUTCSeconds() - result.minute = t.getUTCMinutes() - result.hour = t.getUTCHours() - result.monthday = t.getUTCDate() - result.month = Month(t.getUTCMonth()) - result.year = t.getUTCFullYear() - result.weekday = weekDays[t.getUTCDay()] - - result.yearday = result.monthday - 1 - for month in mJan..<result.month: - result.yearday += getDaysInMonth(month, result.year) - - proc timeInfoToTime(timeInfo: TimeInfo): Time = toTime(timeInfo) - - proc toTime*(timeInfo: TimeInfo): Time = newDate($timeInfo) - - proc `-` (a, b: Time): int64 = - return a.getTime() - b.getTime() +proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign, deprecated.} = + ## Takes an int which contains the number of seconds since the unix epoch and + ## returns a time object. + ## + ## **Deprecated since v0.18.0:** use ``fromUnix`` instead + Time(since1970) - var - startMilsecs = getTime() +proc toSeconds*(time: Time): float {.tags: [], raises: [], benign, deprecated.} = + ## Returns the time in seconds since the unix epoch. + ## + ## **Deprecated since v0.18.0:** use ``toUnix`` instead + float(time) + +proc getLocalTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} = + ## Converts the calendar time `time` to broken-time representation, + ## expressed relative to the user's specified time zone. + ## + ## **Deprecated since v0.18.0:** use ``local`` instead + time.local - proc getStartMilsecs(): int = - ## get the milliseconds from the start of the program - return int(getTime() - startMilsecs) +proc getGMTime*(time: Time): DateTime {.tags: [], raises: [], benign, deprecated.} = + ## Converts the calendar time `time` to broken-down time representation, + ## expressed in Coordinated Universal Time (UTC). + ## + ## **Deprecated since v0.18.0:** use ``utc`` instead + time.utc - proc fromSeconds(since1970: float): Time = result = newDate(since1970 * 1000) +proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign, deprecated.} = + ## Returns the offset of the local (non-DST) timezone in seconds west of UTC. + ## + ## **Deprecated since v0.18.0:** use ``now().utcOffset`` to get the current + ## utc offset (including DST). + when defined(JS): + return newDate().getTimezoneOffset() * 60 + elif defined(freebsd) or defined(netbsd) or defined(openbsd): + var a = timec(nil) + let lt = localtime(addr(a)) + # BSD stores in `gmtoff` offset east of UTC in seconds, + # but posix systems using west of UTC in seconds + return -(lt.gmtoff) + else: + return timezone - proc toSeconds(time: Time): float = result = time.getTime() / 1000 +proc timeInfoToTime*(dt: DateTime): Time {.tags: [], benign, deprecated.} = + ## Converts a broken-down time structure to calendar time representation. + ## + ## **Warning:** This procedure is deprecated since version 0.14.0. + ## Use ``toTime`` instead. + dt.toTime + +when defined(JS): + var startMilsecs = getTime() + proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} = + ## get the milliseconds from the start of the program. **Deprecated since + ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead. + when defined(JS): + ## get the milliseconds from the start of the program + return int(getTime() - startMilsecs) +else: + proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.} = + when defined(macosx): + result = toInt(toFloat(int(getClock())) / (toFloat(clocksPerSec) / 1000.0)) + else: + result = int(getClock()) div (clocksPerSec div 1000) + +proc miliseconds*(t: TimeInterval): int {.deprecated.} = + t.milliseconds + +proc timeToTimeInterval*(t: Time): TimeInterval {.deprecated.} = + ## Converts a Time to a TimeInterval. + ## + ## **Warning:** This procedure is deprecated since version 0.14.0. + ## Use ``toTimeInterval`` instead. + # Milliseconds not available from Time + t.toTimeInterval() - proc getTimezone(): int = result = newDate().getTimezoneOffset() * 60 +proc timeToTimeInfo*(t: Time): DateTime {.deprecated.} = + ## Converts a Time to DateTime. + ## + ## **Warning:** This procedure is deprecated since version 0.14.0. + ## Use ``inZone`` instead. + const epochStartYear = 1970 - proc epochTime*(): float {.tags: [TimeEffect].} = newDate().toSeconds() + let + secs = t.toSeconds().int + daysSinceEpoch = secs div secondsInDay + (yearsSinceEpoch, daysRemaining) = countYearsAndDays(daysSinceEpoch) + daySeconds = secs mod secondsInDay + y = yearsSinceEpoch + epochStartYear -when isMainModule: - # this is testing non-exported function var - t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 - t4L = getLocalTime(fromSeconds(876124714)) - assert toSeconds(t4, initInterval(seconds=0)) == 0.0 - assert toSeconds(t4L, initInterval(milliseconds=1)) == toSeconds(t4, initInterval(milliseconds=1)) - assert toSeconds(t4L, initInterval(seconds=1)) == toSeconds(t4, initInterval(seconds=1)) - assert toSeconds(t4L, initInterval(minutes=1)) == toSeconds(t4, initInterval(minutes=1)) - assert toSeconds(t4L, initInterval(hours=1)) == toSeconds(t4, initInterval(hours=1)) - assert toSeconds(t4L, initInterval(days=1)) == toSeconds(t4, initInterval(days=1)) - assert toSeconds(t4L, initInterval(months=1)) == toSeconds(t4, initInterval(months=1)) - assert toSeconds(t4L, initInterval(years=1)) == toSeconds(t4, initInterval(years=1)) - - # Further tests are in tests/stdlib/ttime.nim - # koch test c stdlib + mon = mJan + days = daysRemaining + daysInMonth = getDaysInMonth(mon, y) + + # calculate month and day remainder + while days > daysInMonth and mon <= mDec: + days -= daysInMonth + mon.inc + daysInMonth = getDaysInMonth(mon, y) + + let + yd = daysRemaining + m = mon # month is zero indexed enum + md = days + # NB: month is zero indexed but dayOfWeek expects 1 indexed. + wd = getDayOfWeek(days, mon, y).Weekday + h = daySeconds div secondsInHour + 1 + mi = (daySeconds mod secondsInHour) div secondsInMin + s = daySeconds mod secondsInMin + result = DateTime(year: y, yearday: yd, month: m, monthday: md, weekday: wd, hour: h, minute: mi, second: s) + +proc getDayOfWeek*(day, month, year: int): WeekDay {.tags: [], raises: [], benign, deprecated.} = + getDayOfWeek(day, month.Month, year) + +proc getDayOfWeekJulian*(day, month, year: int): WeekDay {.deprecated.} = + ## Returns the day of the week enum from day, month and year, + ## according to the Julian calendar. + # Day & month start from one. + let + a = (14 - month) div 12 + y = year - a + m = month + (12*a) - 2 + d = (5 + day + y + (y div 4) + (31*m) div 12) mod 7 + result = d.WeekDay diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index 55c4bf038..2047abda4 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -21,7 +21,7 @@ proc name*(t: typedesc): string {.magic: "TypeTrait".} ## ## proc `$`*(T: typedesc): string = name(T) ## - ## template test(x): stmt = + ## template test(x): typed = ## echo "type: ", type(x), ", value: ", x ## ## test 42 @@ -31,6 +31,10 @@ proc name*(t: typedesc): string {.magic: "TypeTrait".} ## test(@['A','B']) ## # --> type: seq[char], value: @[A, B] +proc `$`*(t: typedesc): string = + ## An alias for `name`. + name(t) + proc arity*(t: typedesc): int {.magic: "TypeTrait".} ## Returns the arity of the given type @@ -49,3 +53,15 @@ proc stripGenericParams*(t: typedesc): typedesc {.magic: "TypeTrait".} ## This trait is similar to `genericHead`, but instead of producing ## error for non-generic types, it will just return them unmodified +proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".} + ## This trait returns true iff the type ``t`` is safe to use for + ## `copyMem`:idx:. Other languages name a type like these `blob`:idx:. + + +when isMainModule: + # echo type(42) + import streams + var ss = newStringStream() + ss.write($type(42)) # needs `$` + ss.setPosition(0) + doAssert ss.readAll() == "int" diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index 7d9c3108b..257c620f7 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -293,33 +293,33 @@ proc runeSubStr*(s: string, pos:int, len:int = int.high): string = if pos < 0: let (o, rl) = runeReverseOffset(s, -pos) if len >= rl: - result = s[o.. s.len-1] + result = s.substr(o, s.len-1) elif len < 0: let e = rl + len if e < 0: result = "" else: - result = s[o.. runeOffset(s, e-(rl+pos) , o)-1] + result = s.substr(o, runeOffset(s, e-(rl+pos) , o)-1) else: - result = s[o.. runeOffset(s, len, o)-1] + result = s.substr(o, runeOffset(s, len, o)-1) else: let o = runeOffset(s, pos) if o < 0: result = "" elif len == int.high: - result = s[o.. s.len-1] + result = s.substr(o, s.len-1) elif len < 0: let (e, rl) = runeReverseOffset(s, -len) discard rl if e <= 0: result = "" else: - result = s[o.. e-1] + result = s.substr(o, e-1) else: var e = runeOffset(s, len, o) if e < 0: e = s.len - result = s[o.. e-1] + result = s.substr(o, e-1) const alphaRanges = [ diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 3772a213a..fbce087ff 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -21,13 +21,41 @@ ## ``nim c -r <testfile.nim>`` exits with 0 or 1 ## ## Running a single test -## --------------------- +## ===================== ## -## Simply specify the test name as a command line argument. +## Specify the test name as a command line argument. ## ## .. code:: ## -## nim c -r test "my super awesome test name" +## nim c -r test "my test name" "another test" +## +## Multiple arguments can be used. +## +## Running a single test suite +## =========================== +## +## Specify the suite name delimited by ``"::"``. +## +## .. code:: +## +## nim c -r test "my test name::" +## +## Selecting tests by pattern +## ========================== +## +## A single ``"*"`` can be used for globbing. +## +## Delimit the end of a suite name with ``"::"``. +## +## Tests matching **any** of the arguments are executed. +## +## .. code:: +## +## nim c -r test fast_suite::mytest1 fast_suite::mytest2 +## nim c -r test "fast_suite::mytest*" +## nim c -r test "auth*::" "crypto::hashing*" +## # Run suites starting with 'bug #' and standalone tests starting with '#' +## nim c -r test 'bug #*::' '::#*' ## ## Example ## ------- @@ -121,7 +149,7 @@ var checkpoints {.threadvar.}: seq[string] formatters {.threadvar.}: seq[OutputFormatter] - testsToRun {.threadvar.}: HashSet[string] + testsFilters {.threadvar.}: HashSet[string] when declared(stdout): abortOnError = existsEnv("NIMTEST_ABORT_ON_ERROR") @@ -300,22 +328,63 @@ method testEnded*(formatter: JUnitOutputFormatter, testResult: TestResult) = method suiteEnded*(formatter: JUnitOutputFormatter) = formatter.stream.writeLine("\t</testsuite>") -proc shouldRun(testName: string): bool = - if testsToRun.len == 0: +proc glob(matcher, filter: string): bool = + ## Globbing using a single `*`. Empty `filter` matches everything. + if filter.len == 0: return true - result = testName in testsToRun + if not filter.contains('*'): + return matcher == filter + + let beforeAndAfter = filter.split('*', maxsplit=1) + if beforeAndAfter.len == 1: + # "foo*" + return matcher.startswith(beforeAndAfter[0]) + + if matcher.len < filter.len - 1: + return false # "12345" should not match "123*345" + + return matcher.startsWith(beforeAndAfter[0]) and matcher.endsWith(beforeAndAfter[1]) + +proc matchFilter(suiteName, testName, filter: string): bool = + if filter == "": + return true + if testName == filter: + # corner case for tests containing "::" in their name + return true + let suiteAndTestFilters = filter.split("::", maxsplit=1) + + if suiteAndTestFilters.len == 1: + # no suite specified + let test_f = suiteAndTestFilters[0] + return glob(testName, test_f) + + return glob(suiteName, suiteAndTestFilters[0]) and glob(testName, suiteAndTestFilters[1]) + +when defined(testing): export matchFilter + +proc shouldRun(currentSuiteName, testName: string): bool = + ## Check if a test should be run by matching suiteName and testName against + ## test filters. + if testsFilters.len == 0: + return true + + for f in testsFilters: + if matchFilter(currentSuiteName, testName, f): + return true + + return false proc ensureInitialized() = if formatters == nil: formatters = @[OutputFormatter(defaultConsoleFormatter())] - if not testsToRun.isValid: - testsToRun.init() - when declared(os): + if not testsFilters.isValid: + testsFilters.init() + when declared(paramCount): # Read tests to run from the command line. for i in 1 .. paramCount(): - testsToRun.incl(paramStr(i)) + testsFilters.incl(paramStr(i)) # These two procs are added as workarounds for # https://github.com/nim-lang/Nim/issues/5549 @@ -395,7 +464,7 @@ template test*(name, body) {.dirty.} = ensureInitialized() - if shouldRun(name): + if shouldRun(when declared(testSuiteName): testSuiteName else: "", name): checkpoints = @[] var testStatusIMPL {.inject.} = OK diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index 4b2e4e052..a651530c3 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -47,6 +47,49 @@ proc add*(url: var Url, a: Url) {.deprecated.} = url = url / a {.pop.} +proc encodeUrl*(s: string): string = + ## Encodes a value to be HTTP safe: This means that characters in the set + ## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result, + ## a space is converted to ``'+'`` and every other character is encoded as + ## ``'%xx'`` where ``xx`` denotes its hexadecimal value. + result = newStringOfCap(s.len + s.len shr 2) # assume 12% non-alnum-chars + for i in 0..s.len-1: + case s[i] + of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(result, s[i]) + of ' ': add(result, '+') + else: + add(result, '%') + add(result, toHex(ord(s[i]), 2)) + +proc decodeUrl*(s: string): string = + ## Decodes a value from its HTTP representation: This means that a ``'+'`` + ## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal + ## value) is converted to the character with ordinal number ``xx``, and + ## and every other character is carried over. + proc handleHexChar(c: char, x: var int) {.inline.} = + case c + of '0'..'9': x = (x shl 4) or (ord(c) - ord('0')) + of 'a'..'f': x = (x shl 4) or (ord(c) - ord('a') + 10) + of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10) + else: assert(false) + + result = newString(s.len) + var i = 0 + var j = 0 + while i < s.len: + case s[i] + of '%': + var x = 0 + handleHexChar(s[i+1], x) + handleHexChar(s[i+2], x) + inc(i, 2) + result[j] = chr(x) + of '+': result[j] = ' ' + else: result[j] = s[i] + inc(i) + inc(j) + setLen(result, j) + proc parseAuthority(authority: string, result: var Uri) = var i = 0 var inPort = false @@ -250,7 +293,7 @@ proc combine*(base: Uri, reference: Uri): Uri = proc combine*(uris: varargs[Uri]): Uri = ## Combines multiple URIs together. result = uris[0] - for i in 1 .. <uris.len: + for i in 1 ..< uris.len: result = combine(result, uris[i]) proc isAbsolute*(uri: Uri): bool = @@ -308,11 +351,16 @@ proc `$`*(u: Uri): string = result.add(":") result.add(u.password) result.add("@") - result.add(u.hostname) + if u.hostname.endswith('/'): + result.add(u.hostname[0..^2]) + else: + result.add(u.hostname) if u.port.len > 0: result.add(":") result.add(u.port) if u.path.len > 0: + if u.hostname.len > 0 and u.path[0] != '/': + result.add('/') result.add(u.path) if u.query.len > 0: result.add("?") @@ -323,6 +371,11 @@ proc `$`*(u: Uri): string = when isMainModule: block: + const test1 = "abc\L+def xyz" + doAssert encodeUrl(test1) == "abc%0A%2Bdef+xyz" + doAssert decodeUrl(encodeUrl(test1)) == test1 + + block: let str = "http://localhost" let test = parseUri(str) doAssert test.path == "" @@ -483,6 +536,34 @@ when isMainModule: let foo = parseUri("http://localhost:9515") / "status" doAssert $foo == "http://localhost:9515/status" + # bug #6649 #6652 + block: + var foo = parseUri("http://example.com") + foo.hostname = "example.com" + foo.path = "baz" + doAssert $foo == "http://example.com/baz" + + foo.hostname = "example.com/" + foo.path = "baz" + doAssert $foo == "http://example.com/baz" + + foo.hostname = "example.com" + foo.path = "/baz" + doAssert $foo == "http://example.com/baz" + + foo.hostname = "example.com/" + foo.path = "/baz" + doAssert $foo == "http://example.com/baz" + + foo.hostname = "example.com/" + foo.port = "8000" + foo.path = "baz" + doAssert $foo == "http://example.com:8000/baz" + + foo = parseUri("file:/dir/file") + foo.path = "relative" + doAssert $foo == "file:relative" + # isAbsolute tests block: doAssert "www.google.com".parseUri().isAbsolute() == false @@ -524,4 +605,4 @@ when isMainModule: doAssert "https://example.com/about/staff.html?".parseUri().isAbsolute == true doAssert "https://example.com/about/staff.html?parameters".parseUri().isAbsolute == true - echo("All good!") \ No newline at end of file + echo("All good!") diff --git a/lib/system.nim b/lib/system.nim index d19a406cb..4d8610737 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -285,6 +285,13 @@ proc low*(x: string): int {.magic: "Low", noSideEffect.} ## low(2) #=> -9223372036854775808 ## low(int) #=> -9223372036854775808 +proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".} + ## use this instead of `=` for a `shallow copy`:idx:. The shallow copy + ## only changes the semantics for sequences and strings (and types which + ## contain those). Be careful with the changed semantics though! There + ## is a reason why the default assignment does a deep copy of sequences + ## and strings. + when defined(nimArrIdx): # :array|openarray|string|seq|cstring|tuple proc `[]`*[I: Ordinal;T](a: T; i: I): T {. @@ -292,15 +299,21 @@ when defined(nimArrIdx): proc `[]=`*[I: Ordinal;T,S](a: T; i: I; x: S) {.noSideEffect, magic: "ArrPut".} proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".} + when defined(nimNewRuntime): + proc `=destroy`*[T](x: var T) {.inline, magic: "Asgn".} = + ## generic `destructor`:idx: implementation that can be overriden. + discard + proc `=sink`*[T](x: var T; y: T) {.inline, magic: "Asgn".} = + ## generic `sink`:idx: implementation that can be overriden. + shallowCopy(x, y) type - Slice*[T] = object ## builtin slice type - a*, b*: T ## the bounds + HSlice*[T, U] = object ## "heterogenous" slice type + a*: T ## the lower bound (inclusive) + b*: U ## the upper bound (inclusive) + Slice*[T] = HSlice[T, T] ## an alias for ``HSlice[T, T]`` -when defined(nimalias): - {.deprecated: [TSlice: Slice].} - -proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} = +proc `..`*[T, U](a: T, b: U): HSlice[T, U] {.noSideEffect, inline, magic: "DotDot".} = ## `slice`:idx: operator that constructs an interval ``[a, b]``, both `a` ## and `b` are inclusive. Slices can also be used in the set constructor ## and in ordinal case statements, but then they are special-cased by the @@ -308,8 +321,8 @@ proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} = result.a = a result.b = b -proc `..`*[T](b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} = - ## `slice`:idx: operator that constructs an interval ``[default(T), b]`` +proc `..`*[T](b: T): HSlice[int, T] {.noSideEffect, inline, magic: "DotDot".} = + ## `slice`:idx: operator that constructs an interval ``[default(int), b]`` result.b = b when not defined(niminheritable): @@ -443,7 +456,14 @@ type WriteIOEffect* = object of IOEffect ## Effect describing a write IO operation. ExecIOEffect* = object of IOEffect ## Effect describing an executing IO operation. - Exception* {.compilerproc.} = object of RootObj ## \ + StackTraceEntry* = object ## In debug mode exceptions store the stack trace that led + ## to them. A StackTraceEntry is a single entry of the + ## stack trace. + procname*: cstring ## name of the proc that is currently executing + line*: int ## line number of the proc that is currently executing + filename*: cstring ## filename of the proc that is currently executing + + Exception* {.compilerproc, magic: "Exception".} = object of RootObj ## \ ## Base exception class. ## ## Each exception has to inherit from `Exception`. See the full `exception @@ -455,7 +475,10 @@ type msg* {.exportc: "message".}: string ## the exception's message. Not ## providing an exception message ## is bad style. - trace: string + when defined(js): + trace: string + else: + trace: seq[StackTraceEntry] up: ref Exception # used for stacking exceptions. Not exported! SystemError* = object of Exception ## \ @@ -638,13 +661,17 @@ proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect.} when defined(nimtypedescfixed): proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.} -proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect.} +proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect, deprecated.} ## unary ``<`` that can be used for nice looking excluding ranges: ## ## .. code-block:: nim ## for i in 0 .. <10: echo i #=> 0 1 2 3 4 5 6 7 8 9 ## ## Semantically this is the same as ``pred``. + ## + ## **Deprecated since version 0.18.0**. For the common excluding range + ## write ``0 ..< 10`` instead of ``0 .. < 10`` (look at the spacing). + ## For ``<x`` write ``pred(x)``. proc succ*[T](x: Ordinal[T], y = 1): T {.magic: "Succ", noSideEffect.} ## returns the ``y``-th successor of the value ``x``. ``T`` has to be @@ -716,6 +743,18 @@ proc newSeqOfCap*[T](cap: Natural): seq[T] {. ## ``cap``. discard +when not defined(JS): + proc newSeqUninitialized*[T: SomeNumber](len: Natural): seq[T] = + ## creates a new sequence of type ``seq[T]`` with length ``len``. + ## + ## Only available for numbers types. Note that the sequence will be + ## uninitialized. After the creation of the sequence you should assign + ## entries to the sequence instead of adding them. + + result = newSeqOfCap[T](len) + var s = cast[PGenericSeq](result) + s.len = len + proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {. magic: "LengthOpenArray", noSideEffect.} proc len*(x: string): int {.magic: "LengthStr", noSideEffect.} @@ -878,7 +917,7 @@ proc `div` *(x, y: int8): int8 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int16): int16 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.} ## computes the integer division. This is roughly the same as - ## ``floor(x/y)``. + ## ``trunc(x/y)``. ## ## .. code-block:: Nim ## 1 div 2 == 0 @@ -1080,7 +1119,7 @@ proc `*`*[T: SomeUnsignedInt](x, y: T): T {.magic: "MulU", noSideEffect.} proc `div`*[T: SomeUnsignedInt](x, y: T): T {.magic: "DivU", noSideEffect.} ## computes the integer division. This is roughly the same as - ## ``floor(x/y)``. + ## ``trunc(x/y)``. ## ## .. code-block:: Nim ## (7 div 5) == 1 @@ -1150,7 +1189,7 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## is achieved by reversing the parameters for ``contains``; ``in`` then ## passes its arguments in reverse order. -proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = +proc contains*[U, V, W](s: HSlice[U, V], value: W): bool {.noSideEffect, inline.} = ## Checks if `value` is within the range of `s`; returns true iff ## `value >= s.a and value <= s.b` ## @@ -1298,6 +1337,7 @@ proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} ## tmp.add("cd") ## assert(tmp == "abcd") + type Endianness* = enum ## is a type describing the endianness of a processor. littleEndian, bigEndian @@ -1412,7 +1452,11 @@ const ## is the value that should be passed to `quit <#quit>`_ to indicate ## failure. -var programResult* {.exportc: "nim_program_result".}: int +when defined(nodejs): + var programResult* {.importc: "process.exitCode".}: int + programResult = 0 +else: + var programResult* {.exportc: "nim_program_result".}: int ## modify this variable to specify the exit code of the program ## under normal circumstances. When the program is terminated ## prematurely using ``quit``, this value is ignored. @@ -1429,7 +1473,8 @@ when defined(nimdoc): ## <#GC_fullCollect>`_. ## ## The proc ``quit(QuitSuccess)`` is called implicitly when your nim - ## program finishes without incident. A raised unhandled exception is + ## program finishes without incident for platforms where this is the + ## expected behavior. A raised unhandled exception is ## equivalent to calling ``quit(QuitFailure)``. ## ## Note that this is a *runtime* call and using ``quit`` inside a macro won't @@ -1480,13 +1525,6 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} = setLen(x, xl + y.len) for i in 0..high(y): x[xl+i] = y[i] -proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".} - ## use this instead of `=` for a `shallow copy`:idx:. The shallow copy - ## only changes the semantics for sequences and strings (and types which - ## contain those). Be careful with the changed semantics though! There - ## is a reason why the default assignment does a deep copy of sequences - ## and strings. - proc del*[T](x: var seq[T], i: Natural) {.noSideEffect.} = ## deletes the item at index `i` by putting ``x[high(x)]`` into position `i`. ## This is an O(1) operation. @@ -1507,7 +1545,7 @@ proc delete*[T](x: var seq[T], i: Natural) {.noSideEffect.} = ## i.delete(2) #=> @[1, 2, 4, 5] template defaultImpl = let xl = x.len - for j in i..xl-2: shallowCopy(x[j], x[j+1]) + for j in i.int..xl-2: shallowCopy(x[j], x[j+1]) setLen(x, xl-1) when nimvm: @@ -1974,34 +2012,80 @@ iterator countdown*[T](a, b: T, step = 1): T {.inline.} = yield res dec(res, step) -iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} = - ## Counts from ordinal value `a` up to `b` (inclusive) with the given - ## step count. `S`, `T` may be any ordinal type, `step` may only - ## be positive. **Note**: This fails to count to ``high(int)`` if T = int for - ## efficiency reasons. - when T is IntLikeForCount: - var res = int(a) - while res <= int(b): - yield T(res) - inc(res, step) - else: - var res: T = T(a) - while res <= b: - yield res - inc(res, step) +when defined(nimNewRoof): + iterator countup*[T](a, b: T, step = 1): T {.inline.} = + ## Counts from ordinal value `a` up to `b` (inclusive) with the given + ## step count. `S`, `T` may be any ordinal type, `step` may only + ## be positive. **Note**: This fails to count to ``high(int)`` if T = int for + ## efficiency reasons. + when T is IntLikeForCount: + var res = int(a) + while res <= int(b): + yield T(res) + inc(res, step) + else: + var res: T = T(a) + while res <= b: + yield res + inc(res, step) + + iterator `..`*[T](a, b: T): T {.inline.} = + ## An alias for `countup`. + when T is IntLikeForCount: + var res = int(a) + while res <= int(b): + yield T(res) + inc(res) + else: + var res: T = T(a) + while res <= b: + yield res + inc(res) + + template dotdotImpl(t) {.dirty.} = + iterator `..`*(a, b: t): t {.inline.} = + ## A type specialized version of ``..`` for convenience so that + ## mixing integer types work better. + var res = a + while res <= b: + yield res + inc(res) + + dotdotImpl(int64) + dotdotImpl(int32) + dotdotImpl(uint64) + dotdotImpl(uint32) + +else: + iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} = + ## Counts from ordinal value `a` up to `b` (inclusive) with the given + ## step count. `S`, `T` may be any ordinal type, `step` may only + ## be positive. **Note**: This fails to count to ``high(int)`` if T = int for + ## efficiency reasons. + when T is IntLikeForCount: + var res = int(a) + while res <= int(b): + yield T(res) + inc(res, step) + else: + var res: T = T(a) + while res <= b: + yield res + inc(res, step) + + iterator `..`*[S, T](a: S, b: T): T {.inline.} = + ## An alias for `countup`. + when T is IntLikeForCount: + var res = int(a) + while res <= int(b): + yield T(res) + inc(res) + else: + var res: T = T(a) + while res <= b: + yield res + inc(res) -iterator `..`*[S, T](a: S, b: T): T {.inline.} = - ## An alias for `countup`. - when T is IntLikeForCount: - var res = int(a) - while res <= int(b): - yield T(res) - inc(res) - else: - var res: T = T(a) - while res <= b: - yield res - inc(res) iterator `||`*[S, T](a: S, b: T, annotation=""): T {. inline, magic: "OmpParFor", sideEffect.} = @@ -2065,6 +2149,9 @@ proc max*[T](x, y: T): T = if y <= x: x else: y {.pop.} +proc high*(T: typedesc[SomeReal]): T = Inf +proc low*(T: typedesc[SomeReal]): T = NegInf + proc clamp*[T](x, a, b: T): T = ## limits the value ``x`` within the interval [a, b] ## @@ -2075,7 +2162,7 @@ proc clamp*[T](x, a, b: T): T = if x > b: return b return x -proc len*[T: Ordinal](x: Slice[T]): int {.noSideEffect, inline.} = +proc len*[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int {.noSideEffect, inline.} = ## length of ordinal slice, when x.b < x.a returns zero length ## ## .. code-block:: Nim @@ -2143,7 +2230,7 @@ iterator items*(E: typedesc[enum]): E = for v in low(E)..high(E): yield v -iterator items*[T](s: Slice[T]): T = +iterator items*[T](s: HSlice[T, T]): T = ## iterates over the slice `s`, yielding each value between `s.a` and `s.b` ## (inclusively). for x in s.a..s.b: @@ -2429,9 +2516,9 @@ proc `$`*[T: tuple|object](x: T): string = when compiles($value): when compiles(value.isNil): if value.isNil: result.add "nil" - else: result.add($value) + else: result.addQuoted(value) else: - result.add($value) + result.addQuoted(value) firstElement = false else: result.add("...") @@ -2451,12 +2538,9 @@ proc collectionToString[T](x: T, prefix, separator, suffix: string): string = if value.isNil: result.add "nil" else: - result.add($value) - # prevent temporary string allocation - elif compiles(result.add(value)): - result.add(value) + result.addQuoted(value) else: - result.add($value) + result.addQuoted(value) result.add(suffix) @@ -2703,9 +2787,9 @@ when defined(nimvarargstyped): ## pretends to be free of side effects, so that it can be used for debugging ## routines marked as `noSideEffect <manual.html#pragmas-nosideeffect-pragma>`_. else: - proc echo*(x: varargs[expr, `$`]) {.magic: "Echo", tags: [WriteIOEffect], + proc echo*(x: varargs[untyped, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign, sideEffect.} - proc debugEcho*(x: varargs[expr, `$`]) {.magic: "Echo", noSideEffect, + proc debugEcho*(x: varargs[untyped, `$`]) {.magic: "Echo", noSideEffect, tags: [], raises: [].} template newException*(exceptn: typedesc, message: string; @@ -2821,7 +2905,7 @@ when not defined(JS): #and not defined(nimscript): fmRead, ## Open the file for read access only. fmWrite, ## Open the file for write access only. ## If the file does not exist, it will be - ## created. + ## created. Existing files will be cleared! fmReadWrite, ## Open the file for read and write access. ## If the file does not exist, it will be ## created. Existing files will be cleared! @@ -2844,7 +2928,10 @@ when not defined(JS): #and not defined(nimscript): elif x > y: result = 1 else: result = 0 else: - result = int(c_strcmp(x, y)) + let minlen = min(x.len, y.len) + result = int(c_memcmp(x.cstring, y.cstring, minlen.csize)) + if result == 0: + result = x.len - y.len when defined(nimscript): proc readFile*(filename: string): string {.tags: [ReadIOEffect], benign.} @@ -3048,9 +3135,6 @@ when not defined(JS): #and not defined(nimscript): ## returns the OS file handle of the file ``f``. This is only useful for ## platform specific programming. - when not defined(nimfix): - {.deprecated: [fileHandle: getFileHandle].} - when declared(newSeq): proc cstringArrayToSeq*(a: cstringArray, len: Natural): seq[string] = ## converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be @@ -3402,6 +3486,36 @@ proc `/`*(x, y: int): float {.inline, noSideEffect.} = ## integer division that results in a float. result = toFloat(x) / toFloat(y) +type + BackwardsIndex* = distinct int ## type that is constructed by ``^`` for + ## reversed array accesses. + +template `^`*(x: int): BackwardsIndex = BackwardsIndex(x) + ## builtin `roof`:idx: operator that can be used for convenient array access. + ## ``a[^x]`` is a shortcut for ``a[a.len-x]``. + +template `..^`*(a, b: untyped): untyped = + ## a shortcut for '.. ^' to avoid the common gotcha that a space between + ## '..' and '^' is required. + a .. ^b + +template `..<`*(a, b: untyped): untyped = + ## a shortcut for 'a..pred(b)'. + a .. pred(b) + +when defined(nimNewRoof): + iterator `..<`*[T](a, b: T): T = + var i = T(a) + while i < b: + yield i + inc i +else: + iterator `..<`*[S, T](a: S, b: T): T = + var i = T(a) + while i < b: + yield i + inc i + template spliceImpl(s, a, L, b: untyped): untyped = # make room for additional elements or cut: var shift = b.len - max(0,L) # ignore negative slice size @@ -3415,19 +3529,25 @@ template spliceImpl(s, a, L, b: untyped): untyped = # cut down: setLen(s, newLen) # fill the hole: - for i in 0 .. <b.len: s[a+i] = b[i] + for i in 0 ..< b.len: s[a+i] = b[i] + +template `^^`(s, i: untyped): untyped = + (when i is BackwardsIndex: s.len - int(i) else: int(i)) when hasAlloc or defined(nimscript): - proc `[]`*(s: string, x: Slice[int]): string {.inline.} = + proc `[]`*[T, U](s: string, x: HSlice[T, U]): string {.inline.} = ## slice operation for strings. ## returns the inclusive range [s[x.a], s[x.b]]: ## ## .. code-block:: nim ## var s = "abcdef" ## assert s[1..3] == "bcd" - result = s.substr(x.a, x.b) + let a = s ^^ x.a + let L = (s ^^ x.b) - a + 1 + result = newString(L) + for i in 0 ..< L: result[i] = s[i + a] - proc `[]=`*(s: var string, x: Slice[int], b: string) = + proc `[]=`*[T, U](s: var string, x: HSlice[T, U], b: string) = ## slice assignment for strings. If ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed: @@ -3436,75 +3556,76 @@ when hasAlloc or defined(nimscript): ## var s = "abcdef" ## s[1 .. ^2] = "xyz" ## assert s == "axyzf" - var a = x.a - var L = x.b - a + 1 + var a = s ^^ x.a + var L = (s ^^ x.b) - a + 1 if L == b.len: - for i in 0 .. <L: s[i+a] = b[i] + for i in 0..<L: s[i+a] = b[i] else: spliceImpl(s, a, L, b) -proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[int]): seq[T] = +proc `[]`*[Idx, T, U, V](a: array[Idx, T], x: HSlice[U, V]): seq[T] = ## slice operation for arrays. ## returns the inclusive range [a[x.a], a[x.b]]: ## ## .. code-block:: nim ## var a = [1,2,3,4] ## assert a[0..2] == @[1,2,3] - when low(a) < 0: - {.error: "Slicing for arrays with negative indices is unsupported.".} - var L = x.b - x.a + 1 + let xa = a ^^ x.a + let L = (a ^^ x.b) - xa + 1 result = newSeq[T](L) - for i in 0.. <L: result[i] = a[i + x.a] + for i in 0..<L: result[i] = a[Idx(i + xa)] -proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[int], b: openArray[T]) = +proc `[]=`*[Idx, T, U, V](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) = ## slice assignment for arrays. - when low(a) < 0: - {.error: "Slicing for arrays with negative indices is unsupported.".} - var L = x.b - x.a + 1 + let xa = a ^^ x.a + let L = (a ^^ x.b) - xa + 1 if L == b.len: - for i in 0 .. <L: a[i+x.a] = b[i] + for i in 0..<L: a[Idx(i + xa)] = b[i] else: sysFatal(RangeError, "different lengths for slice assignment") -proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[Idx]): seq[T] = - ## slice operation for arrays. - var L = ord(x.b) - ord(x.a) + 1 - newSeq(result, L) - for i in 0.. <L: - result[i] = a[Idx(ord(x.a) + i)] - -proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[Idx], b: openArray[T]) = - ## slice assignment for arrays. - var L = ord(x.b) - ord(x.a) + 1 - if L == b.len: - for i in 0 .. <L: - a[Idx(ord(x.a) + i)] = b[i] - else: - sysFatal(RangeError, "different lengths for slice assignment") - -proc `[]`*[T](s: seq[T], x: Slice[int]): seq[T] = +proc `[]`*[T, U, V](s: openArray[T], x: HSlice[U, V]): seq[T] = ## slice operation for sequences. ## returns the inclusive range [s[x.a], s[x.b]]: ## ## .. code-block:: nim ## var s = @[1,2,3,4] ## assert s[0..2] == @[1,2,3] - var a = x.a - var L = x.b - a + 1 + let a = s ^^ x.a + let L = (s ^^ x.b) - a + 1 newSeq(result, L) - for i in 0.. <L: result[i] = s[i + a] + for i in 0 ..< L: result[i] = s[i + a] -proc `[]=`*[T](s: var seq[T], x: Slice[int], b: openArray[T]) = +proc `[]=`*[T, U, V](s: var seq[T], x: HSlice[U, V], b: openArray[T]) = ## slice assignment for sequences. If ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed. - var a = x.a - var L = x.b - a + 1 + let a = s ^^ x.a + let L = (s ^^ x.b) - a + 1 if L == b.len: - for i in 0 .. <L: s[i+a] = b[i] + for i in 0 ..< L: s[i+a] = b[i] else: spliceImpl(s, a, L, b) +proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} = + system.`[]`(s, s.len - int(i)) + +proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} = + a[Idx(a.len - int(i) + int low(a))] +proc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)] + +proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} = + system.`[]`(s, s.len - int(i)) +proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} = + a[Idx(a.len - int(i) + int low(a))] + +proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} = + system.`[]=`(s, s.len - int(i), x) +proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} = + a[Idx(a.len - int(i) + int low(a))] = x +proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} = + s[s.len - int(i)] = x + proc slurp*(filename: string): string {.magic: "Slurp".} ## This is an alias for `staticRead <#staticRead>`_. @@ -3612,7 +3733,7 @@ proc instantiationInfo*(index = -1, fullPaths = false): tuple[ ## .. code-block:: nim ## import strutils ## - ## template testException(exception, code: expr): stmt = + ## template testException(exception, code: untyped): typed = ## try: ## let pos = instantiationInfo() ## discard(code) @@ -3651,6 +3772,7 @@ template assert*(cond: bool, msg = "") = ## that ``AssertionError`` is hidden from the effect system, so it doesn't ## produce ``{.raises: [AssertionError].}``. This exception is only supposed ## to be caught by unit testing frameworks. + ## ## The compiler may not generate any code at all for ``assert`` if it is ## advised to do so through the ``-d:release`` or ``--assertions:off`` ## `command line switches <nimc.html#command-line-switches>`_. @@ -3750,11 +3872,11 @@ type {.deprecated: [PNimrodNode: NimNode].} when false: - template eval*(blk: stmt): stmt = + template eval*(blk: typed): typed = ## executes a block of code at compile time just as if it was a macro ## optionally, the block can return an AST tree that will replace the ## eval expression - macro payload: stmt {.gensym.} = blk + macro payload: typed {.gensym.} = blk payload() when hasAlloc: @@ -3784,6 +3906,65 @@ proc compiles*(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime. when declared(initDebugger): initDebugger() +proc addEscapedChar*(s: var string, c: char) {.noSideEffect, inline.} = + ## Adds a char to string `s` and applies the following escaping: + ## + ## * replaces any ``\`` by ``\\`` + ## * replaces any ``'`` by ``\'`` + ## * replaces any ``"`` by ``\"`` + ## * replaces any other character in the set ``{'\0'..'\31', '\127'..'\255'}`` + ## by ``\xHH`` where ``HH`` is its hexadecimal value. + ## + ## The procedure has been designed so that its output is usable for many + ## different common syntaxes. + ## **Note**: This is not correct for producing Ansi C code! + case c + of '\0'..'\31', '\127'..'\255': + add(s, "\\x") + const HexChars = "0123456789ABCDEF" + let n = ord(c) + s.add(HexChars[int((n and 0xF0) shr 4)]) + s.add(HexChars[int(n and 0xF)]) + of '\\': add(s, "\\\\") + of '\'': add(s, "\\'") + of '\"': add(s, "\\\"") + else: add(s, c) + +proc addQuoted*[T](s: var string, x: T) = + ## Appends `x` to string `s` in place, applying quoting and escaping + ## if `x` is a string or char. See + ## `addEscapedChar <system.html#addEscapedChar>`_ + ## for the escaping scheme. + ## + ## The Nim standard library uses this function on the elements of + ## collections when producing a string representation of a collection. + ## It is recommended to use this function as well for user-side collections. + ## Users may overload `addQuoted` for custom (string-like) types if + ## they want to implement a customized element representation. + ## + ## .. code-block:: Nim + ## var tmp = "" + ## tmp.addQuoted(1) + ## tmp.add(", ") + ## tmp.addQuoted("string") + ## tmp.add(", ") + ## tmp.addQuoted('c') + ## assert(tmp == """1, "string", 'c'""") + when T is string: + s.add("\"") + for c in x: + s.addEscapedChar(c) + s.add("\"") + elif T is char: + s.add("'") + s.addEscapedChar(x) + s.add("'") + # prevent temporary string allocation + elif compiles(s.add(x)): + s.add(x) + else: + s.add($x) + when hasAlloc: # XXX: make these the default (or implement the NilObject optimization) proc safeAdd*[T](x: var seq[T], y: T) {.noSideEffect.} = @@ -3845,31 +4026,6 @@ proc procCall*(x: untyped) {.magic: "ProcCall", compileTime.} = ## procCall someMethod(a, b) discard -proc `^`*[T](x: int; y: openArray[T]): int {.noSideEffect, magic: "Roof".} -proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} = - ## builtin `roof`:idx: operator that can be used for convenient array access. - ## ``a[^x]`` is rewritten to ``a[a.len-x]``. However currently the ``a`` - ## expression must not have side effects for this to compile. Note that since - ## this is a builtin, it automatically works for all kinds of - ## overloaded ``[]`` or ``[]=`` accessors. - discard - -template `..^`*(a, b: untyped): untyped = - ## a shortcut for '.. ^' to avoid the common gotcha that a space between - ## '..' and '^' is required. - a .. ^b - -template `..<`*(a, b: untyped): untyped {.dirty.} = - ## a shortcut for '.. <' to avoid the common gotcha that a space between - ## '..' and '<' is required. - a .. <b - -iterator `..<`*[S,T](a: S, b: T): T = - var i = T(a) - while i < b: - yield i - inc i - proc xlen*(x: string): int {.magic: "XLenStr", noSideEffect.} = discard proc xlen*[T](x: seq[T]): int {.magic: "XLenSeq", noSideEffect.} = ## returns the length of a sequence or a string without testing for 'nil'. @@ -3916,3 +4072,38 @@ when defined(windows) and appType == "console" and defined(nimSetUtf8CodePage): proc setConsoleOutputCP(codepage: cint): cint {.stdcall, dynlib: "kernel32", importc: "SetConsoleOutputCP".} discard setConsoleOutputCP(65001) # 65001 - utf-8 codepage + + +when defined(nimHasRunnableExamples): + proc runnableExamples*(body: untyped) {.magic: "RunnableExamples".} + ## A section you should use to mark `runnable example`:idx: code with. + ## + ## - In normal debug and release builds code within + ## a ``runnableExamples`` section is ignored. + ## - The documentation generator is aware of these examples and considers them + ## part of the ``##`` doc comment. As the last step of documentation + ## generation the examples are put into an ``$file_example.nim`` file, + ## compiled and tested. The collected examples are + ## put into their own module to ensure the examples do not refer to + ## non-exported symbols. +else: + template runnableExamples*(body: untyped) = + discard + +template doAssertRaises*(exception, code: untyped): typed = + ## Raises ``AssertionError`` if specified ``code`` does not raise the + ## specified exception. + runnableExamples: + doAssertRaises(ValueError): + raise newException(ValueError, "Hello World") + + try: + block: + code + raiseAssert(astToStr(exception) & " wasn't raised by:\n" & astToStr(code)) + except exception: + discard + except Exception as exc: + raiseAssert(astToStr(exception) & + " wasn't raised, another error was raised instead by:\n"& + astToStr(code)) diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 78db96e77..e274e8e0c 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -8,8 +8,6 @@ # # Low level allocator for Nim. Has been designed to support the GC. -# TODO: -# - make searching for block O(1) {.push profiler:off.} include osalloc @@ -19,14 +17,17 @@ template track(op, address, size) = memTrackerOp(op, address, size) # We manage *chunks* of memory. Each chunk is a multiple of the page size. -# Each chunk starts at an address that is divisible by the page size. Chunks -# that are bigger than ``ChunkOsReturn`` are returned back to the operating -# system immediately. +# Each chunk starts at an address that is divisible by the page size. const - ChunkOsReturn = 256 * PageSize # 1 MB - InitialMemoryRequest = ChunkOsReturn div 2 # < ChunkOsReturn! + InitialMemoryRequest = 128 * PageSize # 0.5 MB SmallChunkSize = PageSize + MaxFli = 30 + MaxLog2Sli = 5 # 32, this cannot be increased without changing 'uint32' + # everywhere! + MaxSli = 1 shl MaxLog2Sli + FliOffset = 6 + RealFli = MaxFli - FliOffset type PTrunk = ptr Trunk @@ -99,10 +100,12 @@ type MemRegion = object minLargeObj, maxLargeObj: int freeSmallChunks: array[0..SmallChunkSize div MemAlign-1, PSmallChunk] + flBitmap: uint32 + slBitmap: array[RealFli, uint32] + matrix: array[RealFli, array[MaxSli, PBigChunk]] llmem: PLLChunk currMem, maxMem, freeMem: int # memory sizes (allocated from OS) lastSize: int # needed for the case that OS gives us pages linearly - freeChunksList: PBigChunk # XXX make this a datastructure with O(1) access chunkStarts: IntSet root, deleted, last, freeAvlNodes: PAvlNode locked, blockChunkSizeIncrease: bool # if locked, we cannot free pages. @@ -110,7 +113,109 @@ type bottomData: AvlNode heapLinks: HeapLinks -{.deprecated: [TMemRegion: MemRegion].} +const + fsLookupTable: array[byte, int8] = [ + -1'i8, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7 + ] + +proc msbit(x: uint32): int {.inline.} = + let a = if x <= 0xff_ff: + (if x <= 0xff: 0 else: 8) + else: + (if x <= 0xff_ff_ff: 16 else: 24) + result = int(fsLookupTable[byte(x shr a)]) + a + +proc lsbit(x: uint32): int {.inline.} = + msbit(x and ((not x) + 1)) + +proc setBit(nr: int; dest: var uint32) {.inline.} = + dest = dest or (1u32 shl (nr and 0x1f)) + +proc clearBit(nr: int; dest: var uint32) {.inline.} = + dest = dest and not (1u32 shl (nr and 0x1f)) + +proc mappingSearch(r, fl, sl: var int) {.inline.} = + #let t = (1 shl (msbit(uint32 r) - MaxLog2Sli)) - 1 + # This diverges from the standard TLSF algorithm because we need to ensure + # PageSize alignment: + let t = roundup((1 shl (msbit(uint32 r) - MaxLog2Sli)), PageSize) - 1 + r = r + t + fl = msbit(uint32 r) + sl = (r shr (fl - MaxLog2Sli)) - MaxSli + dec fl, FliOffset + r = r and not t + sysAssert((r and PageMask) == 0, "mappingSearch: still not aligned") + +# See http://www.gii.upv.es/tlsf/files/papers/tlsf_desc.pdf for details of +# this algorithm. + +proc mappingInsert(r: int): tuple[fl, sl: int] {.inline.} = + sysAssert((r and PageMask) == 0, "mappingInsert: still not aligned") + result.fl = msbit(uint32 r) + result.sl = (r shr (result.fl - MaxLog2Sli)) - MaxSli + dec result.fl, FliOffset + +template mat(): untyped = a.matrix[fl][sl] + +proc findSuitableBlock(a: MemRegion; fl, sl: var int): PBigChunk {.inline.} = + let tmp = a.slBitmap[fl] and (not 0u32 shl sl) + result = nil + if tmp != 0: + sl = lsbit(tmp) + result = mat() + else: + fl = lsbit(a.flBitmap and (not 0u32 shl (fl + 1))) + if fl > 0: + sl = lsbit(a.slBitmap[fl]) + result = mat() + +template clearBits(sl, fl) = + clearBit(sl, a.slBitmap[fl]) + if a.slBitmap[fl] == 0u32: + # do not forget to cascade: + clearBit(fl, a.flBitmap) + +proc removeChunkFromMatrix(a: var MemRegion; b: PBigChunk) = + let (fl, sl) = mappingInsert(b.size) + if b.next != nil: b.next.prev = b.prev + if b.prev != nil: b.prev.next = b.next + if mat() == b: + mat() = b.next + if mat() == nil: + clearBits(sl, fl) + b.prev = nil + b.next = nil + +proc removeChunkFromMatrix2(a: var MemRegion; b: PBigChunk; fl, sl: int) = + mat() = b.next + if mat() != nil: + mat().prev = nil + else: + clearBits(sl, fl) + b.prev = nil + b.next = nil + +proc addChunkToMatrix(a: var MemRegion; b: PBigChunk) = + let (fl, sl) = mappingInsert(b.size) + b.prev = nil + b.next = mat() + if mat() != nil: + mat().prev = b + mat() = b + setBit(sl, a.slBitmap[fl]) + setBit(fl, a.flBitmap) {.push stack_trace: off.} proc initAllocator() = discard "nothing to do anymore" @@ -203,6 +308,7 @@ proc llDeallocAll(a: var MemRegion) = var next = it.next osDeallocPages(it, PageSize) it = next + a.llmem = nil proc intSetGet(t: IntSet, key: int): PTrunk = var it = t.data[key and high(t.data)] @@ -301,13 +407,14 @@ proc pageAddr(p: pointer): PChunk {.inline.} = result = cast[PChunk](cast[ByteAddress](p) and not PageMask) #sysAssert(Contains(allocator.chunkStarts, pageIndex(result))) -proc writeFreeList(a: MemRegion) = - var it = a.freeChunksList - c_fprintf(stdout, "freeChunksList: %p\n", it) - while it != nil: - c_fprintf(stdout, "it: %p, next: %p, prev: %p, size: %ld\n", - it, it.next, it.prev, it.size) - it = it.next +when false: + proc writeFreeList(a: MemRegion) = + var it = a.freeChunksList + c_fprintf(stdout, "freeChunksList: %p\n", it) + while it != nil: + c_fprintf(stdout, "it: %p, next: %p, prev: %p, size: %ld\n", + it, it.next, it.prev, it.size) + it = it.next const nimMaxHeap {.intdefine.} = 0 @@ -368,6 +475,7 @@ proc requestOsChunks(a: var MemRegion, size: int): PBigChunk = result.prevSize = 0 or (result.prevSize and 1) # unknown # but do not overwrite 'used' field a.lastSize = size # for next request + sysAssert((cast[int](result) and PageMask) == 0, "requestOschunks: unaligned chunk") proc isAccessible(a: MemRegion, p: pointer): bool {.inline.} = result = contains(a.chunkStarts, pageIndex(p)) @@ -418,7 +526,7 @@ proc freeBigChunk(a: var MemRegion, c: PBigChunk) = if isAccessible(a, ri) and chunkUnused(ri): sysAssert(not isSmallChunk(ri), "freeBigChunk 3") if not isSmallChunk(ri): - listRemove(a.freeChunksList, cast[PBigChunk](ri)) + removeChunkFromMatrix(a, cast[PBigChunk](ri)) inc(c.size, ri.size) excl(a.chunkStarts, pageIndex(ri)) when coalescLeft: @@ -429,49 +537,44 @@ proc freeBigChunk(a: var MemRegion, c: PBigChunk) = if isAccessible(a, le) and chunkUnused(le): sysAssert(not isSmallChunk(le), "freeBigChunk 5") if not isSmallChunk(le): - listRemove(a.freeChunksList, cast[PBigChunk](le)) + removeChunkFromMatrix(a, cast[PBigChunk](le)) inc(le.size, c.size) excl(a.chunkStarts, pageIndex(c)) c = cast[PBigChunk](le) incl(a, a.chunkStarts, pageIndex(c)) updatePrevSize(a, c, c.size) - listAdd(a.freeChunksList, c) + addChunkToMatrix(a, c) # set 'used' to false: c.prevSize = c.prevSize and not 1 proc splitChunk(a: var MemRegion, c: PBigChunk, size: int) = var rest = cast[PBigChunk](cast[ByteAddress](c) +% size) - sysAssert(rest notin a.freeChunksList, "splitChunk") rest.size = c.size - size track("rest.origSize", addr rest.origSize, sizeof(int)) + # XXX check if these two nil assignments are dead code given + # addChunkToMatrix's implementation: rest.next = nil rest.prev = nil - # size and not used + # size and not used: rest.prevSize = size sysAssert((size and 1) == 0, "splitChunk 2") + sysAssert((size and PageMask) == 0, + "splitChunk: size is not a multiple of the PageSize") updatePrevSize(a, c, rest.size) c.size = size incl(a, a.chunkStarts, pageIndex(rest)) - listAdd(a.freeChunksList, rest) + addChunkToMatrix(a, rest) proc getBigChunk(a: var MemRegion, size: int): PBigChunk = # use first fit for now: - sysAssert((size and PageMask) == 0, "getBigChunk 1") sysAssert(size > 0, "getBigChunk 2") - result = a.freeChunksList - block search: - while result != nil: - sysAssert chunkUnused(result), "getBigChunk 3" - if result.size == size: - listRemove(a.freeChunksList, result) - break search - elif result.size > size: - listRemove(a.freeChunksList, result) - splitChunk(a, result, size) - break search - result = result.next - sysAssert result != a.freeChunksList, "getBigChunk 4" + var size = size # roundup(size, PageSize) + var fl, sl: int + mappingSearch(size, fl, sl) + sysAssert((size and PageMask) == 0, "getBigChunk: unaligned chunk") + result = findSuitableBlock(a, fl, sl) + if result == nil: if size < InitialMemoryRequest: result = requestOsChunks(a, InitialMemoryRequest) splitChunk(a, result, size) @@ -480,7 +583,10 @@ proc getBigChunk(a: var MemRegion, size: int): PBigChunk = # if we over allocated split the chunk: if result.size > size: splitChunk(a, result, size) - + else: + removeChunkFromMatrix2(a, result, fl, sl) + if result.size >= size + PageSize: + splitChunk(a, result, size) # set 'used' to to true: result.prevSize = 1 track("setUsedToFalse", addr result.origSize, sizeof(int)) @@ -571,14 +677,14 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer = size == 0, "rawAlloc 21") sysAssert(allocInv(a), "rawAlloc: end small size") else: - size = roundup(requestedSize+bigChunkOverhead(), PageSize) + size = requestedSize + bigChunkOverhead() # roundup(requestedSize+bigChunkOverhead(), PageSize) # allocate a large block var c = getBigChunk(a, size) sysAssert c.prev == nil, "rawAlloc 10" sysAssert c.next == nil, "rawAlloc 11" - sysAssert c.size == size, "rawAlloc 12" result = addr(c.data) - sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 13") + sysAssert((cast[ByteAddress](c) and (MemAlign-1)) == 0, "rawAlloc 13") + sysAssert((cast[ByteAddress](c) and PageMask) == 0, "rawAlloc: Not aligned on a page boundary") if a.root == nil: a.root = getBottom(a) add(a, a.root, cast[ByteAddress](result), cast[ByteAddress](result)+%size) sysAssert(isAccessible(a, result), "rawAlloc 14") diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 8c3801687..afc435638 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -213,12 +213,20 @@ proc atomicDec*(memLoc: var int, x: int = 1): int = result = memLoc when defined(vcc): - proc interlockedCompareExchange64(p: pointer; exchange, comparand: int64): int64 - {.importc: "_InterlockedCompareExchange64", header: "<intrin.h>".} - proc interlockedCompareExchange32(p: pointer; exchange, comparand: int32): int32 - {.importc: "_InterlockedCompareExchange", header: "<intrin.h>".} - proc interlockedCompareExchange8(p: pointer; exchange, comparand: byte): byte - {.importc: "_InterlockedCompareExchange64", header: "<intrin.h>".} + when defined(cpp): + proc interlockedCompareExchange64(p: pointer; exchange, comparand: int64): int64 + {.importcpp: "_InterlockedCompareExchange64(static_cast<NI64 volatile *>(#), #, #)", header: "<intrin.h>".} + proc interlockedCompareExchange32(p: pointer; exchange, comparand: int32): int32 + {.importcpp: "_InterlockedCompareExchange(static_cast<NI volatile *>(#), #, #)", header: "<intrin.h>".} + proc interlockedCompareExchange8(p: pointer; exchange, comparand: byte): byte + {.importcpp: "_InterlockedCompareExchange8(static_cast<char volatile *>(#), #, #)", header: "<intrin.h>".} + else: + proc interlockedCompareExchange64(p: pointer; exchange, comparand: int64): int64 + {.importc: "_InterlockedCompareExchange64", header: "<intrin.h>".} + proc interlockedCompareExchange32(p: pointer; exchange, comparand: int32): int32 + {.importc: "_InterlockedCompareExchange", header: "<intrin.h>".} + proc interlockedCompareExchange8(p: pointer; exchange, comparand: byte): byte + {.importc: "_InterlockedCompareExchange8", header: "<intrin.h>".} proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool = when sizeof(T) == 8: diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index 1520f231e..69b680dbd 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -63,7 +63,6 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} = while x != subclass: if x == nil: sysFatal(ObjectConversionError, "invalid object conversion") - break x = x.base proc chckObjAsgn(a, b: PNimType) {.compilerproc, inline.} = diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim index cc6919d36..937c0d6f0 100644 --- a/lib/system/debugger.nim +++ b/lib/system/debugger.nim @@ -127,7 +127,7 @@ proc fileMatches(c, bp: cstring): bool = proc canonFilename*(filename: cstring): cstring = ## returns 'nil' if the filename cannot be found. - for i in 0 .. <dbgFilenameLen: + for i in 0 .. dbgFilenameLen-1: result = dbgFilenames[i] if fileMatches(result, filename): return result result = nil @@ -261,7 +261,7 @@ proc genericHash(dest: pointer, mt: PNimType): int = proc dbgRegisterWatchpoint(address: pointer, name: cstring, typ: PNimType) {.compilerproc.} = let L = watchPointsLen - for i in 0.. <L: + for i in 0 .. pred(L): if watchPoints[i].name == name: # address may have changed: watchPoints[i].address = address @@ -288,7 +288,7 @@ var proc checkWatchpoints = let L = watchPointsLen - for i in 0.. <L: + for i in 0 .. pred(L): let newHash = genericHash(watchPoints[i].address, watchPoints[i].typ) if newHash != watchPoints[i].oldValue: dbgWatchpointHook(watchPoints[i].name) diff --git a/lib/system/endb.nim b/lib/system/endb.nim index 35d8f25c4..d51ae29df 100644 --- a/lib/system/endb.nim +++ b/lib/system/endb.nim @@ -370,7 +370,7 @@ proc commandPrompt() = if dbgUser.len == 0: dbgUser.len = oldLen # now look what we have to do: var i = scanWord(addr dbgUser.data, dbgTemp, 0) - template `?`(x: expr): expr = dbgTemp == cstring(x) + template `?`(x: untyped): untyped = dbgTemp == cstring(x) if ?"s" or ?"step": dbgState = dbStepInto again = false diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 950981227..8e42ea468 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -38,20 +38,29 @@ proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.} proc chckRangeF(x, a, b: float): float {.inline, compilerproc, benign.} proc chckNil(p: pointer) {.noinline, compilerproc, benign.} +type + GcFrame = ptr GcFrameHeader + GcFrameHeader {.compilerproc.} = object + len: int + prev: ptr GcFrameHeader + var framePtr {.threadvar.}: PFrame excHandler {.threadvar.}: PSafePoint # list of exception handlers # a global variable for the root of all try blocks currException {.threadvar.}: ref Exception + gcFramePtr {.threadvar.}: GcFrame type - FrameState = tuple[framePtr: PFrame, excHandler: PSafePoint, currException: ref Exception] + FrameState = tuple[gcFramePtr: GcFrame, framePtr: PFrame, + excHandler: PSafePoint, currException: ref Exception] proc getFrameState*(): FrameState {.compilerRtl, inl.} = - return (framePtr, excHandler, currException) + return (gcFramePtr, framePtr, excHandler, currException) proc setFrameState*(state: FrameState) {.compilerRtl, inl.} = + gcFramePtr = state.gcFramePtr framePtr = state.framePtr excHandler = state.excHandler currException = state.currException @@ -61,9 +70,29 @@ proc getFrame*(): PFrame {.compilerRtl, inl.} = framePtr proc popFrame {.compilerRtl, inl.} = framePtr = framePtr.prev +when false: + proc popFrameOfAddr(s: PFrame) {.compilerRtl.} = + var it = framePtr + if it == s: + framePtr = framePtr.prev + else: + while it != nil: + if it == s: + framePtr = it.prev + break + it = it.prev + proc setFrame*(s: PFrame) {.compilerRtl, inl.} = framePtr = s +proc getGcFrame*(): GcFrame {.compilerRtl, inl.} = gcFramePtr +proc popGcFrame*() {.compilerRtl, inl.} = gcFramePtr = gcFramePtr.prev +proc setGcFrame*(s: GcFrame) {.compilerRtl, inl.} = gcFramePtr = s +proc pushGcFrame*(s: GcFrame) {.compilerRtl, inl.} = + s.prev = gcFramePtr + zeroMem(cast[pointer](cast[int](s)+%sizeof(GcFrameHeader)), s.len*sizeof(pointer)) + gcFramePtr = s + proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} = s.hasRaiseAction = false s.prev = excHandler @@ -138,6 +167,52 @@ when not hasThreadSupport: var tempFrames: array[0..127, PFrame] # should not be alloc'd on stack +const + reraisedFromBegin = -10 + reraisedFromEnd = -100 + +template reraisedFrom(z): untyped = + StackTraceEntry(procname: nil, line: z, filename: nil) + +proc auxWriteStackTrace(f: PFrame; s: var seq[StackTraceEntry]) = + var + it = f + i = 0 + while it != nil: + inc(i) + it = it.prev + var last = i-1 + if s.isNil: + s = newSeq[StackTraceEntry](i) + else: + last = s.len + i - 1 + s.setLen(last+1) + it = f + while it != nil: + s[last] = StackTraceEntry(procname: it.procname, + line: it.line, + filename: it.filename) + it = it.prev + dec last + +template addFrameEntry(s, f: untyped) = + var oldLen = s.len + add(s, f.filename) + if f.line > 0: + add(s, '(') + add(s, $f.line) + add(s, ')') + for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ') + add(s, f.procname) + add(s, "\n") + +proc `$`(s: seq[StackTraceEntry]): string = + result = newStringOfCap(2000) + for i in 0 .. s.len-1: + if s[i].line == reraisedFromBegin: result.add "[[reraised from:\n" + elif s[i].line == reraisedFromEnd: result.add "]]\n" + else: addFrameEntry(result, s[i]) + proc auxWriteStackTrace(f: PFrame, s: var string) = when hasThreadSupport: var @@ -177,17 +252,9 @@ proc auxWriteStackTrace(f: PFrame, s: var string) = if tempFrames[j] == nil: add(s, "(") add(s, $skipped) - add(s, " calls omitted) ...") + add(s, " calls omitted) ...\n") else: - var oldLen = s.len - add(s, tempFrames[j].filename) - if tempFrames[j].line > 0: - add(s, '(') - add(s, $tempFrames[j].line) - add(s, ')') - for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ') - add(s, tempFrames[j].procname) - add(s, "\n") + addFrameEntry(s, tempFrames[j]) proc stackTraceAvailable*(): bool @@ -204,6 +271,13 @@ when hasSomeStackTrace: auxWriteStackTraceWithBacktrace(s) else: add(s, "No stack traceback available\n") + + proc rawWriteStackTrace(s: var seq[StackTraceEntry]) = + when NimStackTrace: + auxWriteStackTrace(framePtr, s) + else: + s = nil + proc stackTraceAvailable(): bool = when NimStackTrace: if framePtr == nil: @@ -223,12 +297,6 @@ proc quitOrDebug() {.inline.} = else: endbStep() # call the debugger -when false: - proc rawRaise*(e: ref Exception) = - ## undocumented. Do not use. - pushCurrentException(e) - c_longjmp(excHandler.context, 1) - var onUnhandledException*: (proc (errorMsg: string) {. nimcall.}) ## set this error \ ## handler to override the existing behaviour on an unhandled exception. @@ -265,7 +333,7 @@ proc raiseExceptionAux(e: ref Exception) = when hasSomeStackTrace: var buf = newStringOfCap(2000) if isNil(e.trace): rawWriteStackTrace(buf) - else: add(buf, e.trace) + else: add(buf, $e.trace) add(buf, "Error: unhandled exception: ") if not isNil(e.msg): add(buf, e.msg) add(buf, " [") @@ -301,12 +369,11 @@ proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = if e.name.isNil: e.name = ename when hasSomeStackTrace: if e.trace.isNil: - e.trace = "" rawWriteStackTrace(e.trace) elif framePtr != nil: - e.trace.add "[[reraised from:\n" + e.trace.add reraisedFrom(reraisedFromBegin) auxWriteStackTrace(framePtr, e.trace) - e.trace.add "]]\n" + e.trace.add reraisedFrom(reraisedFromEnd) raiseExceptionAux(e) proc reraiseException() {.compilerRtl.} = @@ -332,10 +399,15 @@ proc getStackTrace(): string = proc getStackTrace(e: ref Exception): string = if not isNil(e) and not isNil(e.trace): - result = e.trace + result = $e.trace else: result = "" +proc getStackTraceEntries*(e: ref Exception): seq[StackTraceEntry] = + ## Returns the attached stack trace to the exception ``e`` as + ## a ``seq``. This is not yet available for the JS backend. + shallowCopy(result, e.trace) + when defined(nimRequiresNimFrame): proc stackOverflow() {.noinline.} = writeStackTrace() @@ -357,7 +429,7 @@ when defined(endb): var dbgAborting: bool # whether the debugger wants to abort -when not defined(noSignalHandler): +when not defined(noSignalHandler) and not defined(useNimRtl): proc signalHandler(sign: cint) {.exportc: "signalHandler", noconv.} = template processSignal(s, action: untyped) {.dirty.} = if s == SIGINT: action("SIGINT: Interrupted by Ctrl-C.\n") diff --git a/lib/system/gc.nim b/lib/system/gc.nim index a2ff72a30..dac06119d 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -155,14 +155,15 @@ template setColor(c, col) = else: c.refcount = c.refcount and not colorMask or col -proc writeCell(msg: cstring, c: PCell) = - var kind = -1 - var typName: cstring = "nil" - if c.typ != nil: - kind = ord(c.typ.kind) - when defined(nimTypeNames): - if not c.typ.name.isNil: - typName = c.typ.name +when defined(logGC): + proc writeCell(msg: cstring, c: PCell) = + var kind = -1 + var typName: cstring = "nil" + if c.typ != nil: + kind = ord(c.typ.kind) + when defined(nimTypeNames): + if not c.typ.name.isNil: + typName = c.typ.name when leakDetector: c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld from %s(%ld)\n", @@ -317,7 +318,7 @@ proc initGC() = init(gch.marked) init(gch.additionalRoots) when hasThreadSupport: - gch.toDispose = initSharedList[pointer]() + init(gch.toDispose) when useMarkForDebug or useBackupGc: type @@ -642,9 +643,9 @@ when useMarkForDebug or useBackupGc: forAllChildren(d, waMarkPrecise) proc markGlobals(gch: var GcHeap) = - for i in 0 .. < globalMarkersLen: globalMarkers[i]() + for i in 0 .. globalMarkersLen-1: globalMarkers[i]() let d = gch.additionalRoots.d - for i in 0 .. < gch.additionalRoots.len: markS(gch, d[i]) + for i in 0 .. gch.additionalRoots.len-1: markS(gch, d[i]) when logGC: var @@ -652,7 +653,7 @@ when logGC: cycleCheckALen = 0 proc alreadySeen(c: PCell): bool = - for i in 0 .. <cycleCheckALen: + for i in 0 .. cycleCheckALen-1: if cycleCheckA[i] == c: return true if cycleCheckALen == len(cycleCheckA): gcAssert(false, "cycle detection overflow") diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index 6dffc323e..d57a01dc7 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -133,7 +133,7 @@ proc initGC() = init(gch.additionalRoots) init(gch.greyStack) when hasThreadSupport: - gch.toDispose = initSharedList[pointer]() + init(gch.toDispose) # Which color to use for new objects is tricky: When we're marking, # they have to be *white* so that everything is marked that is only @@ -173,7 +173,7 @@ proc internRefcount(p: pointer): int {.exportc: "getRefcount".} = when BitsPerPage mod (sizeof(int)*8) != 0: {.error: "(BitsPerPage mod BitsPerUnit) should be zero!".} -template color(c): expr = c.refCount and colorMask +template color(c): untyped = c.refCount and colorMask template setColor(c, col) = c.refcount = c.refcount and not colorMask or col @@ -487,12 +487,12 @@ proc GC_dumpHeap*(file: File) = var spaceIter: ObjectSpaceIter when false: var d = gch.decStack.d - for i in 0 .. < gch.decStack.len: + for i in 0 .. gch.decStack.len-1: if isAllocatedPtr(gch.region, d[i]): c_fprintf(file, "onstack %p\n", d[i]) else: c_fprintf(file, "onstack_invalid %p\n", d[i]) - for i in 0 .. < globalMarkersLen: globalMarkers[i]() + for i in 0 .. globalMarkersLen-1: globalMarkers[i]() while true: let x = allObjectsAsProc(gch.region, addr spaceIter) if spaceIter.state < 0: break @@ -579,7 +579,7 @@ proc markIncremental(gch: var GcHeap): bool = result = true proc markGlobals(gch: var GcHeap) = - for i in 0 .. < globalMarkersLen: globalMarkers[i]() + for i in 0 .. globalMarkersLen-1: globalMarkers[i]() proc doOperation(p: pointer, op: WalkOp) = if p == nil: return diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index cfc0dfa8a..5fc48d848 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -233,7 +233,7 @@ proc initGC() = init(gch.allocated) init(gch.marked) when hasThreadSupport: - gch.toDispose = initSharedList[pointer]() + init(gch.toDispose) proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} = var d = cast[ByteAddress](dest) @@ -450,9 +450,9 @@ when false: quit 1 proc markGlobals(gch: var GcHeap) = - for i in 0 .. < globalMarkersLen: globalMarkers[i]() + for i in 0 .. globalMarkersLen-1: globalMarkers[i]() let d = gch.additionalRoots.d - for i in 0 .. < gch.additionalRoots.len: mark(gch, d[i]) + for i in 0 .. gch.additionalRoots.len-1: mark(gch, d[i]) proc gcMark(gch: var GcHeap, p: pointer) {.inline.} = # the addresses are not as cells on the stack, so turn them to cells: diff --git a/lib/system/genodealloc.nim b/lib/system/genodealloc.nim new file mode 100644 index 000000000..3646a842d --- /dev/null +++ b/lib/system/genodealloc.nim @@ -0,0 +1,114 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2017 Emery Hemingway +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# Low level dataspace allocator for Genode. + +when not defined(genode): + {.error: "Genode only module".} + +type DataspaceCapability {. + importcpp: "Genode::Dataspace_capability", pure.} = object + +type + Map = object + attachment: pointer + size: int + ds: DataspaceCapability + + SlabMeta = object + next: ptr MapSlab + ds: DataspaceCapability + + MapSlab = object + meta: SlabMeta + maps: array[1,Map] + +const SlabBackendSize = 4096 + +proc ramAvail(): int {. + importcpp: "genodeEnv->pd().avail_ram().value".} + ## Return number of bytes available for allocation. + +proc capsAvail(): int {. + importcpp: "genodeEnv->pd().avail_caps().value".} + ## Return the number of available capabilities. + ## Each dataspace allocation consumes a capability. + +proc allocDataspace(size: int): DataspaceCapability {. + importcpp: "genodeEnv->pd().alloc(@)".} + ## Allocate a dataspace and its capability. + +proc attachDataspace(ds: DataspaceCapability): pointer {. + importcpp: "genodeEnv->rm().attach(@)".} + ## Attach a dataspace into the component address-space. + +proc detachAddress(p: pointer) {. + importcpp: "genodeEnv->rm().detach(@)".} + ## Detach a dataspace from the component address-space. + +proc freeDataspace(ds: DataspaceCapability) {. + importcpp: "genodeEnv->pd().free(@)".} + ## Free a dataspace. + +proc newMapSlab(): ptr MapSlab = + let + ds = allocDataspace SlabBackendSize + p = attachDataspace ds + result = cast[ptr MapSlab](p) + result.meta.ds = ds + +iterator items(s: ptr MapSlab): ptr Map = + let mapCount = (SlabBackendSize - sizeof(SlabMeta)) div sizeof(Map) + for i in 0 .. <mapCount: + yield s.maps[i].addr + +var slabs: ptr MapSlab + +proc osAllocPages(size: int): pointer = + if slabs.isNil: + slabs = newMapSlab() + var + slab = slabs + map: ptr Map + let mapCount = (SlabBackendSize - sizeof(SlabMeta)) div sizeof(Map) + block findFreeMap: + while true: + # lookup first free spot in slabs + for m in slab.items: + if m.attachment.isNil: + map = m + break findFreeMap + if slab.meta.next.isNil: + slab.meta.next = newMapSlab() + # tack a new slab on the tail + slab = slab.meta.next + # move to next slab in linked list + map.ds = allocDataspace size + map.size = size + map.attachment = attachDataspace map.ds + result = map.attachment + +proc osTryAllocPages(size: int): pointer = + if ramAvail() >= size and capsAvail() > 1: + result = osAllocPages size + +proc osDeallocPages(p: pointer; size: int) = + var slab = slabs + while not slab.isNil: + # lookup first free spot in slabs + for m in slab.items: + if m.attachment == p: + if m.size != size: + echo "cannot partially detach dataspace" + quit -1 + detachAddress m.attachment + freeDataspace m.ds + m[] = Map() + return + slab = slab.meta.next diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 24093a310..8065f2255 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -531,13 +531,13 @@ proc mulInt(a, b: int): int {.asmNoStackFrame, compilerproc.} = proc divInt(a, b: int): int {.asmNoStackFrame, compilerproc.} = when defined(nimphp): asm """ - return floor(`a` / `b`); + return trunc(`a` / `b`); """ else: asm """ if (`b` == 0) `raiseDivByZero`(); if (`b` == -1 && `a` == 2147483647) `raiseOverflow`(); - return Math.floor(`a` / `b`); + return Math.trunc(`a` / `b`); """ proc modInt(a, b: int): int {.asmNoStackFrame, compilerproc.} = @@ -549,7 +549,7 @@ proc modInt(a, b: int): int {.asmNoStackFrame, compilerproc.} = asm """ if (`b` == 0) `raiseDivByZero`(); if (`b` == -1 && `a` == 2147483647) `raiseOverflow`(); - return Math.floor(`a` % `b`); + return Math.trunc(`a` % `b`); """ proc addInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} = @@ -594,13 +594,13 @@ proc mulInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} = proc divInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} = when defined(nimphp): asm """ - return floor(`a` / `b`); + return trunc(`a` / `b`); """ else: asm """ if (`b` == 0) `raiseDivByZero`(); if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`(); - return Math.floor(`a` / `b`); + return Math.trunc(`a` / `b`); """ proc modInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} = @@ -612,7 +612,7 @@ proc modInt64(a, b: int): int {.asmNoStackFrame, compilerproc.} = asm """ if (`b` == 0) `raiseDivByZero`(); if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`(); - return Math.floor(`a` % `b`); + return Math.trunc(`a` % `b`); """ proc negInt(a: int): int {.compilerproc.} = diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 824934966..45e0c74c0 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -42,7 +42,8 @@ type # Page size of the system; in most cases 4096 bytes. For exotic OS or # CPU this needs to be changed: const - PageShift = when defined(cpu16): 8 else: 12 + PageShift = when defined(cpu16): 8 else: 12 # \ + # my tests showed no improvments for using larger page sizes. PageSize = 1 shl PageShift PageMask = PageSize-1 @@ -108,7 +109,6 @@ when defined(boehmgc): if result == nil: raiseOutOfMem() proc alloc0(size: Natural): pointer = result = alloc(size) - zeroMem(result, size) proc realloc(p: pointer, newsize: Natural): pointer = result = boehmRealloc(p, newsize) if result == nil: raiseOutOfMem() @@ -118,8 +118,7 @@ when defined(boehmgc): result = boehmAlloc(size) if result == nil: raiseOutOfMem() proc allocShared0(size: Natural): pointer = - result = alloc(size) - zeroMem(result, size) + result = allocShared(size) proc reallocShared(p: pointer, newsize: Natural): pointer = result = boehmRealloc(p, newsize) if result == nil: raiseOutOfMem() @@ -343,7 +342,6 @@ elif defined(gogc): const goFlagNoZero: uint32 = 1 shl 3 proc goRuntimeMallocGC(size: uint, typ: uint, flag: uint32): pointer {.importc: "runtime_mallocgc", dynlib: goLib.} - proc goFree(v: pointer) {.importc: "__go_free", dynlib: goLib.} proc goSetFinalizer(obj: pointer, f: pointer) {.importc: "set_finalizer", codegenDecl:"$1 $2$3 __asm__ (\"main.Set_finalizer\");\n$1 $2$3", dynlib: goLib.} @@ -376,7 +374,6 @@ elif defined(gogc): result = goRuntimeMallocGC(roundup(newsize, sizeof(pointer)).uint, 0.uint, goFlagNoZero) copyMem(result, old, oldsize) zeroMem(cast[pointer](cast[ByteAddress](result) +% oldsize), newsize - oldsize) - goFree(old) proc nimGCref(p: pointer) {.compilerproc, inline.} = discard proc nimGCunref(p: pointer) {.compilerproc, inline.} = discard @@ -573,3 +570,11 @@ when not declared(nimNewSeqOfCap): cast[PGenericSeq](result).reserved = cap {.pop.} + +when not declared(ForeignCell): + type ForeignCell* = object + data*: pointer + + proc protect*(x: pointer): ForeignCell = ForeignCell(data: x) + proc dispose*(x: ForeignCell) = discard + proc isNotForeign*(x: ForeignCell): bool = false diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim index f5b9cf3ed..f91dae41e 100644 --- a/lib/system/nimscript.nim +++ b/lib/system/nimscript.nim @@ -106,7 +106,7 @@ proc cmpic*(a, b: string): int = ## Compares `a` and `b` ignoring case. cmpIgnoreCase(a, b) -proc getEnv*(key: string): string {.tags: [ReadIOEffect].} = +proc getEnv*(key: string; default = ""): string {.tags: [ReadIOEffect].} = ## Retrieves the environment variable of name `key`. builtin diff --git a/lib/system/osalloc.nim b/lib/system/osalloc.nim index 65a057772..1ad4cf695 100644 --- a/lib/system/osalloc.nim +++ b/lib/system/osalloc.nim @@ -78,17 +78,7 @@ when defined(emscripten): munmap(mmapDescr.realPointer, mmapDescr.realSize) elif defined(genode): - - proc osAllocPages(size: int): pointer {. - importcpp: "genodeEnv->rm().attach(genodeEnv->ram().alloc(@))".} - - proc osTryAllocPages(size: int): pointer = - {.emit: """try {""".} - result = osAllocPages size - {.emit: """} catch (...) { }""".} - - proc osDeallocPages(p: pointer, size: int) {. - importcpp: "genodeEnv->rm().detach(#)".} + include genodealloc # osAllocPages, osTryAllocPages, osDeallocPages elif defined(posix): const @@ -166,7 +156,7 @@ elif defined(windows): # space heavily, so we now treat Windows as a strange unmap target. when reallyOsDealloc: if virtualFree(p, 0, MEM_RELEASE) == 0: - cprintf "yes, failing!" + cprintf "virtualFree failing!" quit 1 #VirtualFree(p, size, MEM_DECOMMIT) diff --git a/lib/system/repr.nim b/lib/system/repr.nim index 19fa564fb..982b07467 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -41,14 +41,14 @@ proc `$`(x: uint64): string = let half = i div 2 # Reverse - for t in 0 .. < half: swap(result[t], result[i-t-1]) + for t in 0 .. half-1: swap(result[t], result[i-t-1]) proc reprStrAux(result: var string, s: cstring; len: int) = if cast[pointer](s) == nil: add result, "nil" return add result, reprPointer(cast[pointer](s)) & "\"" - for i in 0.. <len: + for i in 0 .. pred(len): let c = s[i] case c of '"': add result, "\\\"" diff --git a/lib/system/reprjs.nim b/lib/system/reprjs.nim index 5c265a891..658220c11 100644 --- a/lib/system/reprjs.nim +++ b/lib/system/reprjs.nim @@ -9,13 +9,13 @@ # The generic ``repr`` procedure for the javascript backend. proc reprInt(x: int64): string {.compilerproc.} = return $x -proc reprFloat(x: float): string {.compilerproc.} = +proc reprFloat(x: float): string {.compilerproc.} = # Js toString doesn't differentiate between 1.0 and 1, # but we do. if $x == $(x.int): $x & ".0" else: $x -proc reprPointer(p: pointer): string {.compilerproc.} = +proc reprPointer(p: pointer): string {.compilerproc.} = # Do we need to generate the full 8bytes ? In js a pointer is an int anyway var tmp: int {. emit: """ @@ -38,7 +38,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} = result = $typ.node.sons[e].name else: result = $e & " (invalid data!)" - + proc reprChar(x: char): string {.compilerRtl.} = result = "\'" case x @@ -50,7 +50,7 @@ proc reprChar(x: char): string {.compilerRtl.} = proc reprStrAux(result: var string, s: cstring, len: int) = add(result, "\"") - for i in 0 .. <len: + for i in 0 .. len-1: let c = s[i] case c of '"': add(result, "\\\"") @@ -67,7 +67,7 @@ proc reprStr(s: string): string {.compilerRtl.} = if cast[pointer](s).isNil: # Handle nil strings here because they don't have a length field in js # TODO: check for null/undefined before generating call to length in js? - # Also: c backend repr of a nil string is <pointer>"", but repr of an + # Also: c backend repr of a nil string is <pointer>"", but repr of an # array of string that is not initialized is [nil, nil, ...] ?? add(result, "nil") else: @@ -86,7 +86,7 @@ proc addSetElem(result: var string, elem: int, typ: PNimType) = iterator setKeys(s: int): int {.inline.} = # The type of s is a lie, but it's expected to be a set. - # Iterate over the JS object representing a set + # Iterate over the JS object representing a set # and returns the keys as int. var len: int var yieldRes: int @@ -124,16 +124,16 @@ proc initReprClosure(cl: var ReprClosure) = cl.recDepth = -1 # default is to display everything! cl.indent = 0 -proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) +proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) -proc reprArray(a: pointer, typ: PNimType, +proc reprArray(a: pointer, typ: PNimType, cl: var ReprClosure): string {.compilerRtl.} = var isNilArrayOrSeq: bool # isnil is not enough here as it would try to deref `a` without knowing what's inside {. emit: """ - if (`a` == null) { + if (`a` == null) { `isNilArrayOrSeq` = true; - } else if (`a`[0] == null) { + } else if (`a`[0] == null) { `isNilArrayOrSeq` = true; } else { `isNilArrayOrSeq` = false; @@ -146,19 +146,19 @@ proc reprArray(a: pointer, typ: PNimType, result = if typ.kind == tySequence: "@[" else: "[" var len: int = 0 var i: int = 0 - + {. emit: "`len` = `a`.length;\n" .} var dereffed: pointer = a - for i in 0 .. < len: + for i in 0 .. len-1: if i > 0 : add(result, ", ") # advance pointer and point to element at index {. emit: """ - `dereffed`_Idx = `i`; + `dereffed`_Idx = `i`; `dereffed` = `a`[`dereffed`_Idx]; """ .} reprAux(result, dereffed, typ.base, cl) - + add(result, "]") proc isPointedToNil(p: pointer): bool {.inline.}= @@ -181,7 +181,7 @@ proc reprRef(result: var string, p: pointer, typ: PNimType, proc reprRecordAux(result: var string, o: pointer, typ: PNimType, cl: var ReprClosure) = add(result, "[") - + var first: bool = true var val: pointer = o if typ.node.len == 0: @@ -192,7 +192,7 @@ proc reprRecordAux(result: var string, o: pointer, typ: PNimType, cl: var ReprCl reprAux(result, val, typ.node.typ, cl) else: # if the object has more than one field, sons is not nil and contains the fields. - for i in 0 .. <typ.node.len: + for i in 0 .. typ.node.len-1: if first: first = false else: add(result, ",\n") @@ -214,11 +214,11 @@ proc reprJSONStringify(p: int): string {.compilerRtl.} = {. emit: "`tmp` = JSON.stringify(`p`);\n" .} result = $tmp -proc reprAux(result: var string, p: pointer, typ: PNimType, +proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) = if cl.recDepth == 0: add(result, "...") - return + return dec(cl.recDepth) case typ.kind of tyInt..tyInt64, tyUInt..tyUInt64: diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 4f266e0ae..4348ffbb5 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -192,7 +192,7 @@ proc write(f: File, r: float32) = proc write(f: File, r: BiggestFloat) = if c_fprintf(f, "%g", r) < 0: checkErr(f) -proc write(f: File, c: char) = discard c_putc(ord(c), f) +proc write(f: File, c: char) = discard c_putc(cint(c), f) proc write(f: File, a: varargs[string, `$`]) = for x in items(a): write(f, x) @@ -404,4 +404,18 @@ proc setStdIoUnbuffered() = when declared(stdin): discard c_setvbuf(stdin, nil, IONBF, 0) +when declared(stdout): + proc echoBinSafe(args: openArray[string]) {.compilerProc.} = + when not defined(windows): + proc flockfile(f: File) {.importc, noDecl.} + proc funlockfile(f: File) {.importc, noDecl.} + flockfile(stdout) + for s in args: + discard c_fwrite(s.cstring, s.len, 1, stdout) + const linefeed = "\n" # can be 1 or more chars + discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout) + discard c_fflush(stdout) + when not defined(windows): + funlockfile(stdout) + {.pop.} diff --git a/lib/system/sysspawn.nim b/lib/system/sysspawn.nim index 7da45b4dd..dc2d13578 100644 --- a/lib/system/sysspawn.nim +++ b/lib/system/sysspawn.nim @@ -142,7 +142,7 @@ var workersData: array[NumThreads, Worker] proc setup() = - for i in 0.. <NumThreads: + for i in 0 ..< NumThreads: workersData[i].taskArrived = createCondVar() workersData[i].taskStarted = createFastCondVar() createThread(workers[i], slave, addr(workersData[i])) @@ -153,12 +153,12 @@ proc preferSpawn*(): bool = ## it is not necessary to call this directly; use 'spawnX' instead. result = gSomeReady.event -proc spawn*(call: stmt) {.magic: "Spawn".} +proc spawn*(call: typed) {.magic: "Spawn".} ## always spawns a new task, so that the 'call' is never executed on ## the calling thread. 'call' has to be proc call 'p(...)' where 'p' ## is gcsafe and has 'void' as the return type. -template spawnX*(call: stmt) = +template spawnX*(call: typed) = ## spawns a new task if a CPU core is ready, otherwise executes the ## call in the calling thread. Usually it is advised to ## use 'spawn' in order to not block the producer for an unknown diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 43b5a0292..4c5f3d9a1 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -24,10 +24,10 @@ proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} = if a == b: return 0 if a == nil: return -1 if b == nil: return 1 - when defined(nimNoArrayToCstringConversion): - return c_strcmp(addr a.data, addr b.data) - else: - return c_strcmp(a.data, b.data) + let minlen = min(a.len, b.len) + result = c_memcmp(addr a.data, addr b.data, minlen.csize) + if result == 0: + result = a.len - b.len proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} = if a == b: return true @@ -259,7 +259,7 @@ proc incrSeqV2(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} = result.reserved = r proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. - compilerRtl.} = + compilerRtl, inl.} = result = seq if result.space < newLen: let r = max(resize(result.space), newLen) @@ -278,14 +278,15 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. GenericSeqSize +% (i*%elemSize)), extGetCellType(result).base, waPush) let len1 = gch.tempStack.len - for i in len0 .. <len1: + for i in len0 ..< len1: doDecRef(gch.tempStack.d[i], LocalHeap, MaybeCyclic) gch.tempStack.len = len0 else: - for i in newLen..result.len-1: - forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +% - GenericSeqSize +% (i*%elemSize)), - extGetCellType(result).base, waZctDecRef) + if ntfNoRefs notin extGetCellType(result).base.flags: + for i in newLen..result.len-1: + forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +% + GenericSeqSize +% (i*%elemSize)), + extGetCellType(result).base, waZctDecRef) # XXX: zeroing out the memory can still result in crashes if a wiped-out # cell is aliased by another pointer (ie proc parameter or a let variable). @@ -322,36 +323,40 @@ proc nimIntToStr(x: int): string {.compilerRtl.} = result.add x proc add*(result: var string; x: float) = - var buf: array[0..64, char] - when defined(nimNoArrayToCstringConversion): - var n: int = c_sprintf(addr buf, "%.16g", x) + when nimvm: + result.add $x else: - var n: int = c_sprintf(buf, "%.16g", x) - var hasDot = false - for i in 0..n-1: - if buf[i] == ',': - buf[i] = '.' - hasDot = true - elif buf[i] in {'a'..'z', 'A'..'Z', '.'}: - hasDot = true - if not hasDot: - buf[n] = '.' - buf[n+1] = '0' - buf[n+2] = '\0' - # On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' are produced. - # We want to get rid of these here: - if buf[n-1] in {'n', 'N'}: - result.add "nan" - elif buf[n-1] == 'F': - if buf[0] == '-': - result.add "-inf" + var buf: array[0..64, char] + when defined(nimNoArrayToCstringConversion): + var n: int = c_sprintf(addr buf, "%.16g", x) else: - result.add "inf" - else: - var i = 0 - while buf[i] != '\0': - result.add buf[i] - inc i + var n: int = c_sprintf(buf, "%.16g", x) + var hasDot = false + for i in 0..n-1: + if buf[i] == ',': + buf[i] = '.' + hasDot = true + elif buf[i] in {'a'..'z', 'A'..'Z', '.'}: + hasDot = true + if not hasDot: + buf[n] = '.' + buf[n+1] = '0' + buf[n+2] = '\0' + # On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' + # of '-1.#IND' are produced. + # We want to get rid of these here: + if buf[n-1] in {'n', 'N', 'D', 'd'}: + result.add "nan" + elif buf[n-1] == 'F': + if buf[0] == '-': + result.add "-inf" + else: + result.add "inf" + else: + var i = 0 + while buf[i] != '\0': + result.add buf[i] + inc i proc nimFloatToStr(f: float): string {.compilerproc.} = result = newStringOfCap(8) @@ -362,9 +367,9 @@ proc c_strtod(buf: cstring, endptr: ptr cstring): float64 {. const IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'} - powtens = [ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22] + powtens = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22] proc nimParseBiggestFloat(s: string, number: var BiggestFloat, start = 0): int {.compilerProc.} = @@ -508,7 +513,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat, # insert exponent t[ti] = 'E'; inc(ti) - t[ti] = if exp_negative: '-' else: '+'; inc(ti) + t[ti] = (if exp_negative: '-' else: '+'); inc(ti) inc(ti, 3) # insert adjusted exponent diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 96c045e6b..f61cc4280 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -255,9 +255,9 @@ when emulatedThreadVars: proc nimThreadVarsSize(): int {.noconv, importc: "NimThreadVarsSize".} # we preallocate a fixed size for thread local storage, so that no heap -# allocations are needed. Currently less than 7K are used on a 64bit machine. +# allocations are needed. Currently less than 16K are used on a 64bit machine. # We use ``float`` for proper alignment: -const nimTlsSize {.intdefine.} = 8000 +const nimTlsSize {.intdefine.} = 16000 type ThreadLocalStorage = array[0..(nimTlsSize div sizeof(float)), float] @@ -398,7 +398,7 @@ template afterThreadRuns() = threadDestructionHandlers[i]() when not defined(boehmgc) and not hasSharedHeap and not defined(gogc) and not defined(gcRegions): - proc deallocOsPages() + proc deallocOsPages() {.rtl.} when defined(boehmgc): type GCStackBaseProc = proc(sb: pointer, t: pointer) {.noconv.} diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index c3229cc7b..a833377e5 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -111,6 +111,7 @@ const WAIT_TIMEOUT* = 0x00000102'i32 WAIT_FAILED* = 0xFFFFFFFF'i32 INFINITE* = -1'i32 + STILL_ACTIVE* = 0x00000103'i32 STD_INPUT_HANDLE* = -10'i32 STD_OUTPUT_HANDLE* = -11'i32 @@ -541,6 +542,7 @@ var SO_DONTLINGER* {.importc, header: "winsock2.h".}: cint SO_EXCLUSIVEADDRUSE* {.importc, header: "winsock2.h".}: cint # disallow local address reuse SO_ERROR* {.importc, header: "winsock2.h".}: cint + TCP_NODELAY* {.importc, header: "winsock2.h".}: cint proc `==`*(x, y: SocketHandle): bool {.borrow.} diff --git a/lib/wrappers/libuv.nim b/lib/wrappers/libuv.nim deleted file mode 100644 index 3e28815ad..000000000 --- a/lib/wrappers/libuv.nim +++ /dev/null @@ -1,732 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2015 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## libuv is still fast moving target -## This file was last updated against a development HEAD revision of https://github.com/joyent/libuv/ - -## Use the following link to see changes (in uv.h) since then and don't forget to update the information here. -## https://github.com/joyent/libuv/compare/9f6024a6fa9d254527b4b59af724257df870288b...master - -when defined(Windows): - import winlean -else: - import posix - -type - Port* = distinct int16 ## port type - - cssize = int - coff = int - csize = int - - AllocProc* = proc (handle: PHandle, suggested_size: csize): Buf {.cdecl.} - ReadProc* = proc (stream: PStream, nread: cssize, buf: Buf) {.cdecl.} - ReadProc2* = proc (stream: PPipe, nread: cssize, buf: Buf, pending: HandleType) {.cdecl.} - WriteProc* = proc (req: PWrite, status: cint) {.cdecl.} - ConnectProc* = proc (req: PConnect, status: cint) {.cdecl.} - ShutdownProc* = proc (req: PShutdown, status: cint) {.cdecl.} - ConnectionProc* = proc (server: PStream, status: cint) {.cdecl.} - CloseProc* = proc (handle: PHandle) {.cdecl.} - TimerProc* = proc (handle: PTimer, status: cint) {.cdecl.} - AsyncProc* = proc (handle: PAsync, status: cint) {.cdecl.} - PrepareProc* = proc (handle: PPrepare, status: cint) {.cdecl.} - CheckProc* = proc (handle: PCheck, status: cint) {.cdecl.} - IdleProc* = proc (handle: PIdle, status: cint) {.cdecl.} - - PSockAddr* = ptr SockAddr - - GetAddrInfoProc* = proc (handle: PGetAddrInfo, status: cint, res: ptr AddrInfo) - - ExitProc* = proc (a2: PProcess, exit_status: cint, term_signal: cint) - FsProc* = proc (req: PFS) - WorkProc* = proc (req: PWork) - AfterWorkProc* = proc (req: PWork) - - FsEventProc* = proc (handle: PFsEvent, filename: cstring, events: cint, status: cint) - - ErrorCode* {.size: sizeof(cint).} = enum - UNKNOWN = - 1, OK = 0, EOF, EACCESS, EAGAIN, EADDRINUSE, EADDRNOTAVAIL, - EAFNOSUPPORT, EALREADY, EBADF, EBUSY, ECONNABORTED, ECONNREFUSED, - ECONNRESET, EDESTADDRREQ, EFAULT, EHOSTUNREACH, EINTR, EINVAL, EISCONN, - EMFILE, EMSGSIZE, ENETDOWN, ENETUNREACH, ENFILE, ENOBUFS, ENOMEM, ENONET, - ENOPROTOOPT, ENOTCONN, ENOTSOCK, ENOTSUP, ENOENT, EPIPE, EPROTO, - EPROTONOSUPPORT, EPROTOTYPE, ETIMEDOUT, ECHARSET, EAIFAMNOSUPPORT, - EAINONAME, EAISERVICE, EAISOCKTYPE, ESHUTDOWN, EEXIST - - HandleType* {.size: sizeof(cint).} = enum - UNKNOWN_HANDLE = 0, TCP, UDP, NAMED_PIPE, TTY, FILE, TIMER, PREPARE, CHECK, - IDLE, ASYNC, ARES_TASK, ARES_EVENT, PROCESS, FS_EVENT - - ReqType* {.size: sizeof(cint).} = enum - rUNKNOWN_REQ = 0, - rCONNECT, - rACCEPT, - rREAD, - rWRITE, - rSHUTDOWN, - rWAKEUP, - rUDP_SEND, - rFS, - rWORK, - rGETADDRINFO, - rREQ_TYPE_PRIVATE - - Err* {.pure, final, importc: "uv_err_t", header: "uv.h".} = object - code* {.importc: "code".}: ErrorCode - sys_errno* {.importc: "sys_errno_".}: cint - - FsEventType* = enum - evRENAME = 1, - evCHANGE = 2 - - TFsEvent* {.pure, final, importc: "uv_fs_event_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - filename {.importc: "filename".}: cstring - - PFsEvent* = ptr TFsEvent - - FsEvents* {.pure, final, importc: "uv_fs_event_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - filename* {.importc: "filename".}: cstring - - Buf* {.pure, final, importc: "uv_buf_t", header: "uv.h"} = object - base* {.importc: "base".}: cstring - len* {.importc: "len".}: csize - - AnyHandle* {.pure, final, importc: "uv_any_handle", header: "uv.h".} = object - tcp* {.importc: "tcp".}: TTcp - pipe* {.importc: "pipe".}: Pipe - prepare* {.importc: "prepare".}: TPrepare - check* {.importc: "check".}: TCheck - idle* {.importc: "idle".}: TIdle - async* {.importc: "async".}: TAsync - timer* {.importc: "timer".}: TTimer - getaddrinfo* {.importc: "getaddrinfo".}: Getaddrinfo - fs_event* {.importc: "fs_event".}: FsEvents - - AnyReq* {.pure, final, importc: "uv_any_req", header: "uv.h".} = object - req* {.importc: "req".}: Req - write* {.importc: "write".}: Write - connect* {.importc: "connect".}: Connect - shutdown* {.importc: "shutdown".}: Shutdown - fs_req* {.importc: "fs_req".}: Fs - work_req* {.importc: "work_req".}: Work - - ## better import this - uint64 = int64 - - Counters* {.pure, final, importc: "uv_counters_t", header: "uv.h".} = object - eio_init* {.importc: "eio_init".}: uint64 - req_init* {.importc: "req_init".}: uint64 - handle_init* {.importc: "handle_init".}: uint64 - stream_init* {.importc: "stream_init".}: uint64 - tcp_init* {.importc: "tcp_init".}: uint64 - udp_init* {.importc: "udp_init".}: uint64 - pipe_init* {.importc: "pipe_init".}: uint64 - tty_init* {.importc: "tty_init".}: uint64 - prepare_init* {.importc: "prepare_init".}: uint64 - check_init* {.importc: "check_init".}: uint64 - idle_init* {.importc: "idle_init".}: uint64 - async_init* {.importc: "async_init".}: uint64 - timer_init* {.importc: "timer_init".}: uint64 - process_init* {.importc: "process_init".}: uint64 - fs_event_init* {.importc: "fs_event_init".}: uint64 - - Loop* {.pure, final, importc: "uv_loop_t", header: "uv.h".} = object - # ares_handles_* {.importc: "uv_ares_handles_".}: pointer # XXX: This seems to be a private field? - eio_want_poll_notifier* {.importc: "uv_eio_want_poll_notifier".}: TAsync - eio_done_poll_notifier* {.importc: "uv_eio_done_poll_notifier".}: TAsync - eio_poller* {.importc: "uv_eio_poller".}: TIdle - counters* {.importc: "counters".}: Counters - last_err* {.importc: "last_err".}: Err - data* {.importc: "data".}: pointer - - PLoop* = ptr Loop - - Shutdown* {.pure, final, importc: "uv_shutdown_t", header: "uv.h".} = object - typ* {.importc: "type".}: ReqType - data* {.importc: "data".}: pointer - handle* {.importc: "handle".}: PStream - cb* {.importc: "cb".}: ShutdownProc - - PShutdown* = ptr Shutdown - - Handle* {.pure, final, importc: "uv_handle_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - - PHandle* = ptr Handle - - Stream* {.pure, final, importc: "uv_stream_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - alloc_cb* {.importc: "alloc_cb".}: AllocProc - read_cb* {.importc: "read_cb".}: ReadProc - read2_cb* {.importc: "read2_cb".}: ReadProc2 - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - write_queue_size* {.importc: "write_queue_size".}: csize - - PStream* = ptr Stream - - Write* {.pure, final, importc: "uv_write_t", header: "uv.h".} = object - typ* {.importc: "type".}: ReqType - data* {.importc: "data".}: pointer - cb* {.importc: "cb".}: WriteProc - send_handle* {.importc: "send_handle".}: PStream - handle* {.importc: "handle".}: PStream - - PWrite* = ptr Write - - TTcp* {.pure, final, importc: "uv_tcp_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - alloc_cb* {.importc: "alloc_cb".}: AllocProc - read_cb* {.importc: "read_cb".}: ReadProc - read2_cb* {.importc: "read2_cb".}: ReadProc2 - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - write_queue_size* {.importc: "write_queue_size".}: csize - - PTcp* = ptr TTcp - - Connect* {.pure, final, importc: "uv_connect_t", header: "uv.h".} = object - typ* {.importc: "type".}: ReqType - data* {.importc: "data".}: pointer - cb* {.importc: "cb".}: ConnectProc - handle* {.importc: "handle".}: PStream - - PConnect* = ptr Connect - - UdpFlags* = enum - UDP_IPV6ONLY = 1, UDP_PARTIAL = 2 - - ## XXX: better import this - cunsigned = int - - UdpSendProc* = proc (req: PUdpSend, status: cint) - UdpRecvProc* = proc (handle: PUdp, nread: cssize, buf: Buf, adr: ptr SockAddr, flags: cunsigned) - - TUdp* {.pure, final, importc: "uv_udp_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - - PUdp* = ptr TUdp - - UdpSend* {.pure, final, importc: "uv_udp_send_t", header: "uv.h".} = object - typ* {.importc: "type".}: ReqType - data* {.importc: "data".}: pointer - handle* {.importc: "handle".}: PUdp - cb* {.importc: "cb".}: UdpSendProc - - PUdpSend* = ptr UdpSend - - tTTy* {.pure, final, importc: "uv_tty_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - alloc_cb* {.importc: "alloc_cb".}: AllocProc - read_cb* {.importc: "read_cb".}: ReadProc - read2_cb* {.importc: "read2_cb".}: ReadProc2 - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - write_queue_size* {.importc: "write_queue_size".}: csize - - pTTy* = ptr tTTy - - Pipe* {.pure, final, importc: "uv_pipe_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - alloc_cb* {.importc: "alloc_cb".}: AllocProc - read_cb* {.importc: "read_cb".}: ReadProc - read2_cb* {.importc: "read2_cb".}: ReadProc2 - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - write_queue_size* {.importc: "write_queue_size".}: csize - ipc {.importc: "ipc".}: int - - PPipe* = ptr Pipe - - TPrepare* {.pure, final, importc: "uv_prepare_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - - PPrepare* = ptr TPrepare - - TCheck* {.pure, final, importc: "uv_check_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - - PCheck* = ptr TCheck - - TIdle* {.pure, final, importc: "uv_idle_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - - PIdle* = ptr TIdle - - TAsync* {.pure, final, importc: "uv_async_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - - PAsync* = ptr TAsync - - TTimer* {.pure, final, importc: "uv_timer_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - - PTimer* = ptr TTimer - - GetAddrInfo* {.pure, final, importc: "uv_getaddrinfo_t", header: "uv.h".} = object - typ* {.importc: "type".}: ReqType - data* {.importc: "data".}: pointer - loop* {.importc: "loop".}: PLoop - - PGetAddrInfo* = ptr GetAddrInfo - - ProcessOptions* {.pure, final, importc: "uv_process_options_t", header: "uv.h".} = object - exit_cb* {.importc: "exit_cb".}: ExitProc - file* {.importc: "file".}: cstring - args* {.importc: "args".}: cstringArray - env* {.importc: "env".}: cstringArray - cwd* {.importc: "cwd".}: cstring - windows_verbatim_arguments* {.importc: "windows_verbatim_arguments".}: cint - stdin_stream* {.importc: "stdin_stream".}: PPipe - stdout_stream* {.importc: "stdout_stream".}: PPipe - stderr_stream* {.importc: "stderr_stream".}: PPipe - - PProcessOptions* = ptr ProcessOptions - - TProcess* {.pure, final, importc: "uv_process_t", header: "uv.h".} = object - loop* {.importc: "loop".}: PLoop - typ* {.importc: "type".}: HandleType - close_cb* {.importc: "close_cb".}: CloseProc - data* {.importc: "data".}: pointer - exit_cb* {.importc: "exit_cb".}: ExitProc - pid* {.importc: "pid".}: cint - - PProcess* = ptr TProcess - - Work* {.pure, final, importc: "uv_work_t", header: "uv.h".} = object - typ* {.importc: "type".}: ReqType - data* {.importc: "data".}: pointer - loop* {.importc: "loop".}: PLoop - work_cb* {.importc: "work_cb".}: WorkProc - after_work_cb* {.importc: "after_work_cb".}: AfterWorkProc - - PWork* = ptr Work - - FsType* {.size: sizeof(cint).} = enum - FS_UNKNOWN = - 1, FS_CUSTOM, FS_OPEN, FS_CLOSE, FS_READ, FS_WRITE, - FS_SENDFILE, FS_STAT, FS_LSTAT, FS_FSTAT, FS_FTRUNCATE, FS_UTIME, FS_FUTIME, - FS_CHMOD, FS_FCHMOD, FS_FSYNC, FS_FDATASYNC, FS_UNLINK, FS_RMDIR, FS_MKDIR, - FS_RENAME, FS_READDIR, FS_LINK, FS_SYMLINK, FS_READLINK, FS_CHOWN, FS_FCHOWN - - FS* {.pure, final, importc: "uv_fs_t", header: "uv.h".} = object - typ* {.importc: "type".}: ReqType - data* {.importc: "data".}: pointer - loop* {.importc: "loop".}: PLoop - fs_type* {.importc: "fs_type".}: FsType - cb* {.importc: "cb".}: FsProc - result* {.importc: "result".}: cssize - fsPtr* {.importc: "ptr".}: pointer - path* {.importc: "path".}: cstring - errorno* {.importc: "errorno".}: cint - - PFS* = ptr FS - - Req* {.pure, final, importc: "uv_req_t", header: "uv.h".} = object - typ* {.importc: "type".}: ReqType - data* {.importc: "data".}: pointer - - PReq* = ptr Req - - AresOptions* {.pure, final, importc: "ares_options", header: "uv.h".} = object - flags* {.importc: "flags".}: int - timeout* {.importc: "timeout".}: int - tries* {.importc: "tries".}: int - ndots* {.importc: "ndots".}: int - udp_port* {.importc: "udp_port".}: Port - tcp_port* {.importc: "tcp_port".}: Port - socket_send_buffer_size* {.importc: "socket_send_buffer_size".}: int - socket_recv_buffer_size* {.importc: "socket_receive_buffer_size".}: int - servers* {.importc: "servers".}: ptr InAddr - nservers* {.importc: "nservers".}: int - domains* {.importc: "domains".}: ptr cstring - ndomains* {.importc: "ndomains".}: int - lookups* {.importc: "lookups".}: cstring - - #XXX: not yet exported - #ares_sock_state_cb sock_state_cb; - #void *sock_state_cb_data; - #struct apattern *sortlist; - #int nsort; - - PAresOptions* = ptr AresOptions - PAresChannel* = pointer -{.deprecated: [THandle: Handle, THandleType: HandleType, TAnyHandle: AnyHandle, - TAnyReq: AnyReq, TPort: Port, TErrorCode: ErrorCode, TReqType: ReqType, - TErr: Err, TFsEventType: FsEventType, - # TFsEvent: FsEvent, # Name conflict if we drop `T` - TFsEvents: FsEvents, TBuf: Buf, TCounters: Counters, TLoop: Loop, - TShutdown: Shutdown, TStream: Stream, TWrite: Write, - # TTcp: Tcp, # Name conflict if we drop `T` - TConnect: Connect, - TUdpFlags: UdpFlags, - # TUdp: Udp, # Name conflict if we drop `T` - TUdpSend: UdpSend, - # tTTy: TTy, # Name conflict if we drop `T` - TPipe: Pipe, - # TPrepare: Prepare, # Name conflict if we drop `T` - # TCheck: Check, # Name conflict if we drop `T` - # TIdle: Idle, # Name conflict if we drop `T` - # TAsync: Async, # Name conflict if we drop `T` - # TTimer: Timer, # Name conflict if we drop `T` - TGetAddrInfo: GetAddrInfo, TProcessOptions: ProcessOptions, - # TProcess: Process, # Name conflict if we drop `T` - TWork: Work, - TFsType: FsType, TFS: FS, TReq: Req, TAresOptions: AresOptions].} - -proc loop_new*(): PLoop{. - importc: "uv_loop_new", header: "uv.h".} - -proc loop_delete*(a2: PLoop){. - importc: "uv_loop_delete", header: "uv.h".} - -proc default_loop*(): PLoop{. - importc: "uv_default_loop", header: "uv.h".} - -proc run*(a2: PLoop): cint{. - importc: "uv_run", header: "uv.h".} - -proc addref*(a2: PLoop){. - importc: "uv_ref", header: "uv.h".} - -proc unref*(a2: PLoop){. - importc: "uv_unref", header: "uv.h".} - -proc update_time*(a2: PLoop){. - importc: "uv_update_time", header: "uv.h".} - -proc now*(a2: PLoop): int64{. - importc: "uv_now", header: "uv.h".} - -proc last_error*(a2: PLoop): Err{. - importc: "uv_last_error", header: "uv.h".} - -proc strerror*(err: Err): cstring{. - importc: "uv_strerror", header: "uv.h".} - -proc err_name*(err: Err): cstring{. - importc: "uv_err_name", header: "uv.h".} - -proc shutdown*(req: PShutdown, handle: PStream, cb: ShutdownProc): cint{. - importc: "uv_shutdown", header: "uv.h".} - -proc is_active*(handle: PHandle): cint{. - importc: "uv_is_active", header: "uv.h".} - -proc close*(handle: PHandle, close_cb: CloseProc){. - importc: "uv_close", header: "uv.h".} - -proc buf_init*(base: cstring, len: csize): Buf{. - importc: "uv_buf_init", header: "uv.h".} - -proc listen*(stream: PStream, backlog: cint, cb: ConnectionProc): cint{. - importc: "uv_listen", header: "uv.h".} - -proc accept*(server: PStream, client: PStream): cint{. - importc: "uv_accept", header: "uv.h".} - -proc read_start*(a2: PStream, alloc_cb: AllocProc, read_cb: ReadProc): cint{. - importc: "uv_read_start", header: "uv.h".} - -proc read_start*(a2: PStream, alloc_cb: AllocProc, read_cb: ReadProc2): cint{. - importc: "uv_read2_start", header: "uv.h".} - -proc read_stop*(a2: PStream): cint{. - importc: "uv_read_stop", header: "uv.h".} - -proc write*(req: PWrite, handle: PStream, bufs: ptr Buf, bufcnt: cint, cb: WriteProc): cint{. - importc: "uv_write", header: "uv.h".} - -proc write*(req: PWrite, handle: PStream, bufs: ptr Buf, bufcnt: cint, send_handle: PStream, cb: WriteProc): cint{. - importc: "uv_write2", header: "uv.h".} - -proc tcp_init*(a2: PLoop, handle: PTcp): cint{. - importc: "uv_tcp_init", header: "uv.h".} - -proc tcp_bind*(handle: PTcp, a3: SockAddrIn): cint{. - importc: "uv_tcp_bind", header: "uv.h".} - -proc tcp_bind6*(handle: PTcp, a3: TSockAddrIn6): cint{. - importc: "uv_tcp_bind6", header: "uv.h".} - -proc tcp_getsockname*(handle: PTcp, name: ptr SockAddr, namelen: var cint): cint{. - importc: "uv_tcp_getsockname", header: "uv.h".} - -proc tcp_getpeername*(handle: PTcp, name: ptr SockAddr, namelen: var cint): cint{. - importc: "uv_tcp_getpeername", header: "uv.h".} - -proc tcp_connect*(req: PConnect, handle: PTcp, address: SockAddrIn, cb: ConnectProc): cint{. - importc: "uv_tcp_connect", header: "uv.h".} - -proc tcp_connect6*(req: PConnect, handle: PTcp, address: TSockAddrIn6, cb: ConnectProc): cint{. - importc: "uv_tcp_connect6", header: "uv.h".} - -proc udp_init*(a2: PLoop, handle: PUdp): cint{. - importc: "uv_udp_init", header: "uv.h".} - -proc udp_bind*(handle: PUdp, adr: SockAddrIn, flags: cunsigned): cint{. - importc: "uv_udp_bind", header: "uv.h".} - -proc udp_bind6*(handle: PUdp, adr: TSockAddrIn6, flags: cunsigned): cint{. - importc: "uv_udp_bind6", header: "uv.h".} - -proc udp_getsockname*(handle: PUdp, name: ptr SockAddr, namelen: var cint): cint{. - importc: "uv_udp_getsockname", header: "uv.h".} - -proc udp_send*(req: PUdpSend, handle: PUdp, bufs: ptr Buf, bufcnt: cint, adr: SockAddrIn, send_cb: UdpSendProc): cint{. - importc: "uv_udp_send", header: "uv.h".} - -proc udp_send6*(req: PUdpSend, handle: PUdp, bufs: ptr Buf, bufcnt: cint, adr: TSockAddrIn6, send_cb: UdpSendProc): cint{. - importc: "uv_udp_send6", header: "uv.h".} - -proc udp_recv_start*(handle: PUdp, alloc_cb: AllocProc, recv_cb: UdpRecvProc): cint{. - importc: "uv_udp_recv_start", header: "uv.h".} - -proc udp_recv_stop*(handle: PUdp): cint{. - importc: "uv_udp_recv_stop", header: "uv.h".} - -proc tty_init*(a2: PLoop, a3: pTTy, fd: File): cint{. - importc: "uv_tty_init", header: "uv.h".} - -proc tty_set_mode*(a2: pTTy, mode: cint): cint{. - importc: "uv_tty_set_mode", header: "uv.h".} - -proc tty_get_winsize*(a2: pTTy, width: var cint, height: var cint): cint{. - importc: "uv_tty_get_winsize", header: "uv.h".} - -proc tty_reset_mode*() {. - importc: "uv_tty_reset_mode", header: "uv.h".} - -proc guess_handle*(file: File): HandleType{. - importc: "uv_guess_handle", header: "uv.h".} - -proc pipe_init*(a2: PLoop, handle: PPipe, ipc: int): cint{. - importc: "uv_pipe_init", header: "uv.h".} - -proc pipe_open*(a2: PPipe, file: File){. - importc: "uv_pipe_open", header: "uv.h".} - -proc pipe_bind*(handle: PPipe, name: cstring): cint{. - importc: "uv_pipe_bind", header: "uv.h".} - -proc pipe_connect*(req: PConnect, handle: PPipe, name: cstring, cb: ConnectProc): cint{. - importc: "uv_pipe_connect", header: "uv.h".} - -proc prepare_init*(a2: PLoop, prepare: PPrepare): cint{. - importc: "uv_prepare_init", header: "uv.h".} - -proc prepare_start*(prepare: PPrepare, cb: PrepareProc): cint{. - importc: "uv_prepare_start", header: "uv.h".} - -proc prepare_stop*(prepare: PPrepare): cint{. - importc: "uv_prepare_stop", header: "uv.h".} - -proc check_init*(a2: PLoop, check: PCheck): cint{. - importc: "uv_check_init", header: "uv.h".} - -proc check_start*(check: PCheck, cb: CheckProc): cint{. - importc: "uv_check_start", header: "uv.h".} - -proc check_stop*(check: PCheck): cint{. - importc: "uv_check_stop", header: "uv.h".} - -proc idle_init*(a2: PLoop, idle: PIdle): cint{. - importc: "uv_idle_init", header: "uv.h".} - -proc idle_start*(idle: PIdle, cb: IdleProc): cint{. - importc: "uv_idle_start", header: "uv.h".} - -proc idle_stop*(idle: PIdle): cint{. - importc: "uv_idle_stop", header: "uv.h".} - -proc async_init*(a2: PLoop, async: PAsync, async_cb: AsyncProc): cint{. - importc: "uv_async_init", header: "uv.h".} - -proc async_send*(async: PAsync): cint{. - importc: "uv_async_send", header: "uv.h".} - -proc timer_init*(a2: PLoop, timer: PTimer): cint{. - importc: "uv_timer_init", header: "uv.h".} - -proc timer_start*(timer: PTimer, cb: TimerProc, timeout: int64, repeat: int64): cint{. - importc: "uv_timer_start", header: "uv.h".} - -proc timer_stop*(timer: PTimer): cint{. - importc: "uv_timer_stop", header: "uv.h".} - -proc timer_again*(timer: PTimer): cint{. - importc: "uv_timer_again", header: "uv.h".} - -proc timer_set_repeat*(timer: PTimer, repeat: int64){. - importc: "uv_timer_set_repeat", header: "uv.h".} - -proc timer_get_repeat*(timer: PTimer): int64{. - importc: "uv_timer_get_repeat", header: "uv.h".} - -proc ares_init_options*(a2: PLoop, channel: PAresChannel, options: PAresOptions, optmask: cint): cint{. - importc: "uv_ares_init_options", header: "uv.h".} - -proc ares_destroy*(a2: PLoop, channel: PAresChannel){. - importc: "uv_ares_destroy", header: "uv.h".} - -proc getaddrinfo*(a2: PLoop, handle: PGetAddrInfo,getaddrinfo_cb: GetAddrInfoProc, node: cstring, service: cstring, hints: ptr AddrInfo): cint{. - importc: "uv_getaddrinfo", header: "uv.h".} - -proc freeaddrinfo*(ai: ptr AddrInfo){. - importc: "uv_freeaddrinfo", header: "uv.h".} - -proc spawn*(a2: PLoop, a3: PProcess, options: ProcessOptions): cint{. - importc: "uv_spawn", header: "uv.h".} - -proc process_kill*(a2: PProcess, signum: cint): cint{. - importc: "uv_process_kill", header: "uv.h".} - -proc queue_work*(loop: PLoop, req: PWork, work_cb: WorkProc, after_work_cb: AfterWorkProc): cint{. - importc: "uv_queue_work", header: "uv.h".} - -proc req_cleanup*(req: PFS){. - importc: "uv_fs_req_cleanup", header: "uv.h".} - -proc close*(loop: PLoop, req: PFS, file: File, cb: FsProc): cint{. - importc: "uv_fs_close", header: "uv.h".} - -proc open*(loop: PLoop, req: PFS, path: cstring, flags: cint, mode: cint, cb: FsProc): cint{. - importc: "uv_fs_open", header: "uv.h".} - -proc read*(loop: PLoop, req: PFS, file: File, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{. - importc: "uv_fs_read", header: "uv.h".} - -proc unlink*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. - importc: "uv_fs_unlink", header: "uv.h".} - -proc write*(loop: PLoop, req: PFS, file: File, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{. - importc: "uv_fs_write", header: "uv.h".} - -proc mkdir*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{. - importc: "uv_fs_mkdir", header: "uv.h".} - -proc rmdir*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. - importc: "uv_fs_rmdir", header: "uv.h".} - -proc readdir*(loop: PLoop, req: PFS, path: cstring, flags: cint, cb: FsProc): cint{. - importc: "uv_fs_readdir", header: "uv.h".} - -proc stat*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. - importc: "uv_fs_stat", header: "uv.h".} - -proc fstat*(loop: PLoop, req: PFS, file: File, cb: FsProc): cint{. - importc: "uv_fs_fstat", header: "uv.h".} - -proc rename*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, cb: FsProc): cint{. - importc: "uv_fs_rename", header: "uv.h".} - -proc fsync*(loop: PLoop, req: PFS, file: File, cb: FsProc): cint{. - importc: "uv_fs_fsync", header: "uv.h".} - -proc fdatasync*(loop: PLoop, req: PFS, file: File, cb: FsProc): cint{. - importc: "uv_fs_fdatasync", header: "uv.h".} - -proc ftruncate*(loop: PLoop, req: PFS, file: File, offset: coff, cb: FsProc): cint{. - importc: "uv_fs_ftruncate", header: "uv.h".} - -proc sendfile*(loop: PLoop, req: PFS, out_fd: File, in_fd: File, in_offset: coff, length: csize, cb: FsProc): cint{. - importc: "uv_fs_sendfile", header: "uv.h".} - -proc chmod*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{. - importc: "uv_fs_chmod", header: "uv.h".} - -proc utime*(loop: PLoop, req: PFS, path: cstring, atime: cdouble, mtime: cdouble, cb: FsProc): cint{. - importc: "uv_fs_utime", header: "uv.h".} - -proc futime*(loop: PLoop, req: PFS, file: File, atime: cdouble, mtime: cdouble, cb: FsProc): cint{. - importc: "uv_fs_futime", header: "uv.h".} - -proc lstat*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. - importc: "uv_fs_lstat", header: "uv.h".} - -proc link*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, cb: FsProc): cint{. - importc: "uv_fs_link", header: "uv.h".} - -proc symlink*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, flags: cint, cb: FsProc): cint{. - importc: "uv_fs_symlink", header: "uv.h".} - -proc readlink*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{. - importc: "uv_fs_readlink", header: "uv.h".} - -proc fchmod*(loop: PLoop, req: PFS, file: File, mode: cint, cb: FsProc): cint{. - importc: "uv_fs_fchmod", header: "uv.h".} - -proc chown*(loop: PLoop, req: PFS, path: cstring, uid: cint, gid: cint, cb: FsProc): cint{. - importc: "uv_fs_chown", header: "uv.h".} - -proc fchown*(loop: PLoop, req: PFS, file: File, uid: cint, gid: cint, cb: FsProc): cint{. - importc: "uv_fs_fchown", header: "uv.h".} - -proc event_init*(loop: PLoop, handle: PFSEvent, filename: cstring, cb: FsEventProc): cint{. - importc: "uv_fs_event_init", header: "uv.h".} - -proc ip4_addr*(ip: cstring, port: cint): SockAddrIn{. - importc: "uv_ip4_addr", header: "uv.h".} - -proc ip6_addr*(ip: cstring, port: cint): TSockAddrIn6{. - importc: "uv_ip6_addr", header: "uv.h".} - -proc ip4_name*(src: ptr SockAddrIn, dst: cstring, size: csize): cint{. - importc: "uv_ip4_name", header: "uv.h".} - -proc ip6_name*(src: ptr TSockAddrIn6, dst: cstring, size: csize): cint{. - importc: "uv_ip6_name", header: "uv.h".} - -proc exepath*(buffer: cstring, size: var csize): cint{. - importc: "uv_exepath", header: "uv.h".} - -proc hrtime*(): uint64{. - importc: "uv_hrtime", header: "uv.h".} - -proc loadavg*(load: var array[0..2, cdouble]) {. - importc: "uv_loadavg", header: "uv.h"} - -proc get_free_memory*(): cdouble {. - importc: "uv_get_free_memory", header: "uv.h".} - -proc get_total_memory*(): cdouble {. - importc: "uv_get_total_memory", header: "uv.h".} - diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 5cbe2887c..55b0bc3f8 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -64,6 +64,8 @@ type des_key_schedule* = array[1..16, des_ks_struct] + pem_password_cb* = proc(buf: cstring, size, rwflag: cint, userdata: pointer): cint {.cdecl.} + {.deprecated: [PSSL: SslPtr, PSSL_CTX: SslCtx, PBIO: BIO].} const @@ -432,6 +434,12 @@ proc ErrClearError*(){.cdecl, dynlib: DLLUtilName, importc: "ERR_clear_error".} proc ErrFreeStrings*(){.cdecl, dynlib: DLLUtilName, importc: "ERR_free_strings".} proc ErrRemoveState*(pid: cInt){.cdecl, dynlib: DLLUtilName, importc: "ERR_remove_state".} +proc PEM_read_bio_RSA_PUBKEY*(bp: BIO, x: ptr PRSA, pw: pem_password_cb, u: pointer): PRSA {.cdecl, + dynlib: DLLSSLName, importc.} + +proc RSA_verify*(kind: cint, origMsg: pointer, origMsgLen: cuint, signature: pointer, + signatureLen: cuint, rsa: PRSA): cint {.cdecl, dynlib: DLLSSLName, importc.} + when true: discard else: @@ -593,7 +601,7 @@ from strutils import toHex, toLowerAscii proc hexStr(buf: cstring): string = # turn md5s output into a nice hex str result = newStringOfCap(32) - for i in 0 .. <16: + for i in 0 ..< 16: result.add toHex(buf[i].ord, 2).toLowerAscii proc md5_File*(file: string): string {.raises: [IOError,Exception].} = diff --git a/lib/wrappers/pdcurses.nim b/lib/wrappers/pdcurses.nim deleted file mode 100644 index 2d64ac97a..000000000 --- a/lib/wrappers/pdcurses.nim +++ /dev/null @@ -1,1560 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2015 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -{.deadCodeElim: on.} - -discard """ - -curses.h: -#ifdef C2NIM -#dynlib pdcursesdll -#skipinclude -#prefix PDC_ -#def FALSE -#def TRUE -#def NULL -#def bool unsigned char -#def chtype unsigned long -#def cchar_t unsigned long -#def attr_t unsigned long -#def mmask_t unsigned long -#def wchar_t char -#def PDCEX -#cdecl -#endif - -pdcwin.h: -#ifdef C2NIM -#dynlib pdcursesdll -#skipinclude -#prefix pdc_ -#prefix PDC_ -#stdcall -#endif -""" - -when defined(windows): - import windows - - when defined(nimOldDlls): - const pdcursesdll = "pdcurses.dll" - elif defined(cpu64): - const pdcursesdll = "pdcurses64.dll" - else: - const pdcursesdll = "pdcurses32.dll" - - const - unixOS = false - {.pragma: extdecl, stdcall.} - -when not defined(windows): - const - unixOS = true - {.pragma: extdecl, cdecl.} - -type - cunsignedchar = char - cunsignedlong = uint32 - -const - BUILD* = 3401 - PDCURSES* = 1 # PDCurses-only routines - XOPEN* = 1 # X/Open Curses routines - SYSVcurses* = 1 # System V Curses routines - BSDcurses* = 1 # BSD Curses routines - CHTYPE_LONG* = 1 # size of chtype; long - ERR* = (- 1) - OK* = 0 - BUTTON_RELEASED* = 0x00000000 - BUTTON_PRESSED* = 0x00000001 - BUTTON_CLICKED* = 0x00000002 - BUTTON_DOUBLE_CLICKED* = 0x00000003 - BUTTON_TRIPLE_CLICKED* = 0x00000004 - BUTTON_MOVED* = 0x00000005 # PDCurses - WHEEL_SCROLLED* = 0x00000006 # PDCurses - BUTTON_ACTION_MASK* = 0x00000007 # PDCurses - BUTTON_MODIFIER_MASK* = 0x00000038 # PDCurses - MOUSE_MOVED* = 0x00000008 - MOUSE_POSITION* = 0x00000010 - MOUSE_WHEEL_UP* = 0x00000020 - MOUSE_WHEEL_DOWN* = 0x00000040 - BUTTON1_RELEASED* = 0x00000001 - BUTTON1_PRESSED* = 0x00000002 - BUTTON1_CLICKED* = 0x00000004 - BUTTON1_DOUBLE_CLICKED* = 0x00000008 - BUTTON1_TRIPLE_CLICKED* = 0x00000010 - BUTTON1_MOVED* = 0x00000010 # PDCurses - BUTTON2_RELEASED* = 0x00000020 - BUTTON2_PRESSED* = 0x00000040 - BUTTON2_CLICKED* = 0x00000080 - BUTTON2_DOUBLE_CLICKED* = 0x00000100 - BUTTON2_TRIPLE_CLICKED* = 0x00000200 - BUTTON2_MOVED* = 0x00000200 # PDCurses - BUTTON3_RELEASED* = 0x00000400 - BUTTON3_PRESSED* = 0x00000800 - BUTTON3_CLICKED* = 0x00001000 - BUTTON3_DOUBLE_CLICKED* = 0x00002000 - BUTTON3_TRIPLE_CLICKED* = 0x00004000 - BUTTON3_MOVED* = 0x00004000 # PDCurses - BUTTON4_RELEASED* = 0x00008000 - BUTTON4_PRESSED* = 0x00010000 - BUTTON4_CLICKED* = 0x00020000 - BUTTON4_DOUBLE_CLICKED* = 0x00040000 - BUTTON4_TRIPLE_CLICKED* = 0x00080000 - BUTTON5_RELEASED* = 0x00100000 - BUTTON5_PRESSED* = 0x00200000 - BUTTON5_CLICKED* = 0x00400000 - BUTTON5_DOUBLE_CLICKED* = 0x00800000 - BUTTON5_TRIPLE_CLICKED* = 0x01000000 - MOUSE_WHEEL_SCROLL* = 0x02000000 # PDCurses - BUTTON_MODIFIER_SHIFT* = 0x04000000 # PDCurses - BUTTON_MODIFIER_CONTROL* = 0x08000000 # PDCurses - BUTTON_MODIFIER_ALT* = 0x10000000 # PDCurses - ALL_MOUSE_EVENTS* = 0x1FFFFFFF - REPORT_MOUSE_POSITION* = 0x20000000 - A_NORMAL* = 0 - A_ALTCHARSET* = 0x00010000 - A_RIGHTLINE* = 0x00020000 - A_LEFTLINE* = 0x00040000 - A_INVIS* = 0x00080000 - A_UNDERLINE* = 0x00100000 - A_REVERSE* = 0x00200000 - A_BLINK* = 0x00400000 - A_BOLD* = 0x00800000 - A_ATTRIBUTES* = 0xFFFF0000 - A_CHARTEXT* = 0x0000FFFF - A_COLOR* = 0xFF000000 - A_ITALIC* = A_INVIS - A_PROTECT* = (A_UNDERLINE or A_LEFTLINE or A_RIGHTLINE) - ATTR_SHIFT* = 19 - COLOR_SHIFT* = 24 - A_STANDOUT* = (A_REVERSE or A_BOLD) # X/Open - A_DIM* = A_NORMAL - CHR_MSK* = A_CHARTEXT # Obsolete - ATR_MSK* = A_ATTRIBUTES # Obsolete - ATR_NRM* = A_NORMAL # Obsolete - WA_ALTCHARSET* = A_ALTCHARSET - WA_BLINK* = A_BLINK - WA_BOLD* = A_BOLD - WA_DIM* = A_DIM - WA_INVIS* = A_INVIS - WA_LEFT* = A_LEFTLINE - WA_PROTECT* = A_PROTECT - WA_REVERSE* = A_REVERSE - WA_RIGHT* = A_RIGHTLINE - WA_STANDOUT* = A_STANDOUT - WA_UNDERLINE* = A_UNDERLINE - WA_HORIZONTAL* = A_NORMAL - WA_LOW* = A_NORMAL - WA_TOP* = A_NORMAL - WA_VERTICAL* = A_NORMAL - COLOR_BLACK* = 0 - COLOR_RED* = 1 - COLOR_GREEN* = 2 - COLOR_BLUE* = 4 - COLOR_CYAN* = (COLOR_BLUE or COLOR_GREEN) - COLOR_MAGENTA* = (COLOR_RED or COLOR_BLUE) - COLOR_YELLOW* = (COLOR_RED or COLOR_GREEN) - COLOR_WHITE* = 7 - KEY_CODE_YES* = 0x00000100 # If get_wch() gives a key code - KEY_BREAK* = 0x00000101 # Not on PC KBD - KEY_DOWN* = 0x00000102 # Down arrow key - KEY_UP* = 0x00000103 # Up arrow key - KEY_LEFT* = 0x00000104 # Left arrow key - KEY_RIGHT* = 0x00000105 # Right arrow key - KEY_HOME* = 0x00000106 # home key - KEY_BACKSPACE* = 0x00000107 # not on pc - KEY_F0* = 0x00000108 # function keys; 64 reserved - KEY_DL* = 0x00000148 # delete line - KEY_IL* = 0x00000149 # insert line - KEY_DC* = 0x0000014A # delete character - KEY_IC* = 0x0000014B # insert char or enter ins mode - KEY_EIC* = 0x0000014C # exit insert char mode - KEY_CLEAR* = 0x0000014D # clear screen - KEY_EOS* = 0x0000014E # clear to end of screen - KEY_EOL* = 0x0000014F # clear to end of line - KEY_SF* = 0x00000150 # scroll 1 line forward - KEY_SR* = 0x00000151 # scroll 1 line back (reverse) - KEY_NPAGE* = 0x00000152 # next page - KEY_PPAGE* = 0x00000153 # previous page - KEY_STAB* = 0x00000154 # set tab - KEY_CTAB* = 0x00000155 # clear tab - KEY_CATAB* = 0x00000156 # clear all tabs - KEY_ENTER* = 0x00000157 # enter or send (unreliable) - KEY_SRESET* = 0x00000158 # soft/reset (partial/unreliable) - KEY_RESET* = 0x00000159 # reset/hard reset (unreliable) - KEY_PRINT* = 0x0000015A # print/copy - KEY_LL* = 0x0000015B # home down/bottom (lower left) - KEY_ABORT* = 0x0000015C # abort/terminate key (any) - KEY_SHELP* = 0x0000015D # short help - KEY_LHELP* = 0x0000015E # long help - KEY_BTAB* = 0x0000015F # Back tab key - KEY_BEG* = 0x00000160 # beg(inning) key - KEY_CANCEL* = 0x00000161 # cancel key - KEY_CLOSE* = 0x00000162 # close key - KEY_COMMAND* = 0x00000163 # cmd (command) key - KEY_COPY* = 0x00000164 # copy key - KEY_CREATE* = 0x00000165 # create key - KEY_END* = 0x00000166 # end key - KEY_EXIT* = 0x00000167 # exit key - KEY_FIND* = 0x00000168 # find key - KEY_HELP* = 0x00000169 # help key - KEY_MARK* = 0x0000016A # mark key - KEY_MESSAGE* = 0x0000016B # message key - KEY_MOVE* = 0x0000016C # move key - KEY_NEXT* = 0x0000016D # next object key - KEY_OPEN* = 0x0000016E # open key - KEY_OPTIONS* = 0x0000016F # options key - KEY_PREVIOUS* = 0x00000170 # previous object key - KEY_REDO* = 0x00000171 # redo key - KEY_REFERENCE* = 0x00000172 # ref(erence) key - KEY_REFRESH* = 0x00000173 # refresh key - KEY_REPLACE* = 0x00000174 # replace key - KEY_RESTART* = 0x00000175 # restart key - KEY_RESUME* = 0x00000176 # resume key - KEY_SAVE* = 0x00000177 # save key - KEY_SBEG* = 0x00000178 # shifted beginning key - KEY_SCANCEL* = 0x00000179 # shifted cancel key - KEY_SCOMMAND* = 0x0000017A # shifted command key - KEY_SCOPY* = 0x0000017B # shifted copy key - KEY_SCREATE* = 0x0000017C # shifted create key - KEY_SDC* = 0x0000017D # shifted delete char key - KEY_SDL* = 0x0000017E # shifted delete line key - KEY_SELECT* = 0x0000017F # select key - KEY_SEND* = 0x00000180 # shifted end key - KEY_SEOL* = 0x00000181 # shifted clear line key - KEY_SEXIT* = 0x00000182 # shifted exit key - KEY_SFIND* = 0x00000183 # shifted find key - KEY_SHOME* = 0x00000184 # shifted home key - KEY_SIC* = 0x00000185 # shifted input key - KEY_SLEFT* = 0x00000187 # shifted left arrow key - KEY_SMESSAGE* = 0x00000188 # shifted message key - KEY_SMOVE* = 0x00000189 # shifted move key - KEY_SNEXT* = 0x0000018A # shifted next key - KEY_SOPTIONS* = 0x0000018B # shifted options key - KEY_SPREVIOUS* = 0x0000018C # shifted prev key - KEY_SPRINT* = 0x0000018D # shifted print key - KEY_SREDO* = 0x0000018E # shifted redo key - KEY_SREPLACE* = 0x0000018F # shifted replace key - KEY_SRIGHT* = 0x00000190 # shifted right arrow - KEY_SRSUME* = 0x00000191 # shifted resume key - KEY_SSAVE* = 0x00000192 # shifted save key - KEY_SSUSPEND* = 0x00000193 # shifted suspend key - KEY_SUNDO* = 0x00000194 # shifted undo key - KEY_SUSPEND* = 0x00000195 # suspend key - KEY_UNDO* = 0x00000196 # undo key - ALT_0* = 0x00000197 - ALT_1* = 0x00000198 - ALT_2* = 0x00000199 - ALT_3* = 0x0000019A - ALT_4* = 0x0000019B - ALT_5* = 0x0000019C - ALT_6* = 0x0000019D - ALT_7* = 0x0000019E - ALT_8* = 0x0000019F - ALT_9* = 0x000001A0 - ALT_A* = 0x000001A1 - ALT_B* = 0x000001A2 - ALT_C* = 0x000001A3 - ALT_D* = 0x000001A4 - ALT_E* = 0x000001A5 - ALT_F* = 0x000001A6 - ALT_G* = 0x000001A7 - ALT_H* = 0x000001A8 - ALT_I* = 0x000001A9 - ALT_J* = 0x000001AA - ALT_K* = 0x000001AB - ALT_L* = 0x000001AC - ALT_M* = 0x000001AD - ALT_N* = 0x000001AE - ALT_O* = 0x000001AF - ALT_P* = 0x000001B0 - ALT_Q* = 0x000001B1 - ALT_R* = 0x000001B2 - ALT_S* = 0x000001B3 - ALT_T* = 0x000001B4 - ALT_U* = 0x000001B5 - ALT_V* = 0x000001B6 - ALT_W* = 0x000001B7 - ALT_X* = 0x000001B8 - ALT_Y* = 0x000001B9 - ALT_Z* = 0x000001BA - CTL_LEFT* = 0x000001BB # Control-Left-Arrow - CTL_RIGHT* = 0x000001BC - CTL_PGUP* = 0x000001BD - CTL_PGDN* = 0x000001BE - CTL_HOME* = 0x000001BF - CTL_END* = 0x000001C0 - KEY_A1* = 0x000001C1 # upper left on Virtual keypad - KEY_A2* = 0x000001C2 # upper middle on Virt. keypad - KEY_A3* = 0x000001C3 # upper right on Vir. keypad - KEY_B1* = 0x000001C4 # middle left on Virt. keypad - KEY_B2* = 0x000001C5 # center on Virt. keypad - KEY_B3* = 0x000001C6 # middle right on Vir. keypad - KEY_C1* = 0x000001C7 # lower left on Virt. keypad - KEY_C2* = 0x000001C8 # lower middle on Virt. keypad - KEY_C3* = 0x000001C9 # lower right on Vir. keypad - PADSLASH* = 0x000001CA # slash on keypad - PADENTER* = 0x000001CB # enter on keypad - CTL_PADENTER* = 0x000001CC # ctl-enter on keypad - ALT_PADENTER* = 0x000001CD # alt-enter on keypad - PADSTOP* = 0x000001CE # stop on keypad - PADSTAR* = 0x000001CF # star on keypad - PADMINUS* = 0x000001D0 # minus on keypad - PADPLUS* = 0x000001D1 # plus on keypad - CTL_PADSTOP* = 0x000001D2 # ctl-stop on keypad - CTL_PADCENTER* = 0x000001D3 # ctl-enter on keypad - CTL_PADPLUS* = 0x000001D4 # ctl-plus on keypad - CTL_PADMINUS* = 0x000001D5 # ctl-minus on keypad - CTL_PADSLASH* = 0x000001D6 # ctl-slash on keypad - CTL_PADSTAR* = 0x000001D7 # ctl-star on keypad - ALT_PADPLUS* = 0x000001D8 # alt-plus on keypad - ALT_PADMINUS* = 0x000001D9 # alt-minus on keypad - ALT_PADSLASH* = 0x000001DA # alt-slash on keypad - ALT_PADSTAR* = 0x000001DB # alt-star on keypad - ALT_PADSTOP* = 0x000001DC # alt-stop on keypad - CTL_INS* = 0x000001DD # ctl-insert - ALT_DEL* = 0x000001DE # alt-delete - ALT_INS* = 0x000001DF # alt-insert - CTL_UP* = 0x000001E0 # ctl-up arrow - CTL_DOWN* = 0x000001E1 # ctl-down arrow - CTL_TAB* = 0x000001E2 # ctl-tab - ALT_TAB* = 0x000001E3 - ALT_MINUS* = 0x000001E4 - ALT_EQUAL* = 0x000001E5 - ALT_HOME* = 0x000001E6 - ALT_PGUP* = 0x000001E7 - ALT_PGDN* = 0x000001E8 - ALT_END* = 0x000001E9 - ALT_UP* = 0x000001EA # alt-up arrow - ALT_DOWN* = 0x000001EB # alt-down arrow - ALT_RIGHT* = 0x000001EC # alt-right arrow - ALT_LEFT* = 0x000001ED # alt-left arrow - ALT_ENTER* = 0x000001EE # alt-enter - ALT_ESC* = 0x000001EF # alt-escape - ALT_BQUOTE* = 0x000001F0 # alt-back quote - ALT_LBRACKET* = 0x000001F1 # alt-left bracket - ALT_RBRACKET* = 0x000001F2 # alt-right bracket - ALT_SEMICOLON* = 0x000001F3 # alt-semi-colon - ALT_FQUOTE* = 0x000001F4 # alt-forward quote - ALT_COMMA* = 0x000001F5 # alt-comma - ALT_STOP* = 0x000001F6 # alt-stop - ALT_FSLASH* = 0x000001F7 # alt-forward slash - ALT_BKSP* = 0x000001F8 # alt-backspace - CTL_BKSP* = 0x000001F9 # ctl-backspace - PAD0* = 0x000001FA # keypad 0 - CTL_PAD0* = 0x000001FB # ctl-keypad 0 - CTL_PAD1* = 0x000001FC - CTL_PAD2* = 0x000001FD - CTL_PAD3* = 0x000001FE - CTL_PAD4* = 0x000001FF - CTL_PAD5* = 0x00000200 - CTL_PAD6* = 0x00000201 - CTL_PAD7* = 0x00000202 - CTL_PAD8* = 0x00000203 - CTL_PAD9* = 0x00000204 - ALT_PAD0* = 0x00000205 # alt-keypad 0 - ALT_PAD1* = 0x00000206 - ALT_PAD2* = 0x00000207 - ALT_PAD3* = 0x00000208 - ALT_PAD4* = 0x00000209 - ALT_PAD5* = 0x0000020A - ALT_PAD6* = 0x0000020B - ALT_PAD7* = 0x0000020C - ALT_PAD8* = 0x0000020D - ALT_PAD9* = 0x0000020E - CTL_DEL* = 0x0000020F # clt-delete - ALT_BSLASH* = 0x00000210 # alt-back slash - CTL_ENTER* = 0x00000211 # ctl-enter - SHF_PADENTER* = 0x00000212 # shift-enter on keypad - SHF_PADSLASH* = 0x00000213 # shift-slash on keypad - SHF_PADSTAR* = 0x00000214 # shift-star on keypad - SHF_PADPLUS* = 0x00000215 # shift-plus on keypad - SHF_PADMINUS* = 0x00000216 # shift-minus on keypad - SHF_UP* = 0x00000217 # shift-up on keypad - SHF_DOWN* = 0x00000218 # shift-down on keypad - SHF_IC* = 0x00000219 # shift-insert on keypad - SHF_DC* = 0x0000021A # shift-delete on keypad - KEY_MOUSE* = 0x0000021B # "mouse" key - KEY_SHIFT_L* = 0x0000021C # Left-shift - KEY_SHIFT_R* = 0x0000021D # Right-shift - KEY_CONTROL_L* = 0x0000021E # Left-control - KEY_CONTROL_R* = 0x0000021F # Right-control - KEY_ALT_L* = 0x00000220 # Left-alt - KEY_ALT_R* = 0x00000221 # Right-alt - KEY_RESIZE* = 0x00000222 # Window resize - KEY_SUP* = 0x00000223 # Shifted up arrow - KEY_SDOWN* = 0x00000224 # Shifted down arrow - KEY_MIN* = KEY_BREAK # Minimum curses key value - KEY_MAX* = KEY_SDOWN # Maximum curses key - CLIP_SUCCESS* = 0 - CLIP_ACCESS_ERROR* = 1 - CLIP_EMPTY* = 2 - CLIP_MEMORY_ERROR* = 3 - KEY_MODIFIER_SHIFT* = 1 - KEY_MODIFIER_CONTROL* = 2 - KEY_MODIFIER_ALT* = 4 - KEY_MODIFIER_NUMLOCK* = 8 - -when appType == "gui": - const - BUTTON_SHIFT* = BUTTON_MODIFIER_SHIFT - BUTTON_CONTROL* = BUTTON_MODIFIER_CONTROL - BUTTON_CTRL* = BUTTON_MODIFIER_CONTROL - BUTTON_ALT* = BUTTON_MODIFIER_ALT -else: - const - BUTTON_SHIFT* = 0x00000008 - BUTTON_CONTROL* = 0x00000010 - BUTTON_ALT* = 0x00000020 - -type - TMOUSE_STATUS*{.pure, final.} = object - x*: cint # absolute column, 0 based, measured in characters - y*: cint # absolute row, 0 based, measured in characters - button*: array[0..3 - 1, cshort] # state of each button - changes*: cint # flags indicating what has changed with the mouse - - MEVENT*{.pure, final.} = object - id*: cshort # unused, always 0 - x*: cint - y*: cint - z*: cint # x, y same as TMOUSE_STATUS; z unused - bstate*: cunsignedlong # equivalent to changes + button[], but - # in the same format as used for mousemask() - - WINDOW*{.pure, final.} = object - cury*: cint # current pseudo-cursor - curx*: cint - maxy*: cint # max window coordinates - maxx*: cint - begy*: cint # origin on screen - begx*: cint - flags*: cint # window properties - attrs*: cunsignedlong # standard attributes and colors - bkgd*: cunsignedlong # background, normally blank - clear*: cunsignedchar # causes clear at next refresh - leaveit*: cunsignedchar # leaves cursor where it is - scroll*: cunsignedchar # allows window scrolling - nodelay*: cunsignedchar # input character wait flag - immed*: cunsignedchar # immediate update flag - sync*: cunsignedchar # synchronise window ancestors - use_keypad*: cunsignedchar # flags keypad key mode active - y*: ptr ptr cunsignedlong # pointer to line pointer array - firstch*: ptr cint # first changed character in line - lastch*: ptr cint # last changed character in line - tmarg*: cint # top of scrolling region - bmarg*: cint # bottom of scrolling region - delayms*: cint # milliseconds of delay for getch() - parx*: cint - pary*: cint # coords relative to parent (0,0) - parent*: ptr WINDOW # subwin's pointer to parent win - - PANELOBS*{.pure, final.} = object - above*: ptr PANELOBS - pan*: ptr PANEL - - PANEL*{.pure, final.} = object - win*: ptr WINDOW - wstarty*: cint - wendy*: cint - wstartx*: cint - wendx*: cint - below*: ptr PANEL - above*: ptr PANEL - user*: pointer - obscure*: ptr PANELOBS -{.deprecated: [ - #TMOUSE_STATUS: MOUSE_STATUS, # Name conflict when we drop the `T` - TMEVENT: MEVENT, TWINDOW: WINDOW, - TPANELOBS: PANELOBS, TPANEL:PANEL].} - -when unixOS: - type - SCREEN*{.pure, final.} = object - alive*: cunsignedchar # if initscr() called, and not endwin() - autocr*: cunsignedchar # if cr -> lf - cbreak*: cunsignedchar # if terminal unbuffered - echo*: cunsignedchar # if terminal echo - raw_inp*: cunsignedchar # raw input mode (v. cooked input) - raw_out*: cunsignedchar # raw output mode (7 v. 8 bits) - audible*: cunsignedchar # FALSE if the bell is visual - mono*: cunsignedchar # TRUE if current screen is mono - resized*: cunsignedchar # TRUE if TERM has been resized - orig_attr*: cunsignedchar # TRUE if we have the original colors - orig_fore*: cshort # original screen foreground color - orig_back*: cshort # original screen foreground color - cursrow*: cint # position of physical cursor - curscol*: cint # position of physical cursor - visibility*: cint # visibility of cursor - orig_cursor*: cint # original cursor size - lines*: cint # new value for LINES - cols*: cint # new value for COLS - trap_mbe*: cunsignedlong # trap these mouse button events - map_mbe_to_key*: cunsignedlong # map mouse buttons to slk - mouse_wait*: cint # time to wait (in ms) for a button release after a press - slklines*: cint # lines in use by slk_init() - slk_winptr*: ptr WINDOW # window for slk - linesrippedoff*: cint # lines ripped off via ripoffline() - linesrippedoffontop*: cint # lines ripped off on top via ripoffline() - delaytenths*: cint # 1/10ths second to wait block getch() for - preserve*: cunsignedchar # TRUE if screen background to be preserved - restore*: cint # specifies if screen background to be restored, and how - save_key_modifiers*: cunsignedchar # TRUE if each key modifiers saved with each key press - return_key_modifiers*: cunsignedchar # TRUE if modifier keys are returned as "real" keys - key_code*: cunsignedchar # TRUE if last key is a special key; - XcurscrSize*: cint # size of Xcurscr shared memory block - sb_on*: cunsignedchar - sb_viewport_y*: cint - sb_viewport_x*: cint - sb_total_y*: cint - sb_total_x*: cint - sb_cur_y*: cint - sb_cur_x*: cint - line_color*: cshort # color of line attributes - default -1 - {.deprecated: [TSCREEN: SCREEN].} -else: - type - SCREEN*{.pure, final.} = object - alive*: cunsignedchar # if initscr() called, and not endwin() - autocr*: cunsignedchar # if cr -> lf - cbreak*: cunsignedchar # if terminal unbuffered - echo*: cunsignedchar # if terminal echo - raw_inp*: cunsignedchar # raw input mode (v. cooked input) - raw_out*: cunsignedchar # raw output mode (7 v. 8 bits) - audible*: cunsignedchar # FALSE if the bell is visual - mono*: cunsignedchar # TRUE if current screen is mono - resized*: cunsignedchar # TRUE if TERM has been resized - orig_attr*: cunsignedchar # TRUE if we have the original colors - orig_fore*: cshort # original screen foreground color - orig_back*: cshort # original screen foreground color - cursrow*: cint # position of physical cursor - curscol*: cint # position of physical cursor - visibility*: cint # visibility of cursor - orig_cursor*: cint # original cursor size - lines*: cint # new value for LINES - cols*: cint # new value for COLS - trap_mbe*: cunsignedlong # trap these mouse button events - map_mbe_to_key*: cunsignedlong # map mouse buttons to slk - mouse_wait*: cint # time to wait (in ms) for a button release after a press - slklines*: cint # lines in use by slk_init() - slk_winptr*: ptr WINDOW # window for slk - linesrippedoff*: cint # lines ripped off via ripoffline() - linesrippedoffontop*: cint # lines ripped off on top via ripoffline() - delaytenths*: cint # 1/10ths second to wait block getch() for - preserve*: cunsignedchar # TRUE if screen background to be preserved - restore*: cint # specifies if screen background to be restored, and how - save_key_modifiers*: cunsignedchar # TRUE if each key modifiers saved with each key press - return_key_modifiers*: cunsignedchar # TRUE if modifier keys are returned as "real" keys - key_code*: cunsignedchar # TRUE if last key is a special key; - line_color*: cshort # color of line attributes - default -1 - {.deprecated: [TSCREEN: SCREEN].} - -var - LINES*{.importc: "LINES", dynlib: pdcursesdll.}: cint - COLS*{.importc: "COLS", dynlib: pdcursesdll.}: cint - stdscr*{.importc: "stdscr", dynlib: pdcursesdll.}: ptr WINDOW - curscr*{.importc: "curscr", dynlib: pdcursesdll.}: ptr WINDOW - SP*{.importc: "SP", dynlib: pdcursesdll.}: ptr SCREEN - Mouse_status*{.importc: "Mouse_status", dynlib: pdcursesdll.}: MOUSE_STATUS - COLORS*{.importc: "COLORS", dynlib: pdcursesdll.}: cint - COLOR_PAIRS*{.importc: "COLOR_PAIRS", dynlib: pdcursesdll.}: cint - TABSIZE*{.importc: "TABSIZE", dynlib: pdcursesdll.}: cint - acs_map*{.importc: "acs_map", dynlib: pdcursesdll.}: ptr cunsignedlong - ttytype*{.importc: "ttytype", dynlib: pdcursesdll.}: cstring - -template BUTTON_CHANGED*(x: expr): expr = - (Mouse_status.changes and (1 shl ((x) - 1))) - -template BUTTON_STATUS*(x: expr): expr = - (Mouse_status.button[(x) - 1]) - -template ACS_PICK*(w, n: expr): expr = int32(w) or A_ALTCHARSET - -template KEY_F*(n: expr): expr = KEY_F0 + n - -template COLOR_PAIR*(n: expr): expr = - ((cunsignedlong(n) shl COLOR_SHIFT) and A_COLOR) - -template PAIR_NUMBER*(n: expr): expr = - (((n) and A_COLOR) shr COLOR_SHIFT) - -const - #MOUSE_X_POS* = (Mouse_status.x) - #MOUSE_Y_POS* = (Mouse_status.y) - #A_BUTTON_CHANGED* = (Mouse_status.changes and 7) - #MOUSE_MOVED* = (Mouse_status.changes and MOUSE_MOVED) - #MOUSE_POS_REPORT* = (Mouse_status.changes and MOUSE_POSITION) - #MOUSE_WHEEL_UP* = (Mouse_status.changes and MOUSE_WHEEL_UP) - #MOUSE_WHEEL_DOWN* = (Mouse_status.changes and MOUSE_WHEEL_DOWN) - ACS_ULCORNER* = ACS_PICK('l', '+') - ACS_LLCORNER* = ACS_PICK('m', '+') - ACS_URCORNER* = ACS_PICK('k', '+') - ACS_LRCORNER* = ACS_PICK('j', '+') - ACS_RTEE* = ACS_PICK('u', '+') - ACS_LTEE* = ACS_PICK('t', '+') - ACS_BTEE* = ACS_PICK('v', '+') - ACS_TTEE* = ACS_PICK('w', '+') - ACS_HLINE* = ACS_PICK('q', '-') - ACS_VLINE* = ACS_PICK('x', '|') - ACS_PLUS* = ACS_PICK('n', '+') - ACS_S1* = ACS_PICK('o', '-') - ACS_S9* = ACS_PICK('s', '_') - ACS_DIAMOND* = ACS_PICK('`', '+') - ACS_CKBOARD* = ACS_PICK('a', ':') - ACS_DEGREE* = ACS_PICK('f', '\'') - ACS_PLMINUS* = ACS_PICK('g', '#') - ACS_BULLET* = ACS_PICK('~', 'o') - ACS_LARROW* = ACS_PICK(',', '<') - ACS_RARROW* = ACS_PICK('+', '>') - ACS_DARROW* = ACS_PICK('.', 'v') - ACS_UARROW* = ACS_PICK('-', '^') - ACS_BOARD* = ACS_PICK('h', '#') - ACS_LANTERN* = ACS_PICK('i', '*') - ACS_BLOCK* = ACS_PICK('0', '#') - ACS_S3* = ACS_PICK('p', '-') - ACS_S7* = ACS_PICK('r', '-') - ACS_LEQUAL* = ACS_PICK('y', '<') - ACS_GEQUAL* = ACS_PICK('z', '>') - ACS_PI* = ACS_PICK('{', 'n') - ACS_NEQUAL* = ACS_PICK('|', '+') - ACS_STERLING* = ACS_PICK('}', 'L') - ACS_BSSB* = ACS_ULCORNER - ACS_SSBB* = ACS_LLCORNER - ACS_BBSS* = ACS_URCORNER - ACS_SBBS* = ACS_LRCORNER - ACS_SBSS* = ACS_RTEE - ACS_SSSB* = ACS_LTEE - ACS_SSBS* = ACS_BTEE - ACS_BSSS* = ACS_TTEE - ACS_BSBS* = ACS_HLINE - ACS_SBSB* = ACS_VLINE - ACS_SSSS* = ACS_PLUS -discard """WACS_ULCORNER* = (addr((acs_map['l']))) - WACS_LLCORNER* = (addr((acs_map['m']))) - WACS_URCORNER* = (addr((acs_map['k']))) - WACS_LRCORNER* = (addr((acs_map['j']))) - WACS_RTEE* = (addr((acs_map['u']))) - WACS_LTEE* = (addr((acs_map['t']))) - WACS_BTEE* = (addr((acs_map['v']))) - WACS_TTEE* = (addr((acs_map['w']))) - WACS_HLINE* = (addr((acs_map['q']))) - WACS_VLINE* = (addr((acs_map['x']))) - WACS_PLUS* = (addr((acs_map['n']))) - WACS_S1* = (addr((acs_map['o']))) - WACS_S9* = (addr((acs_map['s']))) - WACS_DIAMOND* = (addr((acs_map['`']))) - WACS_CKBOARD* = (addr((acs_map['a']))) - WACS_DEGREE* = (addr((acs_map['f']))) - WACS_PLMINUS* = (addr((acs_map['g']))) - WACS_BULLET* = (addr((acs_map['~']))) - WACS_LARROW* = (addr((acs_map[',']))) - WACS_RARROW* = (addr((acs_map['+']))) - WACS_DARROW* = (addr((acs_map['.']))) - WACS_UARROW* = (addr((acs_map['-']))) - WACS_BOARD* = (addr((acs_map['h']))) - WACS_LANTERN* = (addr((acs_map['i']))) - WACS_BLOCK* = (addr((acs_map['0']))) - WACS_S3* = (addr((acs_map['p']))) - WACS_S7* = (addr((acs_map['r']))) - WACS_LEQUAL* = (addr((acs_map['y']))) - WACS_GEQUAL* = (addr((acs_map['z']))) - WACS_PI* = (addr((acs_map['{']))) - WACS_NEQUAL* = (addr((acs_map['|']))) - WACS_STERLING* = (addr((acs_map['}']))) - WACS_BSSB* = WACS_ULCORNER - WACS_SSBB* = WACS_LLCORNER - WACS_BBSS* = WACS_URCORNER - WACS_SBBS* = WACS_LRCORNER - WACS_SBSS* = WACS_RTEE - WACS_SSSB* = WACS_LTEE - WACS_SSBS* = WACS_BTEE - WACS_BSSS* = WACS_TTEE - WACS_BSBS* = WACS_HLINE - WACS_SBSB* = WACS_VLINE - WACS_SSSS* = WACS_PLUS""" - -proc addch*(a2: cunsignedlong): cint{.extdecl, importc: "addch", - dynlib: pdcursesdll.} -proc addchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "addchnstr", dynlib: pdcursesdll.} -proc addchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "addchstr", - dynlib: pdcursesdll.} -proc addnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "addnstr", - dynlib: pdcursesdll.} -proc addstr*(a2: cstring): cint{.extdecl, importc: "addstr", dynlib: pdcursesdll.} -proc attroff*(a2: cunsignedlong): cint{.extdecl, importc: "attroff", - dynlib: pdcursesdll.} -proc attron*(a2: cunsignedlong): cint{.extdecl, importc: "attron", - dynlib: pdcursesdll.} -proc attrset*(a2: cunsignedlong): cint{.extdecl, importc: "attrset", - dynlib: pdcursesdll.} -proc attr_get*(a2: ptr cunsignedlong; a3: ptr cshort; a4: pointer): cint{.extdecl, - importc: "attr_get", dynlib: pdcursesdll.} -proc attr_off*(a2: cunsignedlong; a3: pointer): cint{.extdecl, - importc: "attr_off", dynlib: pdcursesdll.} -proc attr_on*(a2: cunsignedlong; a3: pointer): cint{.extdecl, importc: "attr_on", - dynlib: pdcursesdll.} -proc attr_set*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl, - importc: "attr_set", dynlib: pdcursesdll.} -proc baudrate*(): cint{.extdecl, importc: "baudrate", dynlib: pdcursesdll.} -proc beep*(): cint{.extdecl, importc: "beep", dynlib: pdcursesdll.} -proc bkgd*(a2: cunsignedlong): cint{.extdecl, importc: "bkgd", dynlib: pdcursesdll.} -proc bkgdset*(a2: cunsignedlong){.extdecl, importc: "bkgdset", dynlib: pdcursesdll.} -proc border*(a2: cunsignedlong; a3: cunsignedlong; a4: cunsignedlong; - a5: cunsignedlong; a6: cunsignedlong; a7: cunsignedlong; - a8: cunsignedlong; a9: cunsignedlong): cint{.extdecl, - importc: "border", dynlib: pdcursesdll.} -proc box*(a2: ptr WINDOW; a3: cunsignedlong; a4: cunsignedlong): cint{.extdecl, - importc: "box", dynlib: pdcursesdll.} -proc can_change_color*(): cunsignedchar{.extdecl, importc: "can_change_color", - dynlib: pdcursesdll.} -proc cbreak*(): cint{.extdecl, importc: "cbreak", dynlib: pdcursesdll.} -proc chgat*(a2: cint; a3: cunsignedlong; a4: cshort; a5: pointer): cint{.extdecl, - importc: "chgat", dynlib: pdcursesdll.} -proc clearok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "clearok", dynlib: pdcursesdll.} -proc clear*(): cint{.extdecl, importc: "clear", dynlib: pdcursesdll.} -proc clrtobot*(): cint{.extdecl, importc: "clrtobot", dynlib: pdcursesdll.} -proc clrtoeol*(): cint{.extdecl, importc: "clrtoeol", dynlib: pdcursesdll.} -proc color_content*(a2: cshort; a3: ptr cshort; a4: ptr cshort; a5: ptr cshort): cint{. - extdecl, importc: "color_content", dynlib: pdcursesdll.} -proc color_set*(a2: cshort; a3: pointer): cint{.extdecl, importc: "color_set", - dynlib: pdcursesdll.} -proc copywin*(a2: ptr WINDOW; a3: ptr WINDOW; a4: cint; a5: cint; a6: cint; - a7: cint; a8: cint; a9: cint; a10: cint): cint{.extdecl, - importc: "copywin", dynlib: pdcursesdll.} -proc curs_set*(a2: cint): cint{.extdecl, importc: "curs_set", dynlib: pdcursesdll.} -proc def_prog_mode*(): cint{.extdecl, importc: "def_prog_mode", - dynlib: pdcursesdll.} -proc def_shell_mode*(): cint{.extdecl, importc: "def_shell_mode", - dynlib: pdcursesdll.} -proc delay_output*(a2: cint): cint{.extdecl, importc: "delay_output", - dynlib: pdcursesdll.} -proc delch*(): cint{.extdecl, importc: "delch", dynlib: pdcursesdll.} -proc deleteln*(): cint{.extdecl, importc: "deleteln", dynlib: pdcursesdll.} -proc delscreen*(a2: ptr SCREEN){.extdecl, importc: "delscreen", - dynlib: pdcursesdll.} -proc delwin*(a2: ptr WINDOW): cint{.extdecl, importc: "delwin", - dynlib: pdcursesdll.} -proc derwin*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{. - extdecl, importc: "derwin", dynlib: pdcursesdll.} -proc doupdate*(): cint{.extdecl, importc: "doupdate", dynlib: pdcursesdll.} -proc dupwin*(a2: ptr WINDOW): ptr WINDOW{.extdecl, importc: "dupwin", - dynlib: pdcursesdll.} -proc echochar*(a2: cunsignedlong): cint{.extdecl, importc: "echochar", - dynlib: pdcursesdll.} -proc echo*(): cint{.extdecl, importc: "echo", dynlib: pdcursesdll.} -proc endwin*(): cint{.extdecl, importc: "endwin", dynlib: pdcursesdll.} -proc erasechar*(): char{.extdecl, importc: "erasechar", dynlib: pdcursesdll.} -proc erase*(): cint{.extdecl, importc: "erase", dynlib: pdcursesdll.} -proc filter*(){.extdecl, importc: "filter", dynlib: pdcursesdll.} -proc flash*(): cint{.extdecl, importc: "flash", dynlib: pdcursesdll.} -proc flushinp*(): cint{.extdecl, importc: "flushinp", dynlib: pdcursesdll.} -proc getbkgd*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "getbkgd", - dynlib: pdcursesdll.} -proc getnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "getnstr", - dynlib: pdcursesdll.} -proc getstr*(a2: cstring): cint{.extdecl, importc: "getstr", dynlib: pdcursesdll.} -proc getwin*(a2: File): ptr WINDOW{.extdecl, importc: "getwin", - dynlib: pdcursesdll.} -proc halfdelay*(a2: cint): cint{.extdecl, importc: "halfdelay", - dynlib: pdcursesdll.} -proc has_colors*(): cunsignedchar{.extdecl, importc: "has_colors", - dynlib: pdcursesdll.} -proc has_ic*(): cunsignedchar{.extdecl, importc: "has_ic", dynlib: pdcursesdll.} -proc has_il*(): cunsignedchar{.extdecl, importc: "has_il", dynlib: pdcursesdll.} -proc hline*(a2: cunsignedlong; a3: cint): cint{.extdecl, importc: "hline", - dynlib: pdcursesdll.} -proc idcok*(a2: ptr WINDOW; a3: cunsignedchar){.extdecl, importc: "idcok", - dynlib: pdcursesdll.} -proc idlok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "idlok", - dynlib: pdcursesdll.} -proc immedok*(a2: ptr WINDOW; a3: cunsignedchar){.extdecl, importc: "immedok", - dynlib: pdcursesdll.} -proc inchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "inchnstr", dynlib: pdcursesdll.} -proc inchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "inchstr", - dynlib: pdcursesdll.} -proc inch*(): cunsignedlong{.extdecl, importc: "inch", dynlib: pdcursesdll.} -proc init_color*(a2: cshort; a3: cshort; a4: cshort; a5: cshort): cint{.extdecl, - importc: "init_color", dynlib: pdcursesdll.} -proc init_pair*(a2: cshort; a3: cshort; a4: cshort): cint{.extdecl, - importc: "init_pair", dynlib: pdcursesdll.} -proc initscr*(): ptr WINDOW{.extdecl, importc: "initscr", dynlib: pdcursesdll.} -proc innstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "innstr", - dynlib: pdcursesdll.} -proc insch*(a2: cunsignedlong): cint{.extdecl, importc: "insch", - dynlib: pdcursesdll.} -proc insdelln*(a2: cint): cint{.extdecl, importc: "insdelln", dynlib: pdcursesdll.} -proc insertln*(): cint{.extdecl, importc: "insertln", dynlib: pdcursesdll.} -proc insnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "insnstr", - dynlib: pdcursesdll.} -proc insstr*(a2: cstring): cint{.extdecl, importc: "insstr", dynlib: pdcursesdll.} -proc instr*(a2: cstring): cint{.extdecl, importc: "instr", dynlib: pdcursesdll.} -proc intrflush*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "intrflush", dynlib: pdcursesdll.} -proc isendwin*(): cunsignedchar{.extdecl, importc: "isendwin", dynlib: pdcursesdll.} -proc is_linetouched*(a2: ptr WINDOW; a3: cint): cunsignedchar{.extdecl, - importc: "is_linetouched", dynlib: pdcursesdll.} -proc is_wintouched*(a2: ptr WINDOW): cunsignedchar{.extdecl, - importc: "is_wintouched", dynlib: pdcursesdll.} -proc keyname*(a2: cint): cstring{.extdecl, importc: "keyname", dynlib: pdcursesdll.} -proc keypad*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "keypad", - dynlib: pdcursesdll.} -proc killchar*(): char{.extdecl, importc: "killchar", dynlib: pdcursesdll.} -proc leaveok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "leaveok", dynlib: pdcursesdll.} -proc longname*(): cstring{.extdecl, importc: "longname", dynlib: pdcursesdll.} -proc meta*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "meta", - dynlib: pdcursesdll.} -proc move*(a2: cint; a3: cint): cint{.extdecl, importc: "move", - dynlib: pdcursesdll.} -proc mvaddch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl, - importc: "mvaddch", dynlib: pdcursesdll.} -proc mvaddchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvaddchnstr", dynlib: pdcursesdll.} -proc mvaddchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvaddchstr", dynlib: pdcursesdll.} -proc mvaddnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvaddnstr", dynlib: pdcursesdll.} -proc mvaddstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvaddstr", dynlib: pdcursesdll.} -proc mvchgat*(a2: cint; a3: cint; a4: cint; a5: cunsignedlong; a6: cshort; - a7: pointer): cint{.extdecl, importc: "mvchgat", dynlib: pdcursesdll.} -proc mvcur*(a2: cint; a3: cint; a4: cint; a5: cint): cint{.extdecl, - importc: "mvcur", dynlib: pdcursesdll.} -proc mvdelch*(a2: cint; a3: cint): cint{.extdecl, importc: "mvdelch", - dynlib: pdcursesdll.} -proc mvderwin*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvderwin", dynlib: pdcursesdll.} -proc mvgetch*(a2: cint; a3: cint): cint{.extdecl, importc: "mvgetch", - dynlib: pdcursesdll.} -proc mvgetnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvgetnstr", dynlib: pdcursesdll.} -proc mvgetstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvgetstr", dynlib: pdcursesdll.} -proc mvhline*(a2: cint; a3: cint; a4: cunsignedlong; a5: cint): cint{.extdecl, - importc: "mvhline", dynlib: pdcursesdll.} -proc mvinch*(a2: cint; a3: cint): cunsignedlong{.extdecl, importc: "mvinch", - dynlib: pdcursesdll.} -proc mvinchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvinchnstr", dynlib: pdcursesdll.} -proc mvinchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvinchstr", dynlib: pdcursesdll.} -proc mvinnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvinnstr", dynlib: pdcursesdll.} -proc mvinsch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl, - importc: "mvinsch", dynlib: pdcursesdll.} -proc mvinsnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvinsnstr", dynlib: pdcursesdll.} -proc mvinsstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvinsstr", dynlib: pdcursesdll.} -proc mvinstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, importc: "mvinstr", - dynlib: pdcursesdll.} -proc mvprintw*(a2: cint; a3: cint; a4: cstring): cint{.varargs, extdecl, - importc: "mvprintw", dynlib: pdcursesdll.} -proc mvscanw*(a2: cint; a3: cint; a4: cstring): cint{.varargs, extdecl, - importc: "mvscanw", dynlib: pdcursesdll.} -proc mvvline*(a2: cint; a3: cint; a4: cunsignedlong; a5: cint): cint{.extdecl, - importc: "mvvline", dynlib: pdcursesdll.} -proc mvwaddchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwaddchnstr", - dynlib: pdcursesdll.} -proc mvwaddchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwaddchstr", dynlib: pdcursesdll.} -proc mvwaddch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{. - extdecl, importc: "mvwaddch", dynlib: pdcursesdll.} -proc mvwaddnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwaddnstr", dynlib: pdcursesdll.} -proc mvwaddstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl, - importc: "mvwaddstr", dynlib: pdcursesdll.} -proc mvwchgat*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cunsignedlong; - a7: cshort; a8: pointer): cint{.extdecl, importc: "mvwchgat", - dynlib: pdcursesdll.} -proc mvwdelch*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvwdelch", dynlib: pdcursesdll.} -proc mvwgetch*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvwgetch", dynlib: pdcursesdll.} -proc mvwgetnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwgetnstr", dynlib: pdcursesdll.} -proc mvwgetstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl, - importc: "mvwgetstr", dynlib: pdcursesdll.} -proc mvwhline*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong; a6: cint): cint{. - extdecl, importc: "mvwhline", dynlib: pdcursesdll.} -proc mvwinchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwinchnstr", - dynlib: pdcursesdll.} -proc mvwinchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwinchstr", dynlib: pdcursesdll.} -proc mvwinch*(a2: ptr WINDOW; a3: cint; a4: cint): cunsignedlong{.extdecl, - importc: "mvwinch", dynlib: pdcursesdll.} -proc mvwinnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwinnstr", dynlib: pdcursesdll.} -proc mvwinsch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{. - extdecl, importc: "mvwinsch", dynlib: pdcursesdll.} -proc mvwinsnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwinsnstr", dynlib: pdcursesdll.} -proc mvwinsstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl, - importc: "mvwinsstr", dynlib: pdcursesdll.} -proc mvwinstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl, - importc: "mvwinstr", dynlib: pdcursesdll.} -proc mvwin*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, importc: "mvwin", - dynlib: pdcursesdll.} -proc mvwprintw*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.varargs, - extdecl, importc: "mvwprintw", dynlib: pdcursesdll.} -proc mvwscanw*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.varargs, - extdecl, importc: "mvwscanw", dynlib: pdcursesdll.} -proc mvwvline*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong; a6: cint): cint{. - extdecl, importc: "mvwvline", dynlib: pdcursesdll.} -proc napms*(a2: cint): cint{.extdecl, importc: "napms", dynlib: pdcursesdll.} -proc newpad*(a2: cint; a3: cint): ptr WINDOW{.extdecl, importc: "newpad", - dynlib: pdcursesdll.} -proc newterm*(a2: cstring; a3: File; a4: File): ptr SCREEN{.extdecl, - importc: "newterm", dynlib: pdcursesdll.} -proc newwin*(a2: cint; a3: cint; a4: cint; a5: cint): ptr WINDOW{.extdecl, - importc: "newwin", dynlib: pdcursesdll.} -proc nl*(): cint{.extdecl, importc: "nl", dynlib: pdcursesdll.} -proc nocbreak*(): cint{.extdecl, importc: "nocbreak", dynlib: pdcursesdll.} -proc nodelay*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "nodelay", dynlib: pdcursesdll.} -proc noecho*(): cint{.extdecl, importc: "noecho", dynlib: pdcursesdll.} -proc nonl*(): cint{.extdecl, importc: "nonl", dynlib: pdcursesdll.} -proc noqiflush*(){.extdecl, importc: "noqiflush", dynlib: pdcursesdll.} -proc noraw*(): cint{.extdecl, importc: "noraw", dynlib: pdcursesdll.} -proc notimeout*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "notimeout", dynlib: pdcursesdll.} -proc overlay*(a2: ptr WINDOW; a3: ptr WINDOW): cint{.extdecl, importc: "overlay", - dynlib: pdcursesdll.} -proc overwrite*(a2: ptr WINDOW; a3: ptr WINDOW): cint{.extdecl, - importc: "overwrite", dynlib: pdcursesdll.} -proc pair_content*(a2: cshort; a3: ptr cshort; a4: ptr cshort): cint{.extdecl, - importc: "pair_content", dynlib: pdcursesdll.} -proc pechochar*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "pechochar", dynlib: pdcursesdll.} -proc pnoutrefresh*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint; - a7: cint; a8: cint): cint{.extdecl, importc: "pnoutrefresh", - dynlib: pdcursesdll.} -proc prefresh*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint; a7: cint; - a8: cint): cint{.extdecl, importc: "prefresh", dynlib: pdcursesdll.} -proc printw*(a2: cstring): cint{.varargs, extdecl, importc: "printw", - dynlib: pdcursesdll.} -proc putwin*(a2: ptr WINDOW; a3: File): cint{.extdecl, importc: "putwin", - dynlib: pdcursesdll.} -proc qiflush*(){.extdecl, importc: "qiflush", dynlib: pdcursesdll.} -proc raw*(): cint{.extdecl, importc: "raw", dynlib: pdcursesdll.} -proc redrawwin*(a2: ptr WINDOW): cint{.extdecl, importc: "redrawwin", - dynlib: pdcursesdll.} -proc refresh*(): cint{.extdecl, importc: "refresh", dynlib: pdcursesdll.} -proc reset_prog_mode*(): cint{.extdecl, importc: "reset_prog_mode", - dynlib: pdcursesdll.} -proc reset_shell_mode*(): cint{.extdecl, importc: "reset_shell_mode", - dynlib: pdcursesdll.} -proc resetty*(): cint{.extdecl, importc: "resetty", dynlib: pdcursesdll.} -#int ripoffline(int, int (*)(WINDOW *, int)); -proc savetty*(): cint{.extdecl, importc: "savetty", dynlib: pdcursesdll.} -proc scanw*(a2: cstring): cint{.varargs, extdecl, importc: "scanw", - dynlib: pdcursesdll.} -proc scr_dump*(a2: cstring): cint{.extdecl, importc: "scr_dump", - dynlib: pdcursesdll.} -proc scr_init*(a2: cstring): cint{.extdecl, importc: "scr_init", - dynlib: pdcursesdll.} -proc scr_restore*(a2: cstring): cint{.extdecl, importc: "scr_restore", - dynlib: pdcursesdll.} -proc scr_set*(a2: cstring): cint{.extdecl, importc: "scr_set", dynlib: pdcursesdll.} -proc scrl*(a2: cint): cint{.extdecl, importc: "scrl", dynlib: pdcursesdll.} -proc scroll*(a2: ptr WINDOW): cint{.extdecl, importc: "scroll", - dynlib: pdcursesdll.} -proc scrollok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, - importc: "scrollok", dynlib: pdcursesdll.} -proc set_term*(a2: ptr SCREEN): ptr SCREEN{.extdecl, importc: "set_term", - dynlib: pdcursesdll.} -proc setscrreg*(a2: cint; a3: cint): cint{.extdecl, importc: "setscrreg", - dynlib: pdcursesdll.} -proc slk_attroff*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attroff", - dynlib: pdcursesdll.} -proc slk_attr_off*(a2: cunsignedlong; a3: pointer): cint{.extdecl, - importc: "slk_attr_off", dynlib: pdcursesdll.} -proc slk_attron*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attron", - dynlib: pdcursesdll.} -proc slk_attr_on*(a2: cunsignedlong; a3: pointer): cint{.extdecl, - importc: "slk_attr_on", dynlib: pdcursesdll.} -proc slk_attrset*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attrset", - dynlib: pdcursesdll.} -proc slk_attr_set*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl, - importc: "slk_attr_set", dynlib: pdcursesdll.} -proc slk_clear*(): cint{.extdecl, importc: "slk_clear", dynlib: pdcursesdll.} -proc slk_color*(a2: cshort): cint{.extdecl, importc: "slk_color", - dynlib: pdcursesdll.} -proc slk_init*(a2: cint): cint{.extdecl, importc: "slk_init", dynlib: pdcursesdll.} -proc slk_label*(a2: cint): cstring{.extdecl, importc: "slk_label", - dynlib: pdcursesdll.} -proc slk_noutrefresh*(): cint{.extdecl, importc: "slk_noutrefresh", - dynlib: pdcursesdll.} -proc slk_refresh*(): cint{.extdecl, importc: "slk_refresh", dynlib: pdcursesdll.} -proc slk_restore*(): cint{.extdecl, importc: "slk_restore", dynlib: pdcursesdll.} -proc slk_set*(a2: cint; a3: cstring; a4: cint): cint{.extdecl, importc: "slk_set", - dynlib: pdcursesdll.} -proc slk_touch*(): cint{.extdecl, importc: "slk_touch", dynlib: pdcursesdll.} -proc standend*(): cint{.extdecl, importc: "standend", dynlib: pdcursesdll.} -proc standout*(): cint{.extdecl, importc: "standout", dynlib: pdcursesdll.} -proc start_color*(): cint{.extdecl, importc: "start_color", dynlib: pdcursesdll.} -proc subpad*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{. - extdecl, importc: "subpad", dynlib: pdcursesdll.} -proc subwin*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{. - extdecl, importc: "subwin", dynlib: pdcursesdll.} -proc syncok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "syncok", - dynlib: pdcursesdll.} -proc termattrs*(): cunsignedlong{.extdecl, importc: "termattrs", - dynlib: pdcursesdll.} -proc termattrs2*(): cunsignedlong{.extdecl, importc: "term_attrs", - dynlib: pdcursesdll.} -proc termname*(): cstring{.extdecl, importc: "termname", dynlib: pdcursesdll.} -proc timeout*(a2: cint){.extdecl, importc: "timeout", dynlib: pdcursesdll.} -proc touchline*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "touchline", dynlib: pdcursesdll.} -proc touchwin*(a2: ptr WINDOW): cint{.extdecl, importc: "touchwin", - dynlib: pdcursesdll.} -proc typeahead*(a2: cint): cint{.extdecl, importc: "typeahead", - dynlib: pdcursesdll.} -proc untouchwin*(a2: ptr WINDOW): cint{.extdecl, importc: "untouchwin", - dynlib: pdcursesdll.} -proc use_env*(a2: cunsignedchar){.extdecl, importc: "use_env", dynlib: pdcursesdll.} -proc vidattr*(a2: cunsignedlong): cint{.extdecl, importc: "vidattr", - dynlib: pdcursesdll.} -proc vid_attr*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl, - importc: "vid_attr", dynlib: pdcursesdll.} -#int vidputs(chtype, int (*)(int)); -#int vid_puts(attr_t, short, void *, int (*)(int)); -proc vline*(a2: cunsignedlong; a3: cint): cint{.extdecl, importc: "vline", - dynlib: pdcursesdll.} -proc vwprintw*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs, - importc: "vw_printw", dynlib: pdcursesdll.} -proc vwprintw2*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs, - importc: "vwprintw", dynlib: pdcursesdll.} -proc vwscanw*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs, - importc: "vw_scanw", dynlib: pdcursesdll.} -proc vwscanw2*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs, - importc: "vwscanw", dynlib: pdcursesdll.} -proc waddchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "waddchnstr", dynlib: pdcursesdll.} -proc waddchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "waddchstr", dynlib: pdcursesdll.} -proc waddch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "waddch", - dynlib: pdcursesdll.} -proc waddnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "waddnstr", dynlib: pdcursesdll.} -proc waddstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "waddstr", - dynlib: pdcursesdll.} -proc wattroff*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "wattroff", dynlib: pdcursesdll.} -proc wattron*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "wattron", dynlib: pdcursesdll.} -proc wattrset*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "wattrset", dynlib: pdcursesdll.} -proc wattr_get*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cshort; - a5: pointer): cint{.extdecl, importc: "wattr_get", - dynlib: pdcursesdll.} -proc wattr_off*(a2: ptr WINDOW; a3: cunsignedlong; a4: pointer): cint{.extdecl, - importc: "wattr_off", dynlib: pdcursesdll.} -proc wattr_on*(a2: ptr WINDOW; a3: cunsignedlong; a4: pointer): cint{.extdecl, - importc: "wattr_on", dynlib: pdcursesdll.} -proc wattr_set*(a2: ptr WINDOW; a3: cunsignedlong; a4: cshort; a5: pointer): cint{. - extdecl, importc: "wattr_set", dynlib: pdcursesdll.} -proc wbkgdset*(a2: ptr WINDOW; a3: cunsignedlong){.extdecl, importc: "wbkgdset", - dynlib: pdcursesdll.} -proc wbkgd*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "wbkgd", - dynlib: pdcursesdll.} -proc wborder*(a2: ptr WINDOW; a3: cunsignedlong; a4: cunsignedlong; - a5: cunsignedlong; a6: cunsignedlong; a7: cunsignedlong; - a8: cunsignedlong; a9: cunsignedlong; a10: cunsignedlong): cint{. - extdecl, importc: "wborder", dynlib: pdcursesdll.} -proc wchgat*(a2: ptr WINDOW; a3: cint; a4: cunsignedlong; a5: cshort; - a6: pointer): cint{.extdecl, importc: "wchgat", dynlib: pdcursesdll.} -proc wclear*(a2: ptr WINDOW): cint{.extdecl, importc: "wclear", - dynlib: pdcursesdll.} -proc wclrtobot*(a2: ptr WINDOW): cint{.extdecl, importc: "wclrtobot", - dynlib: pdcursesdll.} -proc wclrtoeol*(a2: ptr WINDOW): cint{.extdecl, importc: "wclrtoeol", - dynlib: pdcursesdll.} -proc wcolor_set*(a2: ptr WINDOW; a3: cshort; a4: pointer): cint{.extdecl, - importc: "wcolor_set", dynlib: pdcursesdll.} -proc wcursyncup*(a2: ptr WINDOW){.extdecl, importc: "wcursyncup", - dynlib: pdcursesdll.} -proc wdelch*(a2: ptr WINDOW): cint{.extdecl, importc: "wdelch", - dynlib: pdcursesdll.} -proc wdeleteln*(a2: ptr WINDOW): cint{.extdecl, importc: "wdeleteln", - dynlib: pdcursesdll.} -proc wechochar*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "wechochar", dynlib: pdcursesdll.} -proc werase*(a2: ptr WINDOW): cint{.extdecl, importc: "werase", - dynlib: pdcursesdll.} -proc wgetch*(a2: ptr WINDOW): cint{.extdecl, importc: "wgetch", - dynlib: pdcursesdll.} -proc wgetnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "wgetnstr", dynlib: pdcursesdll.} -proc wgetstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "wgetstr", - dynlib: pdcursesdll.} -proc whline*(a2: ptr WINDOW; a3: cunsignedlong; a4: cint): cint{.extdecl, - importc: "whline", dynlib: pdcursesdll.} -proc winchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "winchnstr", dynlib: pdcursesdll.} -proc winchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "winchstr", dynlib: pdcursesdll.} -proc winch*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "winch", - dynlib: pdcursesdll.} -proc winnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "winnstr", dynlib: pdcursesdll.} -proc winsch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "winsch", - dynlib: pdcursesdll.} -proc winsdelln*(a2: ptr WINDOW; a3: cint): cint{.extdecl, importc: "winsdelln", - dynlib: pdcursesdll.} -proc winsertln*(a2: ptr WINDOW): cint{.extdecl, importc: "winsertln", - dynlib: pdcursesdll.} -proc winsnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "winsnstr", dynlib: pdcursesdll.} -proc winsstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winsstr", - dynlib: pdcursesdll.} -proc winstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winstr", - dynlib: pdcursesdll.} -proc wmove*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, importc: "wmove", - dynlib: pdcursesdll.} -proc wnoutrefresh*(a2: ptr WINDOW): cint{.extdecl, importc: "wnoutrefresh", - dynlib: pdcursesdll.} -proc wprintw*(a2: ptr WINDOW; a3: cstring): cint{.varargs, extdecl, - importc: "wprintw", dynlib: pdcursesdll.} -proc wredrawln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "wredrawln", dynlib: pdcursesdll.} -proc wrefresh*(a2: ptr WINDOW): cint{.extdecl, importc: "wrefresh", - dynlib: pdcursesdll.} -proc wscanw*(a2: ptr WINDOW; a3: cstring): cint{.varargs, extdecl, - importc: "wscanw", dynlib: pdcursesdll.} -proc wscrl*(a2: ptr WINDOW; a3: cint): cint{.extdecl, importc: "wscrl", - dynlib: pdcursesdll.} -proc wsetscrreg*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "wsetscrreg", dynlib: pdcursesdll.} -proc wstandend*(a2: ptr WINDOW): cint{.extdecl, importc: "wstandend", - dynlib: pdcursesdll.} -proc wstandout*(a2: ptr WINDOW): cint{.extdecl, importc: "wstandout", - dynlib: pdcursesdll.} -proc wsyncdown*(a2: ptr WINDOW){.extdecl, importc: "wsyncdown", - dynlib: pdcursesdll.} -proc wsyncup*(a2: ptr WINDOW){.extdecl, importc: "wsyncup", dynlib: pdcursesdll.} -proc wtimeout*(a2: ptr WINDOW; a3: cint){.extdecl, importc: "wtimeout", - dynlib: pdcursesdll.} -proc wtouchln*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint): cint{.extdecl, - importc: "wtouchln", dynlib: pdcursesdll.} -proc wvline*(a2: ptr WINDOW; a3: cunsignedlong; a4: cint): cint{.extdecl, - importc: "wvline", dynlib: pdcursesdll.} -proc addnwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "addnwstr", - dynlib: pdcursesdll.} -proc addwstr*(a2: cstring): cint{.extdecl, importc: "addwstr", - dynlib: pdcursesdll.} -proc add_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "add_wch", - dynlib: pdcursesdll.} -proc add_wchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "add_wchnstr", dynlib: pdcursesdll.} -proc add_wchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "add_wchstr", - dynlib: pdcursesdll.} -proc border_set*(a2: ptr cunsignedlong; a3: ptr cunsignedlong; - a4: ptr cunsignedlong; a5: ptr cunsignedlong; - a6: ptr cunsignedlong; a7: ptr cunsignedlong; - a8: ptr cunsignedlong; a9: ptr cunsignedlong): cint{.extdecl, - importc: "border_set", dynlib: pdcursesdll.} -proc box_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cunsignedlong): cint{. - extdecl, importc: "box_set", dynlib: pdcursesdll.} -proc echo_wchar*(a2: ptr cunsignedlong): cint{.extdecl, importc: "echo_wchar", - dynlib: pdcursesdll.} -proc erasewchar*(a2: cstring): cint{.extdecl, importc: "erasewchar", - dynlib: pdcursesdll.} -proc getbkgrnd*(a2: ptr cunsignedlong): cint{.extdecl, importc: "getbkgrnd", - dynlib: pdcursesdll.} -proc getcchar*(a2: ptr cunsignedlong; a3: cstring; a4: ptr cunsignedlong; - a5: ptr cshort; a6: pointer): cint{.extdecl, importc: "getcchar", - dynlib: pdcursesdll.} -proc getn_wstr*(a2: ptr cint; a3: cint): cint{.extdecl, importc: "getn_wstr", - dynlib: pdcursesdll.} -proc get_wch*(a2: ptr cint): cint{.extdecl, importc: "get_wch", - dynlib: pdcursesdll.} -proc get_wstr*(a2: ptr cint): cint{.extdecl, importc: "get_wstr", - dynlib: pdcursesdll.} -proc hline_set*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "hline_set", dynlib: pdcursesdll.} -proc innwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "innwstr", - dynlib: pdcursesdll.} -proc ins_nwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "ins_nwstr", - dynlib: pdcursesdll.} -proc ins_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "ins_wch", - dynlib: pdcursesdll.} -proc ins_wstr*(a2: cstring): cint{.extdecl, importc: "ins_wstr", - dynlib: pdcursesdll.} -proc inwstr*(a2: cstring): cint{.extdecl, importc: "inwstr", - dynlib: pdcursesdll.} -proc in_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "in_wch", - dynlib: pdcursesdll.} -proc in_wchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "in_wchnstr", dynlib: pdcursesdll.} -proc in_wchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "in_wchstr", - dynlib: pdcursesdll.} -proc key_name*(a2: char): cstring{.extdecl, importc: "key_name", - dynlib: pdcursesdll.} -proc killwchar*(a2: cstring): cint{.extdecl, importc: "killwchar", - dynlib: pdcursesdll.} -proc mvaddnwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvaddnwstr", dynlib: pdcursesdll.} -proc mvaddwstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvaddwstr", dynlib: pdcursesdll.} -proc mvadd_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvadd_wch", dynlib: pdcursesdll.} -proc mvadd_wchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvadd_wchnstr", dynlib: pdcursesdll.} -proc mvadd_wchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvadd_wchstr", dynlib: pdcursesdll.} -proc mvgetn_wstr*(a2: cint; a3: cint; a4: ptr cint; a5: cint): cint{.extdecl, - importc: "mvgetn_wstr", dynlib: pdcursesdll.} -proc mvget_wch*(a2: cint; a3: cint; a4: ptr cint): cint{.extdecl, - importc: "mvget_wch", dynlib: pdcursesdll.} -proc mvget_wstr*(a2: cint; a3: cint; a4: ptr cint): cint{.extdecl, - importc: "mvget_wstr", dynlib: pdcursesdll.} -proc mvhline_set*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvhline_set", dynlib: pdcursesdll.} -proc mvinnwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvinnwstr", dynlib: pdcursesdll.} -proc mvins_nwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl, - importc: "mvins_nwstr", dynlib: pdcursesdll.} -proc mvins_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvins_wch", dynlib: pdcursesdll.} -proc mvins_wstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvins_wstr", dynlib: pdcursesdll.} -proc mvinwstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, - importc: "mvinwstr", dynlib: pdcursesdll.} -proc mvin_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvin_wch", dynlib: pdcursesdll.} -proc mvin_wchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvin_wchnstr", dynlib: pdcursesdll.} -proc mvin_wchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl, - importc: "mvin_wchstr", dynlib: pdcursesdll.} -proc mvvline_set*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{. - extdecl, importc: "mvvline_set", dynlib: pdcursesdll.} -proc mvwaddnwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwaddnwstr", dynlib: pdcursesdll.} -proc mvwaddwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{. - extdecl, importc: "mvwaddwstr", dynlib: pdcursesdll.} -proc mvwadd_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwadd_wch", dynlib: pdcursesdll.} -proc mvwadd_wchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwadd_wchnstr", - dynlib: pdcursesdll.} -proc mvwadd_wchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwadd_wchstr", dynlib: pdcursesdll.} -proc mvwgetn_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint; a6: cint): cint{. - extdecl, importc: "mvwgetn_wstr", dynlib: pdcursesdll.} -proc mvwget_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint): cint{. - extdecl, importc: "mvwget_wch", dynlib: pdcursesdll.} -proc mvwget_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint): cint{. - extdecl, importc: "mvwget_wstr", dynlib: pdcursesdll.} -proc mvwhline_set*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwhline_set", - dynlib: pdcursesdll.} -proc mvwinnwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwinnwstr", dynlib: pdcursesdll.} -proc mvwins_nwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{. - extdecl, importc: "mvwins_nwstr", dynlib: pdcursesdll.} -proc mvwins_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwins_wch", dynlib: pdcursesdll.} -proc mvwins_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{. - extdecl, importc: "mvwins_wstr", dynlib: pdcursesdll.} -proc mvwin_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwin_wch", dynlib: pdcursesdll.} -proc mvwin_wchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwin_wchnstr", - dynlib: pdcursesdll.} -proc mvwin_wchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{. - extdecl, importc: "mvwin_wchstr", dynlib: pdcursesdll.} -proc mvwinwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{. - extdecl, importc: "mvwinwstr", dynlib: pdcursesdll.} -proc mvwvline_set*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong; - a6: cint): cint{.extdecl, importc: "mvwvline_set", - dynlib: pdcursesdll.} -proc pecho_wchar*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "pecho_wchar", dynlib: pdcursesdll.} -proc setcchar*(a2: ptr cunsignedlong; a3: cstring; a4: cunsignedlong; - a5: cshort; a6: pointer): cint{.extdecl, importc: "setcchar", - dynlib: pdcursesdll.} -proc slk_wset*(a2: cint; a3: cstring; a4: cint): cint{.extdecl, - importc: "slk_wset", dynlib: pdcursesdll.} -proc unget_wch*(a2: char): cint{.extdecl, importc: "unget_wch", - dynlib: pdcursesdll.} -proc vline_set*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl, - importc: "vline_set", dynlib: pdcursesdll.} -proc waddnwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "waddnwstr", dynlib: pdcursesdll.} -proc waddwstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, - importc: "waddwstr", dynlib: pdcursesdll.} -proc wadd_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wadd_wch", dynlib: pdcursesdll.} -proc wadd_wchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{. - extdecl, importc: "wadd_wchnstr", dynlib: pdcursesdll.} -proc wadd_wchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wadd_wchstr", dynlib: pdcursesdll.} -proc wbkgrnd*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wbkgrnd", dynlib: pdcursesdll.} -proc wbkgrndset*(a2: ptr WINDOW; a3: ptr cunsignedlong){.extdecl, - importc: "wbkgrndset", dynlib: pdcursesdll.} -proc wborder_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cunsignedlong; - a5: ptr cunsignedlong; a6: ptr cunsignedlong; - a7: ptr cunsignedlong; a8: ptr cunsignedlong; - a9: ptr cunsignedlong; a10: ptr cunsignedlong): cint{.extdecl, - importc: "wborder_set", dynlib: pdcursesdll.} -proc wecho_wchar*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wecho_wchar", dynlib: pdcursesdll.} -proc wgetbkgrnd*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wgetbkgrnd", dynlib: pdcursesdll.} -proc wgetn_wstr*(a2: ptr WINDOW; a3: ptr cint; a4: cint): cint{.extdecl, - importc: "wgetn_wstr", dynlib: pdcursesdll.} -proc wget_wch*(a2: ptr WINDOW; a3: ptr cint): cint{.extdecl, - importc: "wget_wch", dynlib: pdcursesdll.} -proc wget_wstr*(a2: ptr WINDOW; a3: ptr cint): cint{.extdecl, - importc: "wget_wstr", dynlib: pdcursesdll.} -proc whline_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "whline_set", dynlib: pdcursesdll.} -proc winnwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "winnwstr", dynlib: pdcursesdll.} -proc wins_nwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl, - importc: "wins_nwstr", dynlib: pdcursesdll.} -proc wins_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "wins_wch", dynlib: pdcursesdll.} -proc wins_wstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, - importc: "wins_wstr", dynlib: pdcursesdll.} -proc winwstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winwstr", - dynlib: pdcursesdll.} -proc win_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "win_wch", dynlib: pdcursesdll.} -proc win_wchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "win_wchnstr", dynlib: pdcursesdll.} -proc win_wchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl, - importc: "win_wchstr", dynlib: pdcursesdll.} -proc wunctrl*(a2: ptr cunsignedlong): cstring{.extdecl, importc: "wunctrl", - dynlib: pdcursesdll.} -proc wvline_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl, - importc: "wvline_set", dynlib: pdcursesdll.} -proc getattrs*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "getattrs", - dynlib: pdcursesdll.} -proc getbegx*(a2: ptr WINDOW): cint{.extdecl, importc: "getbegx", - dynlib: pdcursesdll.} -proc getbegy*(a2: ptr WINDOW): cint{.extdecl, importc: "getbegy", - dynlib: pdcursesdll.} -proc getmaxx*(a2: ptr WINDOW): cint{.extdecl, importc: "getmaxx", - dynlib: pdcursesdll.} -proc getmaxy*(a2: ptr WINDOW): cint{.extdecl, importc: "getmaxy", - dynlib: pdcursesdll.} -proc getparx*(a2: ptr WINDOW): cint{.extdecl, importc: "getparx", - dynlib: pdcursesdll.} -proc getpary*(a2: ptr WINDOW): cint{.extdecl, importc: "getpary", - dynlib: pdcursesdll.} -proc getcurx*(a2: ptr WINDOW): cint{.extdecl, importc: "getcurx", - dynlib: pdcursesdll.} -proc getcury*(a2: ptr WINDOW): cint{.extdecl, importc: "getcury", - dynlib: pdcursesdll.} -proc traceoff*(){.extdecl, importc: "traceoff", dynlib: pdcursesdll.} -proc traceon*(){.extdecl, importc: "traceon", dynlib: pdcursesdll.} -proc unctrl*(a2: cunsignedlong): cstring{.extdecl, importc: "unctrl", - dynlib: pdcursesdll.} -proc crmode*(): cint{.extdecl, importc: "crmode", dynlib: pdcursesdll.} -proc nocrmode*(): cint{.extdecl, importc: "nocrmode", dynlib: pdcursesdll.} -proc draino*(a2: cint): cint{.extdecl, importc: "draino", dynlib: pdcursesdll.} -proc resetterm*(): cint{.extdecl, importc: "resetterm", dynlib: pdcursesdll.} -proc fixterm*(): cint{.extdecl, importc: "fixterm", dynlib: pdcursesdll.} -proc saveterm*(): cint{.extdecl, importc: "saveterm", dynlib: pdcursesdll.} -proc setsyx*(a2: cint; a3: cint): cint{.extdecl, importc: "setsyx", - dynlib: pdcursesdll.} -proc mouse_set*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_set", - dynlib: pdcursesdll.} -proc mouse_on*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_on", - dynlib: pdcursesdll.} -proc mouse_off*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_off", - dynlib: pdcursesdll.} -proc request_mouse_pos*(): cint{.extdecl, importc: "request_mouse_pos", - dynlib: pdcursesdll.} -proc map_button*(a2: cunsignedlong): cint{.extdecl, importc: "map_button", - dynlib: pdcursesdll.} -proc wmouse_position*(a2: ptr WINDOW; a3: ptr cint; a4: ptr cint){.extdecl, - importc: "wmouse_position", dynlib: pdcursesdll.} -proc getmouse*(): cunsignedlong{.extdecl, importc: "getmouse", dynlib: pdcursesdll.} -proc getbmap*(): cunsignedlong{.extdecl, importc: "getbmap", dynlib: pdcursesdll.} -proc assume_default_colors*(a2: cint; a3: cint): cint{.extdecl, - importc: "assume_default_colors", dynlib: pdcursesdll.} -proc curses_version*(): cstring{.extdecl, importc: "curses_version", - dynlib: pdcursesdll.} -proc has_key*(a2: cint): cunsignedchar{.extdecl, importc: "has_key", - dynlib: pdcursesdll.} -proc use_default_colors*(): cint{.extdecl, importc: "use_default_colors", - dynlib: pdcursesdll.} -proc wresize*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "wresize", dynlib: pdcursesdll.} -proc mouseinterval*(a2: cint): cint{.extdecl, importc: "mouseinterval", - dynlib: pdcursesdll.} -proc mousemask*(a2: cunsignedlong; a3: ptr cunsignedlong): cunsignedlong{.extdecl, - importc: "mousemask", dynlib: pdcursesdll.} -proc mouse_trafo*(a2: ptr cint; a3: ptr cint; a4: cunsignedchar): cunsignedchar{. - extdecl, importc: "mouse_trafo", dynlib: pdcursesdll.} -proc nc_getmouse*(a2: ptr MEVENT): cint{.extdecl, importc: "nc_getmouse", - dynlib: pdcursesdll.} -proc ungetmouse*(a2: ptr MEVENT): cint{.extdecl, importc: "ungetmouse", - dynlib: pdcursesdll.} -proc wenclose*(a2: ptr WINDOW; a3: cint; a4: cint): cunsignedchar{.extdecl, - importc: "wenclose", dynlib: pdcursesdll.} -proc wmouse_trafo*(a2: ptr WINDOW; a3: ptr cint; a4: ptr cint; a5: cunsignedchar): cunsignedchar{. - extdecl, importc: "wmouse_trafo", dynlib: pdcursesdll.} -proc addrawch*(a2: cunsignedlong): cint{.extdecl, importc: "addrawch", - dynlib: pdcursesdll.} -proc insrawch*(a2: cunsignedlong): cint{.extdecl, importc: "insrawch", - dynlib: pdcursesdll.} -proc is_termresized*(): cunsignedchar{.extdecl, importc: "is_termresized", - dynlib: pdcursesdll.} -proc mvaddrawch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl, - importc: "mvaddrawch", dynlib: pdcursesdll.} -proc mvdeleteln*(a2: cint; a3: cint): cint{.extdecl, importc: "mvdeleteln", - dynlib: pdcursesdll.} -proc mvinsertln*(a2: cint; a3: cint): cint{.extdecl, importc: "mvinsertln", - dynlib: pdcursesdll.} -proc mvinsrawch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl, - importc: "mvinsrawch", dynlib: pdcursesdll.} -proc mvwaddrawch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{. - extdecl, importc: "mvwaddrawch", dynlib: pdcursesdll.} -proc mvwdeleteln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvwdeleteln", dynlib: pdcursesdll.} -proc mvwinsertln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, - importc: "mvwinsertln", dynlib: pdcursesdll.} -proc mvwinsrawch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{. - extdecl, importc: "mvwinsrawch", dynlib: pdcursesdll.} -proc raw_output*(a2: cunsignedchar): cint{.extdecl, importc: "raw_output", - dynlib: pdcursesdll.} -proc resize_term*(a2: cint; a3: cint): cint{.extdecl, importc: "resize_term", - dynlib: pdcursesdll.} -proc resize_window*(a2: ptr WINDOW; a3: cint; a4: cint): ptr WINDOW{.extdecl, - importc: "resize_window", dynlib: pdcursesdll.} -proc waddrawch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "waddrawch", dynlib: pdcursesdll.} -proc winsrawch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, - importc: "winsrawch", dynlib: pdcursesdll.} -proc wordchar*(): char{.extdecl, importc: "wordchar", dynlib: pdcursesdll.} -proc slk_wlabel*(a2: cint): cstring{.extdecl, importc: "slk_wlabel", - dynlib: pdcursesdll.} -proc debug*(a2: cstring){.varargs, extdecl, importc: "PDC_debug", - dynlib: pdcursesdll.} -proc ungetch*(a2: cint): cint{.extdecl, importc: "PDC_ungetch", - dynlib: pdcursesdll.} -proc set_blink*(a2: cunsignedchar): cint{.extdecl, importc: "PDC_set_blink", - dynlib: pdcursesdll.} -proc set_line_color*(a2: cshort): cint{.extdecl, importc: "PDC_set_line_color", - dynlib: pdcursesdll.} -proc set_title*(a2: cstring){.extdecl, importc: "PDC_set_title", - dynlib: pdcursesdll.} -proc clearclipboard*(): cint{.extdecl, importc: "PDC_clearclipboard", - dynlib: pdcursesdll.} -proc freeclipboard*(a2: cstring): cint{.extdecl, importc: "PDC_freeclipboard", - dynlib: pdcursesdll.} -proc getclipboard*(a2: cstringArray; a3: ptr clong): cint{.extdecl, - importc: "PDC_getclipboard", dynlib: pdcursesdll.} -proc setclipboard*(a2: cstring; a3: clong): cint{.extdecl, - importc: "PDC_setclipboard", dynlib: pdcursesdll.} -proc get_input_fd*(): cunsignedlong{.extdecl, importc: "PDC_get_input_fd", - dynlib: pdcursesdll.} -proc get_key_modifiers*(): cunsignedlong{.extdecl, - importc: "PDC_get_key_modifiers", dynlib: pdcursesdll.} -proc return_key_modifiers*(a2: cunsignedchar): cint{.extdecl, - importc: "PDC_return_key_modifiers", dynlib: pdcursesdll.} -proc save_key_modifiers*(a2: cunsignedchar): cint{.extdecl, - importc: "PDC_save_key_modifiers", dynlib: pdcursesdll.} -proc bottom_panel*(pan: ptr PANEL): cint{.extdecl, importc: "bottom_panel", - dynlib: pdcursesdll.} -proc del_panel*(pan: ptr PANEL): cint{.extdecl, importc: "del_panel", - dynlib: pdcursesdll.} -proc hide_panel*(pan: ptr PANEL): cint{.extdecl, importc: "hide_panel", - dynlib: pdcursesdll.} -proc move_panel*(pan: ptr PANEL; starty: cint; startx: cint): cint{.extdecl, - importc: "move_panel", dynlib: pdcursesdll.} -proc new_panel*(win: ptr WINDOW): ptr PANEL{.extdecl, importc: "new_panel", - dynlib: pdcursesdll.} -proc panel_above*(pan: ptr PANEL): ptr PANEL{.extdecl, importc: "panel_above", - dynlib: pdcursesdll.} -proc panel_below*(pan: ptr PANEL): ptr PANEL{.extdecl, importc: "panel_below", - dynlib: pdcursesdll.} -proc panel_hidden*(pan: ptr PANEL): cint{.extdecl, importc: "panel_hidden", - dynlib: pdcursesdll.} -proc panel_userptr*(pan: ptr PANEL): pointer{.extdecl, importc: "panel_userptr", - dynlib: pdcursesdll.} -proc panel_window*(pan: ptr PANEL): ptr WINDOW{.extdecl, importc: "panel_window", - dynlib: pdcursesdll.} -proc replace_panel*(pan: ptr PANEL; win: ptr WINDOW): cint{.extdecl, - importc: "replace_panel", dynlib: pdcursesdll.} -proc set_panel_userptr*(pan: ptr PANEL; uptr: pointer): cint{.extdecl, - importc: "set_panel_userptr", dynlib: pdcursesdll.} -proc show_panel*(pan: ptr PANEL): cint{.extdecl, importc: "show_panel", - dynlib: pdcursesdll.} -proc top_panel*(pan: ptr PANEL): cint{.extdecl, importc: "top_panel", - dynlib: pdcursesdll.} -proc update_panels*(){.extdecl, importc: "update_panels", dynlib: pdcursesdll.} - -when unixOS: - proc Xinitscr*(a2: cint; a3: cstringArray): ptr WINDOW{.extdecl, - importc: "Xinitscr", dynlib: pdcursesdll.} - proc XCursesExit*(){.extdecl, importc: "XCursesExit", dynlib: pdcursesdll.} - proc sb_init*(): cint{.extdecl, importc: "sb_init", dynlib: pdcursesdll.} - proc sb_set_horz*(a2: cint; a3: cint; a4: cint): cint{.extdecl, - importc: "sb_set_horz", dynlib: pdcursesdll.} - proc sb_set_vert*(a2: cint; a3: cint; a4: cint): cint{.extdecl, - importc: "sb_set_vert", dynlib: pdcursesdll.} - proc sb_get_horz*(a2: ptr cint; a3: ptr cint; a4: ptr cint): cint{.extdecl, - importc: "sb_get_horz", dynlib: pdcursesdll.} - proc sb_get_vert*(a2: ptr cint; a3: ptr cint; a4: ptr cint): cint{.extdecl, - importc: "sb_get_vert", dynlib: pdcursesdll.} - proc sb_refresh*(): cint{.extdecl, importc: "sb_refresh", dynlib: pdcursesdll.} - -template getch*(): expr = - wgetch(stdscr) - -template ungetch*(ch: expr): expr = - ungetch(ch) - -template getbegyx*(w, y, x: expr): expr = - y = getbegy(w) - x = getbegx(w) - -template getmaxyx*(w, y, x: expr): expr = - y = getmaxy(w) - x = getmaxx(w) - -template getparyx*(w, y, x: expr): expr = - y = getpary(w) - x = getparx(w) - -template getyx*(w, y, x: expr): expr = - y = getcury(w) - x = getcurx(w) - -template getsyx*(y, x: expr): stmt = - if curscr.leaveit: - (x) = - 1 - (y) = (x) - else: getyx(curscr, (y), (x)) - -template getmouse*(x: expr): expr = - nc_getmouse(x) - -when defined(windows): - var - atrtab*{.importc: "pdc_atrtab", dynlib: pdcursesdll.}: cstring - con_out*{.importc: "pdc_con_out", dynlib: pdcursesdll.}: HANDLE - con_in*{.importc: "pdc_con_in", dynlib: pdcursesdll.}: HANDLE - quick_edit*{.importc: "pdc_quick_edit", dynlib: pdcursesdll.}: DWORD - - proc get_buffer_rows*(): cint{.extdecl, importc: "PDC_get_buffer_rows", - dynlib: pdcursesdll.} diff --git a/lib/wrappers/tinyc.nim b/lib/wrappers/tinyc.nim index 47b505abc..f2ce92d36 100644 --- a/lib/wrappers/tinyc.nim +++ b/lib/wrappers/tinyc.nim @@ -20,16 +20,12 @@ proc openCCState*(): PccState {.importc: "tcc_new", cdecl.} proc closeCCState*(s: PccState) {.importc: "tcc_delete", cdecl.} ## free a TCC compilation context -proc enableDebug*(s: PccState) {.importc: "tcc_enable_debug", cdecl.} - ## add debug information in the generated code - proc setErrorFunc*(s: PccState, errorOpaque: pointer, errorFun: ErrorFunc) {. cdecl, importc: "tcc_set_error_func".} ## set error/warning display callback -proc setWarning*(s: PccState, warningName: cstring, value: int) {.cdecl, - importc: "tcc_set_warning".} - ## set/reset a warning +proc setOptions*(s: PccState, options: cstring) {.cdecl, importc: "tcc_set_options".} + ## set a options # preprocessor @@ -41,7 +37,6 @@ proc addSysincludePath*(s: PccState, pathname: cstring) {.cdecl, importc: "tcc_add_sysinclude_path".} ## add in system include path - proc defineSymbol*(s: PccState, sym, value: cstring) {.cdecl, importc: "tcc_define_symbol".} ## define preprocessor symbol 'sym'. Can put optional value @@ -65,16 +60,12 @@ proc compileString*(s: PccState, buf: cstring): cint {.cdecl, const - OutputMemory*: cint = 0 ## output will be ran in memory (no + OutputMemory*: cint = 1 ## output will be ran in memory (no ## output file) (default) - OutputExe*: cint = 1 ## executable file - OutputDll*: cint = 2 ## dynamic library - OutputObj*: cint = 3 ## object file - OutputPreprocess*: cint = 4 ## preprocessed file (used internally) - - OutputFormatElf*: cint = 0 ## default output format: ELF - OutputFormatBinary*: cint = 1 ## binary image output - OutputFormatCoff*: cint = 2 ## COFF + OutputExe*: cint = 2 ## executable file + OutputDll*: cint = 3 ## dynamic library + OutputObj*: cint = 4 ## object file + OutputPreprocess*: cint = 5 ## preprocessed file (used internally) proc setOutputType*(s: PCCState, outputType: cint): cint {.cdecl, importc: "tcc_set_output_type".} diff --git a/nimsuggest/nimsuggest.nim b/nimsuggest/nimsuggest.nim index 09c4f15a7..0328b817a 100644 --- a/nimsuggest/nimsuggest.nim +++ b/nimsuggest/nimsuggest.nim @@ -485,7 +485,6 @@ proc mainCommand(graph: ModuleGraph; cache: IdentCache) = registerPass semPass gCmd = cmdIdeTools incl gGlobalOptions, optCaasEnabled - isServing = true wantMainModule() if not fileExists(gProjectFull): @@ -527,6 +526,9 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) = of cmdEnd: break of cmdLongoption, cmdShortOption: case p.key.normalize + of "help": + stdout.writeline(Usage) + quit() of "port": gPort = parseInt(p.val).Port gMode = mtcp diff --git a/nimsuggest/sexp.nim b/nimsuggest/sexp.nim index 61bba10bc..e0983467f 100644 --- a/nimsuggest/sexp.nim +++ b/nimsuggest/sexp.nim @@ -429,7 +429,7 @@ proc toSexp(x: NimNode): NimNode {.compiletime.} = case x.kind of nnkBracket: result = newNimNode(nnkBracket) - for i in 0 .. <x.len: + for i in 0 ..< x.len: result.add(toSexp(x[i])) else: diff --git a/nimsuggest/tests/tchk1.nim b/nimsuggest/tests/tchk1.nim index f9f0dc8fe..7b0b5d5b4 100644 --- a/nimsuggest/tests/tchk1.nim +++ b/nimsuggest/tests/tchk1.nim @@ -23,5 +23,5 @@ chk;;skUnknown;;;;Error;;$file;;14;;0;;"complex statement requires indentation"; chk;;skUnknown;;;;Error;;$file;;12;;0;;"implementation of \'foo\' expected";;0 chk;;skUnknown;;;;Error;;$file;;17;;0;;"invalid indentation";;0 chk;;skUnknown;;;;Hint;;$file;;12;;9;;"\'foo\' is declared but not used [XDeclaredButNotUsed]";;0 -chk;;skUnknown;;;;Hint;;$file;;14;;5;;"\'tchk1.main()\' is declared but not used [XDeclaredButNotUsed]";;0 +chk;;skUnknown;;;;Hint;;$file;;14;;5;;"\'tchk1.main()[declared in tchk1.nim(14, 5)]\' is declared but not used [XDeclaredButNotUsed]";;0 """ diff --git a/nimsuggest/tests/tdot4.nim b/nimsuggest/tests/tdot4.nim index 3d98f9132..25e77ed04 100644 --- a/nimsuggest/tests/tdot4.nim +++ b/nimsuggest/tests/tdot4.nim @@ -2,7 +2,7 @@ discard """ $nimsuggest --tester --maxresults:2 $file >sug $1 sug;;skProc;;tdot4.main;;proc (inp: string): string;;$file;;10;;5;;"";;100;;None -sug;;skProc;;strutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe, locks: 0.};;$lib/pure/strutils.nim;;1497;;5;;"Replaces `sub` in `s` by the string `by`.";;100;;None +sug;;skProc;;strutils.replace;;proc (s: string, sub: string, by: string): string{.noSideEffect, gcsafe, locks: 0.};;$lib/pure/strutils.nim;;1575;;5;;"Replaces `sub` in `s` by the string `by`.";;100;;None """ import strutils diff --git a/nimsuggest/tests/tinclude.nim b/nimsuggest/tests/tinclude.nim index e235254a2..12d40d1e7 100644 --- a/nimsuggest/tests/tinclude.nim +++ b/nimsuggest/tests/tinclude.nim @@ -1,7 +1,7 @@ discard """ $nimsuggest --tester compiler/nim.nim >def compiler/semexprs.nim:13:50 -def;;skType;;ast.PSym;;PSym;;*ast.nim;;686;;2;;"";;100 +def;;skType;;ast.PSym;;PSym;;*ast.nim;;691;;2;;"";;100 >def compiler/semexprs.nim:13:50 -def;;skType;;ast.PSym;;PSym;;*ast.nim;;686;;2;;"";;100 +def;;skType;;ast.PSym;;PSym;;*ast.nim;;691;;2;;"";;100 """ diff --git a/nimsuggest/tests/tstrutils.nim b/nimsuggest/tests/tstrutils.nim index 34da8cb53..ce3e29a15 100644 --- a/nimsuggest/tests/tstrutils.nim +++ b/nimsuggest/tests/tstrutils.nim @@ -1,9 +1,9 @@ discard """ $nimsuggest --tester lib/pure/strutils.nim ->def lib/pure/strutils.nim:2300:6 +>def lib/pure/strutils.nim:2529:6 def;;skTemplate;;system.doAssert;;proc (cond: bool, msg: string): typed;;*/lib/system.nim;;*;;9;;"same as `assert` but is always turned on and not affected by the\x0A``--assertions`` command line switch.";;100 """ -# Line 2300 in strutils.nim is doAssert and this is unlikely to change +# Line 2529 in strutils.nim is doAssert and this is unlikely to change # soon since there are a whole lot of doAsserts there. diff --git a/nimsuggest/tests/tsug_regression.nim b/nimsuggest/tests/tsug_regression.nim index 1e440db2d..ce66aafb2 100644 --- a/nimsuggest/tests/tsug_regression.nim +++ b/nimsuggest/tests/tsug_regression.nim @@ -21,7 +21,7 @@ $nimsuggest --tester $file >sug $1 sug;;skProc;;tables.getOrDefault;;proc (t: Table[getOrDefault.A, getOrDefault.B], key: A): B;;$lib/pure/collections/tables.nim;;178;;5;;"";;100;;None sug;;skProc;;tables.hasKey;;proc (t: Table[hasKey.A, hasKey.B], key: A): bool;;$lib/pure/collections/tables.nim;;233;;5;;"returns true iff `key` is in the table `t`.";;100;;None -sug;;skProc;;tables.add;;proc (t: var Table[add.A, add.B], key: A, val: B);;$lib/pure/collections/tables.nim;;297;;5;;"puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.";;100;;None +sug;;skProc;;tables.add;;proc (t: var Table[add.A, add.B], key: A, val: B);;$lib/pure/collections/tables.nim;;309;;5;;"puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.";;100;;None sug;;skIterator;;tables.allValues;;iterator (t: Table[allValues.A, allValues.B], key: A): B{.inline.};;$lib/pure/collections/tables.nim;;225;;9;;"iterates over any value in the table `t` that belongs to the given `key`.";;100;;None sug;;skProc;;tables.clear;;proc (t: var Table[clear.A, clear.B]);;$lib/pure/collections/tables.nim;;121;;5;;"Resets the table so that it is empty.";;100;;None * diff --git a/readme.md b/readme.md index 1b1e668fd..6fbe60c6a 100644 --- a/readme.md +++ b/readme.md @@ -18,6 +18,7 @@ the latest release, check out [Nim's website][nim-site]. is a bridge between Gitter and the IRC channel. * [Stack Overflow][nim-stackoverflow] - a popular Q/A site for programming related topics that includes posts about Nim. +* [Github Wiki][nim-wiki] - Misc user-contributed content. ## Compiling The compiler currently officially supports the following platform and @@ -95,10 +96,10 @@ This project exists thanks to all the people who contribute. [Read on to find ou [![Setup a bounty via Bountysource][badge-nim-bountysource]][nim-bountysource] [![Donate Bitcoins][badge-nim-bitcoin]][nim-bitcoin] -We welcome everyone's contributions to Nim independent of how small or how large -they are. Anything from small spelling fixes to large modules intended to -be included in the standard library are welcome and appreciated. Before you get -started contributing, you should familiarize yourself with the repository structure: +We welcome all contributions to Nim regardless of how small or large +they are. Everything from spelling fixes to new modules to be included in the +standard library are welcomed and appreciated. Before you start contributing, +you should familiarize yourself with the following repository structure: * ``bin/``, ``build/`` - these directories are empty, but are used when Nim is built. * ``compiler/`` - the compiler source code. Also includes nimfix, and plugins within @@ -126,6 +127,7 @@ However, if you are short on time, you can just run the tests specific to your changes by only running the corresponding categories of tests. Travis CI verifies that all tests pass before allowing the pull request to be accepted, so only running specific tests should be harmless. +Integration tests should go in ``tests/untestable``. If you're looking for ways to contribute, please look at our [issue tracker][nim-issues]. There are always plenty of issues labelled [``Easy``][nim-issues-easy]; these should @@ -203,3 +205,4 @@ Copyright © 2006-2017 Andreas Rumpf, all rights reserved. [badge-nim-bountysource]: https://img.shields.io/bountysource/team/nim/activity.svg?style=flat-square [badge-nim-bitcoin]: https://img.shields.io/badge/bitcoin-1BXfuKM2uvoD6mbx4g5xM3eQhLzkCK77tJ-D69134.svg?style=flat-square [pull-request-instructions]: https://help.github.com/articles/using-pull-requests/ +[nim-wiki]: https://github.com/nim-lang/Nim/wiki diff --git a/tests/arithm/tsubrange.nim b/tests/arithm/tsubrange.nim new file mode 100644 index 000000000..9d60dbd1a --- /dev/null +++ b/tests/arithm/tsubrange.nim @@ -0,0 +1,13 @@ +discard """ + output: '''1''' +""" + +# bug #5854 +type + n16* = range[0'i16..high(int16)] + +var level: n16 = 1 +let maxLevel: n16 = 1 + +level = min(level + 2, maxLevel) +echo level diff --git a/tests/array/troof1.nim b/tests/array/troof1.nim index 96669a121..b486c3448 100644 --- a/tests/array/troof1.nim +++ b/tests/array/troof1.nim @@ -1,7 +1,11 @@ discard """ output: '''@[2, 3, 4]321 9.0 4.0 -(a: 1.0, b: 2.0, c: 8.0)2.0''' +3 +@[(Field0: 1, Field1: 2), (Field0: 3, Field1: 5)] +2 +@["a", "new one", "c"] +@[1, 2, 3]''' """ proc foo[T](x, y: T): T = x @@ -11,26 +15,29 @@ var b: array[3, array[2, float]] = [[1.0,2], [3.0,4], [8.0,9]] echo a[1.. ^1], a[^2], a[^3], a[^4] echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1] -type - MyArray = object - a, b, c: float +b[^1] = [8.8, 8.9] -var - ma = MyArray(a: 1.0, b: 2.0, c: 3.0) +var c: seq[(int, int)] = @[(1,2), (3,4)] -proc len(x: MyArray): int = 3 +proc takeA(x: ptr int) = echo x[] -proc `[]=`(x: var MyArray; idx: range[0..2]; val: float) = - case idx - of 0: x.a = val - of 1: x.b = val - of 2: x.c = val +takeA(addr c[^1][0]) +c[^1][1] = 5 +echo c -proc `[]`(x: var MyArray; idx: range[0..2]): float = - case idx - of 0: result = x.a - of 1: result = x.b - of 2: result = x.c +proc useOpenarray(x: openArray[int]) = + echo x[^2] -ma[^1] = 8.0 -echo ma, ma[^2] +proc mutOpenarray(x: var openArray[string]) = + x[^2] = "new one" + +useOpenarray([1, 2, 3]) + +var z = @["a", "b", "c"] +mutOpenarray(z) +echo z + +# bug #6675 +var y: array[1..5, int] = [1,2,3,4,5] +y[3..5] = [1, 2, 3] +echo y[3..5] diff --git a/tests/array/troof2.nim b/tests/array/troof2.nim deleted file mode 100644 index e4b4f4b3c..000000000 --- a/tests/array/troof2.nim +++ /dev/null @@ -1,10 +0,0 @@ -discard """ - errormsg: "invalid context for '^' as 'foo()' has side effects" - line: "9" -""" -# XXX This needs to be fixed properly! -proc foo(): seq[int] {.sideEffect.} = - echo "ha" - -let f = foo()[^1] - diff --git a/tests/array/troof3.nim b/tests/array/troof3.nim index 4b6e22223..efe0eafb8 100644 --- a/tests/array/troof3.nim +++ b/tests/array/troof3.nim @@ -1,8 +1,7 @@ discard """ - errormsg: "invalid context for '^' as len!=high+1 for 'a'" - line: "8" + output: '''c''' """ -var a: array[1..3, string] +var a: array['a'..'c', string] = ["a", "b", "c"] echo a[^1] diff --git a/tests/array/troof4.nim b/tests/array/troof4.nim deleted file mode 100644 index 7a262d9de..000000000 --- a/tests/array/troof4.nim +++ /dev/null @@ -1,37 +0,0 @@ -discard """ - errormsg: "no surrounding array access context for '^'" - line: "37" -""" - -proc foo[T](x, y: T): T = x - -var a = @[1, 2, 3, 4] -var b: array[3, array[2, float]] = [[1.0,2], [3.0,4], [8.0,9]] -echo a[1.. ^1], a[^2], a[^3], a[^4] -echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1] - -type - MyArray = object - a, b, c: float - -var - ma = MyArray(a: 1.0, b: 2.0, c: 3.0) - -proc len(x: MyArray): int = 3 - -proc `[]=`(x: var MyArray; idx: range[0..2]; val: float) = - case idx - of 0: x.a = val - of 1: x.b = val - of 2: x.c = val - -proc `[]`(x: var MyArray; idx: range[0..2]): float = - case idx - of 0: result = x.a - of 1: result = x.b - of 2: result = x.c - -ma[^1] = 8.0 -echo ma, ma[^2] - -echo(^1) diff --git a/tests/array/troofregression.nim b/tests/array/troofregression.nim new file mode 100644 index 000000000..0b96123a4 --- /dev/null +++ b/tests/array/troofregression.nim @@ -0,0 +1,46 @@ +############################### +#### part from Arraymancer + +type + MetadataArray* = object + data*: array[8, int] + len*: int + +# Commenting the converter removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" +converter toMetadataArray*(se: varargs[int]): MetadataArray {.inline.} = + result.len = se.len + for i in 0..<se.len: + result.data[i] = se[i] + + +when NimVersion >= "0.17.3": + type Index = int or BackwardsIndex + template `^^`(s, i: untyped): untyped = + when i is BackwardsIndex: + s.len - int(i) + else: i +else: + type Index = int + template `^^`(s, i: untyped): untyped = + i + +## With Nim devel from the start of the week (~Oct30) I managed to trigger "lib/system.nim(3536, 4) Error: expression has no address" +## but I can't anymore after updating Nim (Nov5) +## Now commenting this plain compiles and removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" +proc `[]`*(a: var MetadataArray, idx: Index): var int {.inline.} = + a.data[a ^^ idx] + + +############################## +### Completely unrelated lib that triggers the issue + +type + MySeq[T] = ref object + data: seq[T] + +proc test[T](sx: MySeq[T]) = + # Removing the backward index removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" + echo sx.data[^1] # error here + +let s = MySeq[int](data: @[1, 2, 3]) +s.test() diff --git a/tests/async/tasync_in_seq_constr.nim b/tests/async/tasync_in_seq_constr.nim index 7d216e352..46ad74451 100644 --- a/tests/async/tasync_in_seq_constr.nim +++ b/tests/async/tasync_in_seq_constr.nim @@ -1,8 +1,9 @@ discard """ - output: '''@[1, 2, 3, 4]''' + errormsg: "invalid control flow: 'yield' within a constructor" + line: 16 """ -# bug #5314 +# bug #5314, bug #6626 import asyncdispatch diff --git a/tests/async/tasync_traceback.nim b/tests/async/tasync_traceback.nim new file mode 100644 index 000000000..08f7e7317 --- /dev/null +++ b/tests/async/tasync_traceback.nim @@ -0,0 +1,116 @@ +discard """ + exitcode: 0 + disabled: "windows" + output: ''' +b failure +Async traceback: + tasync_traceback.nim(97) tasync_traceback + asyncmacro.nim(395) a + asyncmacro.nim(34) a_continue + ## Resumes an async procedure + tasync_traceback.nim(95) aIter + asyncmacro.nim(395) b + asyncmacro.nim(34) b_continue + ## Resumes an async procedure + tasync_traceback.nim(92) bIter + #[ + tasync_traceback.nim(97) tasync_traceback + asyncmacro.nim(395) a + asyncmacro.nim(43) a_continue + ## Resumes an async procedure + asyncfutures.nim(211) callback= + asyncfutures.nim(190) addCallback + asyncfutures.nim(53) callSoon + asyncmacro.nim(34) a_continue + ## Resumes an async procedure + asyncmacro.nim(0) aIter + asyncfutures.nim(304) read + ]# +Exception message: b failure +Exception type: + +bar failure +Async traceback: + tasync_traceback.nim(113) tasync_traceback + asyncdispatch.nim(1492) waitFor + asyncdispatch.nim(1496) poll + ## Processes asynchronous completion events + asyncdispatch.nim(1262) runOnce + asyncdispatch.nim(183) processPendingCallbacks + ## Executes pending callbacks + asyncmacro.nim(34) bar_continue + ## Resumes an async procedure + tasync_traceback.nim(108) barIter + #[ + tasync_traceback.nim(113) tasync_traceback + asyncdispatch.nim(1492) waitFor + asyncdispatch.nim(1496) poll + ## Processes asynchronous completion events + asyncdispatch.nim(1262) runOnce + asyncdispatch.nim(183) processPendingCallbacks + ## Executes pending callbacks + asyncmacro.nim(34) foo_continue + ## Resumes an async procedure + asyncmacro.nim(0) fooIter + asyncfutures.nim(304) read + ]# +Exception message: bar failure +Exception type:''' +""" +import asyncdispatch + +# Tests to ensure our exception trace backs are friendly. + +# --- Simple test. --- +# +# What does this look like when it's synchronous? +# +# tasync_traceback.nim(23) tasync_traceback +# tasync_traceback.nim(21) a +# tasync_traceback.nim(18) b +# Error: unhandled exception: b failure [OSError] +# +# Good (not quite ideal, but gotta work within constraints) traceback, +# when exception is unhandled: +# +# <traceback for the unhandled exception> +# <very much a bunch of noise> +# <would be ideal to customise this> +# <(the code responsible is in excpt:raiseExceptionAux)> +# Error: unhandled exception: b failure +# =============== +# Async traceback +# =============== +# +# tasync_traceback.nim(23) tasync_traceback +# +# tasync_traceback.nim(21) a +# tasync_traceback.nim(18) b + +proc b(): Future[int] {.async.} = + if true: + raise newException(OSError, "b failure") + +proc a(): Future[int] {.async.} = + return await b() + +let aFut = a() +try: + discard waitFor aFut +except Exception as exc: + echo exc.msg +echo() + +# From #6803 +proc bar(): Future[string] {.async.} = + await sleepAsync(100) + if true: + raise newException(OSError, "bar failure") + +proc foo(): Future[string] {.async.} = return await bar() + +try: + echo waitFor(foo()) +except Exception as exc: + echo exc.msg +echo() \ No newline at end of file diff --git a/tests/async/tasyncall.nim b/tests/async/tasyncall.nim index 7daecd9ef..775dd0c6f 100644 --- a/tests/async/tasyncall.nim +++ b/tests/async/tasyncall.nim @@ -40,8 +40,17 @@ proc testVarargs(x, y, z: int): seq[int] = result = waitFor all(a, b, c) -suite "tasyncall": - test "testFuturesWithValue": +proc testWithDupes() = + var + tasks = newSeq[Future[void]](taskCount) + fut = futureWithoutValue() + + for i in 0..<taskCount: + tasks[i] = fut + + waitFor all(tasks) + +block: let startTime = cpuTime() results = testFuturesWithValue(42) @@ -51,14 +60,21 @@ suite "tasyncall": doAssert execTime * 1000 < taskCount * sleepDuration doAssert results == expected - test "testFuturesWithoutValues": +block: let startTime = cpuTime() testFuturesWithoutValues() let execTime = cpuTime() - startTime doAssert execTime * 1000 < taskCount * sleepDuration - test "testVarargs": +block: + let startTime = cpuTime() + testWithDupes() + let execTime = cpuTime() - startTime + + doAssert execTime * 1000 < taskCount * sleepDuration + +block: let startTime = cpuTime() results = testVarargs(1, 2, 3) @@ -68,7 +84,7 @@ suite "tasyncall": doAssert execTime * 100 < taskCount * sleepDuration doAssert results == expected - test "all on seq[Future]": +block: let noIntFuturesFut = all(newSeq[Future[int]]()) noVoidFuturesFut = all(newSeq[Future[void]]()) diff --git a/tests/async/tasyncdial.nim b/tests/async/tasyncdial.nim index d70e14020..fa81235fe 100644 --- a/tests/async/tasyncdial.nim +++ b/tests/async/tasyncdial.nim @@ -4,6 +4,7 @@ discard """ OK AF_INET OK AF_INET6 ''' + disabled: "travis" """ import diff --git a/tests/async/tasyncfile.nim b/tests/async/tasyncfile.nim index 592f0ebd8..6c0725c88 100644 --- a/tests/async/tasyncfile.nim +++ b/tests/async/tasyncfile.nim @@ -34,4 +34,19 @@ proc main() {.async.} = doAssert data == "foot\ntest2" file.close() + # Issue #5531 + block: + removeFile(fn) + var file = openAsync(fn, fmWrite) + await file.write("test2") + file.close() + file = openAsync(fn, fmWrite) + await file.write("test3") + file.close() + file = openAsync(fn, fmRead) + let data = await file.readAll() + doAssert data == "test3" + file.close() + + waitFor main() diff --git a/tests/async/tasyncsend4757.nim b/tests/async/tasyncsend4757.nim index 1066f38e5..752bb3e75 100644 --- a/tests/async/tasyncsend4757.nim +++ b/tests/async/tasyncsend4757.nim @@ -3,11 +3,22 @@ discard """ output: "Finished" """ -import asyncdispatch +import asyncdispatch, asyncnet + +proc createServer(port: Port) {.async.} = + var server = newAsyncSocket() + server.setSockOpt(OptReuseAddr, true) + bindAddr(server, port) + server.listen() + while true: + let client = await server.accept() + discard await client.recvLine() + +asyncCheck createServer(10335.Port) proc f(): Future[void] {.async.} = let s = newAsyncNativeSocket() - await s.connect("example.com", 80.Port) + await s.connect("localhost", 10335.Port) await s.send("123") echo "Finished" diff --git a/tests/async/tioselectors.nim b/tests/async/tioselectors.nim index 034c2185c..d2e4cfec1 100644 --- a/tests/async/tioselectors.nim +++ b/tests/async/tioselectors.nim @@ -2,7 +2,7 @@ discard """ file: "tioselectors.nim" output: "All tests passed!" """ -import ioselectors +import selectors const hasThreadSupport = compileOption("threads") @@ -579,9 +579,9 @@ else: var event = newSelectEvent() selector.registerEvent(event, 1) discard selector.select(0) - event.setEvent() + event.trigger() var rc1 = selector.select(0) - event.setEvent() + event.trigger() var rc2 = selector.select(0) var rc3 = selector.select(0) assert(len(rc1) == 1 and len(rc2) == 1 and len(rc3) == 0) @@ -611,7 +611,7 @@ else: var event = newSelectEvent() for i in 0..high(thr): createThread(thr[i], event_wait_thread, event) - event.setEvent() + event.trigger() joinThreads(thr) assert(counter == 1) result = true diff --git a/tests/async/tnewasyncudp.nim b/tests/async/tnewasyncudp.nim index b56cdc71b..e61f630e4 100644 --- a/tests/async/tnewasyncudp.nim +++ b/tests/async/tnewasyncudp.nim @@ -86,7 +86,7 @@ proc readMessages(server: AsyncFD) {.async.} = size = 0 var grammString = $cstring(addr buffer) if grammString.startswith("Message ") and - saddr.sin_addr.s_addr == 0x100007F: + saddr.sin_addr.s_addr == nativesockets.ntohl(INADDR_LOOPBACK.uint32): await sendTo(server, addr grammString[0], len(grammString), cast[ptr SockAddr](addr saddr), slen) inc(msgCount) diff --git a/tests/casestmt/tcasestm.nim b/tests/casestmt/tcasestm.nim index 7ac20bf2f..b005d8120 100644 --- a/tests/casestmt/tcasestm.nim +++ b/tests/casestmt/tcasestm.nim @@ -36,5 +36,64 @@ var z = case i echo z #OUT ayyy +let str1 = "Y" +let str2 = "NN" +let a = case str1: + of "Y": true + of "N": false + else: + echo "no good" + quit("quiting") +let b = case str2: + of nil, "": raise newException(ValueError, "Invalid boolean") + elif str2[0] == 'Y': true + elif str2[0] == 'N': false + else: "error".quit(2) +doAssert(a == true) +doAssert(b == false) + +var bb: bool +doassert(not compiles( + bb = case str2: + of nil, "": raise newException(ValueError, "Invalid boolean") + elif str.startsWith("Y"): true + elif str.startsWith("N"): false +)) + +doassert(not compiles( + bb = case str2: + of "Y": true + of "N": false +)) + +doassert(not compiles( + bb = case str2: + of "Y": true + of "N": raise newException(ValueError, "N not allowed") +)) + +doassert(not compiles( + bb = case str2: + of "Y": raise newException(ValueError, "Invalid Y") + else: raise newException(ValueError, "Invalid N") +)) + + +doassert(not compiles( + bb = case str2: + of "Y": + raise newException(ValueError, "Invalid Y") + true + else: raise newException(ValueError, "Invalid") +)) + + +doassert(not compiles( + bb = case str2: + of "Y": + "invalid Y".quit(3) + true + else: raise newException(ValueError, "Invalid") +)) \ No newline at end of file diff --git a/tests/ccgbugs/t6279.nim b/tests/ccgbugs/t6279.nim index 37345d807..5a3d6768c 100644 --- a/tests/ccgbugs/t6279.nim +++ b/tests/ccgbugs/t6279.nim @@ -1,6 +1,6 @@ discard """ cmd: "nim c -r -d:fulldebug -d:smokeCycles --gc:refc $file" -output: '''@[a]''' +output: '''@["a"]''' """ # bug #6279 diff --git a/tests/ccgbugs/t6756.nim b/tests/ccgbugs/t6756.nim new file mode 100644 index 000000000..0f08557eb --- /dev/null +++ b/tests/ccgbugs/t6756.nim @@ -0,0 +1,18 @@ +import typetraits +type + A[T] = ref object + v: T + +template templ(o: A, op: untyped): untyped = + type T = type(o.v) + + var res: A[T] + + block: + var it {.inject.}: T + it = o.v + res = A[T](v: op) + res + +let a = A[int](v: 1) +echo templ(a, it + 2)[] diff --git a/tests/ccgbugs/tbug1081.nim b/tests/ccgbugs/tbug1081.nim index 71628feec..baef99d84 100644 --- a/tests/ccgbugs/tbug1081.nim +++ b/tests/ccgbugs/tbug1081.nim @@ -2,7 +2,8 @@ discard """ output: '''1 0 0 -0''' +0 +x = ['a', 'b', 'c', '0', '1', '2', '3', '4', '5', '6'] and y = ['a', 'b', 'c', '0', '1', '2', '3', '4', '5', '6']''' """ proc `1/1`() = echo(1 div 1) @@ -15,3 +16,19 @@ let `1/4` = 1 div 4 `1/2`() echo `1/3` echo `1/4` + +# bug #6422 + +proc toCharArray1(N : static[int], s: string): array[N, char] = + doAssert s.len <= N + let x = cast[ptr array[N, char]](s.cstring) + x[] + +proc toCharArray2(N : static[int], s: string): array[N, char] = + doAssert s.len <= N + let x = cast[ptr array[N, char]](s.cstring) + result = x[] + +let x = toCharArray1(10, "abc0123456") +let y = toCharArray2(10, "abc0123456") +echo "x = ", $x, " and y = ", $y diff --git a/tests/ccgbugs/tconstobj.nim b/tests/ccgbugs/tconstobj.nim index 98f441e83..51cf661ee 100644 --- a/tests/ccgbugs/tconstobj.nim +++ b/tests/ccgbugs/tconstobj.nim @@ -1,5 +1,5 @@ discard """ - output: '''(FirstName: James, LastName: Franco)''' + output: '''(FirstName: "James", LastName: "Franco")''' """ # bug #1547 diff --git a/tests/ccgbugs/tobjconstr_bad_aliasing.nim b/tests/ccgbugs/tobjconstr_bad_aliasing.nim new file mode 100644 index 000000000..ea51ecacb --- /dev/null +++ b/tests/ccgbugs/tobjconstr_bad_aliasing.nim @@ -0,0 +1,26 @@ +discard """ + output: '''(10, (20, ))''' +""" + +import strutils, sequtils + +# bug #668 + +type + TThing = ref object + data: int + children: seq[TThing] + +proc `$`(t: TThing): string = + result = "($1, $2)" % @[$t.data, join(map(t.children, proc(th: TThing): string = $th), ", ")] + +proc somethingelse(): seq[TThing] = + result = @[TThing(data: 20, children: @[])] + +proc dosomething(): seq[TThing] = + result = somethingelse() + + result = @[TThing(data: 10, children: result)] + +when isMainModule: + echo($dosomething()[0]) diff --git a/tests/ccgbugs/tobjconstr_regression.nim b/tests/ccgbugs/tobjconstr_regression.nim index 87d037894..d29abad97 100644 --- a/tests/ccgbugs/tobjconstr_regression.nim +++ b/tests/ccgbugs/tobjconstr_regression.nim @@ -1,5 +1,5 @@ discard """ - output: "@[(username: user, role: admin, description: desc, email_addr: email), (username: user, role: admin, description: desc, email_addr: email)]" + output: '''@[(username: "user", role: "admin", description: "desc", email_addr: "email"), (username: "user", role: "admin", description: "desc", email_addr: "email")]''' """ type diff --git a/tests/ccgbugs/trefseqsort.nim b/tests/ccgbugs/trefseqsort.nim new file mode 100644 index 000000000..2410770cf --- /dev/null +++ b/tests/ccgbugs/trefseqsort.nim @@ -0,0 +1,33 @@ +discard """ + output: '''@[0, 4, 9, 1, 3, 2] +@[0, 1, 2, 3, 9]''' +""" +# bug #6724 +import algorithm + +type + Bar = object + bar: ref seq[int] + Foo = ref Bar + +proc test(x: ref Foo) = + x.bar[].del(1) + x.bar[].sort(cmp) + +proc main() = + var foo: ref Foo + new(foo) + + var s = @[0, 4, 9, 1, 3, 2] + + var sr: ref seq[int] + new(sr) + sr[] = s + + foo[] = Foo(bar: sr) + echo($foo.bar[]) + + test(foo) + echo($foo.bar[]) + +main() diff --git a/tests/ccgbugs/tret_arg_init.nim b/tests/ccgbugs/tret_arg_init.nim index 3c80fb061..5cd67de3e 100644 --- a/tests/ccgbugs/tret_arg_init.nim +++ b/tests/ccgbugs/tret_arg_init.nim @@ -1,7 +1,7 @@ discard """ - output: '''nil -nil -nil''' + output: ''' + +''' """ type Bar = object diff --git a/tests/ccgbugs/tuple_canon.nim b/tests/ccgbugs/tuple_canon.nim index 45fed8eee..7e9e91836 100644 --- a/tests/ccgbugs/tuple_canon.nim +++ b/tests/ccgbugs/tuple_canon.nim @@ -85,3 +85,31 @@ proc go() = echo "vidx ", $vidx(hg, 1, 2, hiC) go() + +# another sighashes problem: In tuples we have to ignore ranges. + +type + Position = tuple[x, y: int16] + n16 = range[0'i16..high(int16)] + +proc print(pos: Position) = + echo $pos.x, ",", $pos.y + +var x = 0.n16 +var y = 0.n16 +print((x, y)) + + +# bug #6889 +proc createProgressSetterWithPropSetter[T](setter: proc(v: T)) = discard + +type A = distinct array[4, float32] +type B = distinct array[3, float32] + +type Foo[T] = tuple + setter: proc(v: T) + +proc getFoo[T](): Foo[T] = discard + +createProgressSetterWithPropSetter(getFoo[A]().setter) +createProgressSetterWithPropSetter(getFoo[B]().setter) diff --git a/tests/closure/t1641.nim b/tests/closure/t1641.nim new file mode 100644 index 000000000..a3e4da367 --- /dev/null +++ b/tests/closure/t1641.nim @@ -0,0 +1,20 @@ +discard """ + output: '''foo 0 +bar 0 +baz''' +""" + +# bug #1641 +proc baz() = + echo "baz" + +proc bar(x: int, p: proc()) = + echo "bar ", x + p() + +proc foo(x: int, p: proc(x: int)) = + echo "foo ", x + p(x) + +let x = 0 +x.foo do(x: int): x.bar do(): baz() diff --git a/tests/closure/tinvalidclosure3.nim b/tests/closure/tinvalidclosure3.nim new file mode 100644 index 000000000..31c4976f8 --- /dev/null +++ b/tests/closure/tinvalidclosure3.nim @@ -0,0 +1,12 @@ +discard """ + line: 9 + errormsg: "illegal capture 'x'" +""" + +proc outer(arg: string) = + var x = 0 + proc inner {.inline.} = + echo "inner", x + inner() + +outer("abc") \ No newline at end of file diff --git a/tests/collections/tcollections_to_string.nim b/tests/collections/tcollections_to_string.nim new file mode 100644 index 000000000..6cc8a84ff --- /dev/null +++ b/tests/collections/tcollections_to_string.nim @@ -0,0 +1,106 @@ +discard """ + exitcode: 0 + output: "" +""" +import sets +import tables +import deques +import lists +import critbits + +# Tests for tuples +doAssert $(1, 2, 3) == "(Field0: 1, Field1: 2, Field2: 3)" +doAssert $("1", "2", "3") == """(Field0: "1", Field1: "2", Field2: "3")""" +doAssert $('1', '2', '3') == """(Field0: '1', Field1: '2', Field2: '3')""" + +# Tests for seqs +doAssert $(@[1, 2, 3]) == "@[1, 2, 3]" +doAssert $(@["1", "2", "3"]) == """@["1", "2", "3"]""" +doAssert $(@['1', '2', '3']) == """@['1', '2', '3']""" + +# Tests for sets +doAssert $(toSet([1])) == "{1}" +doAssert $(toSet(["1"])) == """{"1"}""" +doAssert $(toSet(['1'])) == """{'1'}""" +doAssert $(toOrderedSet([1, 2, 3])) == "{1, 2, 3}" +doAssert $(toOrderedSet(["1", "2", "3"])) == """{"1", "2", "3"}""" +doAssert $(toOrderedSet(['1', '2', '3'])) == """{'1', '2', '3'}""" + +# Tests for tables +doAssert $({1: "1", 2: "2"}.toTable) == """{1: "1", 2: "2"}""" +doAssert $({"1": 1, "2": 2}.toTable) == """{"1": 1, "2": 2}""" + +# Tests for deques +block: + var d = initDeque[int]() + d.addLast(1) + doAssert $d == "[1]" +block: + var d = initDeque[string]() + d.addLast("1") + doAssert $d == """["1"]""" +block: + var d = initDeque[char]() + d.addLast('1') + doAssert $d == "['1']" + +# Tests for lists +block: + var l = initDoublyLinkedList[int]() + l.append(1) + l.append(2) + l.append(3) + doAssert $l == "[1, 2, 3]" +block: + var l = initDoublyLinkedList[string]() + l.append("1") + l.append("2") + l.append("3") + doAssert $l == """["1", "2", "3"]""" +block: + var l = initDoublyLinkedList[char]() + l.append('1') + l.append('2') + l.append('3') + doAssert $l == """['1', '2', '3']""" + +# Tests for critbits +block: + var t: CritBitTree[int] + t["a"] = 1 + doAssert $t == "{a: 1}" +block: + var t: CritBitTree[string] + t["a"] = "1" + doAssert $t == """{a: "1"}""" +block: + var t: CritBitTree[char] + t["a"] = '1' + doAssert $t == "{a: '1'}" + + +# Test escaping behavior +block: + var s = "" + s.addQuoted('\0') + s.addQuoted('\31') + s.addQuoted('\127') + s.addQuoted('\255') + doAssert s == "'\\x00''\\x1F''\\x7F''\\xFF'" +block: + var s = "" + s.addQuoted('\\') + s.addQuoted('\'') + s.addQuoted('\"') + doAssert s == """'\\''\'''\"'""" + +# Test customized element representation +type CustomString = object + +proc addQuoted(s: var string, x: CustomString) = + s.add("<CustomString>") + +block: + let s = @[CustomString()] + doAssert $s == "@[<CustomString>]" + diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim index 01dab44fc..7fe4c79b1 100644 --- a/tests/collections/ttables.nim +++ b/tests/collections/ttables.nim @@ -48,7 +48,7 @@ block tableTest1: for y in 0..1: assert t[(x,y)] == $x & $y assert($t == - "{(x: 0, y: 1): 01, (x: 0, y: 0): 00, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") + "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (x: 1, y: 0): \"10\", (x: 1, y: 1): \"11\"}") block tableTest2: var t = initTable[string, float]() @@ -213,7 +213,8 @@ block clearCountTableTest: assert t.len() == 0 block withKeyTest: - var t = initSharedTable[int, int]() + var t: SharedTable[int, int] + t.init() t.withKey(1) do (k: int, v: var int, pairExists: var bool): assert(v == 0) pairExists = true diff --git a/tests/collections/ttablesref.nim b/tests/collections/ttablesref.nim index 12af1ccbb..a4030e0dc 100644 --- a/tests/collections/ttablesref.nim +++ b/tests/collections/ttablesref.nim @@ -47,7 +47,7 @@ block tableTest1: for y in 0..1: assert t[(x,y)] == $x & $y assert($t == - "{(x: 0, y: 1): 01, (x: 0, y: 0): 00, (x: 1, y: 0): 10, (x: 1, y: 1): 11}") + "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (x: 1, y: 0): \"10\", (x: 1, y: 1): \"11\"}") block tableTest2: var t = newTable[string, float]() @@ -139,7 +139,7 @@ proc orderedTableSortTest() = block anonZipTest: let keys = @['a','b','c'] let values = @[1, 2, 3] - doAssert "{a: 1, b: 2, c: 3}" == $ toTable zip(keys, values) + doAssert "{'a': 1, 'b': 2, 'c': 3}" == $ toTable zip(keys, values) block clearTableTest: var t = newTable[string, float]() diff --git a/tests/concepts/t1128.nim b/tests/concepts/t1128.nim index 7f7525a13..69a2fa9b7 100644 --- a/tests/concepts/t1128.nim +++ b/tests/concepts/t1128.nim @@ -4,8 +4,8 @@ discard """ type TFooContainer[T] = object - - TContainer[T] = generic var c + + TContainer[T] = concept var c foo(c, T) proc foo[T](c: var TFooContainer[T], val: T) = diff --git a/tests/concepts/t3330.nim b/tests/concepts/t3330.nim index fcd5054ef..722c0a0e0 100644 --- a/tests/concepts/t3330.nim +++ b/tests/concepts/t3330.nim @@ -6,10 +6,10 @@ but expected one of: proc test(foo: Foo[int]) t3330.nim(25, 8) Hint: Non-matching candidates for add(k, string, T) proc add(x: var string; y: string) +proc add(result: var string; x: float) proc add(x: var string; y: char) proc add(result: var string; x: int64) proc add(x: var string; y: cstring) -proc add(result: var string; x: float) proc add[T](x: var seq[T]; y: openArray[T]) proc add[T](x: var seq[T]; y: T) diff --git a/tests/concepts/t6462.nim b/tests/concepts/t6462.nim new file mode 100644 index 000000000..2fa2268f8 --- /dev/null +++ b/tests/concepts/t6462.nim @@ -0,0 +1,23 @@ +discard """ + output: "true" +""" + +import future + +type + FilterMixin*[T] = ref object + test*: (T) -> bool + trans*: (T) -> T + + SeqGen*[T] = ref object + fil*: FilterMixin[T] + + WithFilter[T] = concept a + a.fil is FilterMixin[T] + +proc test*[T](a: WithFilter[T]): (T) -> bool = + a.fil.test + +var s = SeqGen[int](fil: FilterMixin[int](test: nil, trans: nil)) +echo s.test() == nil + diff --git a/tests/concepts/tcomparable.nim b/tests/concepts/tcomparable.nim new file mode 100644 index 000000000..06612a47e --- /dev/null +++ b/tests/concepts/tcomparable.nim @@ -0,0 +1,13 @@ +type + Comparable = concept a + (a < a) is bool + +proc myMax(a, b: Comparable): Comparable = + if a < b: + return b + else: + return a + +doAssert myMax(5, 10) == 10 +doAssert myMax(31.3, 1.23124) == 31.3 + diff --git a/tests/concepts/texplain.nim b/tests/concepts/texplain.nim index 417d1e502..de8ddf890 100644 --- a/tests/concepts/texplain.nim +++ b/tests/concepts/texplain.nim @@ -1,62 +1,66 @@ discard """ cmd: "nim c --verbosity:0 --colors:off $file" nimout: ''' -texplain.nim(99, 10) Hint: Non-matching candidates for e(y) +texplain.nim(103, 10) Hint: Non-matching candidates for e(y) proc e(i: int): int -texplain.nim(102, 7) Hint: Non-matching candidates for e(10) +texplain.nim(106, 7) Hint: Non-matching candidates for e(10) proc e(o: ExplainedConcept): int -texplain.nim(65, 6) ExplainedConcept: undeclared field: 'foo' -texplain.nim(65, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(65, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(65, 5) ExplainedConcept: concept predicate failed -texplain.nim(66, 6) ExplainedConcept: undeclared field: 'bar' -texplain.nim(66, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(66, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(65, 5) ExplainedConcept: concept predicate failed - -texplain.nim(105, 10) Hint: Non-matching candidates for e(10) +texplain.nim(69, 6) ExplainedConcept: undeclared field: 'foo' +texplain.nim(69, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(69, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(69, 5) ExplainedConcept: concept predicate failed +texplain.nim(70, 6) ExplainedConcept: undeclared field: 'bar' +texplain.nim(70, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(70, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(69, 5) ExplainedConcept: concept predicate failed + +texplain.nim(109, 10) Hint: Non-matching candidates for e(10) proc e(o: ExplainedConcept): int -texplain.nim(65, 6) ExplainedConcept: undeclared field: 'foo' -texplain.nim(65, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(65, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(65, 5) ExplainedConcept: concept predicate failed -texplain.nim(66, 6) ExplainedConcept: undeclared field: 'bar' -texplain.nim(66, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(66, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(65, 5) ExplainedConcept: concept predicate failed - -texplain.nim(109, 20) Error: type mismatch: got (NonMatchingType) -but expected one of: +texplain.nim(69, 6) ExplainedConcept: undeclared field: 'foo' +texplain.nim(69, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(69, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(69, 5) ExplainedConcept: concept predicate failed +texplain.nim(70, 6) ExplainedConcept: undeclared field: 'bar' +texplain.nim(70, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(70, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(69, 5) ExplainedConcept: concept predicate failed + +texplain.nim(113, 20) Error: type mismatch: got (NonMatchingType) +but expected one of: proc e(o: ExplainedConcept): int -texplain.nim(65, 5) ExplainedConcept: concept predicate failed +texplain.nim(69, 5) ExplainedConcept: concept predicate failed proc e(i: int): int -texplain.nim(110, 20) Error: type mismatch: got (NonMatchingType) -but expected one of: +expression: e(n) +texplain.nim(114, 20) Error: type mismatch: got (NonMatchingType) +but expected one of: proc r(o: RegularConcept): int -texplain.nim(69, 5) RegularConcept: concept predicate failed +texplain.nim(73, 5) RegularConcept: concept predicate failed proc r[T](a: SomeNumber; b: T; c: auto) proc r(i: string): int -texplain.nim(111, 20) Hint: Non-matching candidates for r(y) +expression: r(n) +texplain.nim(115, 20) Hint: Non-matching candidates for r(y) proc r[T](a: SomeNumber; b: T; c: auto) proc r(i: string): int -texplain.nim(119, 2) Error: type mismatch: got (MatchingType) -but expected one of: +texplain.nim(123, 2) Error: type mismatch: got (MatchingType) +but expected one of: proc f(o: NestedConcept) -texplain.nim(69, 6) RegularConcept: undeclared field: 'foo' -texplain.nim(69, 6) RegularConcept: undeclared field: '.' -texplain.nim(69, 6) RegularConcept: expression '.' cannot be called -texplain.nim(69, 5) RegularConcept: concept predicate failed -texplain.nim(70, 6) RegularConcept: undeclared field: 'bar' -texplain.nim(70, 6) RegularConcept: undeclared field: '.' -texplain.nim(70, 6) RegularConcept: expression '.' cannot be called -texplain.nim(69, 5) RegularConcept: concept predicate failed -texplain.nim(73, 5) NestedConcept: concept predicate failed +texplain.nim(73, 6) RegularConcept: undeclared field: 'foo' +texplain.nim(73, 6) RegularConcept: undeclared field: '.' +texplain.nim(73, 6) RegularConcept: expression '.' cannot be called +texplain.nim(73, 5) RegularConcept: concept predicate failed +texplain.nim(74, 6) RegularConcept: undeclared field: 'bar' +texplain.nim(74, 6) RegularConcept: undeclared field: '.' +texplain.nim(74, 6) RegularConcept: expression '.' cannot be called +texplain.nim(73, 5) RegularConcept: concept predicate failed +texplain.nim(77, 5) NestedConcept: concept predicate failed + +expression: f(y) ''' - line: 119 + line: 123 errormsg: "type mismatch: got (MatchingType)" """ diff --git a/tests/concepts/tinfrecursion.nim b/tests/concepts/tinfrecursion.nim new file mode 100644 index 000000000..60db410de --- /dev/null +++ b/tests/concepts/tinfrecursion.nim @@ -0,0 +1,13 @@ + +# bug #6691 +type + ConceptA = concept c + + ConceptB = concept c + c.myProc(ConceptA) + + Obj = object + +proc myProc(obj: Obj, x: ConceptA) = discard + +echo Obj is ConceptB diff --git a/tests/concepts/titerable.nim b/tests/concepts/titerable.nim new file mode 100644 index 000000000..b18658b2a --- /dev/null +++ b/tests/concepts/titerable.nim @@ -0,0 +1,20 @@ +discard """ + nimout: "int\nint" + output: 15 +""" + +import typetraits + +type + Iterable[T] = concept x + for value in x: + type(value) is T + +proc sum*[T](iter: Iterable[T]): T = + static: echo T.name + for element in iter: + static: echo element.type.name + result += element + +echo sum([1, 2, 3, 4, 5]) + diff --git a/tests/concepts/tmapconcept.nim b/tests/concepts/tmapconcept.nim index 81caed7c6..5082fcb61 100644 --- a/tests/concepts/tmapconcept.nim +++ b/tests/concepts/tmapconcept.nim @@ -1,7 +1,7 @@ discard """ output: '''10 10 -nil + 1''' msg: ''' K=string V=int diff --git a/tests/concepts/tmisc_issues.nim b/tests/concepts/tmisc_issues.nim index d9bb84a2f..662eba380 100644 --- a/tests/concepts/tmisc_issues.nim +++ b/tests/concepts/tmisc_issues.nim @@ -31,7 +31,7 @@ type ConcretePointOfFloat = object type ConcretePoint[Value] = object x, y: Value -type AbstractPointOfFloat = generic p +type AbstractPointOfFloat = concept p p.x is float and p.y is float let p1 = ConcretePointOfFloat(x: 0, y: 0) @@ -89,10 +89,10 @@ type B = object proc size(self: B): int = - return -1 + return -1 proc size(self: A): int = - return 0 + return 0 let b = B() echo b is A diff --git a/tests/cpp/tasync_cpp.nim b/tests/cpp/tasync_cpp.nim index ec78ae26c..a5e3374b6 100644 --- a/tests/cpp/tasync_cpp.nim +++ b/tests/cpp/tasync_cpp.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: "hello" """ diff --git a/tests/cpp/tcasts.nim b/tests/cpp/tcasts.nim new file mode 100644 index 000000000..24ebb8f62 --- /dev/null +++ b/tests/cpp/tcasts.nim @@ -0,0 +1,11 @@ +discard """ + cmd: "nim cpp $file" + output: "" + targets: "cpp" +""" + +block: #5979 + var a = 'a' + var p: pointer = cast[pointer](a) + var c = cast[char](p) + doAssert(c == 'a') diff --git a/tests/cpp/tcovariancerules.nim b/tests/cpp/tcovariancerules.nim index dfe4cb941..9365a3a18 100644 --- a/tests/cpp/tcovariancerules.nim +++ b/tests/cpp/tcovariancerules.nim @@ -1,5 +1,5 @@ discard """ -cmd: "nim cpp $file" +targets: "cpp" output: ''' cat cat diff --git a/tests/cpp/tcppraise.nim b/tests/cpp/tcppraise.nim index a9ea8e6ce..7db9c0cfa 100644 --- a/tests/cpp/tcppraise.nim +++ b/tests/cpp/tcppraise.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''foo bar Need odd and >= 3 digits## diff --git a/tests/cpp/tdont_init_instantiation.nim b/tests/cpp/tdont_init_instantiation.nim index 652cb1414..fe487fba0 100644 --- a/tests/cpp/tdont_init_instantiation.nim +++ b/tests/cpp/tdont_init_instantiation.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''''' disabled: true """ diff --git a/tests/cpp/tembarrassing_generic_failure.nim b/tests/cpp/tembarrassing_generic_failure.nim index 3c31dcdb8..4b5050948 100644 --- a/tests/cpp/tembarrassing_generic_failure.nim +++ b/tests/cpp/tembarrassing_generic_failure.nim @@ -1,4 +1,5 @@ discard """ + targets: "cpp" cmd: "nim cpp --threads:on $file" """ diff --git a/tests/cpp/temitlist.nim b/tests/cpp/temitlist.nim index cef0fc52d..a7a8ebde4 100644 --- a/tests/cpp/temitlist.nim +++ b/tests/cpp/temitlist.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''6.0''' """ diff --git a/tests/cpp/tempty_generic_obj.nim b/tests/cpp/tempty_generic_obj.nim index e2957a5cd..b4c746a30 100644 --- a/tests/cpp/tempty_generic_obj.nim +++ b/tests/cpp/tempty_generic_obj.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''int float''' """ diff --git a/tests/cpp/tgen_prototype_for_importc.nim b/tests/cpp/tgen_prototype_for_importc.nim index 91f34755b..4e5a197a8 100644 --- a/tests/cpp/tgen_prototype_for_importc.nim +++ b/tests/cpp/tgen_prototype_for_importc.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: '''Hello world''' """ diff --git a/tests/cpp/tget_subsystem.nim b/tests/cpp/tget_subsystem.nim index 81009dd39..6fb095a3d 100644 --- a/tests/cpp/tget_subsystem.nim +++ b/tests/cpp/tget_subsystem.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ {.emit: """ @@ -22,10 +22,18 @@ proc getSubsystem*[T](): ptr T {. let input: ptr Input = getSubsystem[Input]() -# bug #4910 +# bugs #4910, #6892 +proc modify(x: var int) = + x = 123 proc foo() = - var ts: array[10, int] + var ts: array[2, int] for t in mitems(ts): - t = 123 + discard + + for t in mitems(ts): + modify(t) + + for i, t in mpairs(ts): + modify(t) diff --git a/tests/cpp/tnativesockets.nim b/tests/cpp/tnativesockets.nim index 6108380a8..c62008050 100644 --- a/tests/cpp/tnativesockets.nim +++ b/tests/cpp/tnativesockets.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ import nativesockets diff --git a/tests/cpp/treturn_array.nim b/tests/cpp/treturn_array.nim index ba4fbd6cc..432b9ce3b 100644 --- a/tests/cpp/treturn_array.nim +++ b/tests/cpp/treturn_array.nim @@ -1,3 +1,6 @@ +discard """ + targets: "cpp" +""" # bug #2259 type Mat4f* = array[0..15, float] diff --git a/tests/cpp/tsigbreak.nim b/tests/cpp/tsigbreak.nim index c8044f2bf..9a381d84f 100644 --- a/tests/cpp/tsigbreak.nim +++ b/tests/cpp/tsigbreak.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ import tables, lists diff --git a/tests/cpp/tstaticvar_via_typedesc.nim b/tests/cpp/tstaticvar_via_typedesc.nim index 7a9fa2afc..0d8f424d0 100644 --- a/tests/cpp/tstaticvar_via_typedesc.nim +++ b/tests/cpp/tstaticvar_via_typedesc.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" output: "42" """ diff --git a/tests/cpp/ttemplatetype.nim b/tests/cpp/ttemplatetype.nim index 7f56a225d..ef24e4cdc 100644 --- a/tests/cpp/ttemplatetype.nim +++ b/tests/cpp/ttemplatetype.nim @@ -1,3 +1,7 @@ +discard """ + targets: "cpp" +""" + type Map {.importcpp: "std::map", header: "<map>".} [T,U] = object diff --git a/tests/cpp/tthread_createthread.nim b/tests/cpp/tthread_createthread.nim index 363136e9d..b46b876b7 100644 --- a/tests/cpp/tthread_createthread.nim +++ b/tests/cpp/tthread_createthread.nim @@ -1,4 +1,5 @@ discard """ + targets: "cpp" cmd: "nim cpp --hints:on --threads:on $options $file" """ diff --git a/tests/cpp/ttypeinfo.nim b/tests/cpp/ttypeinfo.nim index 282c682b2..97825f452 100644 --- a/tests/cpp/ttypeinfo.nim +++ b/tests/cpp/ttypeinfo.nim @@ -1,6 +1,6 @@ discard """ + targets: "cpp" output: '''100''' - cmd: "nim cpp $file" """ import typeinfo diff --git a/tests/cpp/ttypeinfo2.nim b/tests/cpp/ttypeinfo2.nim index 64bd43e96..e3661c848 100644 --- a/tests/cpp/ttypeinfo2.nim +++ b/tests/cpp/ttypeinfo2.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ # bug #2841 import typeinfo diff --git a/tests/cpp/tvector_iterator.nim b/tests/cpp/tvector_iterator.nim index cb5ab33af..9df3754ba 100644 --- a/tests/cpp/tvector_iterator.nim +++ b/tests/cpp/tvector_iterator.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim cpp $file" + targets: "cpp" """ {.emit: """ diff --git a/tests/cpp/tvectorseq.nim b/tests/cpp/tvectorseq.nim index 6eb5dc9e4..4d9ffc3d6 100644 --- a/tests/cpp/tvectorseq.nim +++ b/tests/cpp/tvectorseq.nim @@ -1,7 +1,7 @@ discard """ + targets: "cpp" output: '''(x: 1.0) (x: 0.0)''' - cmd: "nim cpp $file" disabled: "true" """ diff --git a/tests/destructor/tatomicptrs.nim b/tests/destructor/tatomicptrs.nim new file mode 100644 index 000000000..d20596415 --- /dev/null +++ b/tests/destructor/tatomicptrs.nim @@ -0,0 +1,101 @@ +discard """ + output: '''allocating +allocating +allocating +55 +60 +99 +deallocating +deallocating +deallocating +''' + cmd: '''nim c --newruntime $file''' +""" + +type + SharedPtr*[T] = object + x: ptr T + +#proc isNil[T](s: SharedPtr[T]): bool {.inline.} = s.x.isNil + +template incRef(x) = + atomicInc(x.refcount) + +template decRef(x): untyped = atomicDec(x.refcount) + +proc makeShared*[T](x: T): SharedPtr[T] = + # XXX could benefit from 'sink' parameter. + # XXX could benefit from a macro that generates it. + result = cast[SharedPtr[T]](allocShared(sizeof(x))) + result.x[] = x + echo "allocating" + +proc `=destroy`*[T](dest: var SharedPtr[T]) = + var s = dest.x + if s != nil and decRef(s) == 0: + `=destroy`(s[]) + deallocShared(s) + echo "deallocating" + dest.x = nil + +proc `=`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) = + var s = src.x + if s != nil: incRef(s) + #atomicSwap(dest, s) + # XXX use an atomic store here: + swap(dest.x, s) + if s != nil and decRef(s) == 0: + `=destroy`(s[]) + deallocShared(s) + echo "deallocating" + +proc `=sink`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) = + ## XXX make this an atomic store: + if dest.x != src.x: + let s = dest.x + if s != nil: + `=destroy`(s[]) + deallocShared(s) + echo "deallocating" + dest.x = src.x + +template `.`*[T](s: SharedPtr[T]; field: untyped): untyped = + s.x.field + +template `.=`*[T](s: SharedPtr[T]; field, value: untyped) = + s.x.field = value + +from macros import unpackVarargs + +template `.()`*[T](s: SharedPtr[T]; field: untyped, args: varargs[untyped]): untyped = + unpackVarargs(s.x.field, args) + + +type + Tree = SharedPtr[TreeObj] + TreeObj = object + refcount: int + le, ri: Tree + data: int + +proc takesTree(a: Tree) = + if not a.isNil: + takesTree(a.le) + echo a.data + takesTree(a.ri) + +proc createTree(data: int): Tree = + result = makeShared(TreeObj(refcount: 1, data: data)) + +proc createTree(data: int; le, ri: Tree): Tree = + result = makeShared(TreeObj(refcount: 1, le: le, ri: ri, data: data)) + + +proc main = + let le = createTree(55) + let ri = createTree(99) + let t = createTree(60, le, ri) + takesTree(t) + +main() + diff --git a/tests/destructor/tcustomseqs.nim b/tests/destructor/tcustomseqs.nim new file mode 100644 index 000000000..97d7c07b6 --- /dev/null +++ b/tests/destructor/tcustomseqs.nim @@ -0,0 +1,143 @@ +discard """ + output: '''1 +2 +3 +4 +5 +6 +89 +90 +90 +0 0 1 +0 1 2 +0 2 3 +1 0 4 +1 1 5 +1 2 6 +1 3 7 +after 6 6''' + cmd: '''nim c --newruntime $file''' +""" + +import typetraits + +type + myseq*[T] = object + len, cap: int + data: ptr UncheckedArray[T] + +# XXX make code memory safe for overflows in '*' +var + allocCount, deallocCount: int + +proc `=destroy`*[T](x: var myseq[T]) = + if x.data != nil: + when not supportsCopyMem(T): + for i in 0..<x.len: `=destroy`(x[i]) + dealloc(x.data) + inc deallocCount + x.data = nil + x.len = 0 + x.cap = 0 + +proc `=`*[T](a: var myseq[T]; b: myseq[T]) = + if a.data == b.data: return + if a.data != nil: + dealloc(a.data) + inc deallocCount + a.data = nil + a.len = b.len + a.cap = b.cap + if b.data != nil: + a.data = cast[type(a.data)](alloc(a.cap * sizeof(T))) + inc allocCount + when supportsCopyMem(T): + copyMem(a.data, b.data, a.cap * sizeof(T)) + else: + for i in 0..<a.len: + a.data[i] = b.data[i] + +proc `=sink`*[T](a: var myseq[T]; b: myseq[T]) = + if a.data != nil and a.data != b.data: + dealloc(a.data) + inc deallocCount + a.len = b.len + a.cap = b.cap + a.data = b.data + +proc resize[T](s: var myseq[T]) = + if s.cap == 0: s.cap = 8 + else: s.cap = (s.cap * 3) shr 1 + if s.data == nil: inc allocCount + s.data = cast[type(s.data)](realloc(s.data, s.cap * sizeof(T))) + +proc reserveSlot[T](x: var myseq[T]): ptr T = + if x.len >= x.cap: resize(x) + result = addr(x.data[x.len]) + inc x.len + +template add*[T](x: var myseq[T]; y: T) = + reserveSlot(x)[] = y + +proc shrink*[T](x: var myseq[T]; newLen: int) = + assert newLen <= x.len + assert newLen >= 0 + when not supportsCopyMem(T): + for i in countdown(x.len - 1, newLen - 1): + `=destroy`(x.data[i]) + x.len = newLen + +proc grow*[T](x: var myseq[T]; newLen: int; value: T) = + if newLen <= x.len: return + assert newLen >= 0 + if x.cap == 0: x.cap = newLen + else: x.cap = max(newLen, (x.cap * 3) shr 1) + if x.data == nil: inc allocCount + x.data = cast[type(x.data)](realloc(x.data, x.cap * sizeof(T))) + for i in x.len..<newLen: + x.data[i] = value + x.len = newLen + +template default[T](t: typedesc[T]): T = + var v: T + v + +proc setLen*[T](x: var myseq[T]; newLen: int) {.deprecated.} = + if newlen < x.len: shrink(x, newLen) + else: grow(x, newLen, default(T)) + +template `[]`*[T](x: myseq[T]; i: Natural): T = + assert i < x.len + x.data[i] + +template `[]=`*[T](x: myseq[T]; i: Natural; y: T) = + assert i < x.len + x.data[i] = y + +proc createSeq*[T](elems: varargs[T]): myseq[T] = + result.cap = elems.len + result.len = elems.len + result.data = cast[type(result.data)](alloc(result.cap * sizeof(T))) + inc allocCount + when supportsCopyMem(T): + copyMem(result.data, unsafeAddr(elems[0]), result.cap * sizeof(T)) + else: + for i in 0..<result.len: + result.data[i] = elems[i] + +proc len*[T](x: myseq[T]): int {.inline.} = x.len + +proc main = + var s = createSeq(1, 2, 3, 4, 5, 6) + s.add 89 + s.grow s.len + 2, 90 + for i in 0 ..< s.len: + echo s[i] + + var nested = createSeq(createSeq(1, 2, 3), createSeq(4, 5, 6, 7)) + for i in 0 ..< nested.len: + for j in 0 ..< nested[i].len: + echo i, " ", j, " ", nested[i][j] + +main() +echo "after ", allocCount, " ", deallocCount diff --git a/tests/destructor/tcustomstrings.nim b/tests/destructor/tcustomstrings.nim index 2250d4772..1a78df20b 100644 --- a/tests/destructor/tcustomstrings.nim +++ b/tests/destructor/tcustomstrings.nim @@ -4,27 +4,27 @@ foo bar to appendmore here foo bar to appendmore here foo bar to appendmore here foo bar to appendmore here -after 16 16''' +after 20 20''' cmd: '''nim c --newruntime $file''' """ +{.this: self.} + type mystring = object len, cap: int data: ptr UncheckedArray[char] -{.this: self.} - var allocCount, deallocCount: int -proc `=destroy`*(self: var mystring) = - if data != nil: - dealloc(data) +proc `=destroy`*(s: var mystring) = + if s.data != nil: + dealloc(s.data) inc deallocCount - data = nil - len = 0 - cap = 0 + s.data = nil + s.len = 0 + s.cap = 0 proc `=sink`*(a: var mystring, b: mystring) = # we hope this is optimized away for not yet alive objects: @@ -48,10 +48,10 @@ proc `=`*(a: var mystring; b: mystring) = copyMem(a.data, b.data, a.cap+1) proc resize(self: var mystring) = - if cap == 0: cap = 8 - else: cap = (cap * 3) shr 1 - if data == nil: inc allocCount - data = cast[type(data)](realloc(data, cap + 1)) + if self.cap == 0: self.cap = 8 + else: self.cap = (self.cap * 3) shr 1 + if self.data == nil: inc allocCount + self.data = cast[type(data)](realloc(self.data, self.cap + 1)) proc add*(self: var mystring; c: char) = if self.len >= self.cap: resize(self) @@ -92,5 +92,8 @@ proc main(n: int) = a.add c echo cstring(a.data) + var x: array[4, mystring] + for i in 0..high(x): x[i] = create"added to array" + main(1000) echo "after ", allocCount, " ", deallocCount diff --git a/tests/destructor/tdestructor.nim b/tests/destructor/tdestructor.nim index 639dba941..c9f1caf2d 100644 --- a/tests/destructor/tdestructor.nim +++ b/tests/destructor/tdestructor.nim @@ -20,10 +20,10 @@ myobj destroyed ---- myobj destroyed ''' + cmd: '''nim c --newruntime $file''' + disabled: "true" """ -{.experimental.} - type TMyObj = object x, y: int @@ -61,7 +61,7 @@ proc `=destroy`(o: var TMyObj) = if o.p != nil: dealloc o.p echo "myobj destroyed" -proc `=destroy`(o: var TMyGeneric1) = +proc `=destroy`(o: var TMyGeneric1[int]) = echo "mygeneric1 destroyed" proc `=destroy`[A, B](o: var TMyGeneric2[A, B]) = diff --git a/tests/destructor/tdestructor2.nim b/tests/destructor/tdestructor2.nim deleted file mode 100644 index 34fa466af..000000000 --- a/tests/destructor/tdestructor2.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - line: 23 - nimout: " usage of a type with a destructor in a non destructible context" -""" - -{.experimental.} - -type - TMyObj = object - x, y: int - p: pointer - -proc `=destroy`(o: var TMyObj) = - if o.p != nil: dealloc o.p - -proc open: TMyObj = - result = TMyObj(x: 1, y: 2, p: alloc(3)) - - -proc `$`(x: TMyObj): string = $x.y - -proc foo = - discard open() - -# XXX doesn't trigger this yet: -#echo open() - diff --git a/tests/destructor/tdestructor3.nim b/tests/destructor/tdestructor3.nim index d0c53c7bd..3e177d3cd 100644 --- a/tests/destructor/tdestructor3.nim +++ b/tests/destructor/tdestructor3.nim @@ -2,14 +2,14 @@ discard """ output: '''assign destroy destroy -destroy Foo: 5 5 -destroy Foo: 123 -123''' +123 +destroy Foo: 5 +destroy Foo: 123''' + cmd: '''nim c --newruntime $file''' """ # bug #2821 -{.experimental.} type T = object diff --git a/tests/destructor/tmove_objconstr.nim b/tests/destructor/tmove_objconstr.nim new file mode 100644 index 000000000..8aa12ed05 --- /dev/null +++ b/tests/destructor/tmove_objconstr.nim @@ -0,0 +1,59 @@ + +discard """ +output: '''test created +test destroyed 0 +1 +2 +3 +4 +Pony is dying!''' + cmd: '''nim c --newruntime $file''' +""" + +# bug #4214 +type + Data = object + data: string + rc: int + +proc `=destroy`(d: var Data) = + dec d.rc + echo d.data, " destroyed ", d.rc + +proc `=`(dst: var Data, src: Data) = + echo src.data, " copied" + dst.data = src.data & " (copy)" + dec dst.rc + inc dst.rc + +proc initData(s: string): Data = + result = Data(data: s, rc: 1) + echo s, " created" + +proc pointlessWrapper(s: string): Data = + result = initData(s) + +proc main = + var x = pointlessWrapper"test" + +when isMainModule: + main() + +# bug #985 + +type + Pony = object + name: string + +proc `=destroy`(o: var Pony) = + echo "Pony is dying!" + +proc getPony: Pony = + result.name = "Sparkles" + +iterator items(p: Pony): int = + for i in 1..4: + yield i + +for x in getPony(): + echo x diff --git a/tests/destructor/topttree.nim b/tests/destructor/topttree.nim new file mode 100644 index 000000000..924644392 --- /dev/null +++ b/tests/destructor/topttree.nim @@ -0,0 +1,104 @@ +discard """ + output: '''10.0 +60.0 +90.0 +120.0 +10.0 +60.0 +90.0 +120.0 +8 8''' + cmd: '''nim c --newruntime $file''' +""" + +import typetraits + +type + opt[T] = object + data: ptr T + +var + allocCount, deallocCount: int + +proc `=destroy`*[T](x: var opt[T]) = + if x.data != nil: + when not supportsCopyMem(T): + `=destroy`(x.data[]) + dealloc(x.data) + inc deallocCount + x.data = nil + +proc `=`*[T](a: var opt[T]; b: opt[T]) = + if a.data == b.data: return + if a.data != nil: + dealloc(a.data) + inc deallocCount + a.data = nil + if b.data != nil: + a.data = cast[type(a.data)](alloc(sizeof(T))) + inc allocCount + when supportsCopyMem(T): + copyMem(a.data, b.data, sizeof(T)) + else: + a.data[] = b.data[] + +proc `=sink`*[T](a: var opt[T]; b: opt[T]) = + if a.data != nil and a.data != b.data: + dealloc(a.data) + inc deallocCount + a.data = b.data + +proc createOpt*[T](x: T): opt[T] = + result.data = cast[type(result.data)](alloc(sizeof(T))) + inc allocCount + result.data[] = x + +template `[]`[T](x: opt[T]): T = + assert x.p != nil, "attempt to read from moved/destroyed value" + x.p[] + +template `?=`[T](it: untyped; x: opt[T]): bool = + template it: untyped {.inject.} = x.data[] + if x.data != nil: + true + else: + false + +type + Tree = object + data: float + le, ri: opt[Tree] + +proc createTree(data: float): Tree = + result.data = data + +proc insert(t: var opt[Tree]; newVal: float) = + #if it ?= t: + if t.data != nil: + if newVal < t.data[].data: + insert(t.data[].le, newVal) + elif t.data[].data < newVal: + insert(t.data[].ri, newVal) + else: + discard "already in the tree" + else: + t = createOpt(Tree(data: newVal)) + +proc write(t: opt[Tree]) = + if it ?= t: + write(it.le) + write stdout, it.data, "\n" + write(it.ri) + +proc main = + var t: opt[Tree] + insert t, 60.0 + insert t, 90.0 + insert t, 10.0 + insert t, 120.0 + write t + let copy = t + write copy + +main() +echo allocCount, " ", deallocCount diff --git a/tests/errmsgs/tmake_tuple_visible.nim b/tests/errmsgs/tmake_tuple_visible.nim new file mode 100644 index 000000000..43337c2a9 --- /dev/null +++ b/tests/errmsgs/tmake_tuple_visible.nim @@ -0,0 +1,23 @@ +discard """ + errormsg: '''got (tuple of (type NimEdAppWindow, int))''' + line: 22 + nimout: '''got (tuple of (type NimEdAppWindow, int)) +but expected one of: +template xxx(tn: typedesc; i: int)''' +""" + +type + NimEdAppWindow = ptr NimEdAppWindowObj + NimEdAppWindowObj = object + i: int + +template gDefineTypeExtended*(tn: typeDesc) = + discard + +gDefineTypeExtended (NimEdAppWindow) + +template xxx*(tn: typeDesc, i: int) = + discard + +xxx (NimEdAppWindow, 0) +# bug #6776 diff --git a/tests/exprs/texprstmt.nim b/tests/exprs/texprstmt.nim index 0e92702e8..6c9759cf5 100644 --- a/tests/exprs/texprstmt.nim +++ b/tests/exprs/texprstmt.nim @@ -1,6 +1,6 @@ discard """ line: 10 - errormsg: "expression 'result[1 .. -(len(result), 1)]' is of type 'string' and has to be discarded" + errormsg: "expression 'result[1 .. BackwardsIndex(1)]' is of type 'string' and has to be discarded" """ # bug #578 diff --git a/tests/exprs/tstmtexprs.nim b/tests/exprs/tstmtexprs.nim index b2d5db408..2a0ec2821 100644 --- a/tests/exprs/tstmtexprs.nim +++ b/tests/exprs/tstmtexprs.nim @@ -1,11 +1,12 @@ discard """ output: '''24 -(bar: bar) +(bar: "bar") 1244 6 abcdefghijklmnopqrstuvwxyz 145 23 -3''' +3 +2''' """ import strutils @@ -122,3 +123,31 @@ var testTry = PFooBase(field: 5) echo(testTry.field) + +# bug #6166 + +proc quo(op: proc (x: int): bool): int = + result = + if op(3): + 2 + else: + 0 + +echo( + if true: + quo do (a: int) -> bool: + a mod 2 != 0 + else: + quo do (a: int) -> bool: + a mod 3 != 0 +) + +# bug #6980 + +proc fooBool: bool {.discardable.} = + true + +if true: + fooBool() +else: + raise newException(ValueError, "argh") diff --git a/tests/fields/timplicitfieldswithpartial.nim b/tests/fields/timplicitfieldswithpartial.nim index 996912a1a..937833257 100644 --- a/tests/fields/timplicitfieldswithpartial.nim +++ b/tests/fields/timplicitfieldswithpartial.nim @@ -1,6 +1,8 @@ discard """ - output: '''(foo: 38, other: string here) -43''' + output: '''(foo: 38, other: "string here") +43 +100 +90''' """ type @@ -17,3 +19,17 @@ proc my(f: Foo) = var g: Foo new(g) my(g) + +type + FooTask {.partial.} = ref object of RootObj + +proc foo(t: FooTask) {.liftLocals: t.} = + var x = 90 + if true: + var x = 10 + while x < 100: + inc x + echo x + echo x + +foo(FooTask()) diff --git a/tests/float/tfloatnan.nim b/tests/float/tfloatnan.nim new file mode 100644 index 000000000..aa288d342 --- /dev/null +++ b/tests/float/tfloatnan.nim @@ -0,0 +1,16 @@ +discard """ + file: "tfloatnan.nim" + output: '''Nim: nan +Nim: nan (float) +Nim: nan (double) +''' +""" + +let f = NaN +echo "Nim: ", f + +let f32: float32 = NaN +echo "Nim: ", f32, " (float)" + +let f64: float64 = NaN +echo "Nim: ", f64, " (double)" diff --git a/tests/float/tlenientops.nim b/tests/float/tlenientops.nim new file mode 100644 index 000000000..586580670 --- /dev/null +++ b/tests/float/tlenientops.nim @@ -0,0 +1,100 @@ +discard """ + exitcode: 0 + output: "" +""" + +import lenientops + +proc `~=`[T](a, b: T): bool = abs(a - b) < 1e-7 + +block: # math binary operators + let i = 1 + let f = 2.0 + + doAssert i + f ~= 3 + doAssert f + i ~= 3 + + doAssert i - f ~= -1 + doAssert f - i ~= 1 + + doAssert i * f ~= 2 + doAssert f * i ~= 2 + + doAssert i / f ~= 0.5 + doAssert f / i ~= 2 + +block: # comparison operators + doAssert 1.int < 2.float + doAssert 1.float < 2.int + doAssert 1.int <= 2.float + doAssert 1.float <= 2.int + doAssert 2.int >= 1.float + doAssert 2.float >= 1.int + doAssert 2.int > 1.float + doAssert 2.float > 1.int + +block: # all type combinations + let i = 1 + let f = 2.0 + + doAssert i.int + f.float ~= 3 + doAssert i.int + f.float32 ~= 3 + doAssert i.int + f.float64 ~= 3 + doAssert i.int8 + f.float ~= 3 + doAssert i.int8 + f.float32 ~= 3 + doAssert i.int8 + f.float64 ~= 3 + doAssert i.int16 + f.float ~= 3 + doAssert i.int16 + f.float32 ~= 3 + doAssert i.int16 + f.float64 ~= 3 + doAssert i.int32 + f.float ~= 3 + doAssert i.int32 + f.float32 ~= 3 + doAssert i.int32 + f.float64 ~= 3 + doAssert i.int64 + f.float ~= 3 + doAssert i.int64 + f.float32 ~= 3 + doAssert i.int64 + f.float64 ~= 3 + doAssert i.uint + f.float ~= 3 + doAssert i.uint + f.float32 ~= 3 + doAssert i.uint + f.float64 ~= 3 + doAssert i.uint8 + f.float ~= 3 + doAssert i.uint8 + f.float32 ~= 3 + doAssert i.uint8 + f.float64 ~= 3 + doAssert i.uint16 + f.float ~= 3 + doAssert i.uint16 + f.float32 ~= 3 + doAssert i.uint16 + f.float64 ~= 3 + doAssert i.uint32 + f.float ~= 3 + doAssert i.uint32 + f.float32 ~= 3 + doAssert i.uint32 + f.float64 ~= 3 + doAssert i.uint64 + f.float ~= 3 + doAssert i.uint64 + f.float32 ~= 3 + doAssert i.uint64 + f.float64 ~= 3 + + doAssert f.float + i.int ~= 3 + doAssert f.float32 + i.int ~= 3 + doAssert f.float64 + i.int ~= 3 + doAssert f.float + i.int8 ~= 3 + doAssert f.float32 + i.int8 ~= 3 + doAssert f.float64 + i.int8 ~= 3 + doAssert f.float + i.int16 ~= 3 + doAssert f.float32 + i.int16 ~= 3 + doAssert f.float64 + i.int16 ~= 3 + doAssert f.float + i.int32 ~= 3 + doAssert f.float32 + i.int32 ~= 3 + doAssert f.float64 + i.int32 ~= 3 + doAssert f.float + i.int64 ~= 3 + doAssert f.float32 + i.int64 ~= 3 + doAssert f.float64 + i.int64 ~= 3 + doAssert f.float + i.uint ~= 3 + doAssert f.float32 + i.uint ~= 3 + doAssert f.float64 + i.uint ~= 3 + doAssert f.float + i.uint8 ~= 3 + doAssert f.float32 + i.uint8 ~= 3 + doAssert f.float64 + i.uint8 ~= 3 + doAssert f.float + i.uint16 ~= 3 + doAssert f.float32 + i.uint16 ~= 3 + doAssert f.float64 + i.uint16 ~= 3 + doAssert f.float + i.uint32 ~= 3 + doAssert f.float32 + i.uint32 ~= 3 + doAssert f.float64 + i.uint32 ~= 3 + doAssert f.float + i.uint64 ~= 3 + doAssert f.float32 + i.uint64 ~= 3 + doAssert f.float64 + i.uint64 ~= 3 diff --git a/tests/fragmentation/data.nim b/tests/fragmentation/data.nim new file mode 100644 index 000000000..d14123c0f --- /dev/null +++ b/tests/fragmentation/data.nim @@ -0,0 +1,7629 @@ + +const sizes* = [ + 643584, + 140800, + 802, + 2464928, + 488122, + 1161601, + 861051, + 1413, + 389, + 2412032, + 328704, + 323488, + 484864, + 31232, + 38400, + 87552, + 328704, + 242176, + 55808, + 32256, + 15360, + 15080, + 567074, + 1390, + 1390, + 366080, + 186536, + 314368, + 4154, + 3017582, + 62658, + 3874662, + 227, + 126616, + 290, + 261792, + 287, + 151200, + 293, + 34976, + 293, + 28840, + 296, + 20664, + 314, + 223232, + 288, + 53248, + 326, + 12800, + 312, + 473600, + 306, + 2676224, + 308, + 2846720, + 308, + 563712, + 308, + 567296, + 308, + 576000, + 308, + 577024, + 308, + 577536, + 308, + 577536, + 308, + 578560, + 308, + 578560, + 308, + 145920, + 310, + 159232, + 312, + 364544, + 310, + 178176, + 312, + 8032448, + 323, + 29392, + 332, + 35112, + 394, + 85768, + 371, + 88864, + 385, + 23840, + 385, + 176128, + 386, + 126976, + 389, + 24800, + 401, + 118784, + 379, + 21792, + 385, + 259152, + 385, + 172032, + 389, + 40960, + 389, + 114688, + 403, + 57344, + 407, + 7680, + 407, + 126216, + 373, + 29952, + 367, + 148768, + 385, + 27384, + 362, + 24832, + 362, + 50944, + 364, + 20136, + 302, + 32416, + 293, + 69296, + 305, + 36016, + 308, + 89784, + 305, + 5120, + 305, + 49152, + 320, + 30424, + 331, + 12288, + 326, + 62976, + 69120, + 72192, + 503808, + 77824, + 382144, + 163840, + 88728, + 1581, + 1718096, + 66728, + 82172, + 116756, + 4554752, + 59342, + 45794, + 39284, + 66384, + 60294, + 83748, + 83748, + 262148, + 20320, + 28288, + 382, + 3072, + 4222976, + 161, + 1737888, + 2975744, + 487424, + 258048, + 113664, + 372736, + 261632, + 5287936, + 80896, + 89600, + 503808, + 77824, + 554176, + 163840, + 84632, + 1581, + 1714000, + 66728, + 82172, + 116756, + 4571136, + 59342, + 45794, + 39284, + 66384, + 60294, + 83748, + 83748, + 262148, + 20320, + 28288, + 4006400, + 161, + 2256032, + 3150336, + 503296, + 245760, + 133120, + 358400, + 283136, + 5296128, + 10752, + 507904, + 315392, + 11264, + 921600, + 7680, + 118784, + 166560, + 13312, + 5120, + 18768, + 52736, + 8192, + 77824, + 6656, + 106496, + 389120, + 733184, + 53248, + 36864, + 36864, + 655360, + 139264, + 802816, + 169864, + 77824, + 10752, + 94208, + 17808, + 40960, + 36864, + 749568, + 45056, + 188416, + 28672, + 16384, + 69632, + 102400, + 11776, + 10752, + 290816, + 36864, + 36864, + 667648, + 53248, + 49152, + 200704, + 45056, + 40960, + 77824, + 10240, + 9216, + 77504, + 161472, + 163528, + 26304, + 26312, + 96448, + 99016, + 19648, + 19656, + 127680, + 127680, + 364224, + 323272, + 73408, + 71368, + 24776, + 138944, + 128200, + 27328, + 48832, + 37576, + 32960, + 52928, + 40128, + 89792, + 80584, + 25792, + 499392, + 504520, + 163520, + 167624, + 36032, + 36040, + 138944, + 127688, + 4208320, + 4839104, + 77504, + 81608, + 2768576, + 2757832, + 331456, + 321728, + 65224, + 65216, + 56008, + 163520, + 154816, + 48832, + 77504, + 62656, + 48832, + 77504, + 50888, + 57024, + 47296, + 52928, + 40640, + 71360, + 71360, + 22208, + 22208, + 57024, + 45768, + 48832, + 48840, + 3720896, + 4037832, + 790208, + 868040, + 230592, + 230592, + 20160, + 20160, + 29376, + 31944, + 1355456, + 1419976, + 839360, + 851656, + 32960, + 36040, + 179904, + 265920, + 85696, + 85696, + 33472, + 33472, + 392896, + 391872, + 397008, + 48832, + 48832, + 48832, + 48832, + 52928, + 48832, + 48832, + 57024, + 36032, + 36032, + 48832, + 48840, + 48840, + 48832, + 52928, + 48832, + 48832, + 57024, + 36032, + 36032, + 48848, + 48848, + 48848, + 48848, + 52944, + 48848, + 48848, + 57040, + 36048, + 36048, + 57024, + 45760, + 20160, + 20160, + 34528, + 13024, + 397312, + 5120, + 28672, + 659456, + 372736, + 110592, + 9216, + 9728, + 61440, + 28672, + 5632, + 41984, + 29736, + 20056, + 216632, + 110184, + 27032, + 37472, + 31592, + 24376, + 102728, + 280912, + 27472, + 27936, + 23392, + 56624, + 57216, + 38744, + 51016, + 36696, + 48896, + 53024, + 32032, + 34120, + 34120, + 20256, + 107848, + 109928, + 1267040, + 46984, + 496544, + 1174384, + 762288, + 101744, + 32664, + 95712, + 48480, + 365344, + 98448, + 86440, + 35312, + 37704, + 75664, + 101672, + 47912, + 15872, + 11168, + 22856, + 22856, + 506616, + 556824, + 61784, + 30008, + 44848, + 81816, + 31528, + 32768, + 12800, + 27000, + 155000, + 14712, + 14712, + 14712, + 15224, + 14712, + 15224, + 14712, + 14712, + 14712, + 15736, + 14712, + 13688, + 14200, + 122232, + 14200, + 14200, + 14200, + 14200, + 14200, + 14200, + 14712, + 13688, + 14200, + 14200, + 15224, + 14200, + 13688, + 13176, + 978296, + 1580408, + 134520, + 15224, + 15736, + 15736, + 15736, + 15736, + 15736, + 16248, + 15736, + 15736, + 15224, + 16760, + 15224, + 14712, + 15224, + 171384, + 175480, + 159096, + 171384, + 179576, + 171384, + 191864, + 175480, + 175480, + 171384, + 216440, + 167288, + 155000, + 155000, + 40312, + 27000, + 48504, + 14200, + 14200, + 14712, + 14200, + 14200, + 14200, + 14712, + 13688, + 14200, + 14200, + 14712, + 14712, + 13688, + 14200, + 52600, + 56696, + 146704, + 21792, + 286720, + 15360, + 13824, + 7168, + 7168, + 421888, + 36864, + 36864, + 110592, + 4608, + 4096, + 29576, + 29576, + 29576, + 29576, + 40840, + 30088, + 32136, + 27368, + 27528, + 315392, + 381, + 3072, + 1318, + 3072, + 375, + 3072, + 378, + 3072, + 598016, + 53248, + 32768, + 110592, + 43696, + 5283840, + 196608, + 139264, + 397312, + 249856, + 163840, + 864256, + 372736, + 532480, + 36864, + 5632, + 110592, + 5120, + 129664, + 110592, + 10752, + 3203072, + 163840, + 45056, + 57344, + 8192, + 425984, + 81920, + 28672, + 49152, + 671744, + 61440, + 53248, + 2879488, + 229376, + 15360, + 397312, + 684032, + 57344, + 110592, + 356352, + 696320, + 462848, + 53248, + 163840, + 11776, + 98304, + 470240, + 47328, + 745472, + 36864, + 974848, + 397312, + 5062656, + 544768, + 401408, + 290816, + 36864, + 188416, + 28672, + 40960, + 630784, + 81920, + 6144, + 24576, + 32768, + 446464, + 65536, + 126976, + 53248, + 131072, + 11776, + 389120, + 3010560, + 278528, + 253952, + 143360, + 13824, + 258048, + 77824, + 237568, + 16896, + 212992, + 307200, + 32768, + 970752, + 131072, + 11776, + 98304, + 270336, + 28672, + 5992448, + 73728, + 36864, + 491520, + 32768, + 569344, + 69632, + 114688, + 40960, + 692224, + 65536, + 28672, + 77824, + 3584, + 229376, + 32768, + 4096, + 16896, + 139264, + 131072, + 11264, + 15360, + 1282048, + 335872, + 49152, + 634880, + 835584, + 81920, + 98304, + 622592, + 61440, + 7168, + 839680, + 81920, + 5025792, + 434176, + 12288, + 3584, + 1142784, + 188416, + 1630208, + 311296, + 540672, + 36864, + 507904, + 102400, + 2056192, + 139264, + 167936, + 172032, + 4096, + 380928, + 8192, + 40960, + 4096, + 98304, + 7168, + 10584, + 81080, + 23376, + 1257472, + 90112, + 94208, + 5120, + 150168, + 25600, + 2553856, + 69120, + 220672, + 51712, + 1349120, + 1349120, + 167424, + 786432, + 515584, + 291328, + 1681920, + 33792, + 102400, + 102912, + 60928, + 44032, + 631296, + 44544, + 11776, + 408576, + 138752, + 1849856, + 13824, + 33280, + 44544, + 17920, + 11776, + 9153536, + 150016, + 13824, + 24576, + 293888, + 651264, + 818176, + 17920, + 141312, + 64512, + 583168, + 58368, + 830976, + 109568, + 65536, + 24576, + 771584, + 1545728, + 1540608, + 11776, + 144896, + 11776, + 18944, + 67584, + 65536, + 17920, + 848896, + 43520, + 30720, + 27648, + 1935872, + 127488, + 11264, + 44032, + 583168, + 11264, + 67584, + 632320, + 38400, + 8470528, + 127488, + 257536, + 30720, + 111104, + 286720, + 1711616, + 64000, + 240128, + 22016, + 86528, + 174080, + 16896, + 531456, + 17920, + 23552, + 20992, + 20992, + 22528, + 20992, + 19456, + 19456, + 20992, + 20992, + 11500544, + 12260864, + 368128, + 14345216, + 29184, + 29184, + 84480, + 64512, + 925696, + 8003072, + 141312, + 978432, + 2305024, + 6658048, + 1116160, + 1593344, + 1059328, + 777216, + 214016, + 627200, + 11935232, + 1840640, + 12438528, + 5466624, + 86528, + 98816, + 3358720, + 145408, + 126976, + 73728, + 78848, + 94208, + 348672, + 76288, + 2347008, + 2347008, + 2176512, + 237056, + 1130496, + 416768, + 713216, + 1126400, + 61440, + 163328, + 158208, + 61440, + 2173952, + 681472, + 33792, + 15580160, + 16565248, + 463360, + 19202560, + 47104, + 116736, + 89088, + 10677248, + 192512, + 1320448, + 3324416, + 8741888, + 1639936, + 2320384, + 1482752, + 11899392, + 1028608, + 296448, + 921600, + 15390720, + 2292224, + 17390080, + 6968320, + 125952, + 136192, + 4978176, + 193536, + 169984, + 104960, + 43520, + 300, + 112128, + 536, + 110592, + 536, + 112128, + 536, + 2664448, + 1060, + 2664448, + 1060, + 2664448, + 1060, + 71168, + 572, + 72192, + 572, + 71168, + 572, + 131072, + 2416, + 82944, + 3084, + 12800, + 3508, + 15872, + 3576, + 1321984, + 1364, + 653312, + 2124, + 18492416, + 2048, + 6656, + 344, + 1219584, + 416, + 548864, + 2444, + 6656, + 344, + 11776, + 1008, + 54272, + 404, + 63488, + 404, + 64000, + 404, + 624640, + 5752, + 624640, + 5720, + 89600, + 1736, + 164352, + 1096, + 178688, + 1096, + 16384, + 352, + 326656, + 1368, + 315392, + 1368, + 699392, + 1004, + 54784, + 360, + 75776, + 352, + 69120, + 352, + 61440, + 352, + 62976, + 352, + 61952, + 352, + 53760, + 360, + 61440, + 352, + 62464, + 352, + 33280, + 320, + 23552, + 368, + 26112, + 360, + 26624, + 324, + 26112, + 360, + 27648, + 320, + 27136, + 320, + 27136, + 320, + 28160, + 360, + 27648, + 320, + 27648, + 320, + 27648, + 320, + 33280, + 320, + 27648, + 320, + 26112, + 360, + 29696, + 320, + 31232, + 360, + 26112, + 360, + 27648, + 320, + 25088, + 328, + 27648, + 320, + 26624, + 320, + 25088, + 328, + 25088, + 328, + 25088, + 328, + 27648, + 320, + 26112, + 360, + 27136, + 320, + 27136, + 320, + 27648, + 320, + 23552, + 368, + 26624, + 320, + 25600, + 320, + 25600, + 320, + 29696, + 320, + 27648, + 320, + 26624, + 324, + 1927168, + 928, + 2015232, + 928, + 414720, + 588, + 426496, + 588, + 327680, + 708, + 1290240, + 2608, + 83456, + 308, + 86016, + 308, + 109056, + 308, + 100352, + 348, + 86016, + 308, + 109056, + 308, + 83968, + 308, + 87040, + 308, + 76800, + 312, + 87040, + 308, + 88576, + 348, + 79360, + 348, + 79872, + 308, + 75264, + 312, + 87552, + 308, + 76800, + 312, + 86528, + 308, + 88064, + 308, + 80384, + 348, + 88576, + 308, + 83456, + 308, + 79872, + 308, + 96768, + 308, + 86528, + 308, + 78848, + 348, + 82944, + 308, + 88576, + 308, + 87552, + 308, + 79360, + 348, + 69120, + 352, + 83968, + 308, + 88064, + 308, + 82944, + 308, + 70144, + 352, + 80384, + 348, + 75264, + 312, + 96768, + 308, + 10240, + 364, + 9728, + 364, + 9728, + 364, + 9728, + 364, + 9728, + 364, + 9728, + 364, + 10240, + 364, + 9216, + 368, + 9216, + 368, + 163840, + 8280, + 242176, + 2980, + 210432, + 360, + 244224, + 360, + 209408, + 360, + 212480, + 360, + 192512, + 364, + 206336, + 360, + 224768, + 360, + 193536, + 364, + 206336, + 360, + 872960, + 1232, + 1231872, + 1056, + 809472, + 888, + 809472, + 992, + 3544576, + 2160, + 3544576, + 2056, + 3580928, + 2220, + 2396160, + 2568, + 145408, + 316, + 160256, + 316, + 145408, + 316, + 195584, + 364, + 140288, + 316, + 126464, + 324, + 144896, + 316, + 160256, + 316, + 139264, + 316, + 216064, + 356, + 212992, + 356, + 144896, + 316, + 139264, + 316, + 140288, + 316, + 196608, + 364, + 132608, + 316, + 128000, + 324, + 249344, + 356, + 181760, + 316, + 142848, + 316, + 228864, + 356, + 144896, + 316, + 147456, + 316, + 141824, + 316, + 144896, + 316, + 214528, + 356, + 210944, + 356, + 181760, + 316, + 140288, + 320, + 142848, + 316, + 141824, + 316, + 210432, + 356, + 128000, + 324, + 132608, + 316, + 140288, + 320, + 126464, + 324, + 147456, + 316, + 26624, + 364, + 24576, + 364, + 22016, + 368, + 29696, + 364, + 22528, + 368, + 24576, + 364, + 24576, + 364, + 24576, + 364, + 25088, + 364, + 2791936, + 2000, + 161280, + 1048, + 169472, + 1048, + 5100032, + 2612, + 5506560, + 1728, + 8192, + 380, + 101888, + 5804, + 104960, + 3332, + 99328, + 2872, + 8704, + 388, + 35328, + 368, + 11244032, + 5592, + 11244032, + 5592, + 10870784, + 5256, + 10744320, + 7916, + 540160, + 744, + 408064, + 720, + 58368, + 4604, + 58368, + 4604, + 52736, + 5008, + 1554432, + 4636, + 2222080, + 6712, + 7168, + 384, + 6656, + 400, + 6656, + 372, + 272384, + 3816, + 235008, + 2760, + 8192, + 368, + 625664, + 5764, + 563200, + 6720, + 9728, + 392, + 7168, + 404, + 415744, + 4688, + 1320960, + 6228, + 7168, + 376, + 1756160, + 4992, + 1961472, + 6552, + 244736, + 360, + 2317824, + 6480, + 1916928, + 4832, + 6656, + 400, + 8192, + 372, + 7168, + 372, + 405504, + 4152, + 411136, + 5580, + 83456, + 1784, + 84992, + 2280, + 6943744, + 6676, + 8638976, + 9976, + 16384, + 368, + 366080, + 5696, + 294912, + 6460, + 366080, + 5696, + 8192, + 380, + 384000, + 364, + 622592, + 8296, + 564224, + 7396, + 359936, + 4004, + 700416, + 6276, + 7168, + 372, + 1648640, + 6952, + 1498624, + 4620, + 38912, + 360, + 6656, + 396, + 8255488, + 5060, + 7553024, + 5084, + 8255488, + 5060, + 8048640, + 8684, + 4229120, + 7476, + 4243456, + 9716, + 57344, + 372, + 483840, + 4016, + 484352, + 4468, + 20480, + 364, + 6948352, + 8444, + 5271552, + 5800, + 9728, + 364, + 12800, + 376, + 273920, + 2708, + 114176, + 2116, + 256512, + 6212, + 186368, + 6428, + 1016320, + 3228, + 379904, + 7256, + 508928, + 6568, + 470528, + 5128, + 468480, + 3764, + 13023232, + 5424, + 12046336, + 7648, + 13023232, + 5424, + 23040, + 352, + 1604096, + 700, + 625664, + 708, + 608256, + 656, + 722944, + 3524, + 1263104, + 4232, + 243200, + 3632, + 60928, + 720, + 1249280, + 2216, + 233472, + 1212, + 110080, + 1104, + 1939456, + 2864, + 289792, + 1632, + 241664, + 2956, + 535040, + 3040, + 25088, + 688, + 38400, + 544, + 24576, + 1816, + 10240, + 600, + 10752, + 1516, + 68096, + 1056, + 75776, + 424, + 723968, + 2076, + 1162240, + 1976, + 117248, + 760, + 117248, + 3696, + 140800, + 892, + 998400, + 708, + 1829888, + 10068, + 3081216, + 10696, + 1305600, + 4820, + 172032, + 1524, + 7168, + 304, + 578048, + 2232, + 505856, + 2232, + 7168, + 288, + 149504, + 856, + 38400, + 464, + 196608, + 1268, + 198656, + 1268, + 752128, + 2188, + 799232, + 2188, + 164864, + 1912, + 197120, + 1912, + 261632, + 1552, + 259584, + 1552, + 601600, + 1372, + 583680, + 1372, + 19968, + 832, + 19968, + 832, + 375296, + 1556, + 373248, + 1556, + 44032, + 2192, + 44032, + 1696, + 148992, + 1272, + 148992, + 1272, + 71168, + 988, + 71168, + 988, + 108032, + 2516, + 96768, + 1772, + 1223680, + 3812, + 1895936, + 4020, + 560128, + 708, + 392192, + 656, + 1083904, + 2364, + 294400, + 1948, + 446464, + 1620, + 451072, + 1620, + 1251840, + 432, + 611840, + 5216, + 47104, + 620, + 53248, + 620, + 501760, + 3572, + 200192, + 3312, + 2404352, + 580, + 1298944, + 876, + 783360, + 772, + 111104, + 504, + 491008, + 748, + 580096, + 1784, + 6215680, + 696, + 1199616, + 1832, + 1252864, + 2000, + 314880, + 1076, + 346112, + 2008, + 11637248, + 2264, + 1553920, + 3336, + 311296, + 1268, + 259584, + 1652, + 1376256, + 2196, + 1782784, + 3148, + 516096, + 1248, + 1872896, + 3692, + 377856, + 316, + 96256, + 608, + 62464, + 804, + 338432, + 1500, + 296960, + 1512, + 396800, + 1652, + 329216, + 1424, + 859648, + 2168, + 2535424, + 3688, + 1282560, + 2192, + 4596736, + 5784, + 2210816, + 2420, + 139776, + 760, + 4002304, + 4776, + 4817920, + 3500, + 26624, + 352, + 488448, + 2188, + 1078272, + 5188, + 808448, + 5548, + 76288, + 1496, + 50688, + 688, + 603648, + 4856, + 600064, + 3928, + 49152, + 368, + 491008, + 3236, + 487936, + 3120, + 144896, + 2216, + 1013248, + 6708, + 805888, + 6448, + 114688, + 320, + 104448, + 328, + 103936, + 328, + 112128, + 320, + 113152, + 320, + 114688, + 320, + 110592, + 320, + 113664, + 320, + 136192, + 320, + 122880, + 320, + 110592, + 320, + 111616, + 324, + 113152, + 320, + 1485824, + 4928, + 690688, + 10996, + 737280, + 12228, + 108032, + 924, + 101888, + 740, + 6156288, + 4976, + 6376448, + 6200, + 548352, + 1492, + 441344, + 1168, + 1564672, + 8060, + 1538560, + 7084, + 169472, + 368, + 521216, + 4180, + 133632, + 2348, + 134144, + 2348, + 1046016, + 8576, + 1351680, + 4732, + 1823232, + 1872, + 829440, + 3820, + 781312, + 3720, + 5850112, + 10748, + 4831232, + 10408, + 119296, + 2012, + 118784, + 2012, + 19456, + 1652, + 9411584, + 320, + 9260032, + 320, + 367616, + 4564, + 360960, + 4372, + 69632, + 7804, + 68608, + 6724, + 1329152, + 7692, + 1319424, + 6936, + 2029568, + 3088, + 115200, + 4584, + 139776, + 5012, + 2570752, + 1576, + 43520, + 2792, + 42496, + 2792, + 842752, + 7988, + 2548224, + 11824, + 5488128, + 1760, + 260096, + 7020, + 706048, + 3612, + 740352, + 5040, + 16384, + 380, + 235520, + 2536, + 264704, + 2652, + 4364288, + 8256, + 4176896, + 6204, + 16559104, + 3220, + 107008, + 2052, + 1103872, + 3264, + 1098752, + 3056, + 1177600, + 3856, + 1028608, + 3404, + 663552, + 2212, + 665088, + 2396, + 140288, + 560, + 90112, + 2736, + 141824, + 1284, + 6045184, + 13232, + 4726784, + 12052, + 176640, + 4388, + 626688, + 3868, + 621568, + 3868, + 1908224, + 1820, + 704512, + 4976, + 700928, + 4584, + 2672128, + 7920, + 2396160, + 7872, + 4750848, + 4916, + 4597248, + 5928, + 345600, + 7092, + 318976, + 7204, + 31744, + 676, + 32256, + 676, + 593920, + 3824, + 615936, + 4292, + 1656320, + 9112, + 1626112, + 9324, + 177152, + 2020, + 5765632, + 5816, + 56320, + 2228, + 61952, + 2228, + 1814528, + 3612, + 6656, + 380, + 16896, + 456, + 31744, + 844, + 3265024, + 9080, + 4318720, + 11204, + 192512, + 784, + 188416, + 784, + 627200, + 11148, + 681472, + 11644, + 1456640, + 4156, + 306176, + 2064, + 305152, + 1908, + 2410496, + 9624, + 3928576, + 10028, + 3820544, + 9056, + 5166080, + 3392, + 417792, + 1840, + 17920, + 720, + 17920, + 720, + 732672, + 5100, + 832512, + 5676, + 1738752, + 4948, + 1936896, + 452, + 1940480, + 452, + 68608, + 3424, + 68608, + 3428, + 211456, + 4428, + 203776, + 4120, + 467456, + 3208, + 423936, + 4084, + 701952, + 5048, + 474624, + 5268, + 2202112, + 6132, + 136704, + 2432, + 136704, + 2432, + 10240, + 372, + 35840, + 824, + 35840, + 824, + 365568, + 5700, + 365568, + 6176, + 155648, + 2168, + 156160, + 2168, + 24064, + 1004, + 35840, + 1392, + 337408, + 4956, + 341504, + 4688, + 77312, + 5412, + 79360, + 6264, + 2067456, + 10360, + 435712, + 448, + 1226240, + 5600, + 1228800, + 5952, + 16384, + 324, + 16896, + 324, + 16896, + 324, + 16896, + 328, + 15872, + 332, + 16896, + 324, + 17920, + 324, + 16384, + 324, + 16896, + 324, + 16896, + 324, + 15872, + 332, + 16896, + 324, + 18432, + 324, + 99328, + 776, + 2295296, + 8784, + 1970176, + 7988, + 175104, + 7768, + 183808, + 8200, + 23552, + 1244, + 364032, + 4316, + 955904, + 6660, + 1570304, + 8804, + 1491968, + 8444, + 725504, + 528, + 729088, + 528, + 172544, + 928, + 411648, + 7312, + 294400, + 3532, + 313344, + 3416, + 48640, + 984, + 48128, + 984, + 48128, + 1760, + 160768, + 900, + 160768, + 900, + 3207680, + 2016, + 155136, + 4012, + 312320, + 4680, + 287232, + 2888, + 288768, + 2888, + 898560, + 4116, + 894464, + 4116, + 15360, + 364, + 2923520, + 6556, + 103936, + 2668, + 115200, + 4552, + 93696, + 920, + 87552, + 920, + 384512, + 1976, + 374784, + 1976, + 122368, + 2456, + 4463616, + 2788, + 1618432, + 1200, + 69632, + 1672, + 18432, + 328, + 23040, + 1268, + 13824, + 328, + 80384, + 2132, + 363008, + 5288, + 363520, + 5776, + 47616, + 2808, + 206848, + 1952, + 214016, + 2120, + 1050624, + 6560, + 1114112, + 7476, + 1883648, + 1708, + 710144, + 9276, + 937472, + 12088, + 3946496, + 10876, + 3973632, + 11776, + 6656, + 372, + 56832, + 2452, + 2269696, + 10188, + 300544, + 4128, + 299520, + 3920, + 1971712, + 7600, + 1007104, + 3108, + 9728, + 384, + 7168, + 364, + 32256, + 512, + 28672, + 512, + 640000, + 1636, + 24064, + 1976, + 272896, + 3096, + 167936, + 3860, + 1135616, + 4944, + 96768, + 1772, + 1086464, + 10516, + 1362944, + 7912, + 62976, + 656, + 63488, + 656, + 63488, + 656, + 115712, + 320, + 115200, + 320, + 895488, + 9612, + 11264, + 336, + 271360, + 2784, + 394240, + 9496, + 53760, + 784, + 360448, + 6288, + 84480, + 2488, + 588288, + 7708, + 724480, + 7052, + 2811392, + 12416, + 2999296, + 10636, + 34304, + 332, + 38400, + 336, + 38400, + 336, + 1101312, + 4140, + 1100288, + 4072, + 13824, + 332, + 13312, + 332, + 13824, + 332, + 12800, + 336, + 11776, + 372, + 13312, + 332, + 13312, + 332, + 13312, + 332, + 15360, + 332, + 13312, + 332, + 13824, + 332, + 12800, + 336, + 13312, + 332, + 13312, + 332, + 125952, + 3308, + 128000, + 3688, + 431616, + 2860, + 442880, + 3348, + 2013184, + 1400, + 660992, + 5236, + 1506816, + 5124, + 707584, + 3248, + 706560, + 3248, + 1534976, + 572, + 1537536, + 572, + 2013696, + 3344, + 2031616, + 3344, + 57856, + 2364, + 205824, + 1748, + 739328, + 1232, + 741376, + 1232, + 67584, + 1316, + 1430528, + 2832, + 429568, + 620, + 455680, + 620, + 1007616, + 5588, + 1282048, + 2624, + 1265152, + 2628, + 4728320, + 7148, + 4441600, + 6448, + 4735488, + 5152, + 3809280, + 5136, + 4013568, + 5852, + 97280, + 1332, + 978432, + 3564, + 72704, + 2504, + 28672, + 376, + 2288640, + 7400, + 2407936, + 7308, + 901632, + 8740, + 972288, + 9456, + 1052160, + 6812, + 1026560, + 6528, + 1321472, + 9780, + 837120, + 8460, + 288768, + 1108, + 308736, + 1108, + 1195520, + 1948, + 1198080, + 1948, + 181248, + 5368, + 144384, + 4900, + 776704, + 348, + 157696, + 5076, + 60928, + 444, + 60928, + 444, + 209920, + 5220, + 246784, + 756, + 246272, + 756, + 604672, + 8528, + 24064, + 564, + 24064, + 564, + 47104, + 556, + 44032, + 556, + 321536, + 2176, + 332288, + 2176, + 204288, + 2388, + 204800, + 2440, + 107008, + 912, + 82432, + 1448, + 87552, + 1996, + 89088, + 372, + 922112, + 4576, + 508928, + 1944, + 528896, + 1996, + 5450240, + 2776, + 3680768, + 15000, + 3721728, + 16696, + 845312, + 9152, + 3270656, + 4144, + 1602048, + 852, + 1606656, + 852, + 36864, + 564, + 39936, + 564, + 214016, + 3144, + 576000, + 4544, + 580096, + 4468, + 627200, + 6596, + 1623040, + 11196, + 1107456, + 9700, + 2272256, + 13208, + 2289152, + 13624, + 1189376, + 704, + 1203712, + 704, + 470528, + 6616, + 451584, + 5508, + 143360, + 1388, + 143360, + 1388, + 55296, + 2920, + 55808, + 2920, + 82944, + 2444, + 82944, + 2444, + 2862592, + 3168, + 7680, + 372, + 68096, + 1124, + 67584, + 1124, + 1022976, + 1240, + 193024, + 2660, + 193536, + 2660, + 2833408, + 1172, + 195072, + 1564, + 512000, + 2840, + 131072, + 3096, + 313344, + 2100, + 89088, + 2136, + 86016, + 2136, + 1243648, + 1840, + 1280512, + 1840, + 778752, + 1040, + 10240, + 388, + 420864, + 1660, + 3430400, + 5764, + 1161216, + 736, + 2591232, + 9460, + 1972224, + 8028, + 583168, + 6348, + 468992, + 6044, + 553472, + 4172, + 551424, + 3364, + 1433600, + 2712, + 677376, + 2552, + 1743872, + 5072, + 1784320, + 5540, + 1024512, + 2564, + 1110016, + 3572, + 5252096, + 11496, + 5855744, + 13532, + 18944, + 1000, + 12800, + 424, + 149504, + 512, + 9216, + 312, + 84480, + 1308, + 20992, + 992, + 17920, + 996, + 36352, + 1096, + 15872, + 996, + 1478144, + 1736, + 83968, + 432, + 1655296, + 2292, + 1654272, + 2200, + 604160, + 560, + 27136, + 2024, + 43520, + 656, + 21504, + 1316, + 26624, + 324, + 412160, + 2000, + 163840, + 724, + 155136, + 724, + 1257472, + 7584, + 1146368, + 3468, + 18944, + 324, + 2123264, + 5428, + 2144768, + 6080, + 57344, + 896, + 80384, + 1284, + 1655808, + 1172, + 260608, + 1280, + 908800, + 1356, + 532480, + 1196, + 46592, + 340, + 61440, + 300, + 50176, + 300, + 49664, + 300, + 50176, + 300, + 49152, + 300, + 48640, + 300, + 49664, + 300, + 49664, + 300, + 48640, + 300, + 49664, + 300, + 42496, + 340, + 46080, + 300, + 50176, + 300, + 44032, + 304, + 50176, + 300, + 43008, + 340, + 48128, + 300, + 38400, + 344, + 49664, + 300, + 43008, + 340, + 44032, + 340, + 54272, + 300, + 50176, + 300, + 44032, + 304, + 48128, + 300, + 43520, + 340, + 50176, + 300, + 49152, + 300, + 44032, + 304, + 44032, + 304, + 61440, + 300, + 52736, + 340, + 54272, + 300, + 46080, + 300, + 49664, + 300, + 36864, + 344, + 17920, + 308, + 16896, + 312, + 17920, + 308, + 17408, + 308, + 17920, + 308, + 17920, + 308, + 17920, + 308, + 17920, + 308, + 16896, + 312, + 17408, + 308, + 17920, + 308, + 18432, + 308, + 17920, + 308, + 17408, + 308, + 18432, + 308, + 17920, + 308, + 18432, + 308, + 19456, + 308, + 20480, + 308, + 18432, + 308, + 16384, + 312, + 20480, + 308, + 16384, + 312, + 17920, + 308, + 18432, + 308, + 18432, + 308, + 17408, + 308, + 19456, + 308, + 721408, + 1540, + 20518056, + 176, + 25554944, + 176, + 17408, + 1464, + 17408, + 1620, + 78848, + 296, + 118784, + 740, + 2226688, + 1360, + 2097664, + 1360, + 2452992, + 16100, + 2390528, + 15368, + 19825152, + 2436, + 536064, + 1252, + 12187136, + 1832, + 26112, + 2080, + 26112, + 2080, + 26112, + 2084, + 26112, + 2084, + 25088, + 1760, + 25600, + 2088, + 25088, + 2088, + 25088, + 1756, + 25088, + 2084, + 25088, + 2084, + 23552, + 2100, + 23552, + 2100, + 23552, + 2100, + 23552, + 2100, + 168960, + 1064, + 171520, + 1064, + 168960, + 1064, + 6656, + 372, + 7168, + 368, + 12288, + 704, + 14848, + 816, + 3638784, + 856, + 3638272, + 856, + 3700736, + 856, + 11264, + 484, + 68096, + 732, + 68096, + 732, + 68096, + 732, + 118272, + 924, + 933376, + 1352, + 933376, + 1352, + 942080, + 1352, + 683008, + 10132, + 768512, + 3312, + 768000, + 3312, + 230912, + 1488, + 200704, + 1876, + 148480, + 2048, + 391680, + 2204, + 391680, + 2204, + 395264, + 2204, + 13061632, + 620, + 10336768, + 620, + 5653504, + 2256, + 6656, + 348, + 7680, + 304, + 1251840, + 1980, + 796672, + 1984, + 812544, + 2324, + 8192, + 316, + 8704, + 304, + 181248, + 3020, + 252928, + 728, + 176128, + 2856, + 9728, + 356, + 174080, + 3208, + 10752, + 360, + 1075712, + 556, + 9216, + 360, + 150016, + 1260, + 993792, + 864, + 27648, + 300, + 9489920, + 900, + 7684608, + 900, + 7966720, + 1540, + 2586624, + 708, + 1241600, + 1180, + 1172992, + 1336, + 1838592, + 1196, + 10906624, + 2396, + 11145728, + 2580, + 31232, + 312, + 6656, + 360, + 10752, + 316, + 10240, + 316, + 8192, + 308, + 8192, + 308, + 9216, + 320, + 8704, + 312, + 460800, + 768, + 1172992, + 752, + 247808, + 1088, + 1645568, + 584, + 8704, + 308, + 391680, + 536, + 769536, + 1100, + 243200, + 8192, + 304, + 3034624, + 1732, + 8192, + 296, + 283648, + 424, + 8192, + 316, + 8704, + 316, + 6656, + 352, + 6656, + 360, + 19968, + 316, + 8192, + 304, + 9216, + 304, + 9216, + 300, + 8192, + 296, + 10752, + 308, + 26242048, + 2764, + 1180672, + 764, + 36864, + 592, + 522752, + 536, + 9728, + 304, + 128000, + 420, + 273920, + 300, + 26624, + 316, + 8704, + 312, + 1382912, + 3572, + 2391552, + 3368, + 1316864, + 3200, + 8192, + 312, + 8704, + 304, + 8192, + 316, + 636928, + 1956, + 251904, + 752, + 8192, + 312, + 35328, + 1368, + 811520, + 1276, + 306176, + 644, + 408576, + 1240, + 12288, + 316, + 102400, + 504, + 8192, + 308, + 2842112, + 1100, + 19456, + 300, + 32256, + 332, + 31744, + 316, + 9216, + 324, + 9728, + 324, + 14336, + 308, + 36352, + 560, + 9728, + 320, + 805888, + 912, + 221696, + 932, + 802304, + 592, + 19939840, + 3948, + 8192, + 304, + 8192, + 316, + 886784, + 3224, + 1123840, + 3024, + 8192, + 316, + 9216, + 308, + 8704, + 300, + 8704, + 308, + 719360, + 924, + 702464, + 972, + 13918208, + 4076, + 13918208, + 3972, + 257024, + 432, + 94720, + 600, + 1904640, + 1580, + 122880, + 1372, + 122368, + 1252, + 13563392, + 1720, + 4451328, + 2520, + 2031616, + 572, + 7577088, + 748, + 15872, + 636, + 10240, + 308, + 8704, + 308, + 9728, + 308, + 395776, + 872, + 8704, + 304, + 9728, + 300, + 240640, + 2288, + 1309184, + 3864, + 93696, + 292, + 93696, + 292, + 95232, + 292, + 635392, + 572, + 629248, + 572, + 629248, + 572, + 474624, + 3184, + 130560, + 2420, + 84480, + 3088, + 153088, + 3444, + 227840, + 3116, + 339456, + 1420, + 708096, + 5904, + 999936, + 7792, + 1446400, + 2340, + 1404928, + 2340, + 4345344, + 14076, + 4835328, + 15864, + 411136, + 1556, + 411648, + 1556, + 605696, + 1076, + 605184, + 1024, + 13824, + 808, + 183296, + 1680, + 185856, + 1680, + 347136, + 1428, + 141824, + 340, + 222720, + 344, + 721920, + 2112, + 4110336, + 1348, + 248832, + 3588, + 249344, + 3680, + 98816, + 2896, + 99328, + 3012, + 7753728, + 852, + 7665664, + 852, + 7665664, + 852, + 154112, + 892, + 155648, + 892, + 154112, + 892, + 457216, + 1660, + 133632, + 2716, + 137216, + 888, + 136704, + 888, + 136704, + 888, + 118272, + 1832, + 122368, + 736, + 135680, + 736, + 135680, + 736, + 63488, + 300, + 80384, + 572, + 81920, + 572, + 80384, + 572, + 104960, + 3084, + 166912, + 2416, + 14848, + 3508, + 18944, + 3576, + 267264, + 300, + 1542656, + 1364, + 765952, + 2124, + 23862784, + 2048, + 596480, + 2444, + 72704, + 404, + 72704, + 404, + 61440, + 404, + 129024, + 504, + 105984, + 540, + 108032, + 1736, + 28160, + 320, + 30720, + 320, + 26112, + 328, + 28160, + 324, + 28160, + 320, + 28160, + 324, + 29184, + 320, + 26112, + 328, + 28672, + 320, + 28672, + 320, + 26112, + 328, + 27136, + 320, + 28672, + 320, + 34304, + 320, + 28672, + 320, + 27648, + 320, + 27648, + 320, + 29184, + 320, + 26112, + 328, + 28672, + 320, + 27136, + 320, + 34304, + 320, + 29184, + 320, + 30720, + 320, + 28672, + 320, + 29184, + 320, + 28672, + 320, + 28672, + 320, + 2295296, + 928, + 2386432, + 928, + 561664, + 588, + 445952, + 708, + 577536, + 588, + 88064, + 308, + 88576, + 308, + 97792, + 308, + 81408, + 308, + 88064, + 308, + 77824, + 312, + 89088, + 308, + 97792, + 308, + 89088, + 308, + 83968, + 308, + 87040, + 308, + 84480, + 308, + 85504, + 308, + 81408, + 308, + 89600, + 308, + 110080, + 308, + 87552, + 308, + 110080, + 308, + 76288, + 312, + 84480, + 308, + 89600, + 308, + 83968, + 308, + 87552, + 308, + 88576, + 308, + 87040, + 308, + 76288, + 312, + 85504, + 308, + 77824, + 312, + 288768, + 2980, + 193536, + 8280, + 1096192, + 1232, + 1049088, + 992, + 1049088, + 888, + 4356608, + 2160, + 4356608, + 2056, + 2875904, + 2568, + 161792, + 316, + 127488, + 324, + 146432, + 316, + 148480, + 316, + 146432, + 316, + 144384, + 316, + 141312, + 316, + 148480, + 316, + 145920, + 316, + 129024, + 324, + 141312, + 316, + 182784, + 316, + 141824, + 320, + 142848, + 316, + 127488, + 324, + 146432, + 316, + 133632, + 316, + 161792, + 316, + 140288, + 316, + 144384, + 316, + 129024, + 324, + 133632, + 316, + 140288, + 316, + 141824, + 320, + 142848, + 316, + 145920, + 316, + 146432, + 316, + 182784, + 316, + 190464, + 1048, + 6645760, + 2612, + 7172608, + 1728, + 130048, + 5804, + 129536, + 3332, + 14091776, + 5592, + 13456896, + 7916, + 13585920, + 5256, + 671232, + 744, + 65536, + 5008, + 71168, + 4604, + 2784256, + 6712, + 339456, + 3816, + 709120, + 6720, + 1713152, + 6228, + 2441216, + 6552, + 2871296, + 6480, + 541184, + 5580, + 93696, + 2280, + 11535872, + 9976, + 473600, + 5696, + 386048, + 6460, + 800768, + 8296, + 953344, + 6276, + 2007040, + 6952, + 11059712, + 5060, + 10085888, + 5084, + 10799104, + 8684, + 5849600, + 9716, + 633344, + 4468, + 9155072, + 8444, + 327168, + 2708, + 235008, + 6428, + 1310720, + 3228, + 476160, + 7256, + 634368, + 5128, + 16174592, + 5424, + 15025152, + 7648, + 1963008, + 700, + 308224, + 3632, + 82944, + 720, + 1541632, + 2216, + 304640, + 1212, + 132608, + 1104, + 2478592, + 2864, + 383488, + 1632, + 302592, + 2956, + 29184, + 688, + 50176, + 544, + 30208, + 1816, + 12800, + 600, + 13312, + 1516, + 79872, + 1056, + 94720, + 424, + 148992, + 760, + 148992, + 3696, + 221696, + 892, + 225280, + 1524, + 8704, + 304, + 8192, + 288, + 188416, + 856, + 53760, + 464, + 1364480, + 2364, + 91648, + 500, + 1593856, + 432, + 2812416, + 580, + 135680, + 504, + 664064, + 328, + 626688, + 748, + 548864, + 1120, + 720896, + 1784, + 1544192, + 1832, + 1606144, + 2000, + 4137472, + 3300, + 7470592, + 2380, + 387584, + 1076, + 440320, + 2008, + 739840, + 1608, + 13512704, + 2264, + 1871360, + 3336, + 381440, + 1268, + 332288, + 1652, + 1762304, + 2196, + 214016, + 1252, + 2290176, + 3148, + 671232, + 1248, + 1467392, + 2232, + 80896, + 608, + 2438144, + 3692, + 489984, + 316, + 117760, + 608, + 437760, + 1500, + 377344, + 1512, + 175616, + 760, + 744448, + 3928, + 111616, + 320, + 112640, + 324, + 123904, + 320, + 113152, + 320, + 114176, + 320, + 114176, + 320, + 111616, + 320, + 116224, + 320, + 105472, + 328, + 114688, + 320, + 105472, + 328, + 137216, + 320, + 115712, + 320, + 882688, + 12228, + 155136, + 2348, + 144384, + 2012, + 23040, + 1652, + 89600, + 7804, + 161280, + 5012, + 754688, + 3868, + 34304, + 676, + 816128, + 11644, + 372736, + 1908, + 551424, + 5268, + 86016, + 6264, + 16896, + 332, + 17920, + 324, + 17920, + 324, + 18944, + 324, + 17920, + 324, + 18432, + 324, + 19968, + 324, + 17408, + 332, + 17920, + 324, + 17920, + 324, + 17920, + 324, + 17920, + 324, + 17920, + 328, + 241152, + 8200, + 919040, + 528, + 913408, + 528, + 371712, + 2888, + 1105920, + 4116, + 2182656, + 1708, + 1213440, + 12088, + 524288, + 9496, + 460800, + 6288, + 3119616, + 12416, + 47104, + 336, + 14848, + 332, + 16384, + 332, + 14848, + 332, + 13824, + 336, + 13824, + 336, + 14336, + 332, + 14336, + 332, + 14336, + 332, + 14848, + 332, + 14848, + 332, + 14848, + 332, + 14336, + 332, + 14336, + 332, + 913920, + 3248, + 2378240, + 3344, + 998912, + 1232, + 60416, + 556, + 233472, + 2388, + 4872192, + 16696, + 1746432, + 852, + 1432576, + 704, + 1444352, + 704, + 98304, + 2444, + 218112, + 2660, + 4998144, + 716, + 5272064, + 716, + 240128, + 1564, + 1604608, + 1840, + 1565696, + 1840, + 1565696, + 1840, + 1497088, + 736, + 22016, + 1000, + 14848, + 424, + 1531392, + 2684, + 188928, + 512, + 10240, + 312, + 97792, + 1308, + 24064, + 992, + 20480, + 996, + 44544, + 1096, + 18432, + 996, + 31744, + 2024, + 51712, + 656, + 25600, + 1316, + 35328, + 324, + 611328, + 1444, + 526848, + 2000, + 26112, + 324, + 7213568, + 1568, + 2115072, + 1172, + 316416, + 1280, + 646144, + 1196, + 1097216, + 1356, + 47104, + 300, + 50688, + 300, + 51200, + 300, + 51200, + 300, + 51200, + 300, + 45056, + 304, + 49664, + 300, + 47104, + 300, + 51200, + 300, + 49664, + 300, + 50688, + 300, + 62464, + 300, + 51200, + 300, + 50688, + 300, + 50688, + 300, + 49664, + 300, + 55296, + 300, + 45056, + 304, + 51200, + 300, + 45056, + 304, + 50688, + 300, + 55296, + 300, + 49664, + 300, + 51200, + 300, + 62464, + 300, + 51200, + 300, + 50688, + 300, + 45056, + 304, + 19456, + 308, + 19456, + 308, + 18944, + 308, + 19456, + 308, + 18944, + 308, + 18944, + 308, + 22016, + 308, + 22016, + 308, + 20992, + 308, + 18944, + 308, + 19456, + 308, + 18432, + 308, + 18944, + 308, + 19456, + 308, + 18944, + 308, + 19456, + 308, + 19456, + 308, + 17920, + 312, + 18944, + 308, + 18432, + 308, + 19456, + 308, + 17920, + 312, + 19456, + 308, + 17920, + 312, + 20992, + 308, + 19456, + 308, + 18944, + 308, + 17920, + 312, + 910848, + 1540, + 22551712, + 176, + 98816, + 296, + 139264, + 740, + 2679296, + 1360, + 2817024, + 1360, + 23356416, + 2436, + 650752, + 1252, + 14530048, + 1832, + 29696, + 2080, + 29184, + 2084, + 26624, + 2100, + 13312, + 484, + 73728, + 732, + 73728, + 732, + 74240, + 732, + 143872, + 924, + 303104, + 1488, + 12712448, + 620, + 7215616, + 2256, + 9216, + 304, + 1687552, + 1980, + 1063424, + 1984, + 1082880, + 2324, + 9728, + 316, + 10752, + 304, + 349696, + 728, + 1405440, + 556, + 169984, + 1260, + 1175552, + 864, + 31744, + 300, + 10212352, + 900, + 9414656, + 1540, + 3118080, + 708, + 1555456, + 1180, + 1391616, + 1336, + 2229760, + 1196, + 12569600, + 2396, + 35328, + 312, + 12288, + 316, + 12800, + 316, + 9216, + 308, + 9216, + 308, + 10240, + 320, + 10240, + 312, + 1125376, + 1128, + 547328, + 768, + 1424384, + 752, + 295424, + 1088, + 1996288, + 584, + 10752, + 308, + 486912, + 536, + 1000960, + 1100, + 334336, + 9216, + 304, + 9728, + 296, + 338944, + 424, + 9216, + 316, + 10240, + 316, + 22528, + 316, + 9216, + 304, + 10752, + 304, + 10752, + 300, + 9216, + 296, + 12800, + 308, + 2764, + 1433600, + 764, + 642048, + 536, + 314880, + 300, + 10240, + 312, + 1701888, + 3200, + 3041280, + 3368, + 1785344, + 3572, + 9216, + 312, + 10240, + 304, + 9728, + 316, + 867840, + 1948, + 300544, + 752, + 10240, + 312, + 41984, + 1368, + 932352, + 1276, + 345600, + 644, + 517120, + 1240, + 15360, + 316, + 111104, + 504, + 9216, + 308, + 3349504, + 1100, + 24576, + 300, + 36864, + 332, + 36352, + 316, + 10752, + 324, + 10752, + 324, + 16896, + 308, + 41472, + 560, + 11264, + 320, + 950272, + 912, + 260608, + 932, + 989184, + 592, + 24750080, + 3948, + 9216, + 304, + 9216, + 316, + 917504, + 3224, + 1547776, + 3024, + 9216, + 316, + 10752, + 308, + 10752, + 300, + 9728, + 308, + 872448, + 924, + 814592, + 972, + 16530944, + 4076, + 16530944, + 3972, + 290304, + 432, + 111616, + 600, + 2162688, + 1580, + 15892480, + 1720, + 5285888, + 2520, + 2543616, + 572, + 8998912, + 748, + 18944, + 636, + 10240, + 308, + 11776, + 308, + 11264, + 308, + 480256, + 872, + 10240, + 304, + 11264, + 300, + 267264, + 2288, + 108544, + 292, + 107008, + 292, + 107008, + 292, + 841728, + 572, + 847872, + 572, + 842240, + 572, + 219136, + 304, + 105984, + 3088, + 167424, + 2420, + 292352, + 3116, + 195584, + 3444, + 1740288, + 2340, + 1792000, + 2340, + 5146624, + 1348, + 176640, + 892, + 174592, + 892, + 174592, + 892, + 611840, + 1660, + 154112, + 888, + 155648, + 888, + 154112, + 888, + 197632, + 1832, + 301609, + 338048, + 64512, + 135, + 16384, + 3170304, + 1474560, + 1474560, + 16384, + 3170304, + 1024, + 1024, + 4096, + 77728, + 77728, + 4669, + 1224608, + 1209752, + 115616, + 76696, + 76704, + 45472, + 75680, + 75680, + 45472, + 79264, + 79264, + 45984, + 80288, + 80288, + 46488, + 74144, + 74144, + 74136, + 74144, + 44960, + 77728, + 77728, + 45984, + 77728, + 77728, + 75168, + 75168, + 76704, + 76704, + 45472, + 79264, + 79264, + 79256, + 79264, + 45984, + 76704, + 76696, + 78752, + 78752, + 45984, + 77216, + 77216, + 45472, + 67488, + 67488, + 42912, + 66976, + 66976, + 42912, + 75680, + 75680, + 75680, + 75672, + 1056664, + 75680, + 75680, + 45472, + 77728, + 77728, + 45472, + 77728, + 77720, + 45976, + 76704, + 76704, + 45472, + 76696, + 76704, + 45984, + 54176, + 76192, + 76192, + 77208, + 77216, + 44960, + 77216, + 77216, + 76704, + 76704, + 77216, + 77216, + 76192, + 76192, + 44960, + 75168, + 75168, + 45472, + 77208, + 77216, + 4662, + 6534, + 63904, + 63904, + 42400, + 63904, + 63904, + 42400, + 3695719, + 3878410, + 1985867, + 2373000, + 174959, + 177414, + 143754, + 145419, + 162331, + 164347, + 154427, + 156245, + 44859, + 85862, + 86178, + 49091, + 77728, + 395314, + 1, + 95648, + 99744, + 76704, + 45472, + 75672, + 45472, + 79264, + 45984, + 80288, + 46496, + 74144, + 74144, + 44960, + 77728, + 45984, + 77720, + 75160, + 76696, + 45472, + 79264, + 79264, + 45984, + 76696, + 78752, + 45976, + 77208, + 45472, + 67488, + 42904, + 66976, + 42912, + 75672, + 75680, + 812440, + 75672, + 45472, + 77728, + 45472, + 77728, + 45984, + 76704, + 45472, + 76696, + 45984, + 83352, + 54176, + 76184, + 77208, + 44960, + 77216, + 76704, + 77216, + 76192, + 44952, + 75168, + 45472, + 77216, + 4662, + 63904, + 42400, + 63904, + 42392, + 92576, + 12704, + 12192, + 67584, + 1477720, + 7680, + 7680, + 962048, + 958976, + 6480, + 34390, + 136606, + 136606, + 156118, + 556304, + 556304, + 556304, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 8774, + 8774, + 8774, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 136606, + 556304, + 556304, + 556304, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 8774, + 2560, + 1024, + 15360, + 10752, + 2560, + 12288, + 52736, + 6656, + 3072, + 8582, + 3, + 16777270, + 4606392, + 70144, + 808, + 1233, + 2222, + 2090, + 1120, + 1317, + 2038, + 2574, + 1544, + 1215, + 1277, + 2053, + 2088, + 1560, + 1815, + 2177, + 1483, + 846, + 1590, + 2724, + 1676, + 2430, + 1197, + 1429, + 1310, + 1873, + 1914, + 13868, + 8116, + 5632, + 11423, + 78336, + 6996, + 5120, + 1151, + 1848, + 1898, + 1137, + 1802, + 2593, + 4506, + 2839, + 410, + 1093, + 610, + 848, + 422, + 12109, + 5756, + 2092, + 5260, + 3584, + 5120, + 2620, + 80896, + 4680, + 3584, + 229, + 12800, + 592, + 1963, + 1068, + 1080, + 701, + 369, + 711, + 1485, + 540, + 613, + 3148, + 1390, + 2432, + 1488, + 1282, + 711, + 531, + 682, + 468, + 3728, + 9216, + 15256, + 152064, + 3280, + 8192, + 1219, + 2204, + 382, + 1470, + 734, + 347, + 2381, + 370, + 1069, + 832, + 1943, + 11026, + 1535, + 714, + 17920, + 11776, + 1141, + 1029, + 610, + 384, + 141662, + 8016, + 13824, + 29602, + 176128, + 7380, + 11776, + 22718, + 1636, + 2557, + 2804, + 1756, + 1223, + 7091, + 6746, + 1323, + 1139, + 5106, + 1825, + 1624, + 15593, + 2462, + 1932, + 2563, + 1575, + 3258, + 1591, + 1921, + 2920, + 2226, + 20053, + 10426, + 894, + 4608, + 7152, + 78848, + 814, + 4096, + 1050, + 2221, + 5322, + 858, + 779, + 5310, + 1861, + 4670, + 6144, + 17152, + 17920, + 4106, + 5632, + 1200, + 1200, + 1192, + 1204, + 3594, + 1206, + 1192, + 1131, + 1131, + 1123, + 1135, + 2313, + 1137, + 1123, + 8508, + 40057, + 1648, + 15872, + 20463, + 1062, + 7168, + 14398, + 2560, + 972, + 6144, + 1022, + 918, + 1398, + 1737, + 1445, + 1185, + 747, + 1218, + 1307, + 712, + 1331, + 1022, + 1277, + 43151, + 4245, + 3898, + 9216, + 25149, + 55808, + 3496, + 8192, + 2351, + 2054, + 660, + 248, + 321, + 3578, + 1242, + 1770, + 2523, + 2706, + 2691, + 2270, + 1902, + 1276, + 476, + 34272, + 408, + 4096, + 3977, + 2560, + 396, + 3584, + 2214, + 10719, + 751, + 427, + 1150, + 796, + 4968, + 37376, + 63654, + 79360, + 4368, + 28160, + 10240, + 27648, + 5063, + 2292, + 712, + 5480, + 2769, + 446, + 218, + 526, + 3584, + 2800, + 44032, + 504, + 3584, + 22016, + 137, + 252, + 181, + 17920, + 5966, + 164860, + 489984, + 14848, + 5366, + 951, + 770, + 9728, + 12213, + 23982, + 11079, + 567, + 54687, + 3011, + 7220, + 13312, + 23306, + 66560, + 6424, + 11264, + 42483, + 16946, + 453, + 49790, + 5766, + 3584, + 2653, + 85504, + 5062, + 3584, + 2755, + 311, + 879, + 1004, + 717, + 2301, + 2009, + 540, + 1537, + 836, + 1365, + 510, + 488, + 5025, + 651, + 11264, + 2194, + 1402, + 1224, + 1576, + 868, + 1592, + 384, + 1468, + 1556, + 1530, + 1736, + 16622, + 75264, + 9216, + 1732, + 1176, + 1014, + 1324, + 760, + 1240, + 358, + 1180, + 1234, + 1180, + 1198, + 27598, + 781, + 3102, + 2192, + 3130, + 2135, + 3091, + 389, + 3053, + 3160, + 3137, + 3144, + 3051, + 1626, + 1712, + 1695, + 1711, + 1564, + 1326, + 772, + 1492, + 2048, + 21039, + 6740, + 16384, + 28156, + 64512, + 6210, + 13312, + 4208, + 607, + 4161, + 2886, + 1025, + 555, + 377, + 1274, + 663, + 490, + 2004, + 1078, + 1402, + 4082, + 1459, + 2770, + 1100, + 663, + 757, + 654, + 746, + 1052, + 760, + 2089, + 636, + 1394, + 640, + 10752, + 1314, + 20594, + 5772, + 10752, + 13349, + 81408, + 5012, + 9216, + 838, + 2078, + 548, + 2218, + 913, + 945, + 962, + 1775, + 909, + 931, + 1491, + 47126, + 4108, + 6656, + 12750, + 78848, + 3694, + 6144, + 2672, + 3062, + 94720, + 949, + 62743, + 1154, + 5120, + 7501, + 2560, + 1064, + 4608, + 8826, + 25358, + 1396, + 1332, + 22025, + 370, + 7680, + 11953, + 12800, + 330, + 6656, + 1408, + 2046, + 2749, + 1158, + 1051, + 1078, + 2763, + 11286, + 1226, + 1220, + 1221, + 1604, + 6656, + 7379, + 67584, + 1464, + 5632, + 729, + 1129, + 645, + 3054, + 838, + 394, + 5120, + 4621, + 64512, + 392, + 4608, + 592, + 645, + 471, + 1248, + 7168, + 6613, + 81920, + 1188, + 6144, + 139, + 1084, + 1204, + 1082, + 645, + 1928, + 4192, + 18369, + 4979, + 7110, + 1390, + 6656, + 11429, + 78848, + 1310, + 6144, + 1120, + 805, + 5314, + 2613, + 1016, + 1097, + 591, + 3211, + 2542, + 4273, + 344, + 402, + 1584, + 408, + 1341, + 414, + 222486, + 65, + 74064, + 22528, + 22528, + 133, + 966656, + 966656, + 4176, + 44632, + 2560, + 1024, + 13824, + 9728, + 2560, + 11264, + 45568, + 6656, + 3072, + 4848952, + 4669136, + 10976, + 10976, + 11520, + 10976, + 11488, + 12288, + 13248, + 12800, + 13200, + 12720, + 9280, + 9504, + 9856, + 10064, + 9792, + 12304, + 12256, + 12336, + 12384, + 10976, + 12288, + 10224, + 10608, + 9472, + 10240, + 35808, + 36672, + 36656, + 37296, + 36672, + 37472, + 80896, + 70000, + 80896, + 70000, + 916684, + 866652, + 653588, + 649244, + 189124, + 182112, + 182096, + 189264, + 183276, + 188976, + 186728, + 182208, + 180452, + 188932, + 183412, + 184020, + 167620, + 414772, + 410464, + 415776, + 410988, + 10992, + 13552, + 17760, + 1330156, + 1297136, + 1094912, + 1133324, + 963568, + 1056136, + 1723352, + 809512, + 857200, + 822568, + 219524, + 227628, + 227684, + 229412, + 7216, + 6352, + 6672, + 6672, + 7232, + 7216, + 6336, + 5168, + 4320, + 5200, + 4640, + 5168, + 5168, + 4304, + 245572, + 229444, + 226704, + 224248, + 445180, + 383780, + 452056, + 392232, + 448368, + 451860, + 448788, + 455620, + 262288, + 276064, + 270728, + 281096, + 26432, + 26544, + 23440, + 35888, + 36032, + 31760, + 794216, + 793256, + 577340, + 23408, + 23440, + 25024, + 23440, + 25024, + 31712, + 31776, + 33344, + 31808, + 33360, + 667232, + 5600, + 12896, + 672300, + 611212, + 345208, + 611556, + 720012, + 631992, + 580168, + 576004, + 643852, + 313856, + 235848, + 241972, + 333636, + 341072, + 332036, + 338776, + 363200, + 316440, + 331128, + 338140, + 330012, + 65, + 57948, + 36336, + 36816, + 36656, + 876784, + 879640, + 9248, + 8384, + 8368, + 8704, + 9232, + 9248, + 8368, + 6192, + 5328, + 5344, + 5648, + 5280, + 6192, + 5312, + 84241, + 140748, + 154188, + 1805996, + 229912, + 228504, + 271648, + 250668, + 263504, + 269048, + 271832, + 249924, + 266156, + 272460, + 219644, + 207484, + 208428, + 138196, + 143448, + 136176, + 139324, + 143684, + 135328, + 139800, + 140268, + 141608, + 159464, + 140808, + 136228, + 211780, + 66660, + 75340, + 77384, + 76356, + 76352, + 76084, + 75832, + 76104, + 74244, + 74476, + 69916, + 68464, + 71600, + 82744, + 75980, + 70896, + 26040, + 26489, + 29779, + 43318, + 11056, + 12400, + 10032, + 573308, + 40264, + 5680, + 6512, + 214808, + 12896, + 14432, + 10656, + 304568, + 41584, + 38480, + 6528, + 7728, + 327420, + 393764, + 386264, + 117092, + 327516, + 13457192, + 12598388, + 5083240, + 27652, + 9533888, + 9749256, + 840752, + 291356, + 271860, + 8704, + 290236, + 9214528, + 21402208, + 14439388, + 12875900, + 23648676, + 16246936, + 12004804, + 301876, + 78272, + 272840, + 304076, + 309956, + 306076, + 298668, + 295152, + 1422772, + 1377980, + 1462828, + 75160, + 69316, + 206612, + 472216, + 419976, + 336672, + 413712, + 94412, + 99464, + 74520, + 76972, + 74200, + 76300, + 78136, + 76184, + 78756, + 74944, + 73820, + 76080, + 77632, + 73660, + 77284, + 73352, + 13312, + 11056, + 12384, + 17760, + 12288, + 202428, + 173700, + 173080, + 596924, + 581228, + 925736, + 914092, + 509768, + 878372, + 816540, + 523052, + 324448, + 351908, + 1690384, + 1383320, + 441372, + 941172, + 439396, + 448756, + 2454648, + 62944, + 65392, + 59024, + 89456, + 95488, + 84080, + 57936, + 59952, + 60752, + 63296, + 61024, + 81728, + 85360, + 86256, + 90736, + 84848, + 18214352, + 17064020, + 944436, + 932572, + 997912, + 987736, + 25216, + 32512, + 24672, + 20448, + 37952, + 19904, + 26112, + 24784, + 28912, + 24832, + 29200, + 21504, + 19600, + 23120, + 19760, + 23008, + 69232, + 73216, + 65456, + 72192, + 95840, + 67328, + 90336, + 102400, + 64656, + 66464, + 65328, + 68848, + 64400, + 89856, + 92032, + 90288, + 98256, + 89456, + 18087936, + 5680, + 12896, + 257052, + 71000, + 839004, + 768964, + 68260, + 60480, + 2576, + 1110940, + 1093272, + 826840, + 884748, + 254448, + 244240, + 225940, + 252300, + 243284, + 211316, + 223308, + 163324, + 166940, + 163128, + 165288, + 164360, + 157596, + 161736, + 160860, + 166668, + 155584, + 159576, + 158924, + 229848, + 5168, + 5168, + 5232, + 6160, + 5120, + 5552, + 5184, + 5184, + 5200, + 5184, + 6128, + 5184, + 7232, + 6272, + 6304, + 6272, + 5952, + 6528, + 5376, + 7168, + 5360, + 5376, + 6112, + 5600, + 6112, + 5168, + 7104, + 7648, + 6656, + 8704, + 7280, + 6608, + 7008, + 6912, + 6912, + 122784, + 84776, + 14542540, + 13827216, + 13760848, + 13697012, + 3869801, + 2964, + 1555440, + 12958, + 16, + 6686208, + 3592, + 3936, + 358328, + 3912, + 788768, + 354016, + 3944, + 25675936, + 3368788, + 1000444, + 2475780, + 2470724, + 2944004, + 93962, + 398424, + 696279, + 278216, + 278216, + 95294, + 24285, + 76827, + 75202, + 79881, + 91664, + 73901, + 63945, + 94637, + 47381, + 76837, + 75209, + 78636, + 87270, + 73848, + 63938, + 123207, + 170846, + 163655, + 167149, + 190382, + 153710, + 181388, + 192658, + 161077, + 155948, + 173135, + 167996, + 175365, + 175142, + 193292, + 176173, + 208311, + 184305, + 152003, + 166960, + 191011, + 172588, + 179346, + 181738, + 193635, + 172483, + 173778, + 196545, + 168973, + 133549, + 137150, + 133821, + 135595, + 137643, + 133803, + 135918, + 138784, + 134220, + 134548, + 133996, + 136312, + 134303, + 140091, + 139146, + 134894, + 142998, + 136681, + 134007, + 136206, + 137845, + 134156, + 135178, + 137714, + 139707, + 138470, + 136571, + 141663, + 136969, + 820959, + 837651, + 841715, + 852003, + 858806, + 815642, + 836702, + 862614, + 816732, + 829627, + 824255, + 838193, + 831598, + 855467, + 849236, + 832468, + 890837, + 856899, + 821074, + 813929, + 851738, + 822220, + 834980, + 854788, + 859328, + 857391, + 831954, + 870512, + 851084, + 60199, + 54388, + 55658, + 55914, + 55229, + 54883, + 55844, + 56461, + 55369, + 55528, + 55209, + 55065, + 55780, + 54999, + 55374, + 55329, + 58244, + 55876, + 55263, + 54598, + 55896, + 55350, + 55013, + 55676, + 55948, + 55812, + 57234, + 56767, + 55447, + 51921, + 50525, + 50600, + 51372, + 50556, + 50003, + 50750, + 51665, + 52094, + 50200, + 50176, + 50753, + 50648, + 50991, + 51055, + 50490, + 51838, + 50686, + 50748, + 49804, + 50825, + 50376, + 50348, + 50585, + 50627, + 50823, + 52845, + 50831, + 50655, + 80529, + 1180712, + 1177049, + 1166899, + 1170755, + 1174183, + 1156877, + 1163286, + 1172109, + 1175470, + 1161012, + 1156568, + 1165993, + 1158947, + 1176781, + 1181107, + 1161986, + 1193441, + 1171979, + 1157102, + 1168877, + 1180549, + 1160990, + 1163072, + 1172432, + 1180765, + 1171788, + 1165080, + 1184896, + 1166673, + 234710, + 68593, + 17013, + 29907, + 43386, + 230849, + 219577, + 60300, + 15070, + 29907, + 39939, + 1586, + 77849, + 19410, + 610, + 32573, + 1584, + 2409, + 41256, + 10954, + 610, + 19250, + 975360, + 18432, + 286208, + 9728, + 2546176, + 103936, + 2139136, + 65536, + 257024, + 7680, + 321, + 26605, + 8686, + 8762, + 30720, + 7702016, + 199168, + 210432, + 516, + 4, + 117416, + 116608, + 1462, + 20071, + 1392, + 294680, + 9766, + 162, + 22020, + 1527, + 82, + 2560, + 2560, + 147456, + 812544, + 8017408, + 7378944, + 40310, + 40310, + 33170, + 33170, + 177806, + 177806, + 2589632, + 7390720, + 46287, + 48350, + 1618106, + 912766, + 1331040, + 528404, + 1322024, + 404904, + 893472, + 377968, + 429472, + 7393280, + 188278, + 3692612, + 16629137, + 1523154, + 1562816, + 127488, + 319, + 1346, + 8685, + 5632, + 5120, + 162, + 167, + 765, + 977, + 565, + 766, + 368, + 1136, + 883, + 1064, + 417, + 354, + 354, + 354, + 529, + 612, + 791, + 2085, + 406, + 406, + 542, + 595, + 747, + 1881, + 354, + 354, + 354, + 529, + 529, + 612, + 612, + 791, + 791, + 2085, + 2085, + 642, + 1232, + 2946, + 2946, + 4048, + 4901, + 8060, + 22343, + 2851, + 2851, + 3886, + 4751, + 7782, + 21801, + 2946, + 2946, + 4048, + 4901, + 8060, + 22343, + 569, + 375, + 977, + 977, + 1252, + 1826, + 2338, + 5709, + 1010, + 1010, + 1270, + 1775, + 2227, + 5481, + 977, + 977, + 1252, + 1826, + 2338, + 5709, + 893, + 569, + 569, + 689, + 911, + 1250, + 2924, + 526, + 526, + 736, + 864, + 1199, + 2811, + 569, + 569, + 689, + 911, + 1250, + 2924, + 741, + 175, + 184, + 583, + 1185, + 508, + 496, + 434, + 857, + 654, + 835, + 353, + 547, + 1357, + 324, + 618, + 502, + 4, + 1648, + 1624, + 8000, + 861, + 1011, + 991, + 1005, + 1058, + 945, + 963, + 939, + 945, + 945, + 905, + 947, + 914, + 930, + 877, + 897, + 884, + 912, + 901, + 897, + 906, + 900, + 885, + 891, + 906, + 906, + 866, + 872, + 928, + 904, + 886, + 931, + 881, + 857, + 897, + 877, + 904, + 889, + 901, + 885, + 839, + 866, + 892, + 908, + 920, + 893, + 901, + 933, + 874, + 880, + 872, + 872, + 896, + 877, + 873, + 869, + 868, + 826, + 820, + 823, + 814, + 817, + 802, + 846, + 1009, + 1003, + 988, + 823, + 829, + 808, + 814, + 796, + 805, + 832, + 838, + 862, + 838, + 829, + 803, + 799, + 808, + 827, + 823, + 823, + 862, + 850, + 838, + 841, + 847, + 829, + 838, + 814, + 799, + 808, + 790, + 814, + 835, + 817, + 835, + 823, + 844, + 838, + 814, + 817, + 808, + 811, + 832, + 826, + 826, + 829, + 823, + 844, + 823, + 814, + 829, + 832, + 841, + 855, + 832, + 823, + 850, + 814, + 820, + 823, + 826, + 829, + 829, + 876, + 817, + 835, + 814, + 817, + 826, + 847, + 826, + 826, + 820, + 835, + 796, + 793, + 859, + 799, + 796, + 864, + 832, + 832, + 787, + 808, + 885, + 891, + 882, + 878, + 1002, + 1002, + 1017, + 1005, + 1003, + 1015, + 1037, + 1004, + 1036, + 1038, + 1011, + 1077, + 1068, + 1053, + 1005, + 1001, + 1033, + 1038, + 1050, + 1035, + 1006, + 1048, + 1057, + 1057, + 1050, + 1038, + 1017, + 1017, + 1020, + 1018, + 948, + 1035, + 1037, + 1033, + 981, + 972, + 1036, + 1042, + 1054, + 1018, + 964, + 998, + 991, + 976, + 982, + 976, + 970, + 979, + 976, + 1024, + 952, + 955, + 1018, + 973, + 958, + 1007, + 921, + 1050, + 961, + 975, + 981, + 954, + 958, + 1000, + 979, + 981, + 964, + 973, + 970, + 964, + 968, + 1010, + 1012, + 1027, + 1046, + 1012, + 1004, + 977, + 967, + 976, + 999, + 1005, + 1018, + 1012, + 982, + 974, + 972, + 1001, + 998, + 998, + 968, + 971, + 1022, + 1016, + 995, + 977, + 1002, + 1008, + 1026, + 1006, + 1011, + 1036, + 990, + 999, + 1006, + 966, + 1020, + 975, + 929, + 962, + 953, + 1016, + 1048, + 1000, + 1032, + 1000, + 1032, + 1008, + 1040, + 982, + 991, + 988, + 982, + 983, + 998, + 1016, + 979, + 976, + 987, + 1013, + 1025, + 1009, + 1003, + 974, + 951, + 978, + 969, + 954, + 975, + 975, + 969, + 969, + 956, + 972, + 974, + 1001, + 1001, + 1017, + 996, + 1000, + 1024, + 1009, + 987, + 984, + 993, + 1023, + 1053, + 986, + 1011, + 1030, + 1011, + 1030, + 991, + 991, + 975, + 1009, + 987, + 954, + 978, + 969, + 966, + 949, + 982, + 974, + 956, + 989, + 989, + 982, + 956, + 956, + 941, + 956, + 986, + 974, + 920, + 980, + 1056, + 1056, + 1052, + 1009, + 1014, + 1020, + 1008, + 999, + 998, + 1020, + 984, + 932, + 929, + 953, + 967, + 920, + 932, + 920, + 940, + 973, + 962, + 1022, + 1008, + 944, + 957, + 1045, + 953, + 952, + 943, + 952, + 973, + 952, + 962, + 938, + 981, + 984, + 984, + 998, + 975, + 818, + 470294, + 1202, + 1181, + 1045, + 1135, + 1019, + 981, + 1153, + 1019, + 962, + 851, + 961, + 1206, + 1011, + 913, + 830, + 1164, + 865, + 1232, + 898, + 991, + 970, + 1206, + 1168, + 1169, + 1214, + 982, + 937, + 924, + 973, + 937, + 956, + 946, + 1030, + 1154, + 1048, + 978, + 1011, + 1074, + 837, + 1116, + 1020, + 1000, + 969, + 1116, + 991, + 1159, + 1036, + 1014, + 912, + 1092, + 1067, + 988, + 998, + 1055, + 881, + 866, + 1019, + 1089, + 966, + 1024, + 1118, + 1114, + 923, + 925, + 959, + 961, + 1000, + 1206, + 821, + 991, + 824, + 929, + 979, + 1061, + 1156, + 1131, + 944, + 1183, + 995, + 1105, + 1022, + 983, + 1020, + 920, + 1039, + 954, + 1048, + 1042, + 1118, + 974, + 1243, + 1016, + 930, + 1030, + 1068, + 1130, + 938, + 981, + 1149, + 1074, + 959, + 956, + 919, + 941, + 950, + 1006, + 1020, + 913, + 1033, + 867, + 843, + 1149, + 957, + 1068, + 964, + 941, + 914, + 999, + 937, + 837, + 1000, + 1089, + 963, + 998, + 1022, + 1149, + 832, + 855, + 980, + 807, + 1062, + 938, + 947, + 979, + 1022, + 992, + 1030, + 998, + 1014, + 961, + 940, + 957, + 827, + 1153, + 866, + 1114, + 921, + 1012, + 944, + 1151, + 887, + 1060, + 937, + 912, + 1077, + 923, + 1037, + 1071, + 1192, + 986, + 985, + 968, + 994, + 1004, + 824, + 1176, + 990, + 1040, + 947, + 1062, + 1232, + 938, + 1148, + 1032, + 911, + 895, + 743, + 774, + 846, + 5877760, + 95104, + 504, + 1043968, + 53760, + 36, + 36, + 829, + 54230, + 45, + 45, + 811, + 52828, + 42, + 42, + 1055, + 166446, + 65, + 65, + 444, + 98700, + 53, + 53, + 444, + 98752, + 33, + 33, + 381, + 1288, + 36, + 36, + 6067, + 1517020, + 11222, + 20076, + 4034, + 10124, + 4510, + 4150, + 10500, + 3816, + 7532, + 2500, + 7060, + 3124, + 7660, + 2560, + 7612, + 23024, + 28740, + 9932, + 14572, + 6256, + 12140, + 124744, + 46912, + 64756, + 31, + 7177, + 995542, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 819516, + 6537, + 819516, + 30, + 7177, + 997498, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 819522, + 6537, + 819522, + 36, + 318, + 42996, + 357050, + 2242, + 6108, + 7442, + 4242, + 7500, + 3228, + 3686, + 52958, + 3754, + 7356, + 8924, + 2766, + 2846, + 2770, + 1479, + 2558, + 89110, + 6336, + 10140, + 8106, + 12492, + 17880, + 5428, + 5946, + 4008, + 1648, + 5276, + 3424, + 8372, + 6578, + 10812, + 8294, + 11572, + 3202, + 7772, + 37872, + 15974, + 16396, + 28690, + 53252, + 32834, + 20812, + 4288, + 10052, + 4746, + 7788, + 12934, + 19588, + 1154, + 1012, + 2764, + 7052, + 1008, + 690, + 3972, + 1060, + 1022, + 1128, + 692, + 3964, + 2100, + 1062, + 2306, + 6252, + 1416, + 962, + 972, + 1056, + 4500, + 1264, + 2870, + 7748, + 1992, + 1158, + 4676, + 1130, + 4612, + 1164, + 4684, + 1136, + 4636, + 1158, + 4668, + 1158, + 4700, + 1154, + 4660, + 1136, + 4644, + 1104, + 4564, + 1148, + 4652, + 1152, + 4692, + 1190, + 4764, + 1156, + 4692, + 1136, + 4628, + 1162, + 4692, + 1132, + 4620, + 1154, + 4684, + 1128, + 4668, + 1150, + 4660, + 3140, + 1202, + 2452, + 5604, + 5776, + 1546, + 1406, + 1120, + 700, + 3844, + 680, + 4012, + 1116, + 4532, + 7646, + 1316, + 1014, + 1128, + 2570, + 6876, + 1472, + 960, + 1032, + 1044, + 2572, + 1178, + 1080, + 4548, + 1180, + 1344, + 1010, + 1078, + 1114, + 1240, + 1806, + 5380, + 1680, + 5396, + 666, + 3940, + 1006, + 2326, + 6324, + 1144, + 4644, + 1356, + 1010, + 1028, + 6106, + 974, + 1126, + 1478, + 1058, + 4500, + 2694, + 6996, + 2652, + 6972, + 1162, + 3266, + 1176, + 1108, + 1842, + 1084, + 1208, + 1112, + 4580, + 1016, + 1182, + 7232, + 12444, + 31632, + 29344, + 29344, + 8156, + 7756, + 12784, + 17044, + 3426, + 7668, + 3952, + 584, + 39622, + 78064, + 2826, + 7496, + 6270, + 8332, + 110927, + 3108, + 8700, + 975476, + 500344, + 975476, + 35700, + 2230, + 6460, + 5792, + 10036, + 700038, + 5324, + 7326, + 4418, + 8124, + 2058, + 5276, + 3698, + 2314, + 6044, + 10572, + 105198, + 103572, + 68300, + 2554, + 7484, + 4156, + 10156, + 7744, + 4148, + 8660, + 5154, + 9460, + 3958, + 9700, + 70670, + 34596, + 4572, + 3716, + 9768, + 20532, + 1786, + 6036, + 26824, + 31580, + 3724, + 7516, + 4070, + 8156, + 11662, + 12916, + 11968, + 14052, + 13876, + 18172, + 15402, + 22036, + 9956, + 12724, + 10380, + 13964, + 8122, + 12612, + 12616, + 16692, + 4166, + 27662, + 73928, + 153148, + 34544, + 10586, + 34544, + 34544, + 10586, + 34544, + 34544, + 10586, + 34544, + 34544, + 34544, + 34544, + 34544, + 34544, + 34544, + 34544, + 34544, + 229, + 10586, + 229, + 4134, + 7628, + 4010, + 7148, + 60840, + 7160, + 11332, + 6450, + 9740, + 84218, + 118548, + 68062, + 134140, + 26432, + 9832, + 18844, + 2864, + 6574, + 12300, + 17868, + 27084, + 22396, + 27068, + 5378, + 9844, + 145968, + 156116, + 4588, + 8668, + 4754, + 93080, + 107772, + 65972, + 13482, + 80568, + 171806, + 5730, + 27262, + 19720, + 120372, + 28978, + 8198, + 15558, + 49800, + 14466, + 105144, + 20416, + 25830, + 88896, + 24836, + 55742, + 63380, + 8450, + 29398, + 25790, + 12086, + 137326, + 26092, + 56996, + 7526, + 12050, + 243776, + 56662, + 11166, + 23974, + 118782, + 111928, + 107186, + 45598, + 26536, + 19476, + 18622, + 266006, + 86868, + 35708, + 152552, + 19952, + 31048, + 82068, + 22124, + 89728, + 47188, + 98330, + 89444, + 98810, + 104296, + 1574382, + 94068, + 152526, + 205386, + 80412, + 216596, + 126054, + 38968, + 5028, + 66028, + 100404, + 144846, + 40530, + 35686, + 137064, + 88352, + 28582, + 8938, + 11452, + 20706, + 46182, + 44850, + 19038, + 10228, + 88788, + 72772, + 16954, + 143864, + 97254, + 254856, + 10430, + 16894, + 832958, + 24040, + 5732, + 106688, + 23304, + 9538, + 9602, + 8244, + 8322, + 76410, + 23248, + 12244, + 24678, + 24328, + 8714, + 16054, + 17254, + 8372, + 29516, + 142858, + 9088, + 61202, + 38408, + 111000, + 21148, + 6480, + 75332, + 15414, + 103226, + 24976, + 81708, + 85148, + 158182, + 53316, + 27596, + 13248, + 98472, + 10102, + 43146, + 58978, + 230698, + 55956, + 91872, + 32492, + 36630, + 26488, + 36130, + 19834, + 25730, + 18860, + 71780, + 44666, + 27150, + 6068, + 23790, + 61154, + 99100, + 6860, + 4858, + 31168, + 242920, + 75430, + 216056, + 103516, + 157736, + 207412, + 13974, + 15700, + 8942, + 11804, + 318550, + 364956, + 3200, + 8972, + 2388, + 4126, + 5912, + 12516, + 86462, + 76452, + 9070, + 790436, + 1176964, + 61436, + 2190, + 3682, + 3864, + 4182, + 3864, + 768, + 49, + 49, + 49, + 705, + 131728, + 47, + 47, + 705, + 135800, + 43838, + 5884, + 11804, + 60908, + 69412, + 58210, + 98652, + 31186, + 37644, + 3452, + 7972, + 26808, + 38398, + 3852, + 7828, + 1044, + 7892, + 13524, + 33988, + 3386, + 2208, + 25160, + 2982, + 2712, + 6404, + 176484, + 125868, + 51026, + 62572, + 29228, + 40564, + 12568, + 22628, + 19112, + 68176, + 60244, + 30092, + 40810, + 248286, + 551212, + 5276, + 6980, + 30894, + 31930, + 434302, + 98426, + 71644, + 2656, + 10542, + 13516, + 723666, + 83830, + 99418, + 97762, + 329418, + 273392, + 261692, + 37444, + 3174, + 4370, + 13582, + 45834, + 101928, + 19080, + 430184, + 82502, + 13446, + 2140, + 6166, + 87594, + 93928, + 2460, + 214348, + 2154, + 83726, + 35016, + 4186, + 4794, + 8618, + 307862, + 285242, + 64914, + 24424, + 23620, + 5292, + 8186, + 11886, + 33690, + 268356, + 110094, + 40642, + 230496, + 2380, + 5136, + 6788, + 95530, + 8470, + 13622, + 15068, + 33734, + 6066, + 116538, + 34764, + 6694, + 7100, + 3798, + 8272, + 3442, + 398670, + 136934, + 319876, + 28282, + 991868, + 15784, + 1014176, + 243844, + 526428, + 45578, + 3010, + 7756, + 15134, + 2678, + 18102, + 8926, + 10148, + 2818, + 8236, + 20190, + 20596, + 6955, + 1046848, + 369, + 1046848, + 369, + 12338, + 3113, + 91662, + 471312, + 76048, + 15032, + 3130, + 128374, + 530416, + 75288, + 16920, + 3096, + 139821, + 486344, + 75288, + 125728, + 89872, + 89144, + 90608, + 404752, + 1028, + 19667, + 28511, + 65288, + 11194, + 155192, + 315888, + 36472, + 316736, + 13916, + 3066, + 126310, + 401376, + 76048, + 12420, + 3066, + 115628, + 400656, + 75288, + 125728, + 89144, + 89872, + 404072, + 212, + 121440, + 2810, + 60778, + 155128, + 36472, + 54392, + 35424, + 9033, + 6668, + 117460, + 187392, + 36472, + 61632, + 404072, + 121440, + 10476, + 3114, + 87177, + 495376, + 73480, + 13106, + 3130, + 122503, + 501216, + 73512, + 19440, + 2716, + 191560, + 302464, + 11126, + 3093, + 89526, + 497424, + 73480, + 13024, + 3097, + 154115, + 498672, + 76784, + 16988, + 3097, + 190046, + 499184, + 76784, + 9802, + 3097, + 42986, + 499184, + 76784, + 11446, + 3315, + 140902, + 302296, + 36472, + 125728, + 90608, + 91936, + 101216, + 89888, + 90608, + 89888, + 89144, + 98496, + 60608, + 404752, + 1081, + 9697, + 2777, + 20667, + 138512, + 64168, + 14848, + 3049, + 132659, + 411120, + 89072, + 36472, + 92144, + 405488, + 256, + 19667, + 28511, + 65288, + 9311, + 166032, + 36472, + 316736, + 12590, + 3050, + 87645, + 271024, + 68264, + 14850, + 3050, + 153989, + 370968, + 73512, + 11362, + 3050, + 117277, + 370968, + 73512, + 36472, + 125728, + 92864, + 91936, + 92448, + 89872, + 79720, + 404072, + 256, + 9732, + 3046, + 84534, + 357856, + 76232, + 9782, + 3075, + 20816, + 131584, + 73480, + 5174, + 2939, + 12442, + 3114, + 92354, + 468752, + 73480, + 15038, + 3130, + 128291, + 529392, + 73512, + 17742, + 3097, + 176198, + 523248, + 76784, + 11729, + 3097, + 44389, + 522736, + 76784, + 36472, + 125728, + 90608, + 91936, + 89888, + 90608, + 80672, + 404752, + 1083, + 11897, + 2743, + 22579, + 131344, + 73480, + 16770, + 3049, + 144852, + 442864, + 89072, + 36472, + 92144, + 80880, + 405488, + 260, + 12717, + 3043, + 56912, + 318944, + 89072, + 19667, + 28511, + 2236928, + 2239488, + 48464, + 65288, + 11361, + 156656, + 10997, + 10224, + 8796, + 12249, + 8148, + 9369, + 8944, + 10400, + 494960, + 503664, + 473968, + 10758, + 12146, + 483184, + 163696, + 10046, + 10040, + 165232, + 8657, + 9915, + 71952, + 279024, + 60752, + 316400, + 36472, + 316736, + 1721576, + 16797, + 3050, + 162256, + 352024, + 73512, + 13277, + 3050, + 126428, + 352024, + 73512, + 36472, + 125728, + 91936, + 92448, + 89872, + 80672, + 404072, + 268, + 11656, + 3046, + 91773, + 388040, + 76232, + 11904, + 3075, + 22837, + 133392, + 73480, + 121440, + 12423, + 3114, + 92426, + 468752, + 73480, + 15026, + 3130, + 128070, + 529392, + 73512, + 19440, + 2716, + 191560, + 302464, + 13073, + 3093, + 94851, + 469264, + 73480, + 14946, + 3097, + 163489, + 470512, + 76784, + 18910, + 3097, + 199105, + 523248, + 76784, + 11725, + 3097, + 45051, + 522736, + 76784, + 11446, + 3315, + 140902, + 302296, + 36472, + 125728, + 90608, + 91936, + 101216, + 89888, + 90608] diff --git a/tests/fragmentation/tfragment_alloc.nim b/tests/fragmentation/tfragment_alloc.nim new file mode 100644 index 000000000..031588d27 --- /dev/null +++ b/tests/fragmentation/tfragment_alloc.nim @@ -0,0 +1,27 @@ + +discard """ + output: '''occupied ok: true +total ok: true''' +""" + +import strutils, data + +proc main = + var m = 0 + for i in 0..1000_000: + let size = sizes[i mod sizes.len] + let p = alloc(size) + if p == nil: + quit "could not serve request!" + dealloc p + # c_fprintf(stdout, "iteration: %ld size: %ld\n", i, size) + +main() + +let occ = getOccupiedMem() +let total = getTotalMem() + +# Current values on Win64: 824KiB / 106.191MiB + +echo "occupied ok: ", occ < 2 * 1024 * 1024 +echo "total ok: ", total < 120 * 1024 * 1024 diff --git a/tests/fragmentation/tfragment_gc.nim b/tests/fragmentation/tfragment_gc.nim new file mode 100644 index 000000000..1781f6610 --- /dev/null +++ b/tests/fragmentation/tfragment_gc.nim @@ -0,0 +1,30 @@ +discard """ + output: '''occupied ok: true +total ok: true''' +""" + +import strutils, data + +proc main = + var m = 0 + # Since the GC test is slower than the alloc test, we only iterate 100_000 times here: + for i in 0..100_000: + let size = sizes[i mod sizes.len] + let p = newString(size) + # c_fprintf(stdout, "iteration: %ld size: %ld\n", i, size) + +main() + +let occ = getOccupiedMem() +let total = getTotalMem() + +# Concrete values on Win64: 58.152MiB / 188.285MiB + +let occupiedOk = occ < 64 * 1024 * 1024 +if not occupiedOk: + echo "occupied ", formatSize(occ) +echo "occupied ok: ", occupiedOk +let totalOk = total < 210 * 1024 * 1024 +if not totalOk: + echo "total peak memory ", formatSize(total) +echo "total ok: ", totalOk diff --git a/tests/generics/toverloading_typedesc.nim b/tests/generics/toverloading_typedesc.nim index 5882640f2..94f4d860d 100644 --- a/tests/generics/toverloading_typedesc.nim +++ b/tests/generics/toverloading_typedesc.nim @@ -1,5 +1,6 @@ discard """ exitcode: 0 + disabled: '''true''' """ import moverloading_typedesc import tables diff --git a/tests/generics/treentranttypes.nim b/tests/generics/treentranttypes.nim index 9b4774e9b..2ef049ce2 100644 --- a/tests/generics/treentranttypes.nim +++ b/tests/generics/treentranttypes.nim @@ -1,6 +1,6 @@ discard """ output: ''' -(Field0: 10, Field1: (Field0: test, Field1: 1.2)) +(Field0: 10, Field1: (Field0: "test", Field1: 1.2)) 3x3 Matrix [[0.0, 2.0, 3.0], [2.0, 0.0, 5.0], [2.0, 0.0, 5.0]] 2x3 Matrix [[0.0, 2.0, 3.0], [2.0, 0.0, 5.0]] @@ -43,7 +43,7 @@ type Matrix*[M: static[int]; N: static[int]; T] = Vector[M, Vector[N, T]] - + proc arrayTest = # every kind of square matrix works just fine let mat_good: Matrix[3, 3, float] = [[0.0, 2.0, 3.0], diff --git a/tests/js/tarrayboundscheck.nim b/tests/js/tarrayboundscheck.nim new file mode 100644 index 000000000..f0eaeb89d --- /dev/null +++ b/tests/js/tarrayboundscheck.nim @@ -0,0 +1,44 @@ +discard """ + output: '''idx out of bounds: -1 +month out of bounds: 0 +Jan +Feb +Mar +Apr +May +Jun +Jul +Aug +Sep +Oct +Nov +Dec +month out of bounds: 13 +idx out of bounds: 14 +''' +""" + +{.push boundChecks:on.} + +# see issue #6532: +# js backend 0.17.3: array bounds check for non zero based arrays is buggy + +proc test_arrayboundscheck() = + var months: array[1..12, string] = + ["Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + + var indices = [0,1,2,3,4,5,6,7,8,9,10,11,12,13] + + for i in -1 .. 14: + try: + let idx = indices[i] + try: + echo months[idx] + except: + echo "month out of bounds: ", idx + except: + echo "idx out of bounds: ", i + +test_arrayboundscheck() +{.pop.} \ No newline at end of file diff --git a/tests/js/tasync.nim b/tests/js/tasync.nim new file mode 100644 index 000000000..34ef97b8b --- /dev/null +++ b/tests/js/tasync.nim @@ -0,0 +1,32 @@ +discard """ + disabled: true + output: ''' +x +e +''' +""" + +import asyncjs + +# demonstrate forward definition +# for js +proc y(e: int): Future[string] {.async.} + +proc e: int {.discardable.} = + echo "e" + return 2 + +proc x(e: int): Future[void] {.async.} = + var s = await y(e) + echo s + e() + +proc y(e: int): Future[string] {.async.} = + if e > 0: + return await y(0) + else: + return "x" + + +discard x(2) + diff --git a/tests/js/tcodegendeclproc.nim b/tests/js/tcodegendeclproc.nim new file mode 100644 index 000000000..3acf0bc13 --- /dev/null +++ b/tests/js/tcodegendeclproc.nim @@ -0,0 +1,11 @@ +discard """ + output: ''' +-1 +8 +''' + ccodecheck: "'console.log(-1); function fac_' \\d+ '(n_' \\d+ ')'" +""" +proc fac(n: int): int {.codegenDecl: "console.log(-1); function $2($3)".} = + return n + +echo fac(8) diff --git a/tests/js/tcodegendeclvar.nim b/tests/js/tcodegendeclvar.nim new file mode 100644 index 000000000..645443ef7 --- /dev/null +++ b/tests/js/tcodegendeclvar.nim @@ -0,0 +1,10 @@ +discard """ + output: ''' +-1 +2 +''' + ccodecheck: "'console.log(-1); var v_' \\d+ ' = [2]'" +""" + +var v {.codegenDecl: "console.log(-1); var $2".} = 2 +echo v diff --git a/tests/js/test2.nim b/tests/js/test2.nim index 0f460d6f8..0bfb99139 100644 --- a/tests/js/test2.nim +++ b/tests/js/test2.nim @@ -2,7 +2,9 @@ discard """ output: '''foo js 3.14 7 -1''' +1 +-21550 +-21550''' """ # This file tests the JavaScript generator @@ -40,3 +42,14 @@ procThatRefersToConst() # Call bar before it is defined proc procThatRefersToConst() = var i = 0 # Use a var index, otherwise nim will constfold foo[0] echo someConst[i] # JS exception here: foo is still not initialized (undefined) + +# bug #6753 +let x = -1861876800 +const y = 86400 +echo (x - (y - 1)) div y # Now gives `-21550` + +proc foo09() = + let x = -1861876800 + const y = 86400 + echo (x - (y - 1)) div y # Still gives `-21551` +foo09() diff --git a/tests/js/trefbyvar.nim b/tests/js/trefbyvar.nim index d440fcc64..5b168044e 100644 --- a/tests/js/trefbyvar.nim +++ b/tests/js/trefbyvar.nim @@ -66,4 +66,4 @@ proc initTypeA1(a: int; b: string; c: pointer = nil): TypeA1 = result.c_impl = c let x = initTypeA1(1, "a") -doAssert($x == "(a_impl: 1, b_impl: a, c_impl: ...)") +doAssert($x == "(a_impl: 1, b_impl: \"a\", c_impl: ...)") diff --git a/tests/js/ttimes.nim b/tests/js/ttimes.nim index 2868c6d0f..63a4bb04f 100644 --- a/tests/js/ttimes.nim +++ b/tests/js/ttimes.nim @@ -1,4 +1,3 @@ -# test times module with js discard """ action: run """ @@ -9,21 +8,37 @@ import times # Tue 19 Jan 03:14:07 GMT 2038 block yeardayTest: - # check if yearday attribute is properly set on TimeInfo creation - doAssert fromSeconds(2147483647).getGMTime().yearday == 18 - -block localTimezoneTest: - # check if timezone is properly set during Time to TimeInfo conversion - doAssert fromSeconds(2147483647).getLocalTime().timezone == getTimezone() - -block timestampPersistenceTest: - # check if timestamp persists during TimeInfo to Time conversion - const - timeString = "2017-03-21T12:34:56+03:00" - timeStringGmt = "2017-03-21T09:34:56+00:00" - timeStringGmt2 = "2017-03-21T08:34:56+00:00" - fmt = "yyyy-MM-dd'T'HH:mm:sszzz" - # XXX Check which one is the right solution here: - - let x = $timeString.parse(fmt).toTime().getGMTime() - doAssert x == timeStringGmt or x == timeStringGmt2 + doAssert fromUnix(2147483647).utc.yearday == 18 + +block localTime: + var local = now() + let utc = local.utc + doAssert local.toTime == utc.toTime + +let a = fromUnix(1_000_000_000) +let b = fromUnix(1_500_000_000) +doAssert b - a == 500_000_000 + +# Because we can't change the timezone JS uses, we define a simple static timezone for testing. + +proc staticZoneInfoFromUtc(time: Time): ZonedTime = + result.utcOffset = -7200 + result.isDst = false + result.adjTime = (time.toUnix + 7200).Time + +proc staticZoneInfoFromTz(adjTime: Time): ZonedTIme = + result.utcOffset = -7200 + result.isDst = false + result.adjTime = adjTime + +let utcPlus2 = Timezone(zoneInfoFromUtc: staticZoneInfoFromUtc, zoneInfoFromTz: staticZoneInfoFromTz, name: "") + +block timezoneTests: + let dt = initDateTime(01, mJan, 2017, 12, 00, 00, utcPlus2) + doAssert $dt == "2017-01-01T12:00:00+02:00" + doAssert $dt.utc == "2017-01-01T10:00:00+00:00" + doAssert $dt.utc.inZone(utcPlus2) == $dt + +doAssert $initDateTime(01, mJan, 1911, 12, 00, 00, utc()) == "1911-01-01T12:00:00+00:00" +# See #6752 +# doAssert $initDateTime(01, mJan, 1900, 12, 00, 00, utc()) == "0023-01-01T12:00:00+00:00" \ No newline at end of file diff --git a/tests/lexer/tind1.nim b/tests/lexer/tind1.nim index 8a2aea9b2..ffbde48fd 100644 --- a/tests/lexer/tind1.nim +++ b/tests/lexer/tind1.nim @@ -1,6 +1,6 @@ discard """ line: 24 - errormsg: "expression expected, but found 'keyword else'" + errormsg: "invalid indentation" """ import macros @@ -11,7 +11,7 @@ var x = if 4 != 5: else: "no" -macro mymacro(n): untyped {.immediate.} = +macro mymacro(n, b): untyped = discard mymacro: diff --git a/tests/macros/tgettypeinst.nim b/tests/macros/tgettypeinst.nim index 8e1d9bc13..2f1abe193 100644 --- a/tests/macros/tgettypeinst.nim +++ b/tests/macros/tgettypeinst.nim @@ -27,9 +27,10 @@ macro testX(x,inst0: typed; recurse: static[bool]; implX: typed): typed = let inst = x.getTypeInst let instr = inst.symToIdent.treeRepr let inst0r = inst0.symToIdent.treeRepr - #echo instr - #echo inst0r - doAssert(instr == inst0r) + if instr != inst0r: + echo "instr:\n", instr + echo "inst0r:\n", inst0r + doAssert(instr == inst0r) # check that getTypeImpl(x) is correct # if implX is nil then compare to inst0 @@ -41,9 +42,10 @@ macro testX(x,inst0: typed; recurse: static[bool]; implX: typed): typed = else: implX[0][2] let implr = impl.symToIdent.treerepr let impl0r = impl0.symToIdent.treerepr - #echo implr - #echo impl0r - doAssert(implr == impl0r) + if implr != impl0r: + echo "implr:\n", implr + echo "impl0r:\n", impl0r + doAssert(implr == impl0r) result = newStmtList() #template echoString(s: string) = echo s.replace("\n","\n ") @@ -111,6 +113,18 @@ type Generic[T] = seq[int] Concrete = Generic[int] + Generic2[T1, T2] = seq[T1] + Concrete2 = Generic2[int, float] + + Alias1 = float + Alias2 = Concrete + Alias3 = Concrete2 + + Vec[N: static[int],T] = object + arr: array[N,T] + Vec4[T] = Vec[4,T] + + test(bool) test(char) test(int) @@ -144,11 +158,27 @@ test(Tree): left: ref Tree right: ref Tree test(Concrete): - type _ = Generic[int] + type _ = seq[int] test(Generic[int]): type _ = seq[int] test(Generic[float]): type _ = seq[int] +test(Concrete2): + type _ = seq[int] +test(Generic2[int,float]): + type _ = seq[int] +test(Alias1): + type _ = float +test(Alias2): + type _ = seq[int] +test(Alias3): + type _ = seq[int] +test(Vec[4,float32]): + type _ = object + arr: array[0..3,float32] +test(Vec4[float32]): + type _ = object + arr: array[0..3,float32] # bug #4862 static: diff --git a/tests/macros/tnimnode_for_runtime.nim b/tests/macros/tnimnode_for_runtime.nim deleted file mode 100644 index 0520cd0dd..000000000 --- a/tests/macros/tnimnode_for_runtime.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - output: "bla" -""" - -import macros -proc makeMacro: NimNode = - result = nil - -var p = makeMacro() - -echo "bla" - diff --git a/tests/metatype/ttypedesc2.nim b/tests/metatype/ttypedesc2.nim index 7650a6f6b..4b6cfe6bc 100644 --- a/tests/metatype/ttypedesc2.nim +++ b/tests/metatype/ttypedesc2.nim @@ -1,5 +1,5 @@ discard """ - output: "(x: a)" + output: '''(x: 'a')''' """ type diff --git a/tests/misc/tatomic.nim b/tests/misc/tatomic.nim deleted file mode 100644 index f3c56ffe3..000000000 --- a/tests/misc/tatomic.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "tatomic.nim" - line: 7 - errormsg: "identifier expected, but found 'keyword atomic'" -""" -var - atomic: int - -echo atomic - - - diff --git a/tests/misc/tevents.nim b/tests/misc/tevents.nim index 5f2169f29..caf674084 100644 --- a/tests/misc/tevents.nim +++ b/tests/misc/tevents.nim @@ -8,19 +8,19 @@ HandlePrintEvent2: Output -> printing for ME''' import events type - TPrintEventArgs = object of TEventArgs + PrintEventArgs = object of EventArgs user*: string -proc handleprintevent*(e: TEventArgs) = +proc handleprintevent*(e: EventArgs) = write(stdout, "HandlePrintEvent: Output -> Handled print event\n") -proc handleprintevent2*(e: TEventArgs) = - var args: TPrintEventArgs = TPrintEventArgs(e) +proc handleprintevent2*(e: EventArgs) = + var args: PrintEventArgs = PrintEventArgs(e) write(stdout, "HandlePrintEvent2: Output -> printing for " & args.user) var ee = initEventEmitter() -var eventargs: TPrintEventArgs +var eventargs: PrintEventArgs eventargs.user = "ME\n" ##method one test @@ -33,16 +33,16 @@ ee.emit("print", eventargs) ##method two test type - TSomeObject = object of TObject - PrintEvent: TEventHandler + SomeObject = object of RootObj + printEvent: EventHandler -var obj: TSomeObject -obj.PrintEvent = initEventHandler("print") -obj.PrintEvent.addHandler(handleprintevent2) +var obj: SomeObject +obj.printEvent = initEventHandler("print") +obj.printEvent.addHandler(handleprintevent2) -ee.emit(obj.PrintEvent, eventargs) +ee.emit(obj.printEvent, eventargs) -obj.PrintEvent.removeHandler(handleprintevent2) +obj.printEvent.removeHandler(handleprintevent2) -ee.emit(obj.PrintEvent, eventargs) +ee.emit(obj.printEvent, eventargs) diff --git a/tests/misc/tlocals.nim b/tests/misc/tlocals.nim index 3e240d3c8..09b7432f5 100644 --- a/tests/misc/tlocals.nim +++ b/tests/misc/tlocals.nim @@ -1,5 +1,5 @@ discard """ - output: "(x: string here, a: 1)" + output: '''(x: "string here", a: 1)''' """ proc simple[T](a: T) = diff --git a/tests/misc/tromans.nim b/tests/misc/tromans.nim deleted file mode 100644 index 132c73ddd..000000000 --- a/tests/misc/tromans.nim +++ /dev/null @@ -1,71 +0,0 @@ -discard """ - file: "tromans.nim" - output: "success" -""" -import - strutils - -## Convert an integer to a Roman numeral -# See http://en.wikipedia.org/wiki/Roman_numerals for reference - -proc raiseInvalidValue(msg: string) {.noreturn.} = - # Yes, we really need a shorthand for this code... - var e: ref EInvalidValue - new(e) - e.msg = msg - raise e - -# I should use a class, perhaps. -# --> No. Why introduce additional state into such a simple and nice -# interface? State is evil. :D - -proc RomanToDecimal(romanVal: string): int = - result = 0 - var prevVal = 0 - for i in countdown(romanVal.len - 1, 0): - var val = 0 - case romanVal[i] - of 'I', 'i': val = 1 - of 'V', 'v': val = 5 - of 'X', 'x': val = 10 - of 'L', 'l': val = 50 - of 'C', 'c': val = 100 - of 'D', 'd': val = 500 - of 'M', 'm': val = 1000 - else: raiseInvalidValue("Incorrect character in roman numeral! (" & - $romanVal[i] & ")") - if val >= prevVal: - inc(result, val) - else: - dec(result, val) - prevVal = val - -proc DecimalToRoman(decValParam: int): string = - # Apparently numbers cannot be above 4000 - # Well, they can be (using overbar or parenthesis notation) - # but I see little interest (beside coding challenge) in coding them as - # we rarely use huge Roman numeral. - const romanComposites = [ - ("M", 1000), ("CM", 900), - ("D", 500), ("CD", 400), ("C", 100), - ("XC", 90), ("L", 50), ("XL", 40), ("X", 10), ("IX", 9), - ("V", 5), ("IV", 4), ("I", 1)] - if decValParam < 1 or decValParam > 3999: - raiseInvalidValue("number not representable") - result = "" - var decVal = decValParam - for key, val in items(romanComposites): - while decVal >= val: - dec(decVal, val) - result.add(key) - -for i in 1..100: - if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" - -for i in items([1238, 1777, 3830, 2401, 379, 33, 940, 3973]): - if RomanToDecimal(DecimalToRoman(i)) != i: quit "BUG" - -echo "success" #OUT success - - - diff --git a/tests/misc/tupcomingfeatures.nim b/tests/misc/tupcomingfeatures.nim index cf07b06df..d37ce85cf 100644 --- a/tests/misc/tupcomingfeatures.nim +++ b/tests/misc/tupcomingfeatures.nim @@ -6,12 +6,8 @@ discard """ {.this: self.} type - Foo {.partial.} = object - a, b: int - -type - tupcomingfeatures.Foo = object - x: int + Foo = object + a, b, x: int proc yay(self: Foo) = echo a, " ", b, " ", x diff --git a/tests/misc/tvarnums.nim b/tests/misc/tvarnums.nim index a5c30c7eb..5daa2c4b8 100644 --- a/tests/misc/tvarnums.nim +++ b/tests/misc/tvarnums.nim @@ -67,7 +67,7 @@ proc toNum64(b: TBuffer): int64 = proc toNum(b: TBuffer): int32 = # treat first byte different: - result = ze(b[0]) and 63 + result = int32 ze(b[0]) and 63 var i = 0 Shift = 6'i32 diff --git a/tests/modules/mrange.nim b/tests/modules/mrange.nim new file mode 100644 index 000000000..20c424a8c --- /dev/null +++ b/tests/modules/mrange.nim @@ -0,0 +1,5 @@ + +proc range*() = echo "yo" + +proc set*(a: int) = + discard diff --git a/tests/modules/tambig_range.nim b/tests/modules/tambig_range.nim new file mode 100644 index 000000000..010350521 --- /dev/null +++ b/tests/modules/tambig_range.nim @@ -0,0 +1,13 @@ +discard """ + errormsg: "ambiguous identifier: 'range' --use system.range or mrange.range" + line: 13 +""" + +import mrange + +# bug #6965 +type SomeObj = object + s: set[int8] + +# bug #6726 +range() diff --git a/tests/modules/treorder.nim b/tests/modules/treorder.nim index 25280c429..8715e4548 100644 --- a/tests/modules/treorder.nim +++ b/tests/modules/treorder.nim @@ -9,7 +9,6 @@ defined {.reorder: on.} {.experimental.} -{.push callconv: stdcall.} proc bar(x: T) proc foo() = @@ -22,15 +21,16 @@ proc bar(x: T) = echo "works ", x foo(x) +when defined(testdef): + proc whendep() = echo "defined" +else: + proc whendep() = echo "undefined" + foo() type T = int -when defined(testdef): - proc whendep() = echo "defined" -else: - proc whendep() = echo "undefined" when not declared(goo): proc goo(my, omy) = echo my @@ -42,5 +42,3 @@ using my, omy: int goo(3, 4) - -{.pop.} diff --git a/tests/notnil/tmust_compile.nim b/tests/notnil/tmust_compile.nim new file mode 100644 index 000000000..10da154f0 --- /dev/null +++ b/tests/notnil/tmust_compile.nim @@ -0,0 +1,78 @@ +discard """ + output: '''success''' +""" + +# bug #6682 + +type + Fields = enum + A=1, B, C + + Obj = object + fld: array[Fields, int] + + AsGeneric[T] = array[Fields, T] + Obj2[T] = object + fld: AsGeneric[T] + +var a: Obj # this works + +var arr: array[Fields, int] + +var b = Obj() # this doesn't (also doesn't works with additional fields) + +var z = Obj2[int]() + +echo "success" + +# bug #6555 + +import tables + +type + TaskOrNil = ref object + Task = TaskOrNil not nil + +let table = newTable[string, Task]() +table.del("task") + +# bug #6121 + +import json + +type + + foo = object + thing: string not nil + + CTS = ref object + subs_by_sid: Table[int, foo] + + +proc parse(cts: CTS, jn: JsonNode) = + + let ces = foo( + thing: jn.getStr("thing") + ) + + cts.subs_by_sid[0] = ces + + +# bug #6489 + +proc p(x: proc(){.closure.} not nil) = discard +p(proc(){.closure.} = discard) + +# bug #3993 + +type + List[T] = seq[T] not nil + +proc `^^`[T](v: T, lst: List[T]): List[T] = + result = @[v] + result.add(lst) + +proc Nil[T](): List[T] = @[] + +when isMainModule: + let lst = 1 ^^ 2 ^^ Nil[int]() diff --git a/tests/objects/tobjconstr.nim b/tests/objects/tobjconstr.nim index 12478f621..b7da176aa 100644 --- a/tests/objects/tobjconstr.nim +++ b/tests/objects/tobjconstr.nim @@ -1,14 +1,14 @@ discard """ - output: '''(k: kindA, a: (x: abc, z: [1, 1, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 2, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 3, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 4, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 5, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 6, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 7, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 8, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 9, 3]), method: ()) -(k: kindA, a: (x: abc, z: [1, 10, 3]), method: ()) + output: '''(k: kindA, a: (x: "abc", z: [1, 1, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 2, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 3, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 4, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 5, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 6, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 7, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 8, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 9, 3]), method: ()) +(k: kindA, a: (x: "abc", z: [1, 10, 3]), method: ()) (x: 123) (x: 123) (z: 89, y: 0, x: 128) diff --git a/tests/osproc/texecps.nim b/tests/osproc/texecps.nim new file mode 100644 index 000000000..887d79bfb --- /dev/null +++ b/tests/osproc/texecps.nim @@ -0,0 +1,32 @@ +discard """ + file: "texecps.nim" + output: "" +""" + +import osproc, streams, strutils, os + +const NumberOfProcesses = 13 + +var gResults {.threadvar.}: seq[string] + +proc execCb(idx: int, p: Process) = + let exitCode = p.peekExitCode + if exitCode < len(gResults): + gResults[exitCode] = p.outputStream.readAll.strip + +when isMainModule: + + if paramCount() == 0: + gResults = newSeq[string](NumberOfProcesses) + var checks = newSeq[string](NumberOfProcesses) + var commands = newSeq[string](NumberOfProcesses) + for i in 0..len(commands) - 1: + commands[i] = getAppFileName() & " " & $i + checks[i] = $i + let cres = execProcesses(commands, options = {poStdErrToStdOut}, + afterRunEvent = execCb) + doAssert(cres == len(commands) - 1) + doAssert(gResults == checks) + else: + echo paramStr(1) + programResult = parseInt(paramStr(1)) diff --git a/tests/overload/tprefer_tygenericinst.nim b/tests/overload/tprefer_tygenericinst.nim index 56541c7e8..ab461a0f4 100644 --- a/tests/overload/tprefer_tygenericinst.nim +++ b/tests/overload/tprefer_tygenericinst.nim @@ -2,7 +2,11 @@ discard """ output: '''Version 2 was called. This has the highest precedence. This has the second-highest precedence. -This has the lowest precedence.''' +This has the lowest precedence. +baseobj == +true +even better! == +true''' """ # bug #2220 @@ -26,13 +30,13 @@ template testPred(a: untyped) = type SomeA = A|A # A hack to make "A" a typeclass. when a >= 3: - proc p[X](x: X) = - echo "This has the highest precedence." - when a >= 2: proc p[X: A](x: X) = + echo "This has the highest precedence." + when a == 2: + proc p[X: SomeA](x: X) = echo "This has the second-highest precedence." when a >= 1: - proc p[X: SomeA](x: X) = + proc p[X](x: X) = echo "This has the lowest precedence." p(B()) @@ -40,3 +44,25 @@ template testPred(a: untyped) = testPred(3) testPred(2) testPred(1) + +# bug #6526 +type + BaseObj = ref object of RootObj + DerivedObj = ref object of BaseObj + OtherDerivate = ref object of BaseObj + +proc `==`*[T1, T2: BaseObj](a: T1, b: T2): bool = + echo "baseobj ==" + return true + +let a = DerivedObj() +let b = DerivedObj() +echo a == b + +proc `==`*[T1, T2: OtherDerivate](a: T1, b: T2): bool = + echo "even better! ==" + return true + +let a2 = OtherDerivate() +let b2 = OtherDerivate() +echo a2 == b2 diff --git a/tests/overload/tstatic_with_converter.nim b/tests/overload/tstatic_with_converter.nim new file mode 100644 index 000000000..2871744eb --- /dev/null +++ b/tests/overload/tstatic_with_converter.nim @@ -0,0 +1,47 @@ +discard """ +output: ''' +9.0''' +""" + +### bug #6773 + +{.emit: """ /*INCLUDESECTION*/ +typedef double cimported; + +cimported set1_imported(double x) { + return x; +} + +"""} + +type vfloat{.importc: "cimported".} = object + +proc set1(a: float): vfloat {.importc: "set1_imported".} + +converter scalar_to_vector(x: float): vfloat = + set1(x) + +proc sqrt(x: vfloat): vfloat = + x + +proc pow(x, y: vfloat): vfloat = + y + +proc `^`(x: vfloat, exp: static[int]): vfloat = + when exp == 0: + 1.0 + else: + x + +proc `^`(x: vfloat, exp: static[float]): vfloat = + when exp == 0.5: + sqrt(x) + else: + pow(x, exp) + +proc `$`(x: vfloat): string = + let y = cast[ptr float](unsafeAddr x) + echo y[] + +let x = set1(9.0) +echo x^0.5 diff --git a/tests/package_level_objects/definefoo.nim b/tests/package_level_objects/definefoo.nim new file mode 100644 index 000000000..36576ab59 --- /dev/null +++ b/tests/package_level_objects/definefoo.nim @@ -0,0 +1,3 @@ +type + Foo* {.package.} = object + x, y: int diff --git a/tests/package_level_objects/mypackage.nimble b/tests/package_level_objects/mypackage.nimble new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/package_level_objects/mypackage.nimble diff --git a/tests/package_level_objects/tusefoo.nim b/tests/package_level_objects/tusefoo.nim new file mode 100644 index 000000000..f9bae9545 --- /dev/null +++ b/tests/package_level_objects/tusefoo.nim @@ -0,0 +1,16 @@ +discard """ + output: '''@[(x: 3, y: 4)]''' +""" + +type + mypackage.Foo = object + Other = proc (inp: Foo) + +import definefoo + +# after this import, Foo is a completely resolved type, so +# we can create a sequence of it: +var s: seq[Foo] = @[] + +s.add Foo(x: 3, y: 4) +echo s diff --git a/tests/package_level_objects/tusefoo2.nim b/tests/package_level_objects/tusefoo2.nim new file mode 100644 index 000000000..be6b3fcda --- /dev/null +++ b/tests/package_level_objects/tusefoo2.nim @@ -0,0 +1,19 @@ +discard """ + output: '''compiles''' +""" + +# Test that the object type does not need to be resolved at all: + +type + mypackage.Foo = object + Other = proc (inp: Foo) + + Node = ref object + external: ptr Foo + data: string + +var x: Node +new(x) +x.data = "compiles" + +echo x.data diff --git a/tests/parallel/tdisjoint_slice2.nim b/tests/parallel/tdisjoint_slice2.nim index 1e86ea644..25cb2362f 100644 --- a/tests/parallel/tdisjoint_slice2.nim +++ b/tests/parallel/tdisjoint_slice2.nim @@ -11,12 +11,19 @@ discard """ sortoutput: true """ -import threadpool +import threadpool, locks + +var echoLock: Lock +initLock echoLock proc f(a: openArray[int]) = - for x in a: echo x + for x in a: + withLock echoLock: + echo x -proc f(a: int) = echo a +proc f(a: int) = + withLock echoLock: + echo a proc main() = var a: array[0..9, int] = [0,1,2,3,4,5,6,7,8,9] diff --git a/tests/parser/tletcolon.nim b/tests/parser/tletcolon.nim index 6b86535c8..7eaa5e3e5 100644 --- a/tests/parser/tletcolon.nim +++ b/tests/parser/tletcolon.nim @@ -4,7 +4,8 @@ discard """ 44 3 more body code yes -yes''' +yes +block expression works''' """ template x(body): untyped = @@ -32,3 +33,29 @@ let other = x: echo "no" let outer = y(5): echo "yes" + + +# bug #6609 +type + TextureInternalFormat = enum RED, RGB, RGBA + +const channels = 4 + +let format = + if channels == 1: + TextureInternalFormat.RED + elif channels == 3: + TextureInternalFormat.RGB + elif channels == 4: + TextureInternalFormat.RGBA + else: + echo "Texture Format Unknown, assuming RGB" #This echo causes an error + TextureInternalFormat.RGB + +# Block as expressions #3827 +block: + let x = block: + var y = 2 + echo "block expression works" + y*y + doAssert x == 4 \ No newline at end of file diff --git a/tests/parser/tpostexprblocks.nim b/tests/parser/tpostexprblocks.nim index 341ca737a..3b9c956c2 100644 --- a/tests/parser/tpostexprblocks.nim +++ b/tests/parser/tpostexprblocks.nim @@ -1,82 +1,82 @@ discard """ nimout: ''' StmtList - Ident !"foo010" + Ident ident"foo010" Call - Ident !"foo020" + Ident ident"foo020" Call - Ident !"foo030" - Ident !"x" + Ident ident"foo030" + Ident ident"x" Command - Ident !"foo040" - Ident !"x" + Ident ident"foo040" + Ident ident"x" Call - Ident !"foo050" + Ident ident"foo050" StmtList DiscardStmt Empty Call - Ident !"foo060" + Ident ident"foo060" StmtList DiscardStmt Empty Call - Ident !"foo070" + Ident ident"foo070" StrLit test StmtList DiscardStmt Empty Call - Ident !"foo080" + Ident ident"foo080" StrLit test StmtList DiscardStmt Empty Command - Ident !"foo090" + Ident ident"foo090" StrLit test StmtList DiscardStmt Empty Command - Ident !"foo100" + Ident ident"foo100" Call StrLit test StmtList DiscardStmt Empty Command - Ident !"foo101" + Ident ident"foo101" Call IntLit 10 StmtList DiscardStmt Empty Command - Ident !"foo110" + Ident ident"foo110" IntLit 1 Par Infix - Ident !"+" + Ident ident"+" IntLit 2 IntLit 3 StmtList DiscardStmt Empty Command - Ident !"foo120" + Ident ident"foo120" IntLit 1 Call Par Infix - Ident !"+" + Ident ident"+" IntLit 2 IntLit 3 StmtList DiscardStmt Empty Call - Ident !"foo130" + Ident ident"foo130" Do Empty Empty @@ -84,7 +84,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"x" + Ident ident"x" Empty Empty Empty @@ -93,7 +93,7 @@ StmtList DiscardStmt Empty Call - Ident !"foo140" + Ident ident"foo140" Do Empty Empty @@ -101,8 +101,8 @@ StmtList FormalParams Empty IdentDefs - Ident !"x" - Ident !"int" + Ident ident"x" + Ident ident"int" Empty Empty Empty @@ -110,16 +110,16 @@ StmtList DiscardStmt Empty Call - Ident !"foo150" + Ident ident"foo150" Do Empty Empty Empty FormalParams - Ident !"int" + Ident ident"int" IdentDefs - Ident !"x" - Ident !"int" + Ident ident"x" + Ident ident"int" Empty Empty Empty @@ -127,9 +127,9 @@ StmtList DiscardStmt Empty Command - Ident !"foo160" + Ident ident"foo160" Call - Ident !"x" + Ident ident"x" Do Empty Empty @@ -137,7 +137,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"y" + Ident ident"y" Empty Empty Empty @@ -146,7 +146,7 @@ StmtList DiscardStmt Empty Call - Ident !"foo170" + Ident ident"foo170" StmtList DiscardStmt Empty @@ -155,7 +155,7 @@ StmtList DiscardStmt Empty Call - Ident !"foo180" + Ident ident"foo180" StmtList DiscardStmt Empty @@ -167,9 +167,9 @@ StmtList DiscardStmt Empty Command - Ident !"foo190" + Ident ident"foo190" Call - Ident !"x" + Ident ident"x" Do Empty Empty @@ -177,7 +177,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"y" + Ident ident"y" Empty Empty Empty @@ -190,9 +190,9 @@ StmtList Empty Empty FormalParams - Ident !"int" + Ident ident"int" IdentDefs - Ident !"z" + Ident ident"z" Empty Empty Empty @@ -205,10 +205,10 @@ StmtList Empty Empty FormalParams - Ident !"int" + Ident ident"int" IdentDefs - Ident !"w" - Ident !"int" + Ident ident"w" + Ident ident"int" Empty Empty Empty @@ -223,10 +223,10 @@ StmtList DiscardStmt Empty Call - Ident !"foo200" - Ident !"x" + Ident ident"foo200" + Ident ident"x" Call - Ident !"bar" + Ident ident"bar" StmtList DiscardStmt Empty @@ -236,53 +236,53 @@ StmtList Empty VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty - Ident !"foo210" + Ident ident"foo210" VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo220" + Ident ident"foo220" VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo230" - Ident !"x" + Ident ident"foo230" + Ident ident"x" VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Command - Ident !"foo240" - Ident !"x" + Ident ident"foo240" + Ident ident"x" VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo250" + Ident ident"foo250" StmtList DiscardStmt Empty VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo260" + Ident ident"foo260" StmtList DiscardStmt Empty VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Call - Ident !"foo270" + Ident ident"foo270" StmtList DiscardStmt Empty @@ -292,12 +292,12 @@ StmtList Empty VarSection IdentDefs - Ident !"a" + Ident ident"a" Empty Command - Ident !"foo280" + Ident ident"foo280" Call - Ident !"x" + Ident ident"x" Do Empty Empty @@ -305,7 +305,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"y" + Ident ident"y" Empty Empty Empty @@ -318,40 +318,40 @@ StmtList DiscardStmt Empty Asgn - Ident !"a" - Ident !"foo290" + Ident ident"a" + Ident ident"foo290" Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo300" + Ident ident"foo300" Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo310" - Ident !"x" + Ident ident"foo310" + Ident ident"x" Asgn - Ident !"a" + Ident ident"a" Command - Ident !"foo320" - Ident !"x" + Ident ident"foo320" + Ident ident"x" Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo330" + Ident ident"foo330" StmtList DiscardStmt Empty Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo340" + Ident ident"foo340" StmtList DiscardStmt Empty Asgn - Ident !"a" + Ident ident"a" Call - Ident !"foo350" + Ident ident"foo350" StmtList DiscardStmt Empty @@ -360,13 +360,13 @@ StmtList DiscardStmt Empty Asgn - Ident !"a" + Ident ident"a" Command - Ident !"foo360" + Ident ident"foo360" Call DotExpr - Ident !"x" - Ident !"bar" + Ident ident"x" + Ident ident"bar" Do Empty Empty @@ -374,7 +374,7 @@ StmtList FormalParams Empty IdentDefs - Ident !"y" + Ident ident"y" Empty Empty Empty @@ -388,20 +388,20 @@ StmtList Empty Command DotExpr - Ident !"foo370" - Ident !"add" + Ident ident"foo370" + Ident ident"add" Call - Ident !"quote" + Ident ident"quote" StmtList DiscardStmt Empty Call DotExpr - Ident !"foo380" - Ident !"add" + Ident ident"foo380" + Ident ident"add" BracketExpr Call - Ident !"quote" + Ident ident"quote" StmtList DiscardStmt Empty diff --git a/tests/pragmas/tnoreturn.nim b/tests/pragmas/tnoreturn.nim new file mode 100644 index 000000000..4d00c6034 --- /dev/null +++ b/tests/pragmas/tnoreturn.nim @@ -0,0 +1,22 @@ +discard """ +ccodeCheck: "\\i @'__attribute__((noreturn))' .*" +""" + +proc noret1*(i: int) {.noreturn.} = + echo i + + +proc noret2*(i: int): void {.noreturn.} = + echo i + +var p {.used.}: proc(i: int): int +doAssert(not compiles( + p = proc(i: int): int {.noreturn.} = i # noreturn lambda returns int +)) + + +doAssert(not compiles( + block: + noret1(5) + echo 1 # statement after noreturn +)) diff --git a/tests/pragmas/treorder.nim b/tests/pragmas/treorder.nim new file mode 100644 index 000000000..6a6bbff4d --- /dev/null +++ b/tests/pragmas/treorder.nim @@ -0,0 +1,75 @@ +discard """ +output:'''0 +1 +2 +3''' +""" + +import macros +{.reorder: on .} + +echo foo(-1) +echo callWithFoo(0) +echo(CA+CD) +echo useTypes(TA(x:TB(x:1)), 2) +second(0) + +template callWithFoo(arg: untyped): untyped = + foo(arg) + +proc first(i: int): void + +proc second(i: int): void = + make(first) + first(i) + +proc useTypes(a: TA, d: TD): int = + result = a.x.x+d + +type + TDoubleCyclic = ref object + x: TCyclicA + y: TCyclicB + +type + TCyclicA = ref object + x: TDoubleCyclic + +type + TCyclicB = ref object + x: TDoubleCyclic + +const + CA = 1 + CB = CC + +type + TA = object + x: TB + TC = type(CC) + TD = type(CA) + +const + CC = 1 + CD = CB + +type + TB = object + x: TC + +proc foo(x: int): int = + result = bar(x) + +proc bar(x: int): int = + result = x+1 + +macro make(arg: untyped): untyped = + ss &= arg.repr + ss &= " " + discard + +proc first(i: int): void = + make(second) + +static: + var ss: string = "" \ No newline at end of file diff --git a/tests/range/tn8vsint16.nim b/tests/range/tn8vsint16.nim new file mode 100644 index 000000000..bf4f78e3b --- /dev/null +++ b/tests/range/tn8vsint16.nim @@ -0,0 +1,18 @@ +discard """ + output: '''-9''' +""" + +type + n32 = range[0..high(int)] + n8* = range[0'i8..high(int8)] + +proc `+`*(a: n32, b: n32{nkIntLit}): n32 = discard + +proc `-`*(a: n8, b: n8): n8 = n8(system.`-`(a, b)) + +var x, y: n8 +var z: int16 + +# ensure this doesn't call our '-' but system.`-` for int16: +echo z - n8(9) + diff --git a/tests/rational/trat_init.nim b/tests/rational/trat_init.nim index df29ff6e3..360a48537 100644 --- a/tests/rational/trat_init.nim +++ b/tests/rational/trat_init.nim @@ -1,10 +1,14 @@ discard """ - file: "trat_init.nim" - exitcode: "1" + output: '''true''' """ import rationals var z = Rational[int](num: 0, den: 1) o = initRational(num=1, den=1) a = initRational(1, 2) - r = initRational(1, 0) # this fails - no zero denominator + +try: + var + r = initRational(1, 0) # this fails - no zero denominator +except AssertionError: + echo "true" diff --git a/tests/showoff/thello2.nim b/tests/showoff/thello2.nim index d2e2f6227..3ccb4e3be 100644 --- a/tests/showoff/thello2.nim +++ b/tests/showoff/thello2.nim @@ -1,5 +1,5 @@ discard """ - output: '''(a: 3, b: 4, s: abc)''' + output: '''(a: 3, b: 4, s: "abc")''' """ type diff --git a/tests/specialops/tdotops.nim b/tests/specialops/tdotops.nim index bca949922..227204f51 100644 --- a/tests/specialops/tdotops.nim +++ b/tests/specialops/tdotops.nim @@ -11,7 +11,8 @@ no params call to a no params call to b 100 one param call to c with 10 -100''' +100 +0 4''' """ type @@ -23,16 +24,16 @@ type T2 = object x: int -proc `.`*(v: T1, f: string): int = - echo "reading field ", f - return v.x +template `.`*(v: T1, f: untyped): int = + echo "reading field ", astToStr(f) + v.x -proc `.=`(x: var T1, f: string{lit}, v: int) = - echo "assigning ", f, " = ", v - x.x = v +template `.=`(t: var T1, f: untyped, v: int) = + echo "assigning ", astToStr(f), " = ", v + t.x = v -template `.()`(x: T1, f: string, args: varargs[typed]): string = - echo "call to ", f +template `.()`(x: T1, f: untyped, args: varargs[typed]): string = + echo "call to ", astToStr(f) "dot call" echo "" @@ -47,13 +48,13 @@ echo t.y() var d = TD(t) assert(not compiles(d.y)) -proc `.`(v: T2, f: string): int = - echo "no params call to ", f - return v.x +template `.`(v: T2, f: untyped): int = + echo "no params call to ", astToStr(f) + v.x -proc `.`*(v: T2, f: string, a: int): int = - echo "one param call to ", f, " with ", a - return v.x +template `.`*(v: T2, f: untyped, a: int): int = + echo "one param call to ", astToStr(f), " with ", a + v.x var tt = T2(x: 100) @@ -63,3 +64,24 @@ echo tt.c(10) assert(not compiles(tt.d("x"))) assert(not compiles(tt.d(1, 2))) + +# test simple usage that delegates fields: +type + Other = object + a: int + b: string + MyObject = object + nested: Other + x, y: int + +template `.`(x: MyObject; field: untyped): untyped = + x.nested.field + +template `.=`(x: MyObject; field, value: untyped) = + x.nested.field = value + +var m: MyObject + +m.a = 4 +m.b = "foo" +echo m.x, " ", m.a diff --git a/tests/stdlib/somesql.sql b/tests/stdlib/somesql.sql new file mode 100644 index 000000000..285f93cec --- /dev/null +++ b/tests/stdlib/somesql.sql @@ -0,0 +1,298 @@ +create table anon40( + anon41 anon42 primary key default anon43(), + anon44 text unique not null, + anon45 text unique not null, + anon46 text not null, + anon47 text not null, + anon48 text default null, + anon49 text default null, + anon50 text default null, + anon51 text default null, + anon52 text default null, + anon53 text default null, + anon54 text default null, + anon55 text default null, + anon56 text default null, + anon57 text default null, + anon58 text default null, + anon59 text default null, + anon60 text default null, + anon61 text default null, + anon62 varchar(30) default null, + anon63 varchar(30) default null); +create table anon64( + anon41 serial primary key, + anon65 varchar(30) not null unique, + anon46 varchar(30) not null, + anon66 varchar(30) not null, + anon47 varchar(30) not null, + anon67 text not null, + anon55 varchar(30) not null unique, + anon68 varchar(30) default 'o', + anon69 boolean default true, + anon70 int not null references anon40(anon41)); +create table anon71( + anon72 varchar(30) not null primary key, + anon73 varchar(30) not null unique, + anon70 int not null references anon40(anon41)); +create table anon74( + anon72 varchar(30) not null primary key, + anon73 varchar(30) not null unique, + anon75 varchar(30) not null, + anon70 int not null references anon40(anon41), + foreign key(anon75) references anon71(anon72)); +create table anon76( + anon41 serial primary key, + anon72 varchar(30) not null unique, + anon73 varchar(30) not null unique, + anon77 varchar(30) not null, + anon70 int not null references anon40(anon41), + foreign key(anon77) references anon74(anon72)); +create table anon78( + anon41 serial primary key, + anon72 varchar(30) not null unique, + anon73 varchar(30) not null unique, + anon79 int not null, + anon80 varchar(30) default null, + anon81 int not null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41), + foreign key(anon79) references anon78(anon41), + foreign key(anon81) references anon76(anon41)); +create table anon82( + anon41 serial primary key, + anon72 varchar(30) not null unique, + anon73 text not null unique, + anon79 int not null, + anon80 text default null, + anon83 varchar(30) not null default 'd', + anon84 decimal default 0.00, + anon69 boolean not null default true, + anon85 decimal default 0.00, + anon86 decimal default 0.00, + anon87 decimal default 0.00, + anon70 int not null references anon40(anon41), + foreign key(anon79) references anon78(anon41)); +create table anon88( + anon41 serial primary key, + anon72 varchar(30) not null unique, + anon80 text default '', + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon89( + anon90 int not null primary key, + anon91 anon92 default 0.00, + anon93 varchar(30), + anon69 boolean not null default true, + anon70 int not null references anon40(anon41), + foreign key(anon90) references anon82(anon41)); +create table anon94( + anon41 serial primary key, + anon73 text unique not null, + anon80 text default null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon95( + anon41 serial primary key, + anon73 text unique not null, + anon96 int not null references anon94(anon41), + anon80 text default null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon97( + anon41 serial primary key, + anon73 text unique not null, + anon98 int not null references anon95(anon41), + anon80 text default null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon99( + anon41 serial primary key, + anon73 varchar(30) unique not null, + anon100 varchar(30) default null, + anon101 anon102 default 0, + anon103 varchar(30) default 'g', + anon104 int not null, + anon105 decimal not null default 1, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon106( + anon107 varchar(30) default 'g', + anon108 int references anon99(anon41) not null, + anon109 decimal default 1, + anon110 int references anon99(anon41) not null, + anon70 int not null references anon40(anon41)); +create table anon111( + anon41 serial primary key, + anon112 text unique not null, + anon73 text unique not null, + anon113 anon102 references anon97(anon41) not null, + anon114 varchar(30) not null, + anon115 int not null references anon88(anon41), + anon116 int not null references anon82(anon41), + anon117 int not null references anon82(anon41), + anon118 int not null references anon82(anon41), + anon119 int not null references anon82(anon41), + anon120 int not null references anon82(anon41), + anon121 int not null references anon82(anon41), + anon122 int references anon99(anon41) not null, + anon123 decimal default 0.00, + anon124 decimal default 0.00, + anon69 boolean default true, + anon70 int not null references anon40(anon41)); +create table anon125( + anon41 serial primary key, + anon126 int references anon111(anon41) not null, + anon80 text not null, + anon127 varchar(30) not null, + anon128 decimal default 0.00, + anon129 decimal default 0, + anon130 decimal default 0, + anon131 decimal default 0, + anon132 decimal default 0, + anon133 decimal default 0.00, + anon134 decimal default 0.00, + anon135 decimal default 0.00, + anon70 int not null references anon40(anon41), constraint anon136 check anon137(anon126, anon127, anon129)); +create table anon138( + anon41 serial primary key, + anon126 int references anon111(anon41) not null, + anon80 text not null, + anon127 varchar(30) not null, + anon139 date not null, + anon129 decimal default 0, + anon130 decimal default 0, + anon131 decimal default 0, + anon132 decimal default 0, + anon70 int not null references anon40(anon41), constraint anon136 check anon137(anon127, anon129)); +create table anon140( + anon41 serial primary key, + anon141 text unique not null, + anon46 text default null, + anon47 text default null, + anon57 varchar(30) default null, + anon142 text default null, + anon51 text default null, + anon143 varchar(30) default null, + anon53 text default null, + anon54 text default null, + anon55 text default null, + anon45 text default null, + anon69 boolean default true, + anon70 int not null references anon40(anon41)); +create table anon144( + anon41 serial primary key, + anon72 varchar(30) unique not null, + anon73 varchar(30) unique not null, + anon80 varchar(30) default null, + anon69 boolean default true, + anon70 int not null references anon40(anon41)); +create table anon145( + anon41 serial primary key, + anon72 varchar(30) unique not null, + anon73 varchar(30) unique not null, + anon146 int not null, + anon147 anon92 default 1, + anon148 anon92 default 9999999, + anon80 varchar(30) default null, + anon69 boolean default true, + anon149 int default 0, + anon150 int not null, + anon151 anon92 default 0, + anon70 int not null references anon40(anon41), + foreign key(anon150) references anon82(anon41), + foreign key(anon146) references anon144(anon41)); +create table anon152( + anon41 serial primary key, + anon73 varchar(30) not null unique, + anon153 varchar(30) not null unique, + anon80 text default null, + anon69 boolean not null default true, + anon70 int not null references anon40(anon41)); +create table anon154( + anon41 serial primary key not null, + anon155 int not null unique, + date date default anon156 not null, + anon157 anon102 references anon140(anon41) not null, + anon158 anon102 references anon64(anon41) not null, + anon159 decimal default 0 not null, + anon160 decimal default 0 not null, + anon161 decimal default 0 not null, + anon162 decimal default 0 not null, + anon163 decimal default 0 not null, + anon164 decimal default 0 not null, + anon165 decimal default 0.00, + anon166 decimal default 0 not null, + anon167 decimal default 0.00, + anon168 decimal default 0 not null, + anon169 boolean default false, + anon170 varchar(30) default 'ca', + anon171 varchar(30) default 'n', + anon172 varchar(30) not null default 'd', + anon173 decimal default 0.00, + anon174 decimal default 0.00, + anon175 int, + anon176 varchar(30) default null, + anon177 varchar(30) default '', + anon178 varchar(30) default null, + anon70 int not null references anon40(anon41)); +create table anon179( + anon41 serial primary key not null, + anon180 anon102 references anon154(anon41) not null, + anon181 int references anon125(anon41) not null, + anon182 int references anon82(anon41) not null, + anon122 int references anon99(anon41) not null, + anon183 decimal not null, + anon184 decimal default 0.00, + anon174 decimal default 0, + anon160 decimal default 0.00, + anon185 decimal default 0, + anon162 decimal default 0.00, + anon186 decimal default 0, + anon163 decimal default 0.00, + anon187 decimal default 0, + anon164 decimal default 0.00, + anon188 decimal default 0, + anon161 decimal default 0.00, + anon189 decimal default 0.00, + anon168 decimal default 0.00, + anon190 decimal not null, + anon191 decimal default 0, + anon83 varchar(30) not null default 't', + anon192 decimal default 0, + anon193 decimal not null, + anon194 decimal not null, + anon70 int not null references anon40(anon41)); +create table anon195( + anon41 serial not null, + anon196 int not null, + anon175 char not null, + anon90 int not null references anon82, + anon165 decimal default 0.00, + anon70 int not null references anon40(anon41), primary key(anon196, anon175)); +create table anon197( + anon41 serial not null, + anon196 int not null, + anon175 char not null, + anon198 int not null, + anon189 decimal default 0.00, + anon199 varchar(30) default null, + anon200 varchar(30) default null, + anon70 int not null references anon40(anon41), + primary key(anon196, anon175), + foreign key(anon198) references anon145(anon41)); +create table anon201( + anon41 serial primary key, + anon202 varchar(30) not null, + anon203 varchar(30) not null, + anon204 varchar(30) not null, + anon205 varchar(30) not null, + anon206 boolean default null, + anon70 int not null references anon40(anon41)); +create table anon207( + anon41 serial primary key, + anon208 varchar(30) not null, + anon209 varchar(30) not null, + anon204 varchar(30) default null, + anon70 int not null references anon40(anon41)); + diff --git a/tests/stdlib/tfrexp1.nim b/tests/stdlib/tfrexp1.nim new file mode 100644 index 000000000..c6bb2b38c --- /dev/null +++ b/tests/stdlib/tfrexp1.nim @@ -0,0 +1,44 @@ +discard """ + targets: "js c c++" + output: '''ok''' +""" + +import math +import strformat + +const manualTest = false + +proc frexp_test(lo, hi, step: float64) = + var exp: int + var frac: float64 + + var eps = 1e-15.float64 + + var x:float64 = lo + while x <= hi: + frac = frexp(x.float, exp) + let rslt = pow(2.0, float(exp)) * frac + + doAssert(abs(rslt - x) < eps) + + when manualTest: + echo fmt("x: {x:10.3f} exp: {exp:4d} frac: {frac:24.20f} check: {$(abs(rslt - x) < eps):-5s} {rslt: 9.3f}") + x += step + +when manualTest: + var exp: int + var frac: float64 + + for flval in [1.7976931348623157e+308, -1.7976931348623157e+308, # max, min float64 + 3.4028234663852886e+38, -3.4028234663852886e+38, # max, min float32 + 4.9406564584124654e-324, -4.9406564584124654e-324, # smallest/largest positive/negative float64 + 1.4012984643248171e-45, -1.4012984643248171e-45, # smallest/largest positive/negative float32 + 2.2250738585072014e-308, 1.1754943508222875e-38]: # smallest normal float64/float32 + frac = frexp(flval, exp) + echo fmt("{flval:25.16e}, {exp: 6d}, {frac: .20f} {frac * pow(2.0, float(exp)): .20e}") + + frexp_test(-1000.0, 1000.0, 0.0125) +else: + frexp_test(-1000000.0, 1000000.0, 0.125) + +echo "ok" diff --git a/tests/stdlib/tgetfileinfo.nim b/tests/stdlib/tgetfileinfo.nim index 1c897b702..019c2eb7f 100644 --- a/tests/stdlib/tgetfileinfo.nim +++ b/tests/stdlib/tgetfileinfo.nim @@ -61,7 +61,7 @@ proc testGetFileInfo = block: let testFile = open(getAppFilename()) - testHandle = fileHandle(testFile) + testHandle = getFileHandle(testFile) try: discard getFileInfo(testFile) #echo("Handle : Valid File : Success") diff --git a/tests/stdlib/thttpclient.nim b/tests/stdlib/thttpclient.nim index e759e2977..fff02722a 100644 --- a/tests/stdlib/thttpclient.nim +++ b/tests/stdlib/thttpclient.nim @@ -2,6 +2,8 @@ discard """ cmd: "nim c --threads:on -d:ssl $file" exitcode: 0 output: "OK" + disabled: "travis" + disabled: "appveyor" """ import strutils diff --git a/tests/stdlib/tjsonmacro.nim b/tests/stdlib/tjsonmacro.nim index 153cf8556..2cdd82305 100644 --- a/tests/stdlib/tjsonmacro.nim +++ b/tests/stdlib/tjsonmacro.nim @@ -2,7 +2,7 @@ discard """ file: "tjsonmacro.nim" output: "" """ -import json, strutils +import json, strutils, options, tables when isMainModule: # Tests inspired by own use case (with some additional tests). @@ -246,4 +246,138 @@ when isMainModule: var b = Bird(age: 3, height: 1.734, name: "bardo", colors: [red, blue]) let jnode = %b let data = jnode.to(Bird) - doAssert data == b \ No newline at end of file + doAssert data == b + + block: + type + MsgBase = ref object of RootObj + name*: string + + MsgChallenge = ref object of MsgBase + challenge*: string + + let data = %*{"name": "foo", "challenge": "bar"} + let msg = data.to(MsgChallenge) + doAssert msg.name == "foo" + doAssert msg.challenge == "bar" + + block: + type + Color = enum Red, Brown + Thing = object + animal: tuple[fur: bool, legs: int] + color: Color + + var j = parseJson(""" + {"animal":{"fur":true,"legs":6},"color":"Red"} + """) + + let parsed = to(j, Thing) + doAssert parsed.animal.fur + doAssert parsed.animal.legs == 6 + doAssert parsed.color == Red + + block: + type + Car = object + engine: tuple[name: string, capacity: float] + model: string + + let j = """ + {"engine": {"name": "V8", "capacity": 5.5}, "model": "Skyline"} + """ + + var i = 0 + proc mulTest: JsonNode = + i.inc() + return parseJson(j) + + let parsed = mulTest().to(Car) + doAssert parsed.engine.name == "V8" + + doAssert i == 1 + + block: + # Option[T] support! + type + Car1 = object # TODO: Codegen bug when `Car` + engine: tuple[name: string, capacity: Option[float]] + model: string + year: Option[int] + + let noYear = """ + {"engine": {"name": "V8", "capacity": 5.5}, "model": "Skyline"} + """ + + let noYearParsed = parseJson(noYear) + let noYearDeser = to(noYearParsed, Car1) + doAssert noYearDeser.engine.capacity == some(5.5) + doAssert noYearDeser.year.isNone + doAssert noYearDeser.engine.name == "V8" + + # Table[T, Y] support. + block: + type + Friend = object + name: string + age: int + + Dynamic = object + name: string + friends: Table[string, Friend] + + let data = """ + {"friends": { + "John": {"name": "John", "age": 35}, + "Elizabeth": {"name": "Elizabeth", "age": 23} + }, "name": "Dominik"} + """ + + let dataParsed = parseJson(data) + let dataDeser = to(dataParsed, Dynamic) + doAssert dataDeser.name == "Dominik" + doAssert dataDeser.friends["John"].age == 35 + doAssert dataDeser.friends["Elizabeth"].age == 23 + + # JsonNode support + block: + type + Test = object + name: string + fallback: JsonNode + + let data = """ + {"name": "FooBar", "fallback": 56.42} + """ + + let dataParsed = parseJson(data) + let dataDeser = to(dataParsed, Test) + doAssert dataDeser.name == "FooBar" + doAssert dataDeser.fallback.kind == JFloat + doAssert dataDeser.fallback.getFloat() == 56.42 + + # int64, float64 etc support. + block: + type + Test1 = object + a: int8 + b: int16 + c: int32 + d: int64 + e: uint8 + f: uint16 + g: uint32 + h: uint64 + i: float32 + j: float64 + + let data = """ + {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, + "h": 8, "i": 9.9, "j": 10.10} + """ + + let dataParsed = parseJson(data) + let dataDeser = to(dataParsed, Test1) + doAssert dataDeser.a == 1 + doAssert dataDeser.f == 6 + doAssert dataDeser.i == 9.9'f32 \ No newline at end of file diff --git a/tests/stdlib/tjsonmacro_reject.nim b/tests/stdlib/tjsonmacro_reject.nim new file mode 100644 index 000000000..00506449f --- /dev/null +++ b/tests/stdlib/tjsonmacro_reject.nim @@ -0,0 +1,18 @@ +discard """ + file: "tjsonmacro_reject.nim" + line: 11 + errormsg: "Use a named tuple instead of: (string, float)" +""" + +import json + +type + Car = object + engine: (string, float) + model: string + +let j = """ + {"engine": {"name": "V8", "capacity": 5.5}, model: "Skyline"} +""" +let parsed = parseJson(j) +echo(to(parsed, Car)) \ No newline at end of file diff --git a/tests/stdlib/tjsonmacro_reject2.nim b/tests/stdlib/tjsonmacro_reject2.nim new file mode 100644 index 000000000..b01153553 --- /dev/null +++ b/tests/stdlib/tjsonmacro_reject2.nim @@ -0,0 +1,21 @@ +discard """ + file: "tjsonmacro_reject2.nim" + line: 10 + errormsg: "The `to` macro does not support ref objects with cycles." +""" +import json + +type + Misdirection = object + cycle: Cycle + + Cycle = ref object + foo: string + cycle: Misdirection + +let data = """ + {"cycle": null} +""" + +let dataParsed = parseJson(data) +let dataDeser = to(dataParsed, Cycle) \ No newline at end of file diff --git a/tests/stdlib/tlists.nim b/tests/stdlib/tlists.nim index 4caa05c90..37e73c53f 100644 --- a/tests/stdlib/tlists.nim +++ b/tests/stdlib/tlists.nim @@ -17,7 +17,7 @@ block SinglyLinkedListTest1: block SinglyLinkedListTest2: var L: TSinglyLinkedList[string] for d in items(data): L.prepend($d) - assert($L == "[6, 5, 4, 3, 2, 1]") + assert($L == """["6", "5", "4", "3", "2", "1"]""") assert("4" in L) diff --git a/tests/stdlib/tmemfiles2.nim b/tests/stdlib/tmemfiles2.nim index 665e92e8a..7ea94cffc 100644 --- a/tests/stdlib/tmemfiles2.nim +++ b/tests/stdlib/tmemfiles2.nim @@ -1,10 +1,8 @@ discard """ file: "tmemfiles2.nim" - disabled: true output: '''Full read size: 20 Half read size: 10 Data: Hello''' """ -# doesn't work on windows. fmReadWrite doesn't create a file. import memfiles, os var mm, mm_full, mm_half: MemFile diff --git a/tests/stdlib/tnetdial.nim b/tests/stdlib/tnetdial.nim index da6088d70..695150179 100644 --- a/tests/stdlib/tnetdial.nim +++ b/tests/stdlib/tnetdial.nim @@ -2,6 +2,7 @@ discard """ cmd: "nim c --threads:on $file" exitcode: 0 output: "OK" + disabled: "travis" """ import os, net, nativesockets, asyncdispatch diff --git a/tests/stdlib/tparsesql.nim b/tests/stdlib/tparsesql.nim new file mode 100644 index 000000000..3dc949ea1 --- /dev/null +++ b/tests/stdlib/tparsesql.nim @@ -0,0 +1,191 @@ +discard """ + file: "tparsesql.nim" +""" + +import parsesql + +doAssert $parseSQL("SELECT foo FROM table;") == "select foo from table;" +doAssert $parseSQL(""" +SELECT + CustomerName, + ContactName, + Address, + City, + PostalCode, + Country, + CustomerName, + ContactName, + Address, + City, + PostalCode, + Country +FROM table;""") == "select CustomerName, ContactName, Address, City, PostalCode, Country, CustomerName, ContactName, Address, City, PostalCode, Country from table;" + +doAssert $parseSQL("SELECT foo FROM table limit 10") == "select foo from table limit 10;" +doAssert $parseSQL("SELECT foo, bar, baz FROM table limit 10") == "select foo, bar, baz from table limit 10;" +doAssert $parseSQL("SELECT foo AS bar FROM table") == "select foo as bar from table;" +doAssert $parseSQL("SELECT foo AS foo_prime, bar AS bar_prime, baz AS baz_prime FROM table") == "select foo as foo_prime, bar as bar_prime, baz as baz_prime from table;" +doAssert $parseSQL("SELECT * FROM table") == "select * from table;" + + +#TODO add count(*) +#doAssert $parseSQL("SELECT COUNT(*) FROM table" + +doAssert $parseSQL(""" +SELECT * FROM table +WHERE a = b and c = d +""") == "select * from table where a = b and c = d;" + +doAssert $parseSQL(""" +SELECT * FROM table +WHERE not b +""") == "select * from table where not b;" + +doAssert $parseSQL(""" +SELECT + * +FROM + table +WHERE + a and not b +""") == "select * from table where a and not b;" + +doAssert $parseSQL(""" +SELECT * FROM table +WHERE a = b and c = d or n is null and not b + 1 = 3 +""") == "select * from table where a = b and c = d or n is null and not b + 1 = 3;" + +doAssert $parseSQL(""" +SELECT * FROM table +WHERE (a = b and c = d) or (n is null and not b + 1 = 3) +""") == "select * from table where(a = b and c = d) or (n is null and not b + 1 = 3);" + +doAssert $parseSQL(""" +SELECT * FROM table +HAVING a = b and c = d +""") == "select * from table having a = b and c = d;" + +doAssert $parseSQL(""" +SELECT a, b FROM table +GROUP BY a +""") == "select a, b from table group by a;" + +doAssert $parseSQL(""" +SELECT a, b FROM table +GROUP BY 1, 2 +""") == "select a, b from table group by 1, 2;" + +doAssert $parseSQL("SELECT t.a FROM t as t") == "select t.a from t as t;" + +doAssert $parseSQL(""" +SELECT a, b FROM ( + SELECT * FROM t +) +""") == "select a, b from(select * from t);" + +doAssert $parseSQL(""" +SELECT a, b FROM ( + SELECT * FROM t +) as foo +""") == "select a, b from(select * from t) as foo;" + +doAssert $parseSQL(""" +SELECT a, b FROM ( + SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM innerTable as inner1 + ) as inner2 + ) as inner3 + ) as inner4 +) as inner5 +""") == "select a, b from(select * from(select * from(select * from(select * from innerTable as inner1) as inner2) as inner3) as inner4) as inner5;" + +doAssert $parseSQL(""" +SELECT a, b FROM + (SELECT * FROM a), + (SELECT * FROM b), + (SELECT * FROM c) +""") == "select a, b from(select * from a),(select * from b),(select * from c);" + +doAssert $parseSQL(""" +SELECT * FROM Products +WHERE Price BETWEEN 10 AND 20; +""") == "select * from Products where Price between 10 and 20;" + +doAssert $parseSQL(""" +SELECT id FROM a +JOIN b +ON a.id == b.id +""") == "select id from a join b on a.id == b.id;" + +doAssert $parseSQL(""" +SELECT id FROM a +JOIN (SELECT id from c) as b +ON a.id == b.id +""") == "select id from a join(select id from c) as b on a.id == b.id;" + +doAssert $parseSQL(""" +SELECT id FROM a +INNER JOIN b +ON a.id == b.id +""") == "select id from a inner join b on a.id == b.id;" + +doAssert $parseSQL(""" +SELECT id FROM a +OUTER JOIN b +ON a.id == b.id +""") == "select id from a outer join b on a.id == b.id;" + +doAssert $parseSQL(""" +SELECT id FROM a +CROSS JOIN b +ON a.id == b.id +""") == "select id from a cross join b on a.id == b.id;" + +doAssert $parseSQL(""" +CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic'); +CREATE TABLE holidays ( + num_weeks int, + happiness happiness +); +CREATE INDEX table1_attr1 ON table1(attr1); +SELECT * FROM myTab WHERE col1 = 'happy'; +""") == "create type happiness as enum ('happy' , 'very happy' , 'ecstatic' ); create table holidays(num_weeks int , happiness happiness );; create index table1_attr1 on table1(attr1 );; select * from myTab where col1 = 'happy';" + +doAssert $parseSQL(""" +INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country) +VALUES ('Cardinal', 'Tom B. Erichsen', 'Skagen 21', 'Stavanger', '4006', 'Norway'); +""") == "insert into Customers (CustomerName , ContactName , Address , City , PostalCode , Country ) values ('Cardinal' , 'Tom B. Erichsen' , 'Skagen 21' , 'Stavanger' , '4006' , 'Norway' );" + +doAssert $parseSQL(""" +INSERT INTO TableName DEFAULT VALUES +""") == "insert into TableName default values;" + +doAssert $parseSQL(""" +UPDATE Customers +SET ContactName = 'Alfred Schmidt', City= 'Frankfurt' +WHERE CustomerID = 1; +""") == "update Customers set ContactName = 'Alfred Schmidt' , City = 'Frankfurt' where CustomerID = 1;" + +doAssert $parseSQL("DELETE FROM table_name;") == "delete from table_name;" + +doAssert $parseSQL("DELETE * FROM table_name;") == "delete from table_name;" + +doAssert $parseSQL(""" +--Select all: +SELECT * FROM Customers; +""") == "select * from Customers;" + +doAssert $parseSQL(""" +SELECT * FROM Customers WHERE (CustomerName LIKE 'L%' +OR CustomerName LIKE 'R%' /*OR CustomerName LIKE 'S%' +OR CustomerName LIKE 'T%'*/ OR CustomerName LIKE 'W%') +AND Country='USA' +ORDER BY CustomerName; +""") == "select * from Customers where(CustomerName like 'L%' or CustomerName like 'R%' or CustomerName like 'W%') and Country = 'USA' order by CustomerName;" + +# parse keywords as identifires +doAssert $parseSQL(""" +SELECT `SELECT`, `FROM` as `GROUP` FROM `WHERE`; +""") == """select "SELECT", "FROM" as "GROUP" from "WHERE";""" diff --git a/tests/stdlib/treloop.nim b/tests/stdlib/treloop.nim index 35236708c..b4221525d 100644 --- a/tests/stdlib/treloop.nim +++ b/tests/stdlib/treloop.nim @@ -1,5 +1,5 @@ discard """ - output: "@[(, +, 1, 2, )]" + output: '''@["(", "+", " 1", " 2", ")"]''' """ import re diff --git a/tests/stdlib/tsqlparser.nim b/tests/stdlib/tsqlparser.nim new file mode 100644 index 000000000..4a7b2f7d7 --- /dev/null +++ b/tests/stdlib/tsqlparser.nim @@ -0,0 +1,12 @@ +discard """ + output: '''true''' +""" + +# Just check that we can parse 'somesql' and render it without crashes. + +import parsesql, streams, os + +var tree = parseSql(newFileStream(getAppDir() / "somesql.sql"), "somesql") +discard renderSql(tree) + +echo "true" diff --git a/tests/stdlib/tstring.nim b/tests/stdlib/tstring.nim index ddf533a17..660746150 100644 --- a/tests/stdlib/tstring.nim +++ b/tests/stdlib/tstring.nim @@ -50,6 +50,30 @@ proc test_string_slice() = s[2..0] = numbers doAssert s == "ab1234567890cdefghijklmnopqrstuvwxyz" + # bug #6223 + doAssertRaises(IndexError): + discard s[0..999] + echo("OK") +proc test_string_cmp() = + let world = "hello\0world" + let earth = "hello\0earth" + let short = "hello\0" + let hello = "hello" + let goodbye = "goodbye" + + doAssert world == world + doAssert world != earth + doAssert world != short + doAssert world != hello + doAssert world != goodbye + + doAssert cmp(world, world) == 0 + doAssert cmp(world, earth) > 0 + doAssert cmp(world, short) > 0 + doAssert cmp(world, hello) > 0 + doAssert cmp(world, goodbye) > 0 + test_string_slice() +test_string_cmp() diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim index fef1b38c2..071dae5a7 100644 --- a/tests/stdlib/tstrutil.nim +++ b/tests/stdlib/tstrutil.nim @@ -13,15 +13,13 @@ proc testStrip() = proc testRemoveSuffix = var s = "hello\n\r" s.removeSuffix - assert s == "hello\n" - s.removeSuffix assert s == "hello" s.removeSuffix assert s == "hello" s = "hello\n\n" s.removeSuffix - assert s == "hello\n" + assert s == "hello" s = "hello\r" s.removeSuffix @@ -41,7 +39,31 @@ proc testRemoveSuffix = s.removeSuffix({'s','z'}) assert s == "hello" s.removeSuffix({'l','o'}) - assert s == "hell" + assert s == "he" + + s = "aeiou" + s.removeSuffix("") + assert s == "aeiou" + + s = "" + s.removeSuffix("") + assert s == "" + + s = " " + s.removeSuffix + assert s == " " + + s = " " + s.removeSuffix("") + assert s == " " + + s = " " + s.removeSuffix(" ") + assert s == " " + + s = " " + s.removeSuffix(' ') + assert s == "" # Contrary to Chomp in other languages # empty string does not change behaviour @@ -49,9 +71,71 @@ proc testRemoveSuffix = s.removeSuffix("") assert s == "hello\r\n\r\n" +proc testRemovePrefix = + var s = "\n\rhello" + s.removePrefix + assert s == "hello" + s.removePrefix + assert s == "hello" + + s = "\n\nhello" + s.removePrefix + assert s == "hello" + + s = "\rhello" + s.removePrefix + assert s == "hello" + + s = "hello \n there" + s.removePrefix + assert s == "hello \n there" + + s = "hello" + s.removePrefix("hel") + assert s == "lo" + s.removePrefix('l') + assert s == "o" + + s = "hellos" + s.removePrefix({'h','e'}) + assert s == "llos" + s.removePrefix({'l','o'}) + assert s == "s" + + s = "aeiou" + s.removePrefix("") + assert s == "aeiou" + + s = "" + s.removePrefix("") + assert s == "" + + s = " " + s.removePrefix + assert s == " " + + s = " " + s.removePrefix("") + assert s == " " + + s = " " + s.removePrefix(" ") + assert s == " " + + s = " " + s.removePrefix(' ') + assert s == "" + + # Contrary to Chomp in other languages + # empty string does not change behaviour + s = "\r\n\r\nhello" + s.removePrefix("") + assert s == "\r\n\r\nhello" + proc main() = testStrip() testRemoveSuffix() + testRemovePrefix() for p in split("/home/a1:xyz:/usr/bin", {':'}): write(stdout, p) @@ -64,6 +148,25 @@ proc testDelete = delete(s, 0, 0) assert s == "1236789ABCDEFG" + +proc testIsAlphaNumeric = + assert isAlphaNumeric("abcdABC1234") == true + assert isAlphaNumeric("a") == true + assert isAlphaNumeric("abcABC?1234") == false + assert isAlphaNumeric("abcABC 1234") == false + assert isAlphaNumeric(".") == false + +testIsAlphaNumeric() + +proc testIsDigit = + assert isDigit("1") == true + assert isDigit("1234") == true + assert isDigit("abcABC?1234") == false + assert isDigit(".") == false + assert isDigit(":") == false + +testIsDigit() + proc testFind = assert "0123456789ABCDEFGH".find('A') == 10 assert "0123456789ABCDEFGH".find('A', 5) == 10 diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim index 05c91ccb2..a6ac186cc 100644 --- a/tests/stdlib/ttimes.nim +++ b/tests/stdlib/ttimes.nim @@ -1,16 +1,17 @@ # test the new time module discard """ file: "ttimes.nim" - action: "run" + output: '''[Suite] ttimes +''' """ import - times, strutils + times, os, strutils, unittest # $ date --date='@2147483647' # Tue 19 Jan 03:14:07 GMT 2038 -proc checkFormat(t: TimeInfo, format, expected: string) = +proc checkFormat(t: DateTime, format, expected: string) = let actual = t.format(format) if actual != expected: echo "Formatting failure!" @@ -18,7 +19,7 @@ proc checkFormat(t: TimeInfo, format, expected: string) = echo "actual : ", actual doAssert false -let t = getGMTime(fromSeconds(2147483647)) +let t = fromUnix(2147483647).utc t.checkFormat("ddd dd MMM hh:mm:ss yyyy", "Tue 19 Jan 03:14:07 2038") t.checkFormat("ddd ddMMMhh:mm:ssyyyy", "Tue 19Jan03:14:072038") t.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & @@ -27,107 +28,41 @@ t.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & t.checkFormat("yyyyMMddhhmmss", "20380119031407") -let t2 = getGMTime(fromSeconds(160070789)) # Mon 27 Jan 16:06:29 GMT 1975 +let t2 = fromUnix(160070789).utc # Mon 27 Jan 16:06:29 GMT 1975 t2.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & " ss t tt y yy yyy yyyy yyyyy z zz zzz", "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 +0 +00 +00:00") -var t4 = getGMTime(fromSeconds(876124714)) # Mon 6 Oct 08:58:34 BST 1997 +var t4 = fromUnix(876124714).utc # Mon 6 Oct 08:58:34 BST 1997 t4.checkFormat("M MM MMM MMMM", "10 10 Oct October") # Interval tests (t4 - initInterval(years = 2)).checkFormat("yyyy", "1995") (t4 - initInterval(years = 7, minutes = 34, seconds = 24)).checkFormat("yyyy mm ss", "1990 24 10") -proc parseTest(s, f, sExpected: string, ydExpected: int) = - let - parsed = s.parse(f) - parsedStr = $getGMTime(toTime(parsed)) - if parsedStr != sExpected: - echo "Parsing failure!" - echo "expected: ", sExpected - echo "actual : ", parsedStr - doAssert false - doAssert(parsed.yearday == ydExpected) -proc parseTestTimeOnly(s, f, sExpected: string) = - doAssert(sExpected in $s.parse(f)) - -# because setting a specific timezone for testing is platform-specific, we use -# explicit timezone offsets in all tests. - -parseTest("Tuesday at 09:04am on Dec 15, 2015 +0", - "dddd at hh:mmtt on MMM d, yyyy z", "2015-12-15T09:04:00+00:00", 348) -# ANSIC = "Mon Jan _2 15:04:05 2006" -parseTest("Thu Jan 12 15:04:05 2006 +0", "ddd MMM dd HH:mm:ss yyyy z", - "2006-01-12T15:04:05+00:00", 11) -# UnixDate = "Mon Jan _2 15:04:05 MST 2006" -parseTest("Thu Jan 12 15:04:05 2006 +0", "ddd MMM dd HH:mm:ss yyyy z", - "2006-01-12T15:04:05+00:00", 11) -# RubyDate = "Mon Jan 02 15:04:05 -0700 2006" -parseTest("Mon Feb 29 15:04:05 -07:00 2016 +0", "ddd MMM dd HH:mm:ss zzz yyyy z", - "2016-02-29T15:04:05+00:00", 59) # leap day -# RFC822 = "02 Jan 06 15:04 MST" -parseTest("12 Jan 16 15:04 +0", "dd MMM yy HH:mm z", - "2016-01-12T15:04:00+00:00", 11) -# RFC822Z = "02 Jan 06 15:04 -0700" # RFC822 with numeric zone -parseTest("01 Mar 16 15:04 -07:00", "dd MMM yy HH:mm zzz", - "2016-03-01T22:04:00+00:00", 60) # day after february in leap year -# RFC850 = "Monday, 02-Jan-06 15:04:05 MST" -parseTest("Monday, 12-Jan-06 15:04:05 +0", "dddd, dd-MMM-yy HH:mm:ss z", - "2006-01-12T15:04:05+00:00", 11) -# RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" -parseTest("Sun, 01 Mar 2015 15:04:05 +0", "ddd, dd MMM yyyy HH:mm:ss z", - "2015-03-01T15:04:05+00:00", 59) # day after february in non-leap year -# RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" # RFC1123 with numeric zone -parseTest("Thu, 12 Jan 2006 15:04:05 -07:00", "ddd, dd MMM yyyy HH:mm:ss zzz", - "2006-01-12T22:04:05+00:00", 11) -# RFC3339 = "2006-01-02T15:04:05Z07:00" -parseTest("2006-01-12T15:04:05Z-07:00", "yyyy-MM-ddTHH:mm:ssZzzz", - "2006-01-12T22:04:05+00:00", 11) -parseTest("2006-01-12T15:04:05Z-07:00", "yyyy-MM-dd'T'HH:mm:ss'Z'zzz", - "2006-01-12T22:04:05+00:00", 11) -# RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" -parseTest("2006-01-12T15:04:05.999999999Z-07:00", - "yyyy-MM-ddTHH:mm:ss.999999999Zzzz", "2006-01-12T22:04:05+00:00", 11) -for tzFormat in ["z", "zz", "zzz"]: - # formatting timezone as 'Z' for UTC - parseTest("2001-01-12T22:04:05Z", "yyyy-MM-dd'T'HH:mm:ss" & tzFormat, - "2001-01-12T22:04:05+00:00", 11) -# Kitchen = "3:04PM" -parseTestTimeOnly("3:04PM", "h:mmtt", "15:04:00") -#when not defined(testing): -# echo "Kitchen: " & $s.parse(f) -# var ti = timeToTimeInfo(getTime()) -# echo "Todays date after decoding: ", ti -# var tint = timeToTimeInterval(getTime()) -# echo "Todays date after decoding to interval: ", tint - # checking dayOfWeek matches known days -doAssert getDayOfWeek(21, 9, 1900) == dFri -doAssert getDayOfWeek(1, 1, 1970) == dThu -doAssert getDayOfWeek(21, 9, 1970) == dMon -doAssert getDayOfWeek(1, 1, 2000) == dSat -doAssert getDayOfWeek(1, 1, 2021) == dFri -# Julian tests -doAssert getDayOfWeekJulian(21, 9, 1900) == dFri -doAssert getDayOfWeekJulian(21, 9, 1970) == dMon -doAssert getDayOfWeekJulian(1, 1, 2000) == dSat -doAssert getDayOfWeekJulian(1, 1, 2021) == dFri - -# toSeconds tests with GM timezone -let t4L = getGMTime(fromSeconds(876124714)) -doAssert toSeconds(toTime(t4L)) == 876124714 -doAssert toSeconds(toTime(t4L)) + t4L.timezone.float == toSeconds(toTime(t4)) +doAssert getDayOfWeek(01, mJan, 0000) == dSat +doAssert getDayOfWeek(01, mJan, -0023) == dSat +doAssert getDayOfWeek(21, mSep, 1900) == dFri +doAssert getDayOfWeek(01, mJan, 1970) == dThu +doAssert getDayOfWeek(21, mSep, 1970) == dMon +doAssert getDayOfWeek(01, mJan, 2000) == dSat +doAssert getDayOfWeek(01, mJan, 2021) == dFri + +# toUnix tests with GM timezone +let t4L = fromUnix(876124714).utc +doAssert toUnix(toTime(t4L)) == 876124714 +doAssert toUnix(toTime(t4L)) + t4L.utcOffset == toUnix(toTime(t4)) # adding intervals var - a1L = toSeconds(toTime(t4L + initInterval(hours = 1))) + t4L.timezone.float - a1G = toSeconds(toTime(t4)) + 60.0 * 60.0 + a1L = toUnix(toTime(t4L + initInterval(hours = 1))) + t4L.utcOffset + a1G = toUnix(toTime(t4)) + 60 * 60 doAssert a1L == a1G # subtracting intervals -a1L = toSeconds(toTime(t4L - initInterval(hours = 1))) + t4L.timezone.float -a1G = toSeconds(toTime(t4)) - (60.0 * 60.0) +a1L = toUnix(toTime(t4L - initInterval(hours = 1))) + t4L.utcOffset +a1G = toUnix(toTime(t4)) - (60 * 60) doAssert a1L == a1G # add/subtract TimeIntervals and Time/TimeInfo @@ -143,45 +78,16 @@ doAssert ti1 == getTime() ti1 += 1.days doAssert ti1 == getTime() + 1.days -# overflow of TimeIntervals on initalisation -doAssert initInterval(milliseconds = 25000) == initInterval(seconds = 25) -doAssert initInterval(seconds = 65) == initInterval(seconds = 5, minutes = 1) -doAssert initInterval(hours = 25) == initInterval(hours = 1, days = 1) -doAssert initInterval(months = 13) == initInterval(months = 1, years = 1) - # Bug with adding a day to a Time let day = 24.hours let tomorrow = getTime() + day doAssert tomorrow - getTime() == 60*60*24 -doAssert milliseconds(1000 * 60) == minutes(1) -doAssert milliseconds(1000 * 60 * 60) == hours(1) -doAssert milliseconds(1000 * 60 * 60 * 24) == days(1) -doAssert seconds(60 * 60) == hours(1) -doAssert seconds(60 * 60 * 24) == days(1) -doAssert seconds(60 * 60 + 65) == (hours(1) + minutes(1) + seconds(5)) - -# Bug with parse not setting DST properly if the current local DST differs from -# the date being parsed. Need to test parse dates both in and out of DST. We -# are testing that be relying on the fact that tranforming a TimeInfo to a Time -# and back again will correctly set the DST value. With the incorrect parse -# behavior this will introduce a one hour offset from the named time and the -# parsed time if the DST value differs between the current time and the date we -# are parsing. -# -# Unfortunately these tests depend on the locale of the system in which they -# are run. They will not be meaningful when run in a locale without DST. They -# also assume that Jan. 1 and Jun. 1 will have differing isDST values. -let dstT1 = parse("2016-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss") -let dstT2 = parse("2016-06-01 00:00:00", "yyyy-MM-dd HH:mm:ss") -doAssert dstT1 == getLocalTime(toTime(dstT1)) -doAssert dstT2 == getLocalTime(toTime(dstT2)) - # Comparison between Time objects should be detected by compiler # as 'noSideEffect'. proc cmpTimeNoSideEffect(t1: Time, t2: Time): bool {.noSideEffect.} = result = t1 == t2 -doAssert cmpTimeNoSideEffect(0.fromSeconds, 0.fromSeconds) +doAssert cmpTimeNoSideEffect(0.fromUnix, 0.fromUnix) # Additionally `==` generic for seq[T] has explicit 'noSideEffect' pragma # so we can check above condition by comparing seq[Time] sequences let seqA: seq[Time] = @[] @@ -195,43 +101,197 @@ for tz in [ (-1800, "+0", "+00", "+00:30"), # half an hour (7200, "-2", "-02", "-02:00"), # positive (38700, "-10", "-10", "-10:45")]: # positive with three quaters hour - let ti = TimeInfo(monthday: 1, timezone: tz[0]) + let ti = DateTime(month: mJan, monthday: 1, utcOffset: tz[0]) doAssert ti.format("z") == tz[1] doAssert ti.format("zz") == tz[2] doAssert ti.format("zzz") == tz[3] -block formatDst: - var ti = TimeInfo(monthday: 1, isDst: true) - - # BST - ti.timezone = 0 - doAssert ti.format("z") == "+1" - doAssert ti.format("zz") == "+01" - doAssert ti.format("zzz") == "+01:00" - - # EDT - ti.timezone = 5 * 60 * 60 - doAssert ti.format("z") == "-4" - doAssert ti.format("zz") == "-04" - doAssert ti.format("zzz") == "-04:00" - -block dstTest: - let nonDst = TimeInfo(year: 2015, month: mJan, monthday: 01, yearday: 0, - weekday: dThu, hour: 00, minute: 00, second: 00, isDST: false, timezone: 0) - var dst = nonDst - dst.isDst = true - # note that both isDST == true and isDST == false are valid here because - # DST is in effect on January 1st in some southern parts of Australia. - # FIXME: Fails in UTC - # doAssert nonDst.toTime() - dst.toTime() == 3600 - doAssert nonDst.format("z") == "+0" - doAssert dst.format("z") == "+1" - - # parsing will set isDST in relation to the local time. We take a date in - # January and one in July to maximize the probability to hit one date with DST - # and one without on the local machine. However, this is not guaranteed. +block countLeapYears: + # 1920, 2004 and 2020 are leap years, and should be counted starting at the following year + doAssert countLeapYears(1920) + 1 == countLeapYears(1921) + doAssert countLeapYears(2004) + 1 == countLeapYears(2005) + doAssert countLeapYears(2020) + 1 == countLeapYears(2021) + +block timezoneConversion: + var l = now() + let u = l.utc + l = u.local + + doAssert l.timezone == local() + doAssert u.timezone == utc() + +template parseTest(s, f, sExpected: string, ydExpected: int) = let - parsedJan = parse("2016-01-05 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz") - parsedJul = parse("2016-07-01 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz") - doAssert toTime(parsedJan) == fromSeconds(1451962800) - doAssert toTime(parsedJul) == fromSeconds(1467342000) + parsed = s.parse(f, utc()) + parsedStr = $parsed + check parsedStr == sExpected + if parsed.yearday != ydExpected: + echo s + echo parsed.repr + echo parsed.yearday, " exp: ", ydExpected + check(parsed.yearday == ydExpected) + +template parseTestTimeOnly(s, f, sExpected: string) = + check sExpected in $s.parse(f, utc()) + +# because setting a specific timezone for testing is platform-specific, we use +# explicit timezone offsets in all tests. +template runTimezoneTests() = + parseTest("Tuesday at 09:04am on Dec 15, 2015 +0", + "dddd at hh:mmtt on MMM d, yyyy z", "2015-12-15T09:04:00+00:00", 348) + # ANSIC = "Mon Jan _2 15:04:05 2006" + parseTest("Thu Jan 12 15:04:05 2006 +0", "ddd MMM dd HH:mm:ss yyyy z", + "2006-01-12T15:04:05+00:00", 11) + # UnixDate = "Mon Jan _2 15:04:05 MST 2006" + parseTest("Thu Jan 12 15:04:05 2006 +0", "ddd MMM dd HH:mm:ss yyyy z", + "2006-01-12T15:04:05+00:00", 11) + # RubyDate = "Mon Jan 02 15:04:05 -0700 2006" + parseTest("Mon Feb 29 15:04:05 -07:00 2016 +0", "ddd MMM dd HH:mm:ss zzz yyyy z", + "2016-02-29T15:04:05+00:00", 59) # leap day + # RFC822 = "02 Jan 06 15:04 MST" + parseTest("12 Jan 16 15:04 +0", "dd MMM yy HH:mm z", + "2016-01-12T15:04:00+00:00", 11) + # RFC822Z = "02 Jan 06 15:04 -0700" # RFC822 with numeric zone + parseTest("01 Mar 16 15:04 -07:00", "dd MMM yy HH:mm zzz", + "2016-03-01T22:04:00+00:00", 60) # day after february in leap year + # RFC850 = "Monday, 02-Jan-06 15:04:05 MST" + parseTest("Monday, 12-Jan-06 15:04:05 +0", "dddd, dd-MMM-yy HH:mm:ss z", + "2006-01-12T15:04:05+00:00", 11) + # RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" + parseTest("Sun, 01 Mar 2015 15:04:05 +0", "ddd, dd MMM yyyy HH:mm:ss z", + "2015-03-01T15:04:05+00:00", 59) # day after february in non-leap year + # RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" # RFC1123 with numeric zone + parseTest("Thu, 12 Jan 2006 15:04:05 -07:00", "ddd, dd MMM yyyy HH:mm:ss zzz", + "2006-01-12T22:04:05+00:00", 11) + # RFC3339 = "2006-01-02T15:04:05Z07:00" + parseTest("2006-01-12T15:04:05Z-07:00", "yyyy-MM-ddTHH:mm:ssZzzz", + "2006-01-12T22:04:05+00:00", 11) + parseTest("2006-01-12T15:04:05Z-07:00", "yyyy-MM-dd'T'HH:mm:ss'Z'zzz", + "2006-01-12T22:04:05+00:00", 11) + # RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" + parseTest("2006-01-12T15:04:05.999999999Z-07:00", + "yyyy-MM-ddTHH:mm:ss.999999999Zzzz", "2006-01-12T22:04:05+00:00", 11) + for tzFormat in ["z", "zz", "zzz"]: + # formatting timezone as 'Z' for UTC + parseTest("2001-01-12T22:04:05Z", "yyyy-MM-dd'T'HH:mm:ss" & tzFormat, + "2001-01-12T22:04:05+00:00", 11) + # Kitchen = "3:04PM" + parseTestTimeOnly("3:04PM", "h:mmtt", "15:04:00") + #when not defined(testing): + # echo "Kitchen: " & $s.parse(f) + # var ti = timeToTimeInfo(getTime()) + # echo "Todays date after decoding: ", ti + # var tint = timeToTimeInterval(getTime()) + # echo "Todays date after decoding to interval: ", tint + + # Bug with parse not setting DST properly if the current local DST differs from + # the date being parsed. Need to test parse dates both in and out of DST. We + # are testing that be relying on the fact that tranforming a TimeInfo to a Time + # and back again will correctly set the DST value. With the incorrect parse + # behavior this will introduce a one hour offset from the named time and the + # parsed time if the DST value differs between the current time and the date we + # are parsing. + let dstT1 = parse("2016-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss") + let dstT2 = parse("2016-06-01 00:00:00", "yyyy-MM-dd HH:mm:ss") + check dstT1 == toTime(dstT1).local + check dstT2 == toTime(dstT2).local + + block dstTest: + # parsing will set isDST in relation to the local time. We take a date in + # January and one in July to maximize the probability to hit one date with DST + # and one without on the local machine. However, this is not guaranteed. + let + parsedJan = parse("2016-01-05 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz") + parsedJul = parse("2016-07-01 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz") + doAssert toTime(parsedJan) == fromUnix(1451962800) + doAssert toTime(parsedJul) == fromUnix(1467342000) + +suite "ttimes": + + # Generate tests for multiple timezone files where available + # Set the TZ env var for each test + when defined(Linux) or defined(macosx): + const tz_dir = "/usr/share/zoneinfo" + const f = "yyyy-MM-dd HH:mm zzz" + + let orig_tz = getEnv("TZ") + var tz_cnt = 0 + for tz_fn in walkFiles(tz_dir & "/*"): + if symlinkExists(tz_fn) or tz_fn.endsWith(".tab") or + tz_fn.endsWith(".list"): + continue + + test "test for " & tz_fn: + tz_cnt.inc + putEnv("TZ", tz_fn) + runTimezoneTests() + + test "enough timezone files tested": + check tz_cnt > 10 + + test "dst handling": + putEnv("TZ", "Europe/Stockholm") + # In case of an impossible time, the time is moved to after the impossible time period + check initDateTime(26, mMar, 2017, 02, 30, 00).format(f) == "2017-03-26 03:30 +02:00" + # In case of an ambiguous time, the earlier time is choosen + check initDateTime(29, mOct, 2017, 02, 00, 00).format(f) == "2017-10-29 02:00 +02:00" + # These are just dates on either side of the dst switch + check initDateTime(29, mOct, 2017, 01, 00, 00).format(f) == "2017-10-29 01:00 +02:00" + check initDateTime(29, mOct, 2017, 01, 00, 00).isDst + check initDateTime(29, mOct, 2017, 03, 01, 00).format(f) == "2017-10-29 03:01 +01:00" + check (not initDateTime(29, mOct, 2017, 03, 01, 00).isDst) + + check initDateTime(21, mOct, 2017, 01, 00, 00).format(f) == "2017-10-21 01:00 +02:00" + + test "issue #6520": + putEnv("TZ", "Europe/Stockholm") + var local = fromUnix(1469275200).local + var utc = fromUnix(1469275200).utc + + let claimedOffset = local.utcOffset + local.utcOffset = 0 + check claimedOffset == utc.toTime - local.toTime + + test "issue #5704": + putEnv("TZ", "Asia/Seoul") + let diff = parse("19700101-000000", "yyyyMMdd-hhmmss").toTime - parse("19000101-000000", "yyyyMMdd-hhmmss").toTime + check diff == 2208986872 + + test "issue #6465": + putEnv("TZ", "Europe/Stockholm") + let dt = parse("2017-03-25 12:00", "yyyy-MM-dd hh:mm") + check $(dt + 1.days) == "2017-03-26T12:00:00+02:00" + + test "datetime before epoch": + check $fromUnix(-2147483648).utc == "1901-12-13T20:45:52+00:00" + + test "adding/subtracting time across dst": + putenv("TZ", "Europe/Stockholm") + + let dt1 = initDateTime(26, mMar, 2017, 03, 00, 00) + check $(dt1 - 1.seconds) == "2017-03-26T01:59:59+01:00" + + var dt2 = initDateTime(29, mOct, 2017, 02, 59, 59) + check $(dt2 + 1.seconds) == "2017-10-29T02:00:00+01:00" + + putEnv("TZ", orig_tz) + + else: + # not on Linux or macosx: run one parseTest only + test "parseTest": + runTimezoneTests() + + test "isLeapYear": + check isLeapYear(2016) + check (not isLeapYear(2015)) + check isLeapYear(2000) + check (not isLeapYear(1900)) + + test "subtract months": + var dt = initDateTime(1, mFeb, 2017, 00, 00, 00, utc()) + check $(dt - 1.months) == "2017-01-01T00:00:00+00:00" + dt = initDateTime(15, mMar, 2017, 00, 00, 00, utc()) + check $(dt - 1.months) == "2017-02-15T00:00:00+00:00" + dt = initDateTime(31, mMar, 2017, 00, 00, 00, utc()) + # This happens due to monthday overflow. It's consistent with Phobos. + check $(dt - 1.months) == "2017-03-03T00:00:00+00:00" \ No newline at end of file diff --git a/tests/stdlib/tunittest.nim b/tests/stdlib/tunittest.nim index e4a801871..86b9fd037 100644 --- a/tests/stdlib/tunittest.nim +++ b/tests/stdlib/tunittest.nim @@ -13,6 +13,8 @@ discard """ [Suite] bug #5784 +[Suite] test name filtering + ''' """ @@ -120,3 +122,39 @@ suite "bug #5784": field: int var obj: Obj check obj.isNil or obj.field == 0 + +when defined(testing): + suite "test name filtering": + test "test name": + check matchFilter("suite1", "foo", "") + check matchFilter("suite1", "foo", "foo") + check matchFilter("suite1", "foo", "::") + check matchFilter("suite1", "foo", "*") + check matchFilter("suite1", "foo", "::foo") + check matchFilter("suite1", "::foo", "::foo") + + test "test name - glob": + check matchFilter("suite1", "foo", "f*") + check matchFilter("suite1", "foo", "*oo") + check matchFilter("suite1", "12345", "12*345") + check matchFilter("suite1", "q*wefoo", "q*wefoo") + check false == matchFilter("suite1", "foo", "::x") + check false == matchFilter("suite1", "foo", "::x*") + check false == matchFilter("suite1", "foo", "::*x") + # overlap + check false == matchFilter("suite1", "12345", "123*345") + check matchFilter("suite1", "ab*c::d*e::f", "ab*c::d*e::f") + + test "suite name": + check matchFilter("suite1", "foo", "suite1::") + check false == matchFilter("suite1", "foo", "suite2::") + check matchFilter("suite1", "qwe::foo", "qwe::foo") + check matchFilter("suite1", "qwe::foo", "suite1::qwe::foo") + + test "suite name - glob": + check matchFilter("suite1", "foo", "::*") + check matchFilter("suite1", "foo", "*::*") + check matchFilter("suite1", "foo", "*::foo") + check false == matchFilter("suite1", "foo", "*ite2::") + check matchFilter("suite1", "q**we::foo", "q**we::foo") + check matchFilter("suite1", "a::b*c::d*e", "a::b*c::d*e") diff --git a/tests/system/toString.nim b/tests/system/toString.nim index 1279897a7..ea9d6b05b 100644 --- a/tests/system/toString.nim +++ b/tests/system/toString.nim @@ -3,13 +3,13 @@ discard """ """ doAssert "@[23, 45]" == $(@[23, 45]) -doAssert "[32, 45]" == $([32, 45]) -doAssert "@[, foo, bar]" == $(@["", "foo", "bar"]) -doAssert "[, foo, bar]" == $(["", "foo", "bar"]) +doAssert "[32, 45]" == $([32, 45]) +doAssert """@["", "foo", "bar"]""" == $(@["", "foo", "bar"]) +doAssert """["", "foo", "bar"]""" == $(["", "foo", "bar"]) # bug #2395 let alphaSet: set[char] = {'a'..'c'} -doAssert "{a, b, c}" == $alphaSet +doAssert "{'a', 'b', 'c'}" == $alphaSet doAssert "2.3242" == $(2.3242) doAssert "2.982" == $(2.982) doAssert "123912.1" == $(123912.1) @@ -49,5 +49,5 @@ import strutils # array test let arr = ['H','e','l','l','o',' ','W','o','r','l','d','!','\0'] -doAssert $arr == "[H, e, l, l, o, , W, o, r, l, d, !, \0]" +doAssert $arr == "['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\\x00']" doAssert $cstring(unsafeAddr arr) == "Hello World!" diff --git a/tests/system/tsystem_misc.nim b/tests/system/tsystem_misc.nim new file mode 100644 index 000000000..ce36895a1 --- /dev/null +++ b/tests/system/tsystem_misc.nim @@ -0,0 +1,22 @@ +discard """ + output:"" +""" + +# check high/low implementations +doAssert high(int) > low(int) +doAssert high(int8) > low(int8) +doAssert high(int16) > low(int16) +doAssert high(int32) > low(int32) +doAssert high(int64) > low(int64) +# doAssert high(uint) > low(uint) # reconsider depending on issue #6620 +doAssert high(uint8) > low(uint8) +doAssert high(uint16) > low(uint16) +doAssert high(uint32) > low(uint32) +# doAssert high(uint64) > low(uint64) # reconsider depending on issue #6620 +doAssert high(float) > low(float) +doAssert high(float32) > low(float32) +doAssert high(float64) > low(float64) + +# bug #6710 +var s = @[1] +s.delete(0) diff --git a/tests/test_nimscript.nims b/tests/test_nimscript.nims index 2500bac73..d3eb9808e 100644 --- a/tests/test_nimscript.nims +++ b/tests/test_nimscript.nims @@ -21,5 +21,6 @@ import subexes import tables import unicode import uri +import macros echo "Nimscript imports are successful." diff --git a/tests/testament/backend.nim b/tests/testament/backend.nim index 8f0961566..4acef9ca4 100644 --- a/tests/testament/backend.nim +++ b/tests/testament/backend.nim @@ -1,56 +1,16 @@ # # # The Nim Tester -# (c) Copyright 2015 Andreas Rumpf +# (c) Copyright 2017 Andreas Rumpf # # Look at license.txt for more info. # All rights reserved. -import strutils, db_sqlite, os, osproc - -var db: DbConn - -proc createDb() = - db.exec(sql""" - create table if not exists Machine( - id integer primary key, - name varchar(100) not null, - os varchar(20) not null, - cpu varchar(20) not null - );""") - - db.exec(sql""" - create table if not exists [Commit]( - id integer primary key, - hash varchar(256) not null, - branch varchar(50) not null - );""") - - db.exec(sql""" - create table if not exists TestResult( - id integer primary key, - name varchar(100) not null, - category varchar(100) not null, - target varchar(20) not null, - action varchar(10) not null, - result varchar(30) not null, - [commit] int not null, - machine int not null, - expected varchar(10000) not null, - given varchar(10000) not null, - created timestamp not null default (DATETIME('now')), - - foreign key ([commit]) references [commit](id), - foreign key (machine) references machine(id) - );""") - - #db.exec(sql""" - # --create unique index if not exists TsstNameIx on TestResult(name); - # """, []) +import strutils, os, osproc, json type - MachineId* = distinct int64 - CommitId = distinct int64 + MachineId* = distinct string + CommitId = distinct string proc `$`*(id: MachineId): string {.borrow.} proc `$`(id: CommitId): string {.borrow.} @@ -58,11 +18,12 @@ proc `$`(id: CommitId): string {.borrow.} var thisMachine: MachineId thisCommit: CommitId + thisBranch: string {.experimental.} proc `()`(cmd: string{lit}): string = cmd.execProcess.string.strip -proc getMachine*(db: DbConn): MachineId = +proc getMachine*(): MachineId = var name = "hostname"() if name.len == 0: name = when defined(posix): getenv"HOSTNAME".string @@ -70,54 +31,45 @@ proc getMachine*(db: DbConn): MachineId = if name.len == 0: quit "cannot determine the machine name" - let id = db.getValue(sql"select id from Machine where name = ?", name) - if id.len > 0: - result = id.parseInt.MachineId - else: - result = db.insertId(sql"insert into Machine(name, os, cpu) values (?,?,?)", - name, system.hostOS, system.hostCPU).MachineId + result = MachineId(name) -proc getCommit(db: DbConn): CommitId = +proc getCommit(): CommitId = const commLen = "commit ".len let hash = "git log -n 1"()[commLen..commLen+10] - let branch = "git symbolic-ref --short HEAD"() - if hash.len == 0 or branch.len == 0: quit "cannot determine git HEAD" + thisBranch = "git symbolic-ref --short HEAD"() + if hash.len == 0 or thisBranch.len == 0: quit "cannot determine git HEAD" + result = CommitId(hash) - let id = db.getValue(sql"select id from [Commit] where hash = ? and branch = ?", - hash, branch) - if id.len > 0: - result = id.parseInt.CommitId - else: - result = db.insertId(sql"insert into [Commit](hash, branch) values (?, ?)", - hash, branch).CommitId +var + results: File + currentCategory: string + entries: int proc writeTestResult*(name, category, target, action, result, expected, given: string) = - let id = db.getValue(sql"""select id from TestResult - where name = ? and category = ? and target = ? and - machine = ? and [commit] = ?""", - name, category, target, - thisMachine, thisCommit) - if id.len > 0: - db.exec(sql"""update TestResult - set action = ?, result = ?, expected = ?, given = ? - where id = ?""", action, result, expected, given, id) - else: - db.exec(sql"""insert into TestResult(name, category, target, - action, - result, expected, given, - [commit], machine) - values (?,?,?,?,?,?,?,?,?) """, name, category, target, - action, - result, expected, given, - thisCommit, thisMachine) + createDir("testresults") + if currentCategory != category: + if currentCategory.len > 0: + results.writeLine("]") + close(results) + currentCategory = category + results = open("testresults" / category.addFileExt"json", fmWrite) + results.writeLine("[") + entries = 0 + + let jentry = %*{"name": name, "category": category, "target": target, + "action": action, "result": result, "expected": expected, "given": given, + "machine": thisMachine.string, "commit": thisCommit.string, "branch": thisBranch} + if entries > 0: + results.writeLine(",") + results.write($jentry) + inc entries proc open*() = - let dbFile = if existsEnv("TRAVIS") or existsEnv("APPVEYOR"): ":memory:" else: "testament.db" - db = open(connection=dbFile, user="testament", password="", - database="testament") - createDb() - thisMachine = getMachine(db) - thisCommit = getCommit(db) + thisMachine = getMachine() + thisCommit = getCommit() -proc close*() = close(db) +proc close*() = + if currentCategory.len > 0: + results.writeLine("]") + close(results) diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index a93c79f5c..33b93e3c4 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -15,58 +15,52 @@ const rodfilesDir = "tests/rodfiles" - nimcacheDir = rodfilesDir / "nimcache" -proc delNimCache() = +proc delNimCache(filename, options: string) = + let dir = nimcacheDir(filename, options) try: - removeDir(nimcacheDir) + removeDir(dir) except OSError: - echo "[Warning] could not delete: ", nimcacheDir + echo "[Warning] could not delete: ", dir proc runRodFiles(r: var TResults, cat: Category, options: string) = - template test(filename: untyped) = + template test(filename: string, clearCacheFirst=false) = + if clearCacheFirst: delNimCache(filename, options) testSpec r, makeTest(rodfilesDir / filename, options, cat, actionRun) - delNimCache() # test basic recompilation scheme: - test "hallo" + test "hallo", true test "hallo" when false: # test incremental type information: test "hallo2" - delNimCache() # test type converters: - test "aconv" + test "aconv", true test "bconv" - delNimCache() # test G, A, B example from the documentation; test init sections: - test "deada" + test "deada", true test "deada2" - delNimCache() when false: # test method generation: - test "bmethods" + test "bmethods", true test "bmethods2" - delNimCache() # test generics: - test "tgeneric1" + test "tgeneric1", true test "tgeneric2" - delNimCache() proc compileRodFiles(r: var TResults, cat: Category, options: string) = - template test(filename: untyped) = + template test(filename: untyped, clearCacheFirst=true) = + if clearCacheFirst: delNimCache(filename, options) testSpec r, makeTest(rodfilesDir / filename, options, cat) - delNimCache() # test DLL interfacing: - test "gtkex1" + test "gtkex1", true test "gtkex2" - delNimCache() # --------------------- DLL generation tests ---------------------------------- @@ -83,9 +77,9 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = "" testSpec c, makeTest("lib/nimrtl.nim", - options & " --app:lib -d:createNimRtl", cat) + options & " --app:lib -d:createNimRtl --threads:on", cat) testSpec c, makeTest("tests/dll/server.nim", - options & " --app:lib -d:useNimRtl" & rpath, cat) + options & " --app:lib -d:useNimRtl --threads:on" & rpath, cat) when defined(Windows): @@ -101,7 +95,7 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = var nimrtlDll = DynlibFormat % "nimrtl" safeCopyFile("lib" / nimrtlDll, "tests/dll" / nimrtlDll) - testSpec r, makeTest("tests/dll/client.nim", options & " -d:useNimRtl" & rpath, + testSpec r, makeTest("tests/dll/client.nim", options & " -d:useNimRtl --threads:on" & rpath, cat, actionRun) proc dllTests(r: var TResults, cat: Category, options: string) = @@ -205,7 +199,6 @@ proc ioTests(r: var TResults, cat: Category, options: string) = proc asyncTests(r: var TResults, cat: Category, options: string) = template test(filename: untyped) = testSpec r, makeTest(filename, options, cat) - testSpec r, makeTest(filename, options & " -d:upcoming", cat) for t in os.walkFiles("tests/async/t*.nim"): test(t) @@ -219,9 +212,9 @@ proc debuggerTests(r: var TResults, cat: Category, options: string) = proc jsTests(r: var TResults, cat: Category, options: string) = template test(filename: untyped) = testSpec r, makeTest(filename, options & " -d:nodejs", cat, - actionRun, targetJS) + actionRun), targetJS testSpec r, makeTest(filename, options & " -d:nodejs -d:release", cat, - actionRun, targetJS) + actionRun), targetJS for t in os.walkFiles("tests/js/t*.nim"): test(t) @@ -245,10 +238,10 @@ proc testNimInAction(r: var TResults, cat: Category, options: string) = testSpec r, makeTest(filename, options, cat, action) template testJS(filename: untyped) = - testSpec r, makeTest(filename, options, cat, actionCompile, targetJS) + testSpec r, makeTest(filename, options, cat, actionCompile), targetJS template testCPP(filename: untyped) = - testSpec r, makeTest(filename, options, cat, actionCompile, targetCPP) + testSpec r, makeTest(filename, options, cat, actionCompile), targetCPP let tests = [ "niminaction/Chapter3/ChatApp/src/server", @@ -324,9 +317,10 @@ type PackageFilter = enum pfExtraOnly pfAll +var nimbleDir = getEnv("NIMBLE_DIR").string +if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble" let nimbleExe = findExe("nimble") - nimbleDir = getHomeDir() / ".nimble" packageDir = nimbleDir / "pkgs" packageIndex = nimbleDir / "packages.json" @@ -386,7 +380,7 @@ proc testNimblePackages(r: var TResults, cat: Category, filter: PackageFilter) = installStatus = waitForExitEx(installProcess) installProcess.close if installStatus != QuitSuccess: - r.addResult(test, "", "", reInstallFailed) + r.addResult(test, targetC, "", "", reInstallFailed) continue let @@ -395,12 +389,12 @@ proc testNimblePackages(r: var TResults, cat: Category, filter: PackageFilter) = buildStatus = waitForExitEx(buildProcess) buildProcess.close if buildStatus != QuitSuccess: - r.addResult(test, "", "", reBuildFailed) - r.addResult(test, "", "", reSuccess) - r.addResult(packageFileTest, "", "", reSuccess) + r.addResult(test, targetC, "", "", reBuildFailed) + r.addResult(test, targetC, "", "", reSuccess) + r.addResult(packageFileTest, targetC, "", "", reSuccess) except JsonParsingError: echo("[Warning] - Cannot run nimble tests: Invalid package file.") - r.addResult(packageFileTest, "", "", reBuildFailed) + r.addResult(packageFileTest, targetC, "", "", reBuildFailed) # ---------------------------------------------------------------------------- @@ -417,8 +411,9 @@ proc `&?.`(a, b: string): string = proc processSingleTest(r: var TResults, cat: Category, options, test: string) = let test = "tests" & DirSep &.? cat.string / test + let target = if cat.string.normalize == "js": targetJS else: targetC - if existsFile(test): testSpec r, makeTest(test, options, cat) + if existsFile(test): testSpec r, makeTest(test, options, cat), target else: echo "[Warning] - ", test, " test does not exist" proc processCategory(r: var TResults, cat: Category, options: string) = diff --git a/tests/testament/css/boilerplate.css b/tests/testament/css/boilerplate.css deleted file mode 100644 index b209b5aa1..000000000 --- a/tests/testament/css/boilerplate.css +++ /dev/null @@ -1,138 +0,0 @@ -/* ==== Scroll down to find where to put your styles :) ==== */ - -/* HTML5 ✰ Boilerplate */ - -html, body, div, span, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, -small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, figcaption, figure, -footer, header, hgroup, menu, nav, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} - -blockquote, q { quotes: none; } -blockquote:before, blockquote:after, -q:before, q:after { content: ''; content: none; } -ins { background-color: #ff9; color: #000; text-decoration: none; } -mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; } -del { text-decoration: line-through; } -abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; } -table { border-collapse: collapse; border-spacing: 0; } -hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } -input, select { vertical-align: middle; } - -body { font:13px/1.231 sans-serif; *font-size:small; } -select, input, textarea, button { font:99% sans-serif; } -pre, code, kbd, samp { font-family: monospace, sans-serif; } - -html { overflow-y: scroll; } -a:hover, a:active { outline: none; } -ul, ol { margin-left: 2em; } -ol { list-style-type: decimal; } -nav ul, nav li { margin: 0; list-style:none; list-style-image: none; } -small { font-size: 85%; } -strong, th { font-weight: bold; } -td { vertical-align: top; } - -sub, sup { font-size: 75%; line-height: 0; position: relative; } -sup { top: -0.5em; } -sub { bottom: -0.25em; } - -pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; padding: 15px; } -textarea { overflow: auto; } -.ie6 legend, .ie7 legend { margin-left: -7px; } -input[type="radio"] { vertical-align: text-bottom; } -input[type="checkbox"] { vertical-align: bottom; } -.ie7 input[type="checkbox"] { vertical-align: baseline; } -.ie6 input { vertical-align: text-bottom; } -label, input[type="button"], input[type="submit"], input[type="image"], button { cursor: pointer; } -button, input, select, textarea { margin: 0; } -input:valid, textarea:valid { } -input:invalid, textarea:invalid { border-radius: 1px; -moz-box-shadow: 0px 0px 5px red; -webkit-box-shadow: 0px 0px 5px red; box-shadow: 0px 0px 5px red; } -.no-boxshadow input:invalid, .no-boxshadow textarea:invalid { background-color: #f0dddd; } - -a:link { -webkit-tap-highlight-color: #FF5E99; } - -button { width: auto; overflow: visible; } -.ie7 img { -ms-interpolation-mode: bicubic; } - -body, select, input, textarea { color: #444; } -h1, h2, h3, h4, h5, h6 { font-weight: bold; } -a, a:active, a:visited { color: #607890; } -a:hover { color: #036; } - -/* - // ========================================== \\ - || || - || Your styles ! || - || || - \\ ========================================== // -*/ - - - - - - - - - - - - - - - -.ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; } -.hidden { display: none; visibility: hidden; } -.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } -.visuallyhidden.focusable:active, -.visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; } -.invisible { visibility: hidden; } -.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; } -.clearfix:after { clear: both; } -.clearfix { zoom: 1; } - - -@media all and (orientation:portrait) { - -} - -@media all and (orientation:landscape) { - -} - -@media screen and (max-device-width: 480px) { - - /* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ -} - - -@media print { - * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; - -ms-filter: none !important; } - a, a:visited { color: #444 !important; text-decoration: underline; } - a[href]:after { content: " (" attr(href) ")"; } - abbr[title]:after { content: " (" attr(title) ")"; } - .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } - pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } - thead { display: table-header-group; } - tr, img { page-break-inside: avoid; } - @page { margin: 0.5cm; } - p, h2, h3 { orphans: 3; widows: 3; } - h2, h3{ page-break-after: avoid; } -} diff --git a/tests/testament/css/style.css b/tests/testament/css/style.css deleted file mode 100644 index 43a8add68..000000000 --- a/tests/testament/css/style.css +++ /dev/null @@ -1,114 +0,0 @@ -body { - font-size: medium; -} - -div#header { - font-size: 2em; - background-color: #3d3d3d; - border-bottom: solid 2px #000000; - padding: 0.25em; - color: #ffffff; -} - -div#content { - margin: 0.5em; -} - -table { - text-align: left; - margin-bottom: 0.5em; -} - -table td, table th { - padding: 0.15em 0.5em; -} - -tr:nth-child(even) { - background-color: #eee; -} - -/* Awesome buttons :P */ - -a.button { - border-radius: 2px 2px 2px 2px; - background: -moz-linear-gradient(top, #f7f7f7, #ebebeb); - background: -webkit-linear-gradient(top, #f7f7f7, #ebebeb); - background: -o-linear-gradient(top, #f7f7f7, #ebebeb); - text-decoration: none; - color: #3d3d3d; - padding: 5px; - border: solid 1px #9d9d9d; - display: inline-block; - position: relative; - text-align: center; - font-size: small; -} - -a.button.active { - background: -moz-linear-gradient(top, #00B40C, #03A90E); - background: -webkit-linear-gradient(top, #00B40C, #03A90E); - background: -o-linear-gradient(top, #00B40C, #03A90E); - border: solid 1px #148420; - color: #ffffff; -} - -a.button.left { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -a.button.middle { - border-radius: 0; - border-left: 0; -} - -a.button.right { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-left: 0; -} - -a.button:hover { - background: -moz-linear-gradient(top, #0099c7, #0294C1); - background: -webkit-linear-gradient(top, #0099c7, #0294C1); - background: -o-linear-gradient(top, #0099c7, #0294C1); - border: solid 1px #077A9C; - color: #ffffff; -} - -a.button.middle:hover, a.button.right:hover { - border-left: 0; -} - -a.button span.download { - background-image: url("../images/icons.png"); - background-repeat: no-repeat; - display: inline-block; - margin: auto 3px auto auto; - height: 15px; - width: 14px; - position: relative; - background-position: 0 -30px; - top: 3px; -} - -a.button span.book { - background-image: url("../images/icons.png"); - background-repeat: no-repeat; - display: inline-block; - margin: auto 3px auto auto; - height: 15px; - width: 14px; - position: relative; - background-position: 0 0; - top: 3px; -} - -a.button.active span.download, a.button:hover span.download { - background-position: 0 -45px; -} - -a.button.active span.book, a.button:hover span.book { - background-position: 0 -15px; -} - diff --git a/tests/testament/htmlgen.nim b/tests/testament/htmlgen.nim index 15960f09a..bf26a956d 100644 --- a/tests/testament/htmlgen.nim +++ b/tests/testament/htmlgen.nim @@ -1,7 +1,7 @@ # # # Nim Tester -# (c) Copyright 2015 Andreas Rumpf +# (c) Copyright 2017 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -9,220 +9,140 @@ ## HTML generator for the tester. -import db_sqlite, cgi, backend, strutils, json - -const - TableHeader = """<table border="1"> - <tr><td>Test</td><td>Category</td><td>Target</td> - <td>Action</td> - <td>Expected</td> - <td>Given</td> - <td>Success</td></tr>""" - TableFooter = "</table>" - HtmlBegin = """<html> - <head> - <title>Test results</title> - <style type="text/css"> - <!--""" & slurp("css/boilerplate.css") & "\n" & - slurp("css/style.css") & - """ -ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; } -ul#tabs li { display: inline; } -ul#tabs li a { color: #42454a; background-color: #dedbde; - border: 1px solid #c9c3ba; border-bottom: none; - padding: 0.3em; text-decoration: none; } -ul#tabs li a:hover { background-color: #f1f0ee; } -ul#tabs li a.selected { color: #000; background-color: #f1f0ee; - font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; } -div.tabContent { border: 1px solid #c9c3ba; - padding: 0.5em; background-color: #f1f0ee; } -div.tabContent.hide { display: none; } - --> - </style> - <script> - - var tabLinks = new Array(); - var contentDivs = new Array(); - - function init() { - // Grab the tab links and content divs from the page - var tabListItems = document.getElementById('tabs').childNodes; - for (var i = 0; i < tabListItems.length; i++) { - if (tabListItems[i].nodeName == "LI") { - var tabLink = getFirstChildWithTagName(tabListItems[i], 'A'); - var id = getHash(tabLink.getAttribute('href')); - tabLinks[id] = tabLink; - contentDivs[id] = document.getElementById(id); - } - } - // Assign onclick events to the tab links, and - // highlight the first tab - var i = 0; - for (var id in tabLinks) { - tabLinks[id].onclick = showTab; - tabLinks[id].onfocus = function() { this.blur() }; - if (i == 0) tabLinks[id].className = 'selected'; - i++; - } - // Hide all content divs except the first - var i = 0; - for (var id in contentDivs) { - if (i != 0) contentDivs[id].className = 'tabContent hide'; - i++; - } - } - - function showTab() { - var selectedId = getHash(this.getAttribute('href')); - - // Highlight the selected tab, and dim all others. - // Also show the selected content div, and hide all others. - for (var id in contentDivs) { - if (id == selectedId) { - tabLinks[id].className = 'selected'; - contentDivs[id].className = 'tabContent'; - } else { - tabLinks[id].className = ''; - contentDivs[id].className = 'tabContent hide'; - } - } - // Stop the browser following the link - return false; - } - - function getFirstChildWithTagName(element, tagName) { - for (var i = 0; i < element.childNodes.length; i++) { - if (element.childNodes[i].nodeName == tagName) return element.childNodes[i]; - } - } - function getHash(url) { - var hashPos = url.lastIndexOf('#'); - return url.substring(hashPos + 1); - } - </script> - - </head> - <body onload="init()">""" - - HtmlEnd = "</body></html>" - -proc td(s: string): string = - result = "<td>" & s.substr(0, 200).xmlEncode & "</td>" - -proc getCommit(db: DbConn, c: int): string = - var commit = c - for thisCommit in db.rows(sql"select id from [Commit] order by id desc"): - if commit == 0: result = thisCommit[0] - inc commit - -proc generateHtml*(filename: string, commit: int; onlyFailing: bool) = - const selRow = """select name, category, target, action, - expected, given, result - from TestResult - where [commit] = ? and machine = ? - order by category""" - var db = open(connection="testament.db", user="testament", password="", - database="testament") - # search for proper commit: - let lastCommit = db.getCommit(commit) - +import cgi, backend, strutils, json, os, tables, times + +import "testamenthtml.templ" + +proc generateTestResultPanelPartial(outfile: File, testResultRow: JsonNode) = + let + trId = htmlQuote(testResultRow["category"].str & "_" & testResultRow["name"].str). + multiReplace({".": "_", " ": "_", ":": "_"}) + name = testResultRow["name"].str.htmlQuote() + category = testResultRow["category"].str.htmlQuote() + target = testResultRow["target"].str.htmlQuote() + action = testResultRow["action"].str.htmlQuote() + result = htmlQuote testResultRow["result"].str + expected = testResultRow["expected"].str + gotten = testResultRow["given"].str + timestamp = "unknown" + var + panelCtxClass, textCtxClass, bgCtxClass: string + resultSign, resultDescription: string + case result + of "reSuccess": + panelCtxClass = "success" + textCtxClass = "success" + bgCtxClass = "success" + resultSign = "ok" + resultDescription = "PASS" + of "reIgnored": + panelCtxClass = "info" + textCtxClass = "info" + bgCtxClass = "info" + resultSign = "question" + resultDescription = "SKIP" + else: + panelCtxClass = "danger" + textCtxClass = "danger" + bgCtxClass = "danger" + resultSign = "exclamation" + resultDescription = "FAIL" + + outfile.generateHtmlTestresultPanelBegin( + trId, name, target, category, action, resultDescription, + timestamp, result, resultSign, panelCtxClass, textCtxClass, bgCtxClass + ) + if expected.isNilOrWhitespace() and gotten.isNilOrWhitespace(): + outfile.generateHtmlTestresultOutputNone() + else: + outfile.generateHtmlTestresultOutputDetails( + expected.strip().htmlQuote, + gotten.strip().htmlQuote + ) + outfile.generateHtmlTestresultPanelEnd() + +type + AllTests = object + data: JSonNode + totalCount, successCount, ignoredCount, failedCount: int + successPercentage, ignoredPercentage, failedPercentage: BiggestFloat + +proc allTestResults(onlyFailing = false): AllTests = + result.data = newJArray() + for file in os.walkFiles("testresults/*.json"): + let data = parseFile(file) + if data.kind != JArray: + echo "[ERROR] ignoring json file that is not an array: ", file + else: + for elem in data: + let state = elem["result"].str + inc result.totalCount + if state.contains("reSuccess"): inc result.successCount + elif state.contains("reIgnored"): inc result.ignoredCount + if not onlyFailing or not(state.contains("reSuccess")): + result.data.add elem + result.successPercentage = 100 * + (result.successCount.toBiggestFloat / result.totalCount.toBiggestFloat) + result.ignoredPercentage = 100 * + (result.ignoredCount.toBiggestFloat / result.totalCount.toBiggestFloat) + result.failedCount = result.totalCount - + result.successCount - result.ignoredCount + result.failedPercentage = 100 * + (result.failedCount.toBiggestFloat / result.totalCount.toBiggestFloat) + +proc generateTestResultsPanelGroupPartial(outfile: File, allResults: JsonNode) = + for testresultRow in allResults: + generateTestResultPanelPartial(outfile, testresultRow) + +proc generateAllTestsContent(outfile: File, allResults: AllTests, + onlyFailing = false) = + if allResults.data.len < 1: return # Nothing to do if there is no data. + # Only results from one test run means that test run environment info is the + # same for all tests + let + firstRow = allResults.data[0] + commit = htmlQuote firstRow["commit"].str + branch = htmlQuote firstRow["branch"].str + machine = htmlQuote firstRow["machine"].str + + outfile.generateHtmlAllTestsBegin( + machine, commit, branch, + allResults.totalCount, + allResults.successCount, + formatBiggestFloat(allResults.successPercentage, ffDecimal, 2) & "%", + allResults.ignoredCount, + formatBiggestFloat(allResults.ignoredPercentage, ffDecimal, 2) & "%", + allResults.failedCount, + formatBiggestFloat(allResults.failedPercentage, ffDecimal, 2) & "%", + onlyFailing + ) + generateTestResultsPanelGroupPartial(outfile, allResults.data) + outfile.generateHtmlAllTestsEnd() + +proc generateHtml*(filename: string, onlyFailing: bool) = + let + currentTime = getTime().getLocalTime() + timestring = htmlQuote format(currentTime, "yyyy-MM-dd HH:mm:ss 'UTC'zzz") var outfile = open(filename, fmWrite) - outfile.write(HtmlBegin) - - let commit = db.getValue(sql"select hash from [Commit] where id = ?", - lastCommit) - let branch = db.getValue(sql"select branch from [Commit] where id = ?", - lastCommit) - outfile.write("<p><b>$# $#</b></p>" % [branch, commit]) - - # generate navigation: - outfile.write("""<ul id="tabs">""") - for m in db.rows(sql"select id, name, os, cpu from Machine order by id"): - outfile.writeLine """<li><a href="#$#">$#: $#, $#</a></li>""" % m - outfile.write("</ul>") - - for currentMachine in db.rows(sql"select id from Machine order by id"): - let m = currentMachine[0] - outfile.write("""<div class="tabContent" id="$#">""" % m) - - outfile.write(TableHeader) - for row in db.rows(sql(selRow), lastCommit, m): - if onlyFailing and row.len > 0 and row[row.high] == "reSuccess": - discard - else: - outfile.write("<tr>") - for x in row: - outfile.write(x.td) - outfile.write("</tr>") - - outfile.write(TableFooter) - outfile.write("</div>") - outfile.write(HtmlEnd) - close(db) - close(outfile) -proc generateJson*(filename: string, commit: int) = - const - selRow = """select count(*), - sum(result = 'reSuccess'), - sum(result = 'reIgnored') - from TestResult - where [commit] = ? and machine = ? - order by category""" - selDiff = """select A.category || '/' || A.target || '/' || A.name, - A.result, - B.result - from TestResult A - inner join TestResult B - on A.name = B.name and A.category = B.category - where A.[commit] = ? and B.[commit] = ? and A.machine = ? - and A.result != B.result""" - selResults = """select - category || '/' || target || '/' || name, - category, target, action, result, expected, given - from TestResult - where [commit] = ?""" - var db = open(connection="testament.db", user="testament", password="", - database="testament") - let lastCommit = db.getCommit(commit) - if lastCommit.isNil: - quit "cannot determine commit " & $commit - - let previousCommit = db.getCommit(commit-1) + outfile.generateHtmlBegin() - var outfile = open(filename, fmWrite) + generateAllTestsContent(outfile, allTestResults(onlyFailing), onlyFailing) + + outfile.generateHtmlEnd(timestring) - let machine = $backend.getMachine(db) - let data = db.getRow(sql(selRow), lastCommit, machine) - - outfile.writeLine("""{"total": $#, "passed": $#, "skipped": $#""" % data) - - let results = newJArray() - for row in db.rows(sql(selResults), lastCommit): - var obj = newJObject() - obj["name"] = %row[0] - obj["category"] = %row[1] - obj["target"] = %row[2] - obj["action"] = %row[3] - obj["result"] = %row[4] - obj["expected"] = %row[5] - obj["given"] = %row[6] - results.add(obj) - outfile.writeLine(""", "results": """) - outfile.write(results.pretty) - - if not previousCommit.isNil: - let diff = newJArray() - - for row in db.rows(sql(selDiff), previousCommit, lastCommit, machine): - var obj = newJObject() - obj["name"] = %row[0] - obj["old"] = %row[1] - obj["new"] = %row[2] - diff.add obj - outfile.writeLine(""", "diff": """) - outfile.writeLine(diff.pretty) - - outfile.writeLine "}" - close(db) + outfile.flushFile() close(outfile) + +proc dumpJsonTestResults*(prettyPrint, onlyFailing: bool) = + var + outfile = stdout + jsonString: string + + let results = allTestResults(onlyFailing) + if prettyPrint: + jsonString = results.data.pretty() + else: + jsonString = $ results.data + + outfile.writeLine(jsonString) diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim index 89e786d48..ac79e3942 100644 --- a/tests/testament/specs.nim +++ b/tests/testament/specs.nim @@ -12,6 +12,9 @@ import parseutils, strutils, os, osproc, streams, parsecfg var compilerPrefix* = "compiler" / "nim " +let isTravis = existsEnv("TRAVIS") +let isAppVeyor = existsEnv("APPVEYOR") + proc cmdTemplate*(): string = compilerPrefix & "$target --lib:lib --hints:on -d:testing $options $file" @@ -113,7 +116,7 @@ proc specDefaults*(result: var TSpec) = result.maxCodeSize = 0 proc parseTargets*(value: string): set[TTarget] = - for v in value.normalize.split: + for v in value.normalize.splitWhitespace: case v of "c": result.incl(targetC) of "cpp", "c++": result.incl(targetCpp) @@ -149,6 +152,7 @@ proc parseSpec*(filename: string): TSpec = result.sortoutput = parseCfgBool(e.value) of "exitcode": discard parseInt(e.value, result.exitCode) + result.action = actionRun of "msg": result.msg = e.value if result.action != actionRun: @@ -174,6 +178,10 @@ proc parseSpec*(filename: string): TSpec = when defined(unix): result.err = reIgnored of "posix": when defined(posix): result.err = reIgnored + of "travis": + if isTravis: result.err = reIgnored + of "appveyor": + if isAppVeyor: result.err = reIgnored else: raise newException(ValueError, "cannot interpret as a bool: " & e.value) of "cmd": @@ -184,7 +192,7 @@ proc parseSpec*(filename: string): TSpec = of "ccodecheck": result.ccodeCheck = e.value of "maxcodesize": discard parseInt(e.value, result.maxCodeSize) of "target", "targets": - for v in e.value.normalize.split: + for v in e.value.normalize.splitWhitespace: case v of "c": result.targets.incl(targetC) of "cpp", "c++": result.targets.incl(targetCpp) diff --git a/tests/testament/testamenthtml.templ b/tests/testament/testamenthtml.templ new file mode 100644 index 000000000..9190f370e --- /dev/null +++ b/tests/testament/testamenthtml.templ @@ -0,0 +1,297 @@ +#? stdtmpl(subsChar = '%', metaChar = '#', emit = "outfile.write") +#import strutils +# +#proc htmlQuote*(raw: string): string = +# result = raw.multiReplace( +# ("&", "&"), +# ("\"", """), +# ("'", "'"), +# ("<", "<"), +# (">", ">") +# ) +# +#end proc +#proc generateHtmlBegin*(outfile: File) = +<!DOCTYPE html> +<html> +<head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Testament Test Results</title> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js" integrity="sha256-ihAoc6M/JPfrIiIeayPE9xjin4UWjsx2mjW/rtmxLM4=" crossorigin="anonymous"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha256-U5ZEeKfGNOja007MMD3YBI0A3OSZOQbeG6z2f2Y0hu8=" crossorigin="anonymous"></script> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha256-916EbMg70RQy9LHiGkXzG8hSg9EdNy97GazNG/aiY1w=" crossorigin="anonymous" /> + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha256-ZT4HPpdCOt2lvDkXokHuhJfdOKSPFLzeAJik5U/Q+l4=" crossorigin="anonymous" /> + <script> + /** + * Callback function that is executed for each Element in an array. + * @callback executeForElement + * @param {Element} elem Element to operate on + */ + + /** + * + * @param {number} index + * @param {Element[]} elemArray + * @param {executeForElement} executeOnItem + */ + function executeAllAsync(elemArray, index, executeOnItem) { + for (var i = 0; index < elemArray.length && i < 100; i++ , index++) { + var item = elemArray[index]; + executeOnItem(item); + } + if (index < elemArray.length) { + setTimeout(executeAllAsync, 0, elemArray, index, executeOnItem); + } + } + + /** @param {Element} elem */ + function executeShowOnElement(elem) { + while (elem.classList.contains("hidden")) { + elem.classList.remove("hidden"); + } + } + + /** @param {Element} elem */ + function executeHideOnElement(elem) { + if (!elem.classList.contains("hidden")) { + elem.classList.add("hidden"); + } + } + + /** @param {Element} elem */ + function executeExpandOnElement(elem) { + $(elem).collapse("show"); + } + + /** @param {Element} elem */ + function executeCollapseOnElement(elem) { + $(elem).collapse("hide"); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + * @param {executeForElement} executeOnEachPanel + */ + function wholePanelAll(category, executeOnEachPanel) { + var selector = "div.panel"; + if (typeof category === "string" && category) { + selector += "-" + category; + } + + var jqPanels = $(selector); + /** @type {Element[]} */ + var elemArray = jqPanels.toArray(); + + setTimeout(executeAllAsync, 0, elemArray, 0, executeOnEachPanel); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + * @param {executeForElement} executeOnEachPanel + */ + function panelBodyAll(category, executeOnEachPanelBody) { + var selector = "div.panel"; + if (typeof category === "string" && category) { + selector += "-" + category; + } + + var jqPanels = $(selector); + + var jqPanelBodies = $("div.panel-body", jqPanels); + /** @type {Element[]} */ + var elemArray = jqPanelBodies.toArray(); + + setTimeout(executeAllAsync, 0, elemArray, 0, executeOnEachPanelBody); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + */ + function showAll(category) { + wholePanelAll(category, executeShowOnElement); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + */ + function hideAll(category) { + wholePanelAll(category, executeHideOnElement); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + */ + function expandAll(category) { + panelBodyAll(category, executeExpandOnElement); + } + + /** + * @param {string} [category] Optional bootstrap panel context class (danger, warning, info, success) + */ + function collapseAll(category) { + panelBodyAll(category, executeCollapseOnElement); + } + </script> +</head> +<body> + <div class="container"> + <h1>Testament Test Results <small>Nim Tester</small></h1> +#end proc +#proc generateHtmlAllTestsBegin*(outfile: File, machine, commit, branch: string, +# totalCount: BiggestInt, +# successCount: BiggestInt, successPercentage: string, +# ignoredCount: BiggestInt, ignoredPercentage: string, +# failedCount: BiggestInt, failedPercentage: string, onlyFailing = false) = + <dl class="dl-horizontal"> + <dt>Hostname</dt> + <dd>%machine</dd> + <dt>Git Commit</dt> + <dd><code>%commit</code></dd> + <dt title="Git Branch reference">Branch ref.</dt> + <dd>%branch</dd> + </dl> + <dl class="dl-horizontal"> + <dt>All Tests</dt> + <dd> + <span class="glyphicon glyphicon-th-list"></span> + %totalCount + </dd> + <dt>Successful Tests</dt> + <dd> + <span class="glyphicon glyphicon-ok-sign"></span> + %successCount (%successPercentage) + </dd> + <dt>Skipped Tests</dt> + <dd> + <span class="glyphicon glyphicon-question-sign"></span> + %ignoredCount (%ignoredPercentage) + </dd> + <dt>Failed Tests</dt> + <dd> + <span class="glyphicon glyphicon-exclamation-sign"></span> + %failedCount (%failedPercentage) + </dd> + </dl> + <div class="table-responsive"> + <table class="table table-condensed"> +# if not onlyFailing: + <tr> + <th class="text-right" style="vertical-align:middle">All Tests</th> + <td> + <div class="btn-group"> + <button class="btn btn-default" type="button" onclick="showAll();">Show All</button> + <button class="btn btn-default" type="button" onclick="hideAll();">Hide All</button> + <button class="btn btn-default" type="button" onclick="expandAll();">Expand All</button> + <button class="btn btn-default" type="button" onclick="collapseAll();">Collapse All</button> + </div> + </td> + </tr> + <tr> + <th class="text-right" style="vertical-align:middle">Successful Tests</th> + <td> + <div class="btn-group"> + <button class="btn btn-default" type="button" onclick="showAll('success');">Show All</button> + <button class="btn btn-default" type="button" onclick="hideAll('success');">Hide All</button> + <button class="btn btn-default" type="button" onclick="expandAll('success');">Expand All</button> + <button class="btn btn-default" type="button" onclick="collapseAll('success');">Collapse All</button> + </div> + </td> + </tr> +# end if + <tr> + <th class="text-right" style="vertical-align:middle">Skipped Tests</th> + <td> + <div class="btn-group"> + <button class="btn btn-default" type="button" onclick="showAll('info');">Show All</button> + <button class="btn btn-default" type="button" onclick="hideAll('info');">Hide All</button> + <button class="btn btn-default" type="button" onclick="expandAll('info');">Expand All</button> + <button class="btn btn-default" type="button" onclick="collapseAll('info');">Collapse All</button> + </div> + </td> + </tr> + <tr> + <th class="text-right" style="vertical-align:middle">Failed Tests</th> + <td> + <div class="btn-group"> + <button class="btn btn-default" type="button" onclick="showAll('danger');">Show All</button> + <button class="btn btn-default" type="button" onclick="hideAll('danger');">Hide All</button> + <button class="btn btn-default" type="button" onclick="expandAll('danger');">Expand All</button> + <button class="btn btn-default" type="button" onclick="collapseAll('danger');">Collapse All</button> + </div> + </td> + </tr> + </table> + </div> + <div class="panel-group"> +#end proc +#proc generateHtmlTestresultPanelBegin*(outfile: File, trId, name, target, category, +# action, resultDescription, timestamp, result, resultSign, +# panelCtxClass, textCtxClass, bgCtxClass: string) = + <div id="panel-testResult-%trId" class="panel panel-%panelCtxClass"> + <div class="panel-heading" style="cursor:pointer" data-toggle="collapse" data-target="#panel-body-testResult-%trId" aria-controls="panel-body-testResult-%trId" aria-expanded="false"> + <div class="row"> + <h4 class="col-xs-3 col-sm-1 panel-title"> + <span class="glyphicon glyphicon-%resultSign-sign"></span> + <strong>%resultDescription</strong> + </h4> + <h4 class="col-xs-1 panel-title"><span class="badge">%target</span></h4> + <h4 class="col-xs-5 col-sm-7 panel-title" title="%name"><code class="text-%textCtxClass">%name</code></h4> + <h4 class="col-xs-3 col-sm-3 panel-title text-right"><span class="badge">%category</span></h4> + </div> + </div> + <div id="panel-body-testResult-%trId" class="panel-body collapse bg-%bgCtxClass"> + <dl class="dl-horizontal"> + <dt>Name</dt> + <dd><code class="text-%textCtxClass">%name</code></dd> + <dt>Category</dt> + <dd><span class="badge">%category</span></dd> + <dt>Timestamp</dt> + <dd>%timestamp</dd> + <dt>Nim Action</dt> + <dd><code class="text-%textCtxClass">%action</code></dd> + <dt>Nim Backend Target</dt> + <dd><span class="badge">%target</span></dd> + <dt>Code</dt> + <dd><code class="text-%textCtxClass">%result</code></dd> + </dl> +#end proc +#proc generateHtmlTestresultOutputDetails*(outfile: File, expected, gotten: string) = + <div class="table-responsive"> + <table class="table table-condensed"> + <thead> + <tr> + <th>Expected</th> + <th>Actual</th> + </tr> + </thead> + <tbody> + <tr> + <td><pre>%expected</pre></td> + <td><pre>%gotten</pre></td> + </tr> + </tbody> + </table> + </div> +#end proc +#proc generateHtmlTestresultOutputNone*(outfile: File) = + <p class="sr-only">No output details</p> +#end proc +#proc generateHtmlTestresultPanelEnd*(outfile: File) = + </div> + </div> +#end proc +#proc generateHtmlAllTestsEnd*(outfile: File) = + </div> +#end proc +#proc generateHtmlEnd*(outfile: File, timestamp: string) = + <hr /> + <footer> + <p> + Report generated by: <code>testament</code> – Nim Tester + <br /> + Made with Nim. Generated on: %timestamp + </p> + </footer> + </div> +</body> +</html> diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim index e4bbc3a00..870f9f865 100644 --- a/tests/testament/tester.nim +++ b/tests/testament/tester.nim @@ -1,7 +1,7 @@ # # # Nim Tester -# (c) Copyright 2015 Andreas Rumpf +# (c) Copyright 2017 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -12,7 +12,7 @@ import parseutils, strutils, pegs, os, osproc, streams, parsecfg, json, marshal, backend, parseopt, specs, htmlgen, browsers, terminal, - algorithm, compiler/nodejs, re, times, sets + algorithm, compiler/nodejs, times, sets, md5 const resultsFile = "testresults.html" @@ -24,15 +24,12 @@ Command: all run all tests c|category <category> run all the tests of a certain category r|run <test> run single test file - html [commit] generate $1 from the database; uses the latest - commit or a specific one (use -1 for the commit - before latest etc) + html generate $1 from the database Arguments: arguments are passed to the compiler Options: --print also print results to the console --failing only show failing/ignored tests - --pedantic return non-zero status code if there are failures --targets:"c c++ js objc" run tests for specified targets (default: all) --nim:path use a particular nim executable (default: compiler/nim) """ % resultsFile @@ -47,7 +44,6 @@ type name: string cat: Category options: string - target: TTarget action: TTestAction startTime: float @@ -75,8 +71,14 @@ proc getFileDir(filename: string): string = if not result.isAbsolute(): result = getCurrentDir() / result +proc nimcacheDir(filename, options: string): string = + ## Give each test a private nimcache dir so they don't clobber each other's. + return "nimcache" / (filename & '_' & options.getMD5) + proc callCompiler(cmdTemplate, filename, options: string, - target: TTarget): TSpec = + target: TTarget, extraOptions=""): TSpec = + let nimcache = nimcacheDir(filename, options) + let options = options & " --nimCache:" & nimcache.quoteShell & extraOptions let c = parseCmdLine(cmdTemplate % ["target", targetToCmd[target], "options", options, "file", filename.quoteShell, "filedir", filename.getFileDir()]) @@ -158,20 +160,21 @@ proc `$`(x: TResults): string = "Tests skipped: $2 / $3 <br />\n") % [$x.passed, $x.skipped, $x.total] -proc addResult(r: var TResults, test: TTest, +proc addResult(r: var TResults, test: TTest, target: TTarget, expected, given: string, success: TResultEnum) = - let name = test.name.extractFilename & test.options + let name = test.name.extractFilename & " " & $target & test.options let duration = epochTime() - test.startTime + let durationStr = duration.formatFloat(ffDecimal, precision = 8) backend.writeTestResult(name = name, category = test.cat.string, - target = $test.target, + target = $target, action = $test.action, result = $success, expected = expected, given = given) r.data.addf("$#\t$#\t$#\t$#", name, expected, given, $success) if success == reSuccess: - styledEcho fgGreen, "PASS: ", fgCyan, name + styledEcho fgGreen, "PASS: ", fgCyan, alignLeft(name, 60), fgBlue, " (", durationStr, " secs)" elif success == reIgnored: styledEcho styleDim, fgYellow, "SKIP: ", styleBright, fgCyan, name else: @@ -191,49 +194,54 @@ proc addResult(r: var TResults, test: TTest, ("Skipped", "") else: ("Failed", "Failure: " & $success & "\nExpected:\n" & expected & "\n\n" & "Gotten:\n" & given) - var p = startProcess("appveyor", args=["AddTest", test.name.replace("\\", "/") & test.options, "-Framework", "nim-testament", "-FileName", test.cat.string, "-Outcome", outcome, "-ErrorMessage", msg, "-Duration", $(duration*1000).int], options={poStdErrToStdOut, poUsePath, poParentStreams}) + var p = startProcess("appveyor", args=["AddTest", test.name.replace("\\", "/") & test.options, + "-Framework", "nim-testament", "-FileName", + test.cat.string, + "-Outcome", outcome, "-ErrorMessage", msg, + "-Duration", $(duration*1000).int], + options={poStdErrToStdOut, poUsePath, poParentStreams}) discard waitForExit(p) close(p) -proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest) = +proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest, target: TTarget) = if strip(expected.msg) notin strip(given.msg): - r.addResult(test, expected.msg, given.msg, reMsgsDiffer) + r.addResult(test, target, expected.msg, given.msg, reMsgsDiffer) elif expected.nimout.len > 0 and expected.nimout.normalizeMsg notin given.nimout.normalizeMsg: - r.addResult(test, expected.nimout, given.nimout, reMsgsDiffer) + r.addResult(test, target, expected.nimout, given.nimout, reMsgsDiffer) elif expected.tfile == "" and extractFilename(expected.file) != extractFilename(given.file) and "internal error:" notin expected.msg: - r.addResult(test, expected.file, given.file, reFilesDiffer) + r.addResult(test, target, expected.file, given.file, reFilesDiffer) elif expected.line != given.line and expected.line != 0 or expected.column != given.column and expected.column != 0: - r.addResult(test, $expected.line & ':' & $expected.column, + r.addResult(test, target, $expected.line & ':' & $expected.column, $given.line & ':' & $given.column, reLinesDiffer) elif expected.tfile != "" and extractFilename(expected.tfile) != extractFilename(given.tfile) and "internal error:" notin expected.msg: - r.addResult(test, expected.tfile, given.tfile, reFilesDiffer) + r.addResult(test, target, expected.tfile, given.tfile, reFilesDiffer) elif expected.tline != given.tline and expected.tline != 0 or expected.tcolumn != given.tcolumn and expected.tcolumn != 0: - r.addResult(test, $expected.tline & ':' & $expected.tcolumn, + r.addResult(test, target, $expected.tline & ':' & $expected.tcolumn, $given.tline & ':' & $given.tcolumn, reLinesDiffer) else: - r.addResult(test, expected.msg, given.msg, reSuccess) + r.addResult(test, target, expected.msg, given.msg, reSuccess) inc(r.passed) -proc generatedFile(path, name: string, target: TTarget): string = +proc generatedFile(test: TTest, target: TTarget): string = + let (_, name, _) = test.name.splitFile let ext = targetToExt[target] - result = path / "nimcache" / + result = nimcacheDir(test.name, test.options) / (if target == targetJS: "" else: "compiler_") & name.changeFileExt(ext) proc needsCodegenCheck(spec: TSpec): bool = result = spec.maxCodeSize > 0 or spec.ccodeCheck.len > 0 -proc codegenCheck(test: TTest, spec: TSpec, expectedMsg: var string, +proc codegenCheck(test: TTest, target: TTarget, spec: TSpec, expectedMsg: var string, given: var TSpec) = try: - let (path, name, _) = test.name.splitFile - let genFile = generatedFile(path, name, test.target) + let genFile = generatedFile(test, target) let contents = readFile(genFile).string let check = spec.ccodeCheck if check.len > 0: @@ -265,13 +273,13 @@ proc makeDeterministic(s: string): string = sort(x, system.cmp) result = join(x, "\n") -proc compilerOutputTests(test: TTest, given: var TSpec, expected: TSpec; - r: var TResults) = +proc compilerOutputTests(test: TTest, target: TTarget, given: var TSpec, + expected: TSpec; r: var TResults) = var expectedmsg: string = "" var givenmsg: string = "" if given.err == reSuccess: if expected.needsCodegenCheck: - codegenCheck(test, expected, expectedmsg, given) + codegenCheck(test, target, expected, expectedmsg, given) givenmsg = given.msg if expected.nimout.len > 0: expectedmsg = expected.nimout @@ -280,29 +288,9 @@ proc compilerOutputTests(test: TTest, given: var TSpec, expected: TSpec; else: givenmsg = given.nimout.strip if given.err == reSuccess: inc(r.passed) - r.addResult(test, expectedmsg, givenmsg, given.err) - -proc analyzeAndConsolidateOutput(s: string): string = - result = "" - let rows = s.splitLines - for i in 0 ..< rows.len: - if (let pos = find(rows[i], "Traceback (most recent call last)"); pos != -1): - result = substr(rows[i], pos) & "\n" - for i in i+1 ..< rows.len: - result.add rows[i] & "\n" - if not (rows[i] =~ re"^[^(]+\(\d+\)\s+"): - return - elif (let pos = find(rows[i], "SIGSEGV: Illegal storage access."); pos != -1): - result = substr(rows[i], pos) - return - -proc testSpec(r: var TResults, test: TTest) = - # major entry point for a single test - if test.target notin targets: - r.addResult(test, "", "", reIgnored) - inc(r.skipped) - return + r.addResult(test, target, expectedmsg, givenmsg, given.err) +proc testSpec(r: var TResults, test: TTest, target = targetC) = let tname = test.name.addFileExt(".nim") #echo "TESTING ", tname inc(r.total) @@ -314,83 +302,90 @@ proc testSpec(r: var TResults, test: TTest) = expected.action = actionRunNoSpec if expected.err == reIgnored: - r.addResult(test, "", "", reIgnored) + r.addResult(test, target, "", "", reIgnored) inc(r.skipped) return - case expected.action - of actionCompile: - var given = callCompiler(expected.cmd, test.name, - test.options & " --stdout --hint[Path]:off --hint[Processing]:off", - test.target) - compilerOutputTests(test, given, expected, r) - of actionRun, actionRunNoSpec: - # In this branch of code "early return" pattern is clearer than deep - # nested conditionals - the empty rows in between to clarify the "danger" - var given = callCompiler(expected.cmd, test.name, test.options, - test.target) - - if given.err != reSuccess: - r.addResult(test, "", given.msg, given.err) - return - - let isJsTarget = test.target == targetJS - var exeFile: string - if isJsTarget: - let (dir, file, _) = splitFile(tname) - exeFile = dir / "nimcache" / file & ".js" # *TODO* hardcoded "nimcache" - else: - exeFile = changeFileExt(tname, ExeExt) - - if not existsFile(exeFile): - r.addResult(test, expected.outp, "executable not found", reExeNotFound) - return - - let nodejs = if isJsTarget: findNodeJs() else: "" - if isJsTarget and nodejs == "": - r.addResult(test, expected.outp, "nodejs binary not in PATH", - reExeNotFound) - return - - let exeCmd = (if isJsTarget: nodejs & " " else: "") & exeFile - var (buf, exitCode) = execCmdEx(exeCmd, options = {poStdErrToStdOut}) - - # Treat all failure codes from nodejs as 1. Older versions of nodejs used - # to return other codes, but for us it is sufficient to know that it's not 0. - if exitCode != 0: exitCode = 1 - - let bufB = if expected.sortoutput: makeDeterministic(strip(buf.string)) - else: strip(buf.string) - let expectedOut = strip(expected.outp) - - if exitCode != expected.exitCode: - r.addResult(test, "exitcode: " & $expected.exitCode, - "exitcode: " & $exitCode & "\n\nOutput:\n" & - analyzeAndConsolidateOutput(bufB), - reExitCodesDiffer) - return - - if bufB != expectedOut and expected.action != actionRunNoSpec: - if not (expected.substr and expectedOut in bufB): - given.err = reOutputsDiffer - r.addResult(test, expected.outp, bufB, reOutputsDiffer) - return - - compilerOutputTests(test, given, expected, r) - return - - of actionReject: - var given = callCompiler(expected.cmd, test.name, test.options, - test.target) - cmpMsgs(r, expected, given, test) - return - -proc testNoSpec(r: var TResults, test: TTest) = + if expected.targets == {}: + expected.targets.incl(target) + + for target in expected.targets: + if target notin targets: + r.addResult(test, target, "", "", reIgnored) + inc(r.skipped) + continue + + case expected.action + of actionCompile: + var given = callCompiler(expected.cmd, test.name, test.options, target, + extraOptions=" --stdout --hint[Path]:off --hint[Processing]:off") + compilerOutputTests(test, target, given, expected, r) + of actionRun, actionRunNoSpec: + # In this branch of code "early return" pattern is clearer than deep + # nested conditionals - the empty rows in between to clarify the "danger" + var given = callCompiler(expected.cmd, test.name, test.options, + target) + + if given.err != reSuccess: + r.addResult(test, target, "", given.msg, given.err) + continue + + let isJsTarget = target == targetJS + var exeFile: string + if isJsTarget: + let (_, file, _) = splitFile(tname) + exeFile = nimcacheDir(test.name, test.options) / file & ".js" + else: + exeFile = changeFileExt(tname, ExeExt) + + if not existsFile(exeFile): + r.addResult(test, target, expected.outp, "executable not found", reExeNotFound) + continue + + let nodejs = if isJsTarget: findNodeJs() else: "" + if isJsTarget and nodejs == "": + r.addResult(test, target, expected.outp, "nodejs binary not in PATH", + reExeNotFound) + continue + + let exeCmd = (if isJsTarget: nodejs & " " else: "") & exeFile + var (buf, exitCode) = execCmdEx(exeCmd, options = {poStdErrToStdOut}) + + # Treat all failure codes from nodejs as 1. Older versions of nodejs used + # to return other codes, but for us it is sufficient to know that it's not 0. + if exitCode != 0: exitCode = 1 + + let bufB = if expected.sortoutput: makeDeterministic(strip(buf.string)) + else: strip(buf.string) + let expectedOut = strip(expected.outp) + + if exitCode != expected.exitCode: + r.addResult(test, target, "exitcode: " & $expected.exitCode, + "exitcode: " & $exitCode & "\n\nOutput:\n" & + bufB, reExitCodesDiffer) + continue + + if bufB != expectedOut and expected.action != actionRunNoSpec: + if not (expected.substr and expectedOut in bufB): + given.err = reOutputsDiffer + r.addResult(test, target, expected.outp, bufB, reOutputsDiffer) + continue + + compilerOutputTests(test, target, given, expected, r) + continue + + of actionReject: + var given = callCompiler(expected.cmd, test.name, test.options, + target) + cmpMsgs(r, expected, given, test, target) + continue + +proc testNoSpec(r: var TResults, test: TTest, target = targetC) = # does not extract the spec because the file is not supposed to have any #let tname = test.name.addFileExt(".nim") inc(r.total) - let given = callCompiler(cmdTemplate(), test.name, test.options, test.target) - r.addResult(test, "", given.msg, given.err) + let given = callCompiler(cmdTemplate(), test.name, test.options, target) + r.addResult(test, target, "", given.msg, given.err) if given.err == reSuccess: inc(r.passed) proc testC(r: var TResults, test: TTest) = @@ -398,9 +393,9 @@ proc testC(r: var TResults, test: TTest) = let tname = test.name.addFileExt(".c") inc(r.total) styledEcho "Processing ", fgCyan, extractFilename(tname) - var given = callCCompiler(cmdTemplate(), test.name & ".c", test.options, test.target) + var given = callCCompiler(cmdTemplate(), test.name & ".c", test.options, targetC) if given.err != reSuccess: - r.addResult(test, "", given.msg, given.err) + r.addResult(test, targetC, "", given.msg, given.err) elif test.action == actionRun: let exeFile = changeFileExt(test.name, ExeExt) var (_, exitCode) = execCmdEx(exeFile, options = {poStdErrToStdOut, poUsePath}) @@ -408,10 +403,10 @@ proc testC(r: var TResults, test: TTest) = if given.err == reSuccess: inc(r.passed) proc makeTest(test, options: string, cat: Category, action = actionCompile, - target = targetC, env: string = ""): TTest = + env: string = ""): TTest = # start with 'actionCompile', will be overwritten in the spec: result = TTest(cat: cat, name: test, options: options, - target: target, action: action, startTime: epochTime()) + action: action, startTime: epochTime()) when defined(windows): const @@ -436,7 +431,8 @@ proc main() = backend.open() var optPrintResults = false var optFailing = false - var optPedantic = false + + var targetsStr = "" var p = initOptParser() p.next() @@ -444,8 +440,10 @@ proc main() = case p.key.string.normalize of "print", "verbose": optPrintResults = true of "failing": optFailing = true - of "pedantic": optPedantic = true - of "targets": targets = parseTargets(p.val.string) + of "pedantic": discard "now always enabled" + of "targets": + targetsStr = p.val.string + targets = parseTargets(targetsStr) of "nim": compilerPrefix = p.val.string else: quit Usage p.next() @@ -456,13 +454,22 @@ proc main() = case action of "all": let testsDir = "tests" & DirSep + var myself = quoteShell(findExe("tests" / "testament" / "tester")) + if targetsStr.len > 0: + myself &= " " & quoteShell("--targets:" & targetsStr) + + myself &= " " & quoteShell("--nim:" & compilerPrefix) + + var cmds: seq[string] = @[] + let rest = if p.cmdLineRest.string.len > 0: " " & p.cmdLineRest.string else: "" for kind, dir in walkDir(testsDir): assert testsDir.startsWith(testsDir) let cat = dir[testsDir.len .. ^1] if kind == pcDir and cat notin ["testament", "testdata", "nimcache"]: - processCategory(r, Category(cat), p.cmdLineRest.string) - for a in AdditionalCategories: - processCategory(r, Category(a), p.cmdLineRest.string) + cmds.add(myself & " cat " & cat & rest) + for cat in AdditionalCategories: + cmds.add(myself & " cat " & cat & rest) + quit osproc.execProcesses(cmds, {poEchoCmd, poStdErrToStdOut, poUsePath, poParentStreams}) of "c", "cat", "category": var cat = Category(p.key) p.next @@ -473,10 +480,7 @@ proc main() = var cat = Category(subdir) processSingleTest(r, cat, p.cmdLineRest.string, file) of "html": - var commit = 0 - discard parseInt(p.cmdLineRest.string, commit) - generateHtml(resultsFile, commit, optFailing) - generateJson(jsonFile, commit) + generateHtml(resultsFile, optFailing) else: quit Usage @@ -484,11 +488,10 @@ proc main() = if action == "html": openDefaultBrowser(resultsFile) else: echo r, r.data backend.close() - if optPedantic: - var failed = r.total - r.passed - r.skipped - if failed > 0: - echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ", r.skipped - quit(QuitFailure) + var failed = r.total - r.passed - r.skipped + if failed > 0: + echo "FAILURE! total: ", r.total, " passed: ", r.passed, " skipped: ", r.skipped + quit(QuitFailure) if paramCount() == 0: quit Usage diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim index 7f5a359f5..eb265f420 100644 --- a/tests/tuples/tuple_with_nil.nim +++ b/tests/tuples/tuple_with_nil.nim @@ -485,7 +485,7 @@ proc writeformat(o: var Writer; b: bool; fmt: Format) = else: raise newException(FormatError, "Boolean values must of one of the following types: s,b,o,x,X,d,n") -proc writeformat(o: var Writer; ary: openarray[any]; fmt: Format) = +proc writeformat(o: var Writer; ary: openarray[system.any]; fmt: Format) = ## Write array `ary` according to format `fmt` using output object ## `o` and output function `add`. if ary.len == 0: return diff --git a/tests/typerel/typeof_in_template.nim b/tests/typerel/typeof_in_template.nim index 9ec06f2e3..3724cc994 100644 --- a/tests/typerel/typeof_in_template.nim +++ b/tests/typerel/typeof_in_template.nim @@ -1,5 +1,5 @@ discard """ - output: '''@[a, c]''' + output: '''@["a", "c"]''' """ # bug #3230 diff --git a/tests/types/tillegaltyperecursion2.nim b/tests/types/tillegaltyperecursion2.nim new file mode 100644 index 000000000..b5ffdda72 --- /dev/null +++ b/tests/types/tillegaltyperecursion2.nim @@ -0,0 +1,8 @@ +discard """ + errormsg: "invalid recursion in type 'Executor'" + line: 8 +""" +# bug reported by PR #5637 +type + Executor[N] = Executor[N] +var e: Executor[int] diff --git a/tests/types/tinheritpartialgeneric.nim b/tests/types/tinheritpartialgeneric.nim index a00df26fa..1845778bf 100644 --- a/tests/types/tinheritpartialgeneric.nim +++ b/tests/types/tinheritpartialgeneric.nim @@ -1,6 +1,6 @@ discard """ - output: '''(c: hello, a: 10, b: 12.0) -(a: 15.5, b: hello) + output: '''(c: "hello", a: 10, b: 12.0) +(a: 15.5, b: "hello") (a: 11.75, b: 123)''' """ diff --git a/tests/types/tinheritref.nim b/tests/types/tinheritref.nim index ecd62a06f..00af0538d 100644 --- a/tests/types/tinheritref.nim +++ b/tests/types/tinheritref.nim @@ -1,5 +1,7 @@ discard """ - output: "23" + output: '''23 +1.5 +''' """ # bug #554, #179 @@ -25,3 +27,24 @@ type var it: TKeysIterator[int, string] = nil +#bug #5521 +type + Texture = enum + Smooth + Coarse + + FruitBase = object of RootObj + color: int + case kind: Texture + of Smooth: + skin: float64 + of Coarse: + grain: int + + Apple = object of FruitBase + width: int + taste: float64 + +var x = Apple(kind: Smooth, skin: 1.5) +var u = x.skin +echo u diff --git a/tests/types/tparameterizedparent2.nim b/tests/types/tparameterizedparent2.nim index 999db2ac5..e96b9edbe 100644 --- a/tests/types/tparameterizedparent2.nim +++ b/tests/types/tparameterizedparent2.nim @@ -2,7 +2,7 @@ discard """ output: '''(width: 11, color: 13) (width: 15, weight: 13, taste: 11, color: 14) (width: 17, color: 16) -(width: 12.0, taste: yummy, color: 13) +(width: 12.0, taste: "yummy", color: 13) (width: 0, tast_e: 0.0, kind: Smooth, skin: 1.5, color: 12)''' """ # bug #5264 diff --git a/tests/types/tyet_another_generic_regression.nim b/tests/types/tyet_another_generic_regression.nim new file mode 100644 index 000000000..914166e06 --- /dev/null +++ b/tests/types/tyet_another_generic_regression.nim @@ -0,0 +1,13 @@ +import system + +type Bar[T] = ref object + value: T + +type types = int32|int64 # if I change this to just int32 or int64 it works (compiles) + +# if I replace Bar everywhere with seq it also compiles fine +proc Foo[T: Bar[types]](): T = + when T is Bar: nil + +discard Foo[Bar[int32]]() +#bug #6073 diff --git a/tests/untestable/readme.markdown b/tests/untestable/readme.markdown index fcb7f4f28..de1ba9459 100644 --- a/tests/untestable/readme.markdown +++ b/tests/untestable/readme.markdown @@ -1,2 +1,9 @@ -This directory contains tests which are not automatically executed -for various reasons. Mainly due to dependencies on external services. \ No newline at end of file +This directory contains integration tests which are not automatically executed +for various reasons: +- dependency on external services +- dependency on files / configuration / state of the local host +- tests that are extremely slow or require large amounts of memory or storage +- tests that spawn local daemons + +Integration tests can become stale very quickly. Automated ./koch tests are +strongly recommended. diff --git a/tests/untestable/tpostgres.nim b/tests/untestable/tpostgres.nim index 486d0d703..d3397e53a 100644 --- a/tests/untestable/tpostgres.nim +++ b/tests/untestable/tpostgres.nim @@ -304,7 +304,24 @@ doAssert parseInt(dbCols[40].typ.name) > 0 doAssert dbCols[41].name == "range_col" doAssert dbCols[41].typ.kind == DbTypeKind.dbComposite doAssert dbCols[41].typ.name == "int4range" - + +# issue 6571 +db.exec(sql"DROP TABLE IF EXISTS DICTIONARY") +db.exec(sql("""CREATE TABLE DICTIONARY( + id SERIAL PRIMARY KEY, + entry VARCHAR(1000) NOT NULL, + definition VARCHAR(4000) NOT NULL + );""")) +var entry = "ã‚ã£ã" +var definition = "(int) (See ã‚ã‚ãã†ãã†) oh, really (uninterested)/oh yeah?/hmmmmm" +discard db.getRow( + SqlQuery("INSERT INTO DICTIONARY(entry, definition) VALUES(\'$1\', \'$2\') RETURNING id" % [entry, definition])) +doAssert db.getValue(sql"SELECT definition FROM DICTIONARY WHERE entry = ?", entry) == definition +entry = "Format string entry" +definition = "Format string definition" +db.exec(sql"INSERT INTO DICTIONARY(entry, definition) VALUES (?, ?)", entry, definition) +doAssert db.getValue(sql"SELECT definition FROM DICTIONARY WHERE entry = ?", entry) == definition + echo("All tests succeeded!") db.close() diff --git a/tests/vm/tableinstatic.nim b/tests/vm/tableinstatic.nim index 54e7c11f0..b0d24b477 100644 --- a/tests/vm/tableinstatic.nim +++ b/tests/vm/tableinstatic.nim @@ -2,7 +2,7 @@ discard """ nimout: '''0 0 0 -{hallo: 123, welt: 456}''' +{"hallo": "123", "welt": "456"}''' """ import tables diff --git a/tests/vm/tcastint.nim b/tests/vm/tcastint.nim new file mode 100644 index 000000000..7b9ddd7d9 --- /dev/null +++ b/tests/vm/tcastint.nim @@ -0,0 +1,120 @@ +discard """ + file: "tcastint.nim" + output: "OK" +""" + +type + Dollar = distinct int + XCoord = distinct int32 + Digit = range[-9..0] + +# those are necessary for comparisons below. +proc `==`(x, y: Dollar): bool {.borrow.} +proc `==`(x, y: XCoord): bool {.borrow.} + +proc dummy[T](x: T): T = x + +proc test() = + let U8 = 0b1011_0010'u8 + let I8 = 0b1011_0010'i8 + let C8 = 0b1011_0010'u8.char + let C8_1 = 0b1011_0011'u8.char + let U16 = 0b10100111_00101000'u16 + let I16 = 0b10100111_00101000'i16 + let U32 = 0b11010101_10011100_11011010_01010000'u32 + let I32 = 0b11010101_10011100_11011010_01010000'i32 + let U64A = 0b11000100_00111111_01111100_10001010_10011001_01001000_01111010_00010001'u64 + let I64A = 0b11000100_00111111_01111100_10001010_10011001_01001000_01111010_00010001'i64 + let U64B = 0b00110010_11011101_10001111_00101000_00000000_00000000_00000000_00000000'u64 + let I64B = 0b00110010_11011101_10001111_00101000_00000000_00000000_00000000_00000000'i64 + when sizeof(int) == 8: + let UX = U64A.uint + let IX = I64A.int + elif sizeof(int) == 4: + let UX = U32.uint + let IX = I32.int + elif sizeof(int) == 2: + let UX = U16.uint + let IX = I16.int + else: + let UX = U8.uint + let IX = I8.int + + doAssert(cast[char](I8) == C8) + doAssert(cast[uint8](I8) == U8) + doAssert(cast[uint16](I16) == U16) + doAssert(cast[uint32](I32) == U32) + doAssert(cast[uint64](I64A) == U64A) + doAssert(cast[uint64](I64B) == U64B) + doAssert(cast[int8](U8) == I8) + doAssert(cast[int16](U16) == I16) + doAssert(cast[int32](U32) == I32) + doAssert(cast[int64](U64A) == I64A) + doAssert(cast[int64](U64B) == I64B) + doAssert(cast[uint](IX) == UX) + doAssert(cast[int](UX) == IX) + + doAssert(cast[char](I8 + 1) == C8_1) + doAssert(cast[uint8](I8 + 1) == U8 + 1) + doAssert(cast[uint16](I16 + 1) == U16 + 1) + doAssert(cast[uint32](I32 + 1) == U32 + 1) + doAssert(cast[uint64](I64A + 1) == U64A + 1) + doAssert(cast[uint64](I64B + 1) == U64B + 1) + doAssert(cast[int8](U8 + 1) == I8 + 1) + doAssert(cast[int16](U16 + 1) == I16 + 1) + doAssert(cast[int32](U32 + 1) == I32 + 1) + doAssert(cast[int64](U64A + 1) == I64A + 1) + doAssert(cast[int64](U64B + 1) == I64B + 1) + doAssert(cast[uint](IX + 1) == UX + 1) + doAssert(cast[int](UX + 1) == IX + 1) + + doAssert(cast[char](I8.dummy) == C8.dummy) + doAssert(cast[uint8](I8.dummy) == U8.dummy) + doAssert(cast[uint16](I16.dummy) == U16.dummy) + doAssert(cast[uint32](I32.dummy) == U32.dummy) + doAssert(cast[uint64](I64A.dummy) == U64A.dummy) + doAssert(cast[uint64](I64B.dummy) == U64B.dummy) + doAssert(cast[int8](U8.dummy) == I8.dummy) + doAssert(cast[int16](U16.dummy) == I16.dummy) + doAssert(cast[int32](U32.dummy) == I32.dummy) + doAssert(cast[int64](U64A.dummy) == I64A.dummy) + doAssert(cast[int64](U64B.dummy) == I64B.dummy) + doAssert(cast[uint](IX.dummy) == UX.dummy) + doAssert(cast[int](UX.dummy) == IX.dummy) + + + doAssert(cast[int64](if false: U64B else: 0'u64) == (if false: I64B else: 0'i64)) + + block: + let raw = 3 + let money = Dollar(raw) # this must be a variable, is otherwise constant folded. + doAssert(cast[int](money) == raw) + doAssert(cast[Dollar](raw) == money) + block: + let raw = 150'i32 + let position = XCoord(raw) # this must be a variable, is otherwise constant folded. + doAssert(cast[int32](position) == raw) + doAssert(cast[XCoord](raw) == position) + block: + let raw = -2 + let digit = Digit(raw) + doAssert(cast[int](digit) == raw) + doAssert(cast[Digit](raw) == digit) + + when defined nimvm: + doAssert(not compiles(cast[float](I64A))) + doAssert(not compiles(cast[float32](I64A))) + + doAssert(not compiles(cast[char](I64A))) + doAssert(not compiles(cast[uint16](I64A))) + doAssert(not compiles(cast[uint32](I64A))) + + doAssert(not compiles(cast[uint16](I8))) + doAssert(not compiles(cast[uint32](I8))) + doAssert(not compiles(cast[uint64](I8))) + +test() +static: + test() + +echo "OK" diff --git a/tests/vm/tconstobj.nim b/tests/vm/tconstobj.nim index 51f30fb78..38fcdd844 100644 --- a/tests/vm/tconstobj.nim +++ b/tests/vm/tconstobj.nim @@ -1,5 +1,5 @@ discard """ - output: '''(name: hello) + output: '''(name: "hello") (-1, 0)''' """ diff --git a/tests/vm/tnimnode.nim b/tests/vm/tnimnode.nim index 60e3189b0..0614b9807 100644 --- a/tests/vm/tnimnode.nim +++ b/tests/vm/tnimnode.nim @@ -26,12 +26,12 @@ proc checkNode(arg: NimNode; name: string): void {. compileTime .} = seqAppend.add(arg) # bit this creates a copy arg.add newCall(ident"echo", newLit("Hello World")) - assertEq arg.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq node.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq nodeArray[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq nodeSeq[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq seqAppend[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" - assertEq seqAppend[1].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(!"echo"), StrLit(Hello World)))""" + assertEq arg.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq node.lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq nodeArray[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq nodeSeq[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq seqAppend[0].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" + assertEq seqAppend[1].lispRepr , """StmtList(DiscardStmt(Empty()), Call(Ident(ident"echo"), StrLit(Hello World)))""" echo "OK" diff --git a/tests/vm/trgba.nim b/tests/vm/trgba.nim index da1a2d0c5..923ea1b2e 100644 --- a/tests/vm/trgba.nim +++ b/tests/vm/trgba.nim @@ -22,14 +22,14 @@ template `B=`*(self: TAggRgba8, val: byte) = template `A=`*(self: TAggRgba8, val: byte) = self[3] = val -proc ABGR* (val: int| int64): TAggRgba8 = +proc ABGR*(val: int| int64): TAggRgba8 = var V = val - result.R = V and 0xFF + result.R = byte(V and 0xFF) V = V shr 8 - result.G = V and 0xFF + result.G = byte(V and 0xFF) V = V shr 8 - result.B = V and 0xFF - result.A = (V shr 8) and 0xFF + result.B = byte(V and 0xFF) + result.A = byte((V shr 8) and 0xFF) const c1 = ABGR(0xFF007F7F) diff --git a/tinyc/arm-asm.c b/tinyc/arm-asm.c new file mode 100644 index 000000000..3b5ae661c --- /dev/null +++ b/tinyc/arm-asm.c @@ -0,0 +1,94 @@ +/*************************************************************/ +/* + * ARM dummy assembler for TCC + * + */ + +#ifdef TARGET_DEFS_ONLY + +#define CONFIG_TCC_ASM +#define NB_ASM_REGS 16 + +ST_FUNC void g(int c); +ST_FUNC void gen_le16(int c); +ST_FUNC void gen_le32(int c); + +/*************************************************************/ +#else +/*************************************************************/ + +#include "tcc.h" + +static void asm_error(void) +{ + tcc_error("ARM asm not implemented."); +} + +/* XXX: make it faster ? */ +ST_FUNC void g(int c) +{ + int ind1; + if (nocode_wanted) + return; + ind1 = ind + 1; + if (ind1 > cur_text_section->data_allocated) + section_realloc(cur_text_section, ind1); + cur_text_section->data[ind] = c; + ind = ind1; +} + +ST_FUNC void gen_le16 (int i) +{ + g(i); + g(i>>8); +} + +ST_FUNC void gen_le32 (int i) +{ + gen_le16(i); + gen_le16(i>>16); +} + +ST_FUNC void gen_expr32(ExprValue *pe) +{ + gen_le32(pe->v); +} + +ST_FUNC void asm_opcode(TCCState *s1, int opcode) +{ + asm_error(); +} + +ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) +{ + asm_error(); +} + +/* generate prolog and epilog code for asm statement */ +ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, + int nb_outputs, int is_output, + uint8_t *clobber_regs, + int out_reg) +{ +} + +ST_FUNC void asm_compute_constraints(ASMOperand *operands, + int nb_operands, int nb_outputs, + const uint8_t *clobber_regs, + int *pout_reg) +{ +} + +ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) +{ + asm_error(); +} + +ST_FUNC int asm_parse_regvar (int t) +{ + asm_error(); + return -1; +} + +/*************************************************************/ +#endif /* ndef TARGET_DEFS_ONLY */ diff --git a/tinyc/arm-gen.c b/tinyc/arm-gen.c index 050a8ad88..f535a09ce 100644 --- a/tinyc/arm-gen.c +++ b/tinyc/arm-gen.c @@ -1,7 +1,8 @@ /* * ARMv4 code generator for TCC - * - * Copyright (c) 2003 Daniel Glöckner + * + * Copyright (c) 2003 Daniel Glöckner + * Copyright (c) 2012 Thomas Preud'homme * * Based on i386-gen.c by Fabrice Bellard * @@ -20,10 +21,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef TCC_ARM_EABI -#define TCC_ARM_VFP -#endif +#ifdef TARGET_DEFS_ONLY +#if defined(TCC_ARM_EABI) && !defined(TCC_ARM_VFP) +#error "Currently TinyCC only supports float computation with VFP instructions" +#endif /* number of available registers */ #ifdef TCC_ARM_VFP @@ -32,13 +34,17 @@ #define NB_REGS 9 #endif +#ifndef TCC_CPU_VERSION +# define TCC_CPU_VERSION 5 +#endif + /* a register can belong to several classes. The classes must be sorted from more general to more precise (see gv2() code which does assumptions on it). */ #define RC_INT 0x0001 /* generic integer register */ #define RC_FLOAT 0x0002 /* generic float register */ #define RC_R0 0x0004 -#define RC_R1 0x0008 +#define RC_R1 0x0008 #define RC_R2 0x0010 #define RC_R3 0x0020 #define RC_R12 0x0040 @@ -73,34 +79,10 @@ enum { TREG_F6, TREG_F7, #endif + TREG_SP = 13, + TREG_LR, }; -int reg_classes[NB_REGS] = { - /* r0 */ RC_INT | RC_R0, - /* r1 */ RC_INT | RC_R1, - /* r2 */ RC_INT | RC_R2, - /* r3 */ RC_INT | RC_R3, - /* r12 */ RC_INT | RC_R12, - /* f0 */ RC_FLOAT | RC_F0, - /* f1 */ RC_FLOAT | RC_F1, - /* f2 */ RC_FLOAT | RC_F2, - /* f3 */ RC_FLOAT | RC_F3, -#ifdef TCC_ARM_VFP - /* d4/s8 */ RC_FLOAT | RC_F4, -/* d5/s10 */ RC_FLOAT | RC_F5, -/* d6/s12 */ RC_FLOAT | RC_F6, -/* d7/s14 */ RC_FLOAT | RC_F7, -#endif -}; - -static int two2mask(int a,int b) { - return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT); -} - -static int regmask(int r) { - return reg_classes[r]&~(RC_INT|RC_FLOAT); -} - #ifdef TCC_ARM_VFP #define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0) #endif @@ -122,16 +104,7 @@ static int regmask(int r) { /* defined if structures are passed as pointers. Otherwise structures are directly pushed on stack. */ -//#define FUNC_STRUCT_PARAM_AS_PTR - -#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) -static CType float_type, double_type, func_float_type, func_double_type; -#define func_ldouble_type func_double_type -#else -#define func_float_type func_old_type -#define func_double_type func_old_type -#define func_ldouble_type func_old_type -#endif +/* #define FUNC_STRUCT_PARAM_AS_PTR */ /* pointer size, in bytes */ #define PTR_SIZE 4 @@ -157,46 +130,113 @@ static CType float_type, double_type, func_float_type, func_double_type; #define CHAR_IS_UNSIGNED /******************************************************/ -/* ELF defines */ +#else /* ! TARGET_DEFS_ONLY */ +/******************************************************/ +#include "tcc.h" -#define EM_TCC_TARGET EM_ARM +enum float_abi float_abi; -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_ARM_ABS32 -#define R_JMP_SLOT R_ARM_JUMP_SLOT -#define R_COPY R_ARM_COPY +ST_DATA const int reg_classes[NB_REGS] = { + /* r0 */ RC_INT | RC_R0, + /* r1 */ RC_INT | RC_R1, + /* r2 */ RC_INT | RC_R2, + /* r3 */ RC_INT | RC_R3, + /* r12 */ RC_INT | RC_R12, + /* f0 */ RC_FLOAT | RC_F0, + /* f1 */ RC_FLOAT | RC_F1, + /* f2 */ RC_FLOAT | RC_F2, + /* f3 */ RC_FLOAT | RC_F3, +#ifdef TCC_ARM_VFP + /* d4/s8 */ RC_FLOAT | RC_F4, +/* d5/s10 */ RC_FLOAT | RC_F5, +/* d6/s12 */ RC_FLOAT | RC_F6, +/* d7/s14 */ RC_FLOAT | RC_F7, +#endif +}; -#define ELF_START_ADDR 0x00008000 -#define ELF_PAGE_SIZE 0x1000 +static int func_sub_sp_offset, last_itod_magic; +static int leaffunc; + +#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) +static CType float_type, double_type, func_float_type, func_double_type; +ST_FUNC void arm_init(struct TCCState *s) +{ + float_type.t = VT_FLOAT; + double_type.t = VT_DOUBLE; + func_float_type.t = VT_FUNC; + func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD); + func_double_type.t = VT_FUNC; + func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD); + + float_abi = s->float_abi; +#ifndef TCC_ARM_HARDFLOAT + tcc_warning("soft float ABI currently not supported: default to softfp"); +#endif +} +#else +#define func_float_type func_old_type +#define func_double_type func_old_type +#define func_ldouble_type func_old_type +ST_FUNC void arm_init(struct TCCState *s) +{ +#if 0 +#if !defined (TCC_ARM_VFP) + tcc_warning("Support for FPA is deprecated and will be removed in next" + " release"); +#endif +#if !defined (TCC_ARM_EABI) + tcc_warning("Support for OABI is deprecated and will be removed in next" + " release"); +#endif +#endif +} +#endif + +static int two2mask(int a,int b) { + return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT); +} + +static int regmask(int r) { + return reg_classes[r]&~(RC_INT|RC_FLOAT); +} /******************************************************/ -static unsigned long func_sub_sp_offset,last_itod_magic; -static int leaffunc; -void o(unsigned long i) +#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP) +const char *default_elfinterp(struct TCCState *s) +{ + if (s->float_abi == ARM_HARD_FLOAT) + return "/lib/ld-linux-armhf.so.3"; + else + return "/lib/ld-linux.so.3"; +} +#endif + +void o(uint32_t i) { /* this is a good place to start adding big-endian support*/ int ind1; - + if (nocode_wanted) + return; ind1 = ind + 4; if (!cur_text_section) - error("compiler error! This happens f.ex. if the compiler\n" + tcc_error("compiler error! This happens f.ex. if the compiler\n" "can't evaluate constant expressions outside of a function."); if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); cur_text_section->data[ind++] = i&255; i>>=8; cur_text_section->data[ind++] = i&255; - i>>=8; + i>>=8; cur_text_section->data[ind++] = i&255; i>>=8; cur_text_section->data[ind++] = i; } -static unsigned long stuff_const(unsigned long op,unsigned long c) +static uint32_t stuff_const(uint32_t op, uint32_t c) { int try_neg=0; - unsigned long nc = 0,negop = 0; + uint32_t nc = 0, negop = 0; switch(op&0x1F00000) { @@ -230,7 +270,7 @@ static unsigned long stuff_const(unsigned long op,unsigned long c) break; } do { - unsigned long m; + uint32_t m; int i; if(c<256) /* catch undefined <<32 */ return op|c; @@ -247,13 +287,13 @@ static unsigned long stuff_const(unsigned long op,unsigned long c) //only add,sub -void stuff_const_harder(unsigned long op,unsigned long v) { - unsigned long x; +void stuff_const_harder(uint32_t op, uint32_t v) { + uint32_t x; x=stuff_const(op,v); if(x) o(x); else { - unsigned long a[16],nv,no,o2,n2; + uint32_t a[16], nv, no, o2, n2; int i,j,k; a[0]=0xff; o2=(op&0xfff0ffff)|((op&0xf000)<<4);; @@ -303,13 +343,13 @@ void stuff_const_harder(unsigned long op,unsigned long v) { } } -unsigned long encbranch(int pos,int addr,int fail) +uint32_t encbranch(int pos, int addr, int fail) { addr-=pos+8; addr/=4; if(addr>=0x1000000 || addr<-0x1000000) { if(fail) - error("FIXME: function bigger than 32MB"); + tcc_error("FIXME: function bigger than 32MB"); return 0; } return 0x0A000000|(addr&0xffffff); @@ -318,7 +358,7 @@ unsigned long encbranch(int pos,int addr,int fail) int decbranch(int pos) { int x; - x=*(int *)(cur_text_section->data + pos); + x=*(uint32_t *)(cur_text_section->data + pos); x&=0x00ffffff; if(x&0x800000) x-=0x1000000; @@ -328,10 +368,10 @@ int decbranch(int pos) /* output a symbol and patch all calls to it */ void gsym_addr(int t, int a) { - unsigned long *x; + uint32_t *x; int lt; while(t) { - x=(unsigned long *)(cur_text_section->data + t); + x=(uint32_t *)(cur_text_section->data + t); t=decbranch(lt=t); if(a==lt+4) *x=0xE1A00000; // nop @@ -348,34 +388,36 @@ void gsym(int t) } #ifdef TCC_ARM_VFP -static unsigned long vfpr(int r) +static uint32_t vfpr(int r) { if(r<TREG_F0 || r>TREG_F7) - error("compiler error! register %i is no vfp register",r); - return r-5; + tcc_error("compiler error! register %i is no vfp register",r); + return r - TREG_F0; } #else -static unsigned long fpr(int r) +static uint32_t fpr(int r) { if(r<TREG_F0 || r>TREG_F3) - error("compiler error! register %i is no fpa register",r); - return r-5; + tcc_error("compiler error! register %i is no fpa register",r); + return r - TREG_F0; } #endif -static unsigned long intr(int r) +static uint32_t intr(int r) { - if(r==4) + if(r == TREG_R12) return 12; - if((r<0 || r>4) && r!=14) - error("compiler error! register %i is no int register",r); - return r; + if(r >= TREG_R0 && r <= TREG_R3) + return r - TREG_R0; + if (r >= TREG_SP && r <= TREG_LR) + return r + (13 - TREG_SP); + tcc_error("compiler error! register %i is no int register",r); } -static void calcaddr(unsigned long *base,int *off,int *sgn,int maxoff,unsigned shift) +static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift) { if(*off>maxoff || *off&((1<<shift)-1)) { - unsigned long x,y; + uint32_t x, y; x=0xE280E000; if(*sgn) x=0xE240E000; @@ -399,7 +441,7 @@ static void calcaddr(unsigned long *base,int *off,int *sgn,int maxoff,unsigned s } } -static unsigned long mapcc(int cc) +static uint32_t mapcc(int cc) { switch(cc) { @@ -428,7 +470,7 @@ static unsigned long mapcc(int cc) case TOK_GT: return 0xC0000000; /* GT */ } - error("unexpected condition code"); + tcc_error("unexpected condition code"); return 0xE0000000; /* AL */ } @@ -461,7 +503,7 @@ static int negcc(int cc) case TOK_GT: return TOK_LE; } - error("unexpected condition code"); + tcc_error("unexpected condition code"); return TOK_NE; } @@ -469,12 +511,12 @@ static int negcc(int cc) void load(int r, SValue *sv) { int v, ft, fc, fr, sign; - unsigned long op; + uint32_t op; SValue v1; fr = sv->r; ft = sv->type.t; - fc = sv->c.ul; + fc = sv->c.i; if(fc>=0) sign=0; @@ -482,23 +524,25 @@ void load(int r, SValue *sv) sign=1; fc=-fc; } - + v = fr & VT_VALMASK; if (fr & VT_LVAL) { - unsigned long base=0xB; // fp + uint32_t base = 0xB; // fp if(v == VT_LLOCAL) { v1.type.t = VT_PTR; v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = sv->c.ul; - load(base=14 /* lr */, &v1); + v1.c.i = sv->c.i; + load(TREG_LR, &v1); + base = 14; /* lr */ fc=sign=0; v=VT_LOCAL; } else if(v == VT_CONST) { v1.type.t = VT_PTR; v1.r = fr&~VT_LVAL; - v1.c.ul = sv->c.ul; + v1.c.i = sv->c.i; v1.sym=sv->sym; - load(base=14, &v1); + load(TREG_LR, &v1); + base = 14; /* lr */ fc=sign=0; v=VT_LOCAL; } else if(v < VT_CONST) { @@ -547,7 +591,7 @@ void load(int r, SValue *sv) op=0xE5100000; if(!sign) op|=0x800000; - if ((ft & VT_BTYPE) == VT_BYTE) + if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL) op|=0x400000; o(op|(intr(r)<<12)|fc|(base<<16)); } @@ -555,38 +599,38 @@ void load(int r, SValue *sv) } } else { if (v == VT_CONST) { - op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.ul); + op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i); if (fr & VT_SYM || !op) { o(0xE59F0000|(intr(r)<<12)); o(0xEA000000); if(fr & VT_SYM) greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); - o(sv->c.ul); + o(sv->c.i); } else o(op); return; } else if (v == VT_LOCAL) { - op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.ul); + op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i); if (fr & VT_SYM || !op) { o(0xE59F0000|(intr(r)<<12)); o(0xEA000000); if(fr & VT_SYM) // needed ? greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); - o(sv->c.ul); + o(sv->c.i); o(0xE08B0000|(intr(r)<<12)|intr(r)); } else o(op); return; } else if(v == VT_CMP) { - o(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12)); - o(mapcc(negcc(sv->c.ul))|0x3A00000|(intr(r)<<12)); + o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12)); + o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12)); return; } else if (v == VT_JMP || v == VT_JMPI) { int t; t = v & 1; o(0xE3A00000|(intr(r)<<12)|t); o(0xEA000000); - gsym(sv->c.ul); + gsym(sv->c.i); o(0xE3A00000|(intr(r)<<12)|(t^1)); return; } else if (v < VT_CONST) { @@ -601,7 +645,7 @@ void load(int r, SValue *sv) return; } } - error("load unimplemented!"); + tcc_error("load unimplemented!"); } /* store register 'r' in lvalue 'v' */ @@ -609,11 +653,11 @@ void store(int r, SValue *sv) { SValue v1; int v, ft, fc, fr, sign; - unsigned long op; + uint32_t op; fr = sv->r; ft = sv->type.t; - fc = sv->c.ul; + fc = sv->c.i; if(fc>=0) sign=0; @@ -621,10 +665,10 @@ void store(int r, SValue *sv) sign=1; fc=-fc; } - - v = fr & VT_VALMASK; + + v = fr & VT_VALMASK; if (fr & VT_LVAL || fr == VT_LOCAL) { - unsigned long base=0xb; + uint32_t base = 0xb; /* fp */ if(v < VT_CONST) { base=intr(v); v=VT_LOCAL; @@ -632,20 +676,21 @@ void store(int r, SValue *sv) } else if(v == VT_CONST) { v1.type.t = ft; v1.r = fr&~VT_LVAL; - v1.c.ul = sv->c.ul; + v1.c.i = sv->c.i; v1.sym=sv->sym; - load(base=14, &v1); + load(TREG_LR, &v1); + base = 14; /* lr */ fc=sign=0; - v=VT_LOCAL; + v=VT_LOCAL; } if(v == VT_LOCAL) { if(is_float(ft)) { calcaddr(&base,&fc,&sign,1020,2); #ifdef TCC_ARM_VFP op=0xED000A00; /* fsts */ - if(!sign) - op|=0x800000; - if ((ft & VT_BTYPE) != VT_FLOAT) + if(!sign) + op|=0x800000; + if ((ft & VT_BTYPE) != VT_FLOAT) op|=0x100; /* fsts -> fstd */ o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16)); #else @@ -675,14 +720,14 @@ void store(int r, SValue *sv) op=0xE5000000; if(!sign) op|=0x800000; - if ((ft & VT_BTYPE) == VT_BYTE) + if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL) op|=0x400000; o(op|(intr(r)<<12)|fc|(base<<16)); } return; } } - error("store unimplemented"); + tcc_error("store unimplemented"); } static void gadd_sp(int val) @@ -695,9 +740,9 @@ static void gcall_or_jmp(int is_jmp) { int r; if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - unsigned long x; + uint32_t x; /* constant case */ - x=encbranch(ind,ind+vtop->c.ul,0); + x=encbranch(ind,ind+vtop->c.i,0); if(x) { if (vtop->r & VT_SYM) { /* relocation case */ @@ -711,7 +756,7 @@ static void gcall_or_jmp(int is_jmp) o(0xE51FF004); // ldr pc,[pc,#-4] if (vtop->r & VT_SYM) greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32); - o(vtop->c.ul); + o(vtop->c.i); } } else { /* otherwise, indirect call */ @@ -722,233 +767,545 @@ static void gcall_or_jmp(int is_jmp) } } -/* Generate function call. The function address is pushed first, then - all the parameters in call order. This functions pops all the - parameters and the function address. */ -void gfunc_call(int nb_args) +static int unalias_ldbl(int btype) { - int size, align, r, args_size, i; - Sym *func_sym; - signed char plan[4][2]={{-1,-1},{-1,-1},{-1,-1},{-1,-1}}; - int todo=0xf, keep, plan2[4]={0,0,0,0}; +#if LDOUBLE_SIZE == 8 + if (btype == VT_LDOUBLE) + btype = VT_DOUBLE; +#endif + return btype; +} - r = vtop->r & VT_VALMASK; - if (r == VT_CMP || (r & ~1) == VT_JMP) - gv(RC_INT); -#ifdef TCC_ARM_EABI - if((vtop[-nb_args].type.ref->type.t & VT_BTYPE) == VT_STRUCT - && type_size(&vtop[-nb_args].type, &align) <= 4) { - SValue tmp; - tmp=vtop[-nb_args]; - vtop[-nb_args]=vtop[-nb_args+1]; - vtop[-nb_args+1]=tmp; - --nb_args; - } - - vpushi(0); - vtop->type.t = VT_LLONG; - args_size = 0; - for(i = nb_args + 1 ; i-- ;) { - size = type_size(&vtop[-i].type, &align); - if(args_size & (align-1)) { - vpushi(0); - vtop->type.t = VT_VOID; /* padding */ - vrott(i+2); - args_size += 4; - ++nb_args; +/* Return whether a structure is an homogeneous float aggregate or not. + The answer is true if all the elements of the structure are of the same + primitive float type and there is less than 4 elements. + + type: the type corresponding to the structure to be tested */ +static int is_hgen_float_aggr(CType *type) +{ + if ((type->t & VT_BTYPE) == VT_STRUCT) { + struct Sym *ref; + int btype, nb_fields = 0; + + ref = type->ref->next; + btype = unalias_ldbl(ref->type.t & VT_BTYPE); + if (btype == VT_FLOAT || btype == VT_DOUBLE) { + for(; ref && btype == unalias_ldbl(ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++); + return !ref && nb_fields <= 4; } - args_size += (size + 3) & -4; } - vtop--; + return 0; +} + +struct avail_regs { + signed char avail[3]; /* 3 holes max with only float and double alignments */ + int first_hole; /* first available hole */ + int last_hole; /* last available hole (none if equal to first_hole) */ + int first_free_reg; /* next free register in the sequence, hole excluded */ +}; + +#define AVAIL_REGS_INITIALIZER (struct avail_regs) { { 0, 0, 0}, 0, 0, 0 } + +/* Find suitable registers for a VFP Co-Processor Register Candidate (VFP CPRC + param) according to the rules described in the procedure call standard for + the ARM architecture (AAPCS). If found, the registers are assigned to this + VFP CPRC parameter. Registers are allocated in sequence unless a hole exists + and the parameter is a single float. + + avregs: opaque structure to keep track of available VFP co-processor regs + align: alignment constraints for the param, as returned by type_size() + size: size of the parameter, as returned by type_size() */ +int assign_vfpreg(struct avail_regs *avregs, int align, int size) +{ + int first_reg = 0; + + if (avregs->first_free_reg == -1) + return -1; + if (align >> 3) { /* double alignment */ + first_reg = avregs->first_free_reg; + /* alignment constraint not respected so use next reg and record hole */ + if (first_reg & 1) + avregs->avail[avregs->last_hole++] = first_reg++; + } else { /* no special alignment (float or array of float) */ + /* if single float and a hole is available, assign the param to it */ + if (size == 4 && avregs->first_hole != avregs->last_hole) + return avregs->avail[avregs->first_hole++]; + else + first_reg = avregs->first_free_reg; + } + if (first_reg + size / 4 <= 16) { + avregs->first_free_reg = first_reg + size / 4; + return first_reg; + } + avregs->first_free_reg = -1; + return -1; +} + +/* Returns whether all params need to be passed in core registers or not. + This is the case for function part of the runtime ABI. */ +int floats_in_core_regs(SValue *sval) +{ + if (!sval->sym) + return 0; + + switch (sval->sym->v) { + case TOK___floatundisf: + case TOK___floatundidf: + case TOK___fixunssfdi: + case TOK___fixunsdfdi: +#ifndef TCC_ARM_VFP + case TOK___fixunsxfdi: +#endif + case TOK___floatdisf: + case TOK___floatdidf: + case TOK___fixsfdi: + case TOK___fixdfdi: + return 1; + + default: + return 0; + } +} + +/* Return the number of registers needed to return the struct, or 0 if + returning via struct pointer. */ +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) { +#ifdef TCC_ARM_EABI + int size, align; + size = type_size(vt, &align); + if (float_abi == ARM_HARD_FLOAT && !variadic && + (is_float(vt->t) || is_hgen_float_aggr(vt))) { + *ret_align = 8; + *regsize = 8; + ret->ref = NULL; + ret->t = VT_DOUBLE; + return (size + 7) >> 3; + } else if (size <= 4) { + *ret_align = 4; + *regsize = 4; + ret->ref = NULL; + ret->t = VT_INT; + return 1; + } else + return 0; +#else + return 0; #endif - args_size = 0; - for(i = nb_args ; i-- && args_size < 16 ;) { +} + +/* Parameters are classified according to how they are copied to their final + destination for the function call. Because the copying is performed class + after class according to the order in the union below, it is important that + some constraints about the order of the members of this union are respected: + - CORE_STRUCT_CLASS must come after STACK_CLASS; + - CORE_CLASS must come after STACK_CLASS, CORE_STRUCT_CLASS and + VFP_STRUCT_CLASS; + - VFP_STRUCT_CLASS must come after VFP_CLASS. + See the comment for the main loop in copy_params() for the reason. */ +enum reg_class { + STACK_CLASS = 0, + CORE_STRUCT_CLASS, + VFP_CLASS, + VFP_STRUCT_CLASS, + CORE_CLASS, + NB_CLASSES +}; + +struct param_plan { + int start; /* first reg or addr used depending on the class */ + int end; /* last reg used or next free addr depending on the class */ + SValue *sval; /* pointer to SValue on the value stack */ + struct param_plan *prev; /* previous element in this class */ +}; + +struct plan { + struct param_plan *pplans; /* array of all the param plans */ + struct param_plan *clsplans[NB_CLASSES]; /* per class lists of param plans */ +}; + +#define add_param_plan(plan,pplan,class) \ + do { \ + pplan.prev = plan->clsplans[class]; \ + plan->pplans[plan ## _nb] = pplan; \ + plan->clsplans[class] = &plan->pplans[plan ## _nb++]; \ + } while(0) + +/* Assign parameters to registers and stack with alignment according to the + rules in the procedure call standard for the ARM architecture (AAPCS). + The overall assignment is recorded in an array of per parameter structures + called parameter plans. The parameter plans are also further organized in a + number of linked lists, one per class of parameter (see the comment for the + definition of union reg_class). + + nb_args: number of parameters of the function for which a call is generated + float_abi: float ABI in use for this function call + plan: the structure where the overall assignment is recorded + todo: a bitmap that record which core registers hold a parameter + + Returns the amount of stack space needed for parameter passing + + Note: this function allocated an array in plan->pplans with tcc_malloc. It + is the responsibility of the caller to free this array once used (ie not + before copy_params). */ +static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) +{ + int i, size, align; + int ncrn /* next core register number */, nsaa /* next stacked argument address*/; + int plan_nb = 0; + struct param_plan pplan; + struct avail_regs avregs = AVAIL_REGS_INITIALIZER; + + ncrn = nsaa = 0; + *todo = 0; + plan->pplans = tcc_malloc(nb_args * sizeof(*plan->pplans)); + memset(plan->clsplans, 0, sizeof(plan->clsplans)); + for(i = nb_args; i-- ;) { + int j, start_vfpreg = 0; + CType type = vtop[-i].type; + type.t &= ~VT_ARRAY; + size = type_size(&type, &align); + size = (size + 3) & ~3; + align = (align + 3) & ~3; switch(vtop[-i].type.t & VT_BTYPE) { case VT_STRUCT: case VT_FLOAT: case VT_DOUBLE: case VT_LDOUBLE: - size = type_size(&vtop[-i].type, &align); - size = (size + 3) & -4; - args_size += size; + if (float_abi == ARM_HARD_FLOAT) { + int is_hfa = 0; /* Homogeneous float aggregate */ + + if (is_float(vtop[-i].type.t) + || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) { + int end_vfpreg; + + start_vfpreg = assign_vfpreg(&avregs, align, size); + end_vfpreg = start_vfpreg + ((size - 1) >> 2); + if (start_vfpreg >= 0) { + pplan = (struct param_plan) {start_vfpreg, end_vfpreg, &vtop[-i]}; + if (is_hfa) + add_param_plan(plan, pplan, VFP_STRUCT_CLASS); + else + add_param_plan(plan, pplan, VFP_CLASS); + continue; + } else + break; + } + } + ncrn = (ncrn + (align-1)/4) & ~((align/4) - 1); + if (ncrn + size/4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) { + /* The parameter is allocated both in core register and on stack. As + * such, it can be of either class: it would either be the last of + * CORE_STRUCT_CLASS or the first of STACK_CLASS. */ + for (j = ncrn; j < 4 && j < ncrn + size / 4; j++) + *todo|=(1<<j); + pplan = (struct param_plan) {ncrn, j, &vtop[-i]}; + add_param_plan(plan, pplan, CORE_STRUCT_CLASS); + ncrn += size/4; + if (ncrn > 4) + nsaa = (ncrn - 4) * 4; + } else { + ncrn = 4; break; + } + continue; default: - plan[nb_args-1-i][0]=args_size/4; - args_size += 4; - if ((vtop[-i].type.t & VT_BTYPE) == VT_LLONG && args_size < 16) { - plan[nb_args-1-i][1]=args_size/4; - args_size += 4; + if (ncrn < 4) { + int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG; + + if (is_long) { + ncrn = (ncrn + 1) & -2; + if (ncrn == 4) + break; + } + pplan = (struct param_plan) {ncrn, ncrn, &vtop[-i]}; + ncrn++; + if (is_long) + pplan.end = ncrn++; + add_param_plan(plan, pplan, CORE_CLASS); + continue; } } + nsaa = (nsaa + (align - 1)) & ~(align - 1); + pplan = (struct param_plan) {nsaa, nsaa + size, &vtop[-i]}; + add_param_plan(plan, pplan, STACK_CLASS); + nsaa += size; /* size already rounded up before */ } - args_size = keep = 0; - for(i = 0;i < nb_args; i++) { - vnrott(keep+1); - if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { - size = type_size(&vtop->type, &align); - /* align to stack align size */ - size = (size + 3) & -4; - /* allocate the necessary size on stack */ - gadd_sp(-size); - /* generate structure store */ - r = get_reg(RC_INT); - o(0xE1A0000D|(intr(r)<<12)); - vset(&vtop->type, r | VT_LVAL, 0); - vswap(); - vstore(); - vtop--; - args_size += size; - } else if (is_float(vtop->type.t)) { + return nsaa; +} + +#undef add_param_plan + +/* Copy parameters to their final destination (core reg, VFP reg or stack) for + function call. + + nb_args: number of parameters the function take + plan: the overall assignment plan for parameters + todo: a bitmap indicating what core reg will hold a parameter + + Returns the number of SValue added by this function on the value stack */ +static int copy_params(int nb_args, struct plan *plan, int todo) +{ + int size, align, r, i, nb_extra_sval = 0; + struct param_plan *pplan; + int pass = 0; + + /* Several constraints require parameters to be copied in a specific order: + - structures are copied to the stack before being loaded in a reg; + - floats loaded to an odd numbered VFP reg are first copied to the + preceding even numbered VFP reg and then moved to the next VFP reg. + + It is thus important that: + - structures assigned to core regs must be copied after parameters + assigned to the stack but before structures assigned to VFP regs because + a structure can lie partly in core registers and partly on the stack; + - parameters assigned to the stack and all structures be copied before + parameters assigned to a core reg since copying a parameter to the stack + require using a core reg; + - parameters assigned to VFP regs be copied before structures assigned to + VFP regs as the copy might use an even numbered VFP reg that already + holds part of a structure. */ +again: + for(i = 0; i < NB_CLASSES; i++) { + for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) { + + if (pass + && (i != CORE_CLASS || pplan->sval->r < VT_CONST)) + continue; + + vpushv(pplan->sval); + pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */ + switch(i) { + case STACK_CLASS: + case CORE_STRUCT_CLASS: + case VFP_STRUCT_CLASS: + if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) { + int padding = 0; + size = type_size(&pplan->sval->type, &align); + /* align to stack align size */ + size = (size + 3) & ~3; + if (i == STACK_CLASS && pplan->prev) + padding = pplan->start - pplan->prev->end; + size += padding; /* Add padding if any */ + /* allocate the necessary size on stack */ + gadd_sp(-size); + /* generate structure store */ + r = get_reg(RC_INT); + o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */ + vset(&vtop->type, r | VT_LVAL, 0); + vswap(); + vstore(); /* memcpy to current sp + potential padding */ + + /* Homogeneous float aggregate are loaded to VFP registers + immediately since there is no way of loading data in multiple + non consecutive VFP registers as what is done for other + structures (see the use of todo). */ + if (i == VFP_STRUCT_CLASS) { + int first = pplan->start, nb = pplan->end - first + 1; + /* vpop.32 {pplan->start, ..., pplan->end} */ + o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb); + /* No need to write the register used to a SValue since VFP regs + cannot be used for gcall_or_jmp */ + } + } else { + if (is_float(pplan->sval->type.t)) { #ifdef TCC_ARM_VFP - r=vfpr(gv(RC_FLOAT))<<12; - size=4; - if ((vtop->type.t & VT_BTYPE) != VT_FLOAT) - { - size=8; - r|=0x101; /* fstms -> fstmd */ - } - o(0xED2D0A01+r); + r = vfpr(gv(RC_FLOAT)) << 12; + if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT) + size = 4; + else { + size = 8; + r |= 0x101; /* vpush.32 -> vpush.64 */ + } + o(0xED2D0A01 + r); /* vpush */ #else - r=fpr(gv(RC_FLOAT))<<12; - if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) - size = 4; - else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) - size = 8; - else - size = LDOUBLE_SIZE; - - if (size == 12) - r|=0x400000; - else if(size == 8) - r|=0x8000; - - o(0xED2D0100|r|(size>>2)); + r = fpr(gv(RC_FLOAT)) << 12; + if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT) + size = 4; + else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE) + size = 8; + else + size = LDOUBLE_SIZE; + + if (size == 12) + r |= 0x400000; + else if(size == 8) + r|=0x8000; + + o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */ #endif - vtop--; - args_size += size; - } else { - int s; - /* simple type (currently always same size) */ - /* XXX: implicit cast ? */ - size=4; - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - lexpand_nr(); - s=RC_INT; - if(nb_args-i<5 && plan[nb_args-i-1][1]!=-1) { - s=regmask(plan[nb_args-i-1][1]); - todo&=~(1<<plan[nb_args-i-1][1]); - } - if(s==RC_INT) { - r = gv(s); - o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */ - vtop--; - } else { - plan2[keep]=s; - keep++; - vswap(); - } - size = 8; - } - s=RC_INT; - if(nb_args-i<5 && plan[nb_args-i-1][0]!=-1) { - s=regmask(plan[nb_args-i-1][0]); - todo&=~(1<<plan[nb_args-i-1][0]); + } else { + /* simple type (currently always same size) */ + /* XXX: implicit cast ? */ + size=4; + if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) { + lexpand_nr(); + size = 8; + r = gv(RC_INT); + o(0xE52D0004|(intr(r)<<12)); /* push r */ + vtop--; + } + r = gv(RC_INT); + o(0xE52D0004|(intr(r)<<12)); /* push r */ + } + if (i == STACK_CLASS && pplan->prev) + gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */ + } + break; + + case VFP_CLASS: + gv(regmask(TREG_F0 + (pplan->start >> 1))); + if (pplan->start & 1) { /* Must be in upper part of double register */ + o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */ + vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */ + } + break; + + case CORE_CLASS: + if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) { + lexpand_nr(); + gv(regmask(pplan->end)); + pplan->sval->r2 = vtop->r; + vtop--; + } + gv(regmask(pplan->start)); + /* Mark register as used so that gcall_or_jmp use another one + (regs >=4 are free as never used to pass parameters) */ + pplan->sval->r = vtop->r; + break; } -#ifdef TCC_ARM_EABI - if(vtop->type.t == VT_VOID) { - if(s == RC_INT) - o(0xE24DD004); /* sub sp,sp,#4 */ - vtop--; - } else -#endif - if(s == RC_INT) { - r = gv(s); - o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */ - vtop--; - } else { - plan2[keep]=s; - keep++; + vtop--; + } + } + + /* second pass to restore registers that were saved on stack by accident. + Maybe redundant after the "lvalue_save" patch in tccgen.c:gv() */ + if (++pass < 2) + goto again; + + /* Manually free remaining registers since next parameters are loaded + * manually, without the help of gv(int). */ + save_regs(nb_args); + + if(todo) { + o(0xE8BD0000|todo); /* pop {todo} */ + for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) { + int r; + pplan->sval->r = pplan->start; + /* An SValue can only pin 2 registers at best (r and r2) but a structure + can occupy more than 2 registers. Thus, we need to push on the value + stack some fake parameter to have on SValue for each registers used + by a structure (r2 is not used). */ + for (r = pplan->start + 1; r <= pplan->end; r++) { + if (todo & (1 << r)) { + nb_extra_sval++; + vpushi(0); + vtop->r = r; + } } - args_size += size; } } - for(i=keep;i--;) { - gv(plan2[i]); - vrott(keep); + return nb_extra_sval; +} + +/* Generate function call. The function address is pushed first, then + all the parameters in call order. This functions pops all the + parameters and the function address. */ +void gfunc_call(int nb_args) +{ + int r, args_size; + int def_float_abi = float_abi; + int todo; + struct plan plan; + +#ifdef TCC_ARM_EABI + int variadic; + + if (float_abi == ARM_HARD_FLOAT) { + variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS); + if (variadic || floats_in_core_regs(&vtop[-nb_args])) + float_abi = ARM_SOFTFP_FLOAT; } -save_regs(keep); /* save used temporary registers */ - keep++; - if(args_size) { - int n; - n=args_size/4; - if(n>4) - n=4; - todo&=((1<<n)-1); - if(todo) { - int i; - o(0xE8BD0000|todo); - for(i=0;i<4;i++) - if(todo&(1<<i)) { - vpushi(0); - vtop->r=i; - keep++; - } - } - args_size-=n*4; +#endif + /* cannot let cpu flags if other instruction are generated. Also avoid leaving + VT_JMP anywhere except on the top of the stack because it would complicate + the code generator. */ + r = vtop->r & VT_VALMASK; + if (r == VT_CMP || (r & ~1) == VT_JMP) + gv(RC_INT); + + args_size = assign_regs(nb_args, float_abi, &plan, &todo); + +#ifdef TCC_ARM_EABI + if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */ + args_size = (args_size + 7) & ~7; + o(0xE24DD004); /* sub sp, sp, #4 */ } - vnrott(keep); - func_sym = vtop->type.ref; +#endif + + nb_args += copy_params(nb_args, &plan, todo); + tcc_free(plan.pplans); + + /* Move fct SValue on top as required by gcall_or_jmp */ + vrotb(nb_args + 1); gcall_or_jmp(0); if (args_size) - gadd_sp(args_size); -#ifdef TCC_ARM_EABI - if((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT - && type_size(&vtop->type.ref->type, &align) <= 4) - { - store(REG_IRET,vtop-keep); - ++keep; - } -#ifdef TCC_ARM_VFP - else if(is_float(vtop->type.ref->type.t)) { + gadd_sp(args_size); /* pop all parameters passed on the stack */ +#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) + if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) { if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) { - o(0xEE000A10); /* fmsr s0,r0 */ + o(0xEE000A10); /*vmov s0, r0 */ } else { - o(0xEE000B10); /* fmdlr d0,r0 */ - o(0xEE201B10); /* fmdhr d0,r1 */ + o(0xEE000B10); /* vmov.32 d0[0], r0 */ + o(0xEE201B10); /* vmov.32 d0[1], r1 */ } } #endif -#endif - vtop-=keep; - leaffunc = 0; + vtop -= nb_args + 1; /* Pop all params and fct address from value stack */ + leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */ + float_abi = def_float_abi; } /* generate function prolog of type 't' */ void gfunc_prolog(CType *func_type) { Sym *sym,*sym2; - int n,addr,size,align; + int n, nf, size, align, rs, struct_ret = 0; + int addr, pn, sn; /* pn=core, sn=stack */ + CType ret_type; + +#ifdef TCC_ARM_EABI + struct avail_regs avregs = AVAIL_REGS_INITIALIZER; +#endif sym = func_type->ref; func_vt = sym->type; - - n = 0; - addr = 0; - if((func_vt.t & VT_BTYPE) == VT_STRUCT - && type_size(&func_vt,&align) > 4) + func_var = (func_type->ref->f.func_type == FUNC_ELLIPSIS); + + n = nf = 0; + if ((func_vt.t & VT_BTYPE) == VT_STRUCT && + !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs)) { - func_vc = addr; - addr += 4; n++; + struct_ret = 1; + func_vc = 12; /* Offset from fp of the place to store the result */ } - for(sym2=sym->next;sym2 && n<4;sym2=sym2->next) { + for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) { size = type_size(&sym2->type, &align); - n += (size + 3) / 4; +#ifdef TCC_ARM_EABI + if (float_abi == ARM_HARD_FLOAT && !func_var && + (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) { + int tmpnf = assign_vfpreg(&avregs, align, size); + tmpnf += (size + 3) / 4; + nf = (tmpnf > nf) ? tmpnf : nf; + } else +#endif + if (n < 4) + n += (size + 3) / 4; } o(0xE1A0C00D); /* mov ip,sp */ - if(func_type->ref->c == FUNC_ELLIPSIS) + if (func_var) n=4; - if(n) { + if (n) { if(n>4) n=4; #ifdef TCC_ARM_EABI @@ -956,33 +1313,73 @@ void gfunc_prolog(CType *func_type) #endif o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */ } + if (nf) { + if (nf>16) + nf=16; + nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */ + o(0xED2D0A00|nf); /* save s0-s15 on stack if needed */ + } o(0xE92D5800); /* save fp, ip, lr */ - o(0xE28DB00C); /* add fp, sp, #12 */ + o(0xE1A0B00D); /* mov fp, sp */ func_sub_sp_offset = ind; - o(0xE1A00000); /* nop, leave space for stack adjustment */ + o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */ + +#ifdef TCC_ARM_EABI + if (float_abi == ARM_HARD_FLOAT) { + func_vc += nf * 4; + avregs = AVAIL_REGS_INITIALIZER; + } +#endif + pn = struct_ret, sn = 0; while ((sym = sym->next)) { CType *type; type = &sym->type; size = type_size(type, &align); - size = (size + 3) & -4; + size = (size + 3) >> 2; + align = (align + 3) & ~3; +#ifdef TCC_ARM_EABI + if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t) + || is_hgen_float_aggr(&sym->type))) { + int fpn = assign_vfpreg(&avregs, align, size << 2); + if (fpn >= 0) + addr = fpn * 4; + else + goto from_stack; + } else +#endif + if (pn < 4) { #ifdef TCC_ARM_EABI - addr = (addr + align - 1) & -align; + pn = (pn + (align-1)/4) & -(align/4); #endif - sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr); - addr += size; + addr = (nf + pn) * 4; + pn += size; + if (!sn && pn > 4) + sn = (pn - 4); + } else { +#ifdef TCC_ARM_EABI +from_stack: + sn = (sn + (align-1)/4) & -(align/4); +#endif + addr = (n + nf + sn) * 4; + sn += size; + } + sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), + addr + 12); } last_itod_magic=0; leaffunc = 1; - loc = -12; + loc = 0; } /* generate function epilog */ void gfunc_epilog(void) { - unsigned long x; + uint32_t x; int diff; -#ifdef TCC_ARM_EABI - if(is_float(func_vt.t)) { + /* Copy float return value to core register if base standard is used and + float computation is made with VFP */ +#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) + if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) { if((func_vt.t & VT_BTYPE) == VT_FLOAT) o(0xEE100A10); /* fmrs r0, s0 */ else { @@ -991,24 +1388,24 @@ void gfunc_epilog(void) } } #endif - o(0xE91BA800); /* restore fp, sp, pc */ + o(0xE89BA800); /* restore fp, sp, pc */ diff = (-loc + 3) & -4; #ifdef TCC_ARM_EABI if(!leaffunc) - diff = (diff + 7) & -8; + diff = ((diff + 11) & -8) - 4; #endif - if(diff > 12) { + if(diff > 0) { x=stuff_const(0xE24BD000, diff); /* sub sp,fp,# */ if(x) - *(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = x; + *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x; else { - unsigned long addr; + int addr; addr=ind; o(0xE59FC004); /* ldr ip,[pc+4] */ o(0xE04BD00C); /* sub sp,fp,ip */ o(0xE1A0F00E); /* mov pc,lr */ o(diff); - *(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1); + *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1); } } } @@ -1017,6 +1414,8 @@ void gfunc_epilog(void) int gjmp(int t) { int r; + if (nocode_wanted) + return t; r=ind; o(0xE0000000|encbranch(r,t,1)); return r; @@ -1032,10 +1431,14 @@ void gjmp_addr(int a) int gtst(int inv, int t) { int v, r; - unsigned long op; + uint32_t op; + v = vtop->r & VT_VALMASK; r=ind; - if (v == VT_CMP) { + + if (nocode_wanted) { + ; + } else if (v == VT_CMP) { op=mapcc(inv?negcc(vtop->c.i):vtop->c.i); op|=encbranch(r,t,1); o(op); @@ -1045,14 +1448,14 @@ int gtst(int inv, int t) if(!vtop->c.i) vtop->c.i=t; else { - unsigned long *x; + uint32_t *x; int p,lp; if(t) { p = vtop->c.i; do { p = decbranch(lp=p); } while(p); - x = (unsigned long *)(cur_text_section->data + lp); + x = (uint32_t *)(cur_text_section->data + lp); *x &= 0xff000000; *x |= encbranch(lp,t,1); } @@ -1062,29 +1465,6 @@ int gtst(int inv, int t) t = gjmp(t); gsym(vtop->c.i); } - } else { - if (is_float(vtop->type.t)) { - r=gv(RC_FLOAT); -#ifdef TCC_ARM_VFP - o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */ - o(0xEEF1FA10); /* fmstat */ -#else - o(0xEE90F118|(fpr(r)<<16)); -#endif - vtop->r = VT_CMP; - vtop->c.i = TOK_NE; - return gtst(inv, t); - } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - } else { - v = gv(RC_INT); - o(0xE3300000|(intr(v)<<16)); - vtop->r = VT_CMP; - vtop->c.i = TOK_NE; - return gtst(inv, t); - } } vtop--; return t; @@ -1094,7 +1474,7 @@ int gtst(int inv, int t) void gen_opi(int op) { int c, func = 0; - unsigned long opc = 0,r,fr; + uint32_t opc = 0, r, fr; unsigned short retreg = REG_IRET; c=0; @@ -1210,7 +1590,7 @@ void gen_opi(int op) vswap(); opc=0xE0000000|(opc<<20)|(c<<16); if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - unsigned long x; + uint32_t x; x=stuff_const(opc|0x2000000,vtop->c.i); if(x) { r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r))); @@ -1256,7 +1636,7 @@ done: vtop->r = retreg; break; default: - error("gen_opi %i unimplemented!",op); + tcc_error("gen_opi %i unimplemented!",op); } } @@ -1273,10 +1653,10 @@ static int is_zero(int i) } /* generate a floating point operation 'v = t1 op t2' instruction. The - * two operands are guaranted to have the same floating point type */ + * two operands are guaranteed to have the same floating point type */ void gen_opf(int op) { - unsigned long x; + uint32_t x; int fneg=0,r; x=0xEE000A00|T2CPR(vtop->type.t); switch(op) { @@ -1309,8 +1689,8 @@ void gen_opf(int op) x|=0x800000; break; default: - if(op < TOK_ULT && op > TOK_GT) { - error("unknown fp op %x!",op); + if(op < TOK_ULT || op > TOK_GT) { + tcc_error("unknown fp op %x!",op); return; } if(is_zero(-1)) { @@ -1342,7 +1722,7 @@ void gen_opf(int op) case TOK_UGE: op=TOK_GE; break; case TOK_UGT: op=TOK_GT; break; } - + vtop->r = VT_CMP; vtop->c.i = op; return; @@ -1364,10 +1744,10 @@ void gen_opf(int op) } #else -static int is_fconst() +static uint32_t is_fconst() { long double f; - int r; + uint32_t r; if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) return 0; if (vtop->type.t == VT_FLOAT) @@ -1403,11 +1783,10 @@ static int is_fconst() } /* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ + two operands are guaranteed to have the same floating point type */ void gen_opf(int op) { - unsigned long x; - int r,r2,c1,c2; + uint32_t x, r, r2, c1, c2; //fputs("gen_opf\n",stderr); vswap(); c1 = is_fconst(); @@ -1494,7 +1873,7 @@ void gen_opf(int op) r=fpr(gv(RC_FLOAT)); vswap(); r2=fpr(gv(RC_FLOAT)); - } + } break; default: if(op >= TOK_ULT && op <= TOK_GT) { @@ -1506,7 +1885,7 @@ void gen_opf(int op) case TOK_UGE: case TOK_ULE: case TOK_UGT: - error("unsigned comparison on floats?"); + tcc_error("unsigned comparison on floats?"); break; case TOK_LT: op=TOK_Nset; @@ -1550,7 +1929,7 @@ void gen_opf(int op) vtop[-1].r = VT_CMP; vtop[-1].c.i = op; } else { - error("unknown fp op %x!",op); + tcc_error("unknown fp op %x!",op); return; } } @@ -1570,19 +1949,20 @@ void gen_opf(int op) /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' and 'long long' cases. */ -void gen_cvt_itof1(int t) +ST_FUNC void gen_cvt_itof1(int t) { - int r,r2,bt; + uint32_t r, r2; + int bt; bt=vtop->type.t & VT_BTYPE; if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) { #ifndef TCC_ARM_VFP - unsigned int dsize=0; + uint32_t dsize = 0; #endif r=intr(gv(RC_INT)); #ifdef TCC_ARM_VFP r2=vfpr(vtop->r=get_reg(RC_FLOAT)); o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */ - r2<<=12; + r2|=r2<<12; if(!(vtop->type.t & VT_UNSIGNED)) r2|=0x80; /* fuitoX -> fsituX */ o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/ @@ -1592,7 +1972,7 @@ void gen_cvt_itof1(int t) dsize=0x80; /* flts -> fltd */ o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */ if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) { - unsigned int off=0; + uint32_t off = 0; o(0xE3500000|(r<<12)); /* cmp */ r=fpr(get_reg(RC_FLOAT)); if(last_itod_magic) { @@ -1646,13 +2026,14 @@ void gen_cvt_itof1(int t) return; } } - error("unimplemented gen_cvt_itof %x!",vtop->type.t); + tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t); } /* convert fp to int 't' type */ void gen_cvt_ftoi(int t) { - int r,r2,u,func=0; + uint32_t r, r2; + int u, func = 0; u=t&VT_UNSIGNED; t&=VT_BTYPE; r2=vtop->type.t & VT_BTYPE; @@ -1660,7 +2041,7 @@ void gen_cvt_ftoi(int t) #ifdef TCC_ARM_VFP r=vfpr(gv(RC_FLOAT)); u=u?0:0x10000; - o(0xEEBC0A40|(r<<12)|r|T2CPR(r2)); /* ftoXiY */ + o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */ r2=intr(vtop->r=get_reg(RC_INT)); o(0xEE100A10|(r<<16)|(r2<<12)); return; @@ -1705,7 +2086,7 @@ void gen_cvt_ftoi(int t) vtop->r = REG_IRET; return; } - error("unimplemented gen_cvt_ftoi!"); + tcc_error("unimplemented gen_cvt_ftoi!"); } /* convert from one floating point type to another */ @@ -1713,7 +2094,7 @@ void gen_cvt_ftof(int t) { #ifdef TCC_ARM_VFP if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) { - int r=vfpr(gv(RC_FLOAT)); + uint32_t r = vfpr(gv(RC_FLOAT)); o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t)); } #else @@ -1729,6 +2110,42 @@ void ggoto(void) vtop--; } +/* Save the stack pointer onto the stack and return the location of its address */ +ST_FUNC void gen_vla_sp_save(int addr) { + SValue v; + v.type.t = VT_PTR; + v.r = VT_LOCAL | VT_LVAL; + v.c.i = addr; + store(TREG_SP, &v); +} + +/* Restore the SP from a location on the stack */ +ST_FUNC void gen_vla_sp_restore(int addr) { + SValue v; + v.type.t = VT_PTR; + v.r = VT_LOCAL | VT_LVAL; + v.c.i = addr; + load(TREG_SP, &v); +} + +/* Subtract from the stack pointer, and push the resulting value onto the stack */ +ST_FUNC void gen_vla_alloc(CType *type, int align) { + int r = intr(gv(RC_INT)); + o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */ +#ifdef TCC_ARM_EABI + if (align < 8) + align = 8; +#else + if (align < 4) + align = 4; +#endif + if (align & (align - 1)) + tcc_error("alignment is not a power of 2: %i", align); + o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */ + vpop(); +} + /* end of ARM code generator */ /*************************************************************/ - +#endif +/*************************************************************/ diff --git a/tinyc/arm-link.c b/tinyc/arm-link.c new file mode 100644 index 000000000..aee35afef --- /dev/null +++ b/tinyc/arm-link.c @@ -0,0 +1,392 @@ +#ifdef TARGET_DEFS_ONLY + +#define EM_TCC_TARGET EM_ARM + +/* relocation type for 32 bit data relocation */ +#define R_DATA_32 R_ARM_ABS32 +#define R_DATA_PTR R_ARM_ABS32 +#define R_JMP_SLOT R_ARM_JUMP_SLOT +#define R_GLOB_DAT R_ARM_GLOB_DAT +#define R_COPY R_ARM_COPY +#define R_RELATIVE R_ARM_RELATIVE + +#define R_NUM R_ARM_NUM + +#define ELF_START_ADDR 0x00008000 +#define ELF_PAGE_SIZE 0x1000 + +#define PCRELATIVE_DLLPLT 1 +#define RELOCATE_DLLPLT 0 + +enum float_abi { + ARM_SOFTFP_FLOAT, + ARM_HARD_FLOAT, +}; + +#else /* !TARGET_DEFS_ONLY */ + +#include "tcc.h" + +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_ABS32: + case R_ARM_REL32: + case R_ARM_GOTPC: + case R_ARM_GOTOFF: + case R_ARM_GOT32: + case R_ARM_COPY: + case R_ARM_GLOB_DAT: + case R_ARM_NONE: + return 0; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + case R_ARM_PLT32: + case R_ARM_THM_PC22: + case R_ARM_THM_JUMP24: + case R_ARM_PREL31: + case R_ARM_V4BX: + case R_ARM_JUMP_SLOT: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe whether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_ARM_NONE: + case R_ARM_COPY: + case R_ARM_GLOB_DAT: + case R_ARM_JUMP_SLOT: + return NO_GOTPLT_ENTRY; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + case R_ARM_PLT32: + case R_ARM_THM_PC22: + case R_ARM_THM_JUMP24: + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_PREL31: + case R_ARM_ABS32: + case R_ARM_REL32: + case R_ARM_V4BX: + return AUTO_GOTPLT_ENTRY; + + case R_ARM_GOTPC: + case R_ARM_GOTOFF: + return BUILD_GOT_ONLY; + + case R_ARM_GOT32: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) +{ + Section *plt = s1->plt; + uint8_t *p; + unsigned plt_offset; + + /* when building a DLL, GOT entry accesses must be done relative to + start of GOT (see x86_64 example above) */ + if (s1->output_type == TCC_OUTPUT_DLL) + tcc_error("DLLs unimplemented!"); + + /* empty PLT: create PLT0 entry that push address of call site and + jump to ld.so resolution routine (GOT + 8) */ + if (plt->data_offset == 0) { + p = section_ptr_add(plt, 20); + write32le(p, 0xe52de004); /* push {lr} */ + write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */ + write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */ + write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */ + /* p+16 is set in relocate_plt */ + } + plt_offset = plt->data_offset; + + if (attr->plt_thumb_stub) { + p = section_ptr_add(plt, 4); + write32le(p, 0x4778); /* bx pc */ + write32le(p+2, 0x46c0); /* nop */ + } + p = section_ptr_add(plt, 16); + /* Jump to GOT entry where ld.so initially put address of PLT0 */ + write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] */ + write32le(p+4, 0xe08fc00c); /* add ip, pc, ip */ + write32le(p+8, 0xe59cf000); /* ldr pc, [ip] */ + /* p + 12 contains offset to GOT entry once patched by relocate_plt */ + write32le(p+12, got_offset); + return plt_offset; +} + +/* relocate the PLT: compute addresses and offsets in the PLT now that final + address for PLT and GOT are known (see fill_program_header) */ +ST_FUNC void relocate_plt(TCCState *s1) +{ + uint8_t *p, *p_end; + + if (!s1->plt) + return; + + p = s1->plt->data; + p_end = p + s1->plt->data_offset; + + if (p < p_end) { + int x = s1->got->sh_addr - s1->plt->sh_addr - 12; + write32le(s1->plt->data + 16, x - 16); + p += 20; + while (p < p_end) { + if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */ + p += 4; + add32le(p + 12, x + s1->plt->data - p); + p += 16; + } + } +} + +void relocate_init(Section *sr) {} + +void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) +{ + ElfW(Sym) *sym; + int sym_index; + + sym_index = ELFW(R_SYM)(rel->r_info); + sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; + + switch(type) { + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + case R_ARM_PLT32: + { + int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko; + x = (*(int *) ptr) & 0xffffff; +#ifdef DEBUG_RELOC + printf ("reloc %d: x=0x%x val=0x%x ", type, x, val); +#endif + (*(int *)ptr) &= 0xff000000; + if (x & 0x800000) + x -= 0x1000000; + x <<= 2; + blx_avail = (TCC_CPU_VERSION >= 5); + is_thumb = val & 1; + is_bl = (*(unsigned *) ptr) >> 24 == 0xeb; + is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl)); + x += val - addr; +#ifdef DEBUG_RELOC + printf (" newx=0x%x name=%s\n", x, + (char *) symtab_section->link->data + sym->st_name); +#endif + h = x & 2; + th_ko = (x & 3) && (!blx_avail || !is_call); + if (th_ko || x >= 0x2000000 || x < -0x2000000) + tcc_error("can't relocate value at %x,%d",addr, type); + x >>= 2; + x &= 0xffffff; + /* Only reached if blx is avail and it is a call */ + if (is_thumb) { + x |= h << 24; + (*(int *)ptr) = 0xfa << 24; /* bl -> blx */ + } + (*(int *) ptr) |= x; + } + return; + /* Since these relocations only concern Thumb-2 and blx instruction was + introduced before Thumb-2, we can assume blx is available and not + guard its use */ + case R_ARM_THM_PC22: + case R_ARM_THM_JUMP24: + { + int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11; + int to_thumb, is_call, to_plt, blx_bit = 1 << 12; + Section *plt; + + /* weak reference */ + if (sym->st_shndx == SHN_UNDEF && + ELFW(ST_BIND)(sym->st_info) == STB_WEAK) + return; + + /* Get initial offset */ + hi = (*(uint16_t *)ptr); + lo = (*(uint16_t *)(ptr+2)); + s = (hi >> 10) & 1; + j1 = (lo >> 13) & 1; + j2 = (lo >> 11) & 1; + i1 = (j1 ^ s) ^ 1; + i2 = (j2 ^ s) ^ 1; + imm10 = hi & 0x3ff; + imm11 = lo & 0x7ff; + x = (s << 24) | (i1 << 23) | (i2 << 22) | + (imm10 << 12) | (imm11 << 1); + if (x & 0x01000000) + x -= 0x02000000; + + /* Relocation infos */ + to_thumb = val & 1; + plt = s1->plt; + to_plt = (val >= plt->sh_addr) && + (val < plt->sh_addr + plt->data_offset); + is_call = (type == R_ARM_THM_PC22); + + if (!to_thumb && !to_plt && !is_call) { + int index; + uint8_t *p; + char *name, buf[1024]; + Section *text_section; + + name = (char *) symtab_section->link->data + sym->st_name; + text_section = s1->sections[sym->st_shndx]; + /* Modify reloc to target a thumb stub to switch to ARM */ + snprintf(buf, sizeof(buf), "%s_from_thumb", name); + index = put_elf_sym(symtab_section, + text_section->data_offset + 1, + sym->st_size, sym->st_info, 0, + sym->st_shndx, buf); + to_thumb = 1; + val = text_section->data_offset + 1; + rel->r_info = ELFW(R_INFO)(index, type); + /* Create a thumb stub function to switch to ARM mode */ + put_elf_reloc(symtab_section, text_section, + text_section->data_offset + 4, R_ARM_JUMP24, + sym_index); + p = section_ptr_add(text_section, 8); + write32le(p, 0x4778); /* bx pc */ + write32le(p+2, 0x46c0); /* nop */ + write32le(p+4, 0xeafffffe); /* b $sym */ + } + + /* Compute final offset */ + x += val - addr; + if (!to_thumb && is_call) { + blx_bit = 0; /* bl -> blx */ + x = (x + 3) & -4; /* Compute offset from aligned PC */ + } + + /* Check that relocation is possible + * offset must not be out of range + * if target is to be entered in arm mode: + - bit 1 must not set + - instruction must be a call (bl) or a jump to PLT */ + if (!to_thumb || x >= 0x1000000 || x < -0x1000000) + if (to_thumb || (val & 2) || (!is_call && !to_plt)) + tcc_error("can't relocate value at %x,%d",addr, type); + + /* Compute and store final offset */ + s = (x >> 24) & 1; + i1 = (x >> 23) & 1; + i2 = (x >> 22) & 1; + j1 = s ^ (i1 ^ 1); + j2 = s ^ (i2 ^ 1); + imm10 = (x >> 12) & 0x3ff; + imm11 = (x >> 1) & 0x7ff; + (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) | + (s << 10) | imm10); + (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) | + (j1 << 13) | blx_bit | (j2 << 11) | + imm11); + } + return; + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_ABS_NC: + { + int x, imm4, imm12; + if (type == R_ARM_MOVT_ABS) + val >>= 16; + imm12 = val & 0xfff; + imm4 = (val >> 12) & 0xf; + x = (imm4 << 16) | imm12; + if (type == R_ARM_THM_MOVT_ABS) + *(int *)ptr |= x; + else + *(int *)ptr += x; + } + return; + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_ABS_NC: + { + int x, i, imm4, imm3, imm8; + if (type == R_ARM_THM_MOVT_ABS) + val >>= 16; + imm8 = val & 0xff; + imm3 = (val >> 8) & 0x7; + i = (val >> 11) & 1; + imm4 = (val >> 12) & 0xf; + x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4; + if (type == R_ARM_THM_MOVT_ABS) + *(int *)ptr |= x; + else + *(int *)ptr += x; + } + return; + case R_ARM_PREL31: + { + int x; + x = (*(int *)ptr) & 0x7fffffff; + (*(int *)ptr) &= 0x80000000; + x = (x * 2) / 2; + x += val - addr; + if((x^(x>>1))&0x40000000) + tcc_error("can't relocate value at %x,%d",addr, type); + (*(int *)ptr) |= x & 0x7fffffff; + } + case R_ARM_ABS32: + *(int *)ptr += val; + return; + case R_ARM_REL32: + *(int *)ptr += val - addr; + return; + case R_ARM_GOTPC: + *(int *)ptr += s1->got->sh_addr - addr; + return; + case R_ARM_GOTOFF: + *(int *)ptr += val - s1->got->sh_addr; + return; + case R_ARM_GOT32: + /* we load the got offset */ + *(int *)ptr += s1->sym_attrs[sym_index].got_offset; + return; + case R_ARM_COPY: + return; + case R_ARM_V4BX: + /* trade Thumb support for ARMv4 support */ + if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10) + *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */ + return; + case R_ARM_GLOB_DAT: + case R_ARM_JUMP_SLOT: + *(addr_t *)ptr = val; + return; + case R_ARM_NONE: + /* Nothing to do. Normally used to indicate a dependency + on a certain symbol (like for exception handling under EABI). */ + return; + default: + fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n", + type, (unsigned)addr, ptr, (unsigned)val); + return; + } +} + +#endif /* !TARGET_DEFS_ONLY */ diff --git a/tinyc/arm64-gen.c b/tinyc/arm64-gen.c new file mode 100644 index 000000000..86b3af73b --- /dev/null +++ b/tinyc/arm64-gen.c @@ -0,0 +1,1837 @@ +/* + * A64 code generator for TCC + * + * Copyright (c) 2014-2015 Edmund Grimley Evans + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#ifdef TARGET_DEFS_ONLY + +// Number of registers available to allocator: +#define NB_REGS 28 // x0-x18, x30, v0-v7 + +#define TREG_R(x) (x) // x = 0..18 +#define TREG_R30 19 +#define TREG_F(x) (x + 20) // x = 0..7 + +// Register classes sorted from more general to more precise: +#define RC_INT (1 << 0) +#define RC_FLOAT (1 << 1) +#define RC_R(x) (1 << (2 + (x))) // x = 0..18 +#define RC_R30 (1 << 21) +#define RC_F(x) (1 << (22 + (x))) // x = 0..7 + +#define RC_IRET (RC_R(0)) // int return register class +#define RC_FRET (RC_F(0)) // float return register class + +#define REG_IRET (TREG_R(0)) // int return register number +#define REG_FRET (TREG_F(0)) // float return register number + +#define PTR_SIZE 8 + +#define LDOUBLE_SIZE 16 +#define LDOUBLE_ALIGN 16 + +#define MAX_ALIGN 16 + +#define CHAR_IS_UNSIGNED + +/******************************************************/ +#else /* ! TARGET_DEFS_ONLY */ +/******************************************************/ +#include "tcc.h" +#include <assert.h> + +ST_DATA const int reg_classes[NB_REGS] = { + RC_INT | RC_R(0), + RC_INT | RC_R(1), + RC_INT | RC_R(2), + RC_INT | RC_R(3), + RC_INT | RC_R(4), + RC_INT | RC_R(5), + RC_INT | RC_R(6), + RC_INT | RC_R(7), + RC_INT | RC_R(8), + RC_INT | RC_R(9), + RC_INT | RC_R(10), + RC_INT | RC_R(11), + RC_INT | RC_R(12), + RC_INT | RC_R(13), + RC_INT | RC_R(14), + RC_INT | RC_R(15), + RC_INT | RC_R(16), + RC_INT | RC_R(17), + RC_INT | RC_R(18), + RC_R30, // not in RC_INT as we make special use of x30 + RC_FLOAT | RC_F(0), + RC_FLOAT | RC_F(1), + RC_FLOAT | RC_F(2), + RC_FLOAT | RC_F(3), + RC_FLOAT | RC_F(4), + RC_FLOAT | RC_F(5), + RC_FLOAT | RC_F(6), + RC_FLOAT | RC_F(7) +}; + +#define IS_FREG(x) ((x) >= TREG_F(0)) + +static uint32_t intr(int r) +{ + assert(TREG_R(0) <= r && r <= TREG_R30); + return r < TREG_R30 ? r : 30; +} + +static uint32_t fltr(int r) +{ + assert(TREG_F(0) <= r && r <= TREG_F(7)); + return r - TREG_F(0); +} + +// Add an instruction to text section: +ST_FUNC void o(unsigned int c) +{ + int ind1 = ind + 4; + if (nocode_wanted) + return; + if (ind1 > cur_text_section->data_allocated) + section_realloc(cur_text_section, ind1); + write32le(cur_text_section->data + ind, c); + ind = ind1; +} + +static int arm64_encode_bimm64(uint64_t x) +{ + int neg = x & 1; + int rep, pos, len; + + if (neg) + x = ~x; + if (!x) + return -1; + + if (x >> 2 == (x & (((uint64_t)1 << (64 - 2)) - 1))) + rep = 2, x &= ((uint64_t)1 << 2) - 1; + else if (x >> 4 == (x & (((uint64_t)1 << (64 - 4)) - 1))) + rep = 4, x &= ((uint64_t)1 << 4) - 1; + else if (x >> 8 == (x & (((uint64_t)1 << (64 - 8)) - 1))) + rep = 8, x &= ((uint64_t)1 << 8) - 1; + else if (x >> 16 == (x & (((uint64_t)1 << (64 - 16)) - 1))) + rep = 16, x &= ((uint64_t)1 << 16) - 1; + else if (x >> 32 == (x & (((uint64_t)1 << (64 - 32)) - 1))) + rep = 32, x &= ((uint64_t)1 << 32) - 1; + else + rep = 64; + + pos = 0; + if (!(x & (((uint64_t)1 << 32) - 1))) x >>= 32, pos += 32; + if (!(x & (((uint64_t)1 << 16) - 1))) x >>= 16, pos += 16; + if (!(x & (((uint64_t)1 << 8) - 1))) x >>= 8, pos += 8; + if (!(x & (((uint64_t)1 << 4) - 1))) x >>= 4, pos += 4; + if (!(x & (((uint64_t)1 << 2) - 1))) x >>= 2, pos += 2; + if (!(x & (((uint64_t)1 << 1) - 1))) x >>= 1, pos += 1; + + len = 0; + if (!(~x & (((uint64_t)1 << 32) - 1))) x >>= 32, len += 32; + if (!(~x & (((uint64_t)1 << 16) - 1))) x >>= 16, len += 16; + if (!(~x & (((uint64_t)1 << 8) - 1))) x >>= 8, len += 8; + if (!(~x & (((uint64_t)1 << 4) - 1))) x >>= 4, len += 4; + if (!(~x & (((uint64_t)1 << 2) - 1))) x >>= 2, len += 2; + if (!(~x & (((uint64_t)1 << 1) - 1))) x >>= 1, len += 1; + + if (x) + return -1; + if (neg) { + pos = (pos + len) & (rep - 1); + len = rep - len; + } + return ((0x1000 & rep << 6) | (((rep - 1) ^ 31) << 1 & 63) | + ((rep - pos) & (rep - 1)) << 6 | (len - 1)); +} + +static uint32_t arm64_movi(int r, uint64_t x) +{ + uint64_t m = 0xffff; + int e; + if (!(x & ~m)) + return 0x52800000 | r | x << 5; // movz w(r),#(x) + if (!(x & ~(m << 16))) + return 0x52a00000 | r | x >> 11; // movz w(r),#(x >> 16),lsl #16 + if (!(x & ~(m << 32))) + return 0xd2c00000 | r | x >> 27; // movz x(r),#(x >> 32),lsl #32 + if (!(x & ~(m << 48))) + return 0xd2e00000 | r | x >> 43; // movz x(r),#(x >> 48),lsl #48 + if ((x & ~m) == m << 16) + return (0x12800000 | r | + (~x << 5 & 0x1fffe0)); // movn w(r),#(~x) + if ((x & ~(m << 16)) == m) + return (0x12a00000 | r | + (~x >> 11 & 0x1fffe0)); // movn w(r),#(~x >> 16),lsl #16 + if (!~(x | m)) + return (0x92800000 | r | + (~x << 5 & 0x1fffe0)); // movn x(r),#(~x) + if (!~(x | m << 16)) + return (0x92a00000 | r | + (~x >> 11 & 0x1fffe0)); // movn x(r),#(~x >> 16),lsl #16 + if (!~(x | m << 32)) + return (0x92c00000 | r | + (~x >> 27 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32 + if (!~(x | m << 48)) + return (0x92e00000 | r | + (~x >> 43 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32 + if (!(x >> 32) && (e = arm64_encode_bimm64(x | x << 32)) >= 0) + return 0x320003e0 | r | (uint32_t)e << 10; // movi w(r),#(x) + if ((e = arm64_encode_bimm64(x)) >= 0) + return 0xb20003e0 | r | (uint32_t)e << 10; // movi x(r),#(x) + return 0; +} + +static void arm64_movimm(int r, uint64_t x) +{ + uint32_t i; + if ((i = arm64_movi(r, x))) + o(i); // a single MOV + else { + // MOVZ/MOVN and 1-3 MOVKs + int z = 0, m = 0; + uint32_t mov1 = 0xd2800000; // movz + uint64_t x1 = x; + for (i = 0; i < 64; i += 16) { + z += !(x >> i & 0xffff); + m += !(~x >> i & 0xffff); + } + if (m > z) { + x1 = ~x; + mov1 = 0x92800000; // movn + } + for (i = 0; i < 64; i += 16) + if (x1 >> i & 0xffff) { + o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17); + // movz/movn x(r),#(*),lsl #(i) + break; + } + for (i += 16; i < 64; i += 16) + if (x1 >> i & 0xffff) + o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17); + // movk x(r),#(*),lsl #(i) + } +} + +// Patch all branches in list pointed to by t to branch to a: +ST_FUNC void gsym_addr(int t_, int a_) +{ + uint32_t t = t_; + uint32_t a = a_; + while (t) { + unsigned char *ptr = cur_text_section->data + t; + uint32_t next = read32le(ptr); + if (a - t + 0x8000000 >= 0x10000000) + tcc_error("branch out of range"); + write32le(ptr, (a - t == 4 ? 0xd503201f : // nop + 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b + t = next; + } +} + +// Patch all branches in list pointed to by t to branch to current location: +ST_FUNC void gsym(int t) +{ + gsym_addr(t, ind); +} + +static int arm64_type_size(int t) +{ + switch (t & VT_BTYPE) { + case VT_INT: return 2; + case VT_BYTE: return 0; + case VT_SHORT: return 1; + case VT_PTR: return 3; + case VT_FUNC: return 3; + case VT_FLOAT: return 2; + case VT_DOUBLE: return 3; + case VT_LDOUBLE: return 4; + case VT_BOOL: return 0; + case VT_LLONG: return 3; + } + assert(0); + return 0; +} + +static void arm64_spoff(int reg, uint64_t off) +{ + uint32_t sub = off >> 63; + if (sub) + off = -off; + if (off < 4096) + o(0x910003e0 | sub << 30 | reg | off << 10); + // (add|sub) x(reg),sp,#(off) + else { + arm64_movimm(30, off); // use x30 for offset + o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30 + } +} + +static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off) +{ + uint32_t sz = sz_; + if (sz >= 2) + sg = 0; + if (!(off & ~((uint32_t)0xfff << sz))) + o(0x39400000 | dst | bas << 5 | off << (10 - sz) | + (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)] + else if (off < 256 || -off <= 256) + o(0x38400000 | dst | bas << 5 | (off & 511) << 12 | + (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)] + else { + arm64_movimm(30, off); // use x30 for offset + o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | + (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30] + } +} + +static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off) +{ + uint32_t sz = sz_; + if (!(off & ~((uint32_t)0xfff << sz))) + o(0x3d400000 | dst | bas << 5 | off << (10 - sz) | + (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)] + else if (off < 256 || -off <= 256) + o(0x3c400000 | dst | bas << 5 | (off & 511) << 12 | + (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)] + else { + arm64_movimm(30, off); // use x30 for offset + o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 | + sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30] + } +} + +static void arm64_ldrs(int reg_, int size) +{ + uint32_t reg = reg_; + // Use x30 for intermediate value in some cases. + switch (size) { + default: assert(0); break; + case 1: + arm64_ldrx(0, 0, reg, reg, 0); + break; + case 2: + arm64_ldrx(0, 1, reg, reg, 0); + break; + case 3: + arm64_ldrx(0, 1, 30, reg, 0); + arm64_ldrx(0, 0, reg, reg, 2); + o(0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16 + break; + case 4: + arm64_ldrx(0, 2, reg, reg, 0); + break; + case 5: + arm64_ldrx(0, 2, 30, reg, 0); + arm64_ldrx(0, 0, reg, reg, 4); + o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 + break; + case 6: + arm64_ldrx(0, 2, 30, reg, 0); + arm64_ldrx(0, 1, reg, reg, 4); + o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 + break; + case 7: + arm64_ldrx(0, 2, 30, reg, 0); + arm64_ldrx(0, 2, reg, reg, 3); + o(0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8 + o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 + break; + case 8: + arm64_ldrx(0, 3, reg, reg, 0); + break; + case 9: + arm64_ldrx(0, 0, reg + 1, reg, 8); + arm64_ldrx(0, 3, reg, reg, 0); + break; + case 10: + arm64_ldrx(0, 1, reg + 1, reg, 8); + arm64_ldrx(0, 3, reg, reg, 0); + break; + case 11: + arm64_ldrx(0, 2, reg + 1, reg, 7); + o(0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8 + arm64_ldrx(0, 3, reg, reg, 0); + break; + case 12: + arm64_ldrx(0, 2, reg + 1, reg, 8); + arm64_ldrx(0, 3, reg, reg, 0); + break; + case 13: + arm64_ldrx(0, 3, reg + 1, reg, 5); + o(0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24 + arm64_ldrx(0, 3, reg, reg, 0); + break; + case 14: + arm64_ldrx(0, 3, reg + 1, reg, 6); + o(0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16 + arm64_ldrx(0, 3, reg, reg, 0); + break; + case 15: + arm64_ldrx(0, 3, reg + 1, reg, 7); + o(0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8 + arm64_ldrx(0, 3, reg, reg, 0); + break; + case 16: + o(0xa9400000 | reg | (reg+1) << 10 | reg << 5); + // ldp x(reg),x(reg+1),[x(reg)] + break; + } +} + +static void arm64_strx(int sz_, int dst, int bas, uint64_t off) +{ + uint32_t sz = sz_; + if (!(off & ~((uint32_t)0xfff << sz))) + o(0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30); + // str(*) x(dst),[x(bas],#(off)] + else if (off < 256 || -off <= 256) + o(0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30); + // stur(*) x(dst),[x(bas],#(off)] + else { + arm64_movimm(30, off); // use x30 for offset + o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30); + // str(*) x(dst),[x(bas),x30] + } +} + +static void arm64_strv(int sz_, int dst, int bas, uint64_t off) +{ + uint32_t sz = sz_; + if (!(off & ~((uint32_t)0xfff << sz))) + o(0x3d000000 | dst | bas << 5 | off << (10 - sz) | + (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)] + else if (off < 256 || -off <= 256) + o(0x3c000000 | dst | bas << 5 | (off & 511) << 12 | + (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)] + else { + arm64_movimm(30, off); // use x30 for offset + o(0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 | + sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30] + } +} + +static void arm64_sym(int r, Sym *sym, unsigned long addend) +{ + // Currently TCC's linker does not generate COPY relocations for + // STT_OBJECTs when tcc is invoked with "-run". This typically + // results in "R_AARCH64_ADR_PREL_PG_HI21 relocation failed" when + // a program refers to stdin. A workaround is to avoid that + // relocation and use only relocations with unlimited range. + int avoid_adrp = 1; + + if (avoid_adrp || sym->a.weak) { + // (GCC uses a R_AARCH64_ABS64 in this case.) + greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G0_NC, addend); + o(0xd2800000 | r); // mov x(rt),#0,lsl #0 + greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G1_NC, addend); + o(0xf2a00000 | r); // movk x(rt),#0,lsl #16 + greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G2_NC, addend); + o(0xf2c00000 | r); // movk x(rt),#0,lsl #32 + greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G3, addend); + o(0xf2e00000 | r); // movk x(rt),#0,lsl #48 + } + else { + greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, addend); + o(0x90000000 | r); + greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, addend); + o(0x91000000 | r | r << 5); + } +} + +ST_FUNC void load(int r, SValue *sv) +{ + int svtt = sv->type.t; + int svr = sv->r & ~VT_LVAL_TYPE; + int svrv = svr & VT_VALMASK; + uint64_t svcul = (uint32_t)sv->c.i; + svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul; + + if (svr == (VT_LOCAL | VT_LVAL)) { + if (IS_FREG(r)) + arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcul); + else + arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt), + intr(r), 29, svcul); + return; + } + + if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) { + if (IS_FREG(r)) + arm64_ldrv(arm64_type_size(svtt), fltr(r), intr(svrv), 0); + else + arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt), + intr(r), intr(svrv), 0); + return; + } + + if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { + arm64_sym(30, sv->sym, svcul); // use x30 for address + if (IS_FREG(r)) + arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0); + else + arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt), + intr(r), 30, 0); + return; + } + + if (svr == (VT_CONST | VT_SYM)) { + arm64_sym(intr(r), sv->sym, svcul); + return; + } + + if (svr == VT_CONST) { + if ((svtt & VT_BTYPE) != VT_VOID) + arm64_movimm(intr(r), arm64_type_size(svtt) == 3 ? + sv->c.i : (uint32_t)svcul); + return; + } + + if (svr < VT_CONST) { + if (IS_FREG(r) && IS_FREG(svr)) + if (svtt == VT_LDOUBLE) + o(0x4ea01c00 | fltr(r) | fltr(svr) << 5); + // mov v(r).16b,v(svr).16b + else + o(0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr) + else if (!IS_FREG(r) && !IS_FREG(svr)) + o(0xaa0003e0 | intr(r) | intr(svr) << 16); // mov x(r),x(svr) + else + assert(0); + return; + } + + if (svr == VT_LOCAL) { + if (-svcul < 0x1000) + o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#... + else { + arm64_movimm(30, -svcul); // use x30 for offset + o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30 + } + return; + } + + if (svr == VT_JMP || svr == VT_JMPI) { + int t = (svr == VT_JMPI); + arm64_movimm(intr(r), t); + o(0x14000002); // b .+8 + gsym(svcul); + arm64_movimm(intr(r), t ^ 1); + return; + } + + if (svr == (VT_LLOCAL | VT_LVAL)) { + arm64_ldrx(0, 3, 30, 29, svcul); // use x30 for offset + if (IS_FREG(r)) + arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0); + else + arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt), + intr(r), 30, 0); + return; + } + + printf("load(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul); + assert(0); +} + +ST_FUNC void store(int r, SValue *sv) +{ + int svtt = sv->type.t; + int svr = sv->r & ~VT_LVAL_TYPE; + int svrv = svr & VT_VALMASK; + uint64_t svcul = (uint32_t)sv->c.i; + svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul; + + if (svr == (VT_LOCAL | VT_LVAL)) { + if (IS_FREG(r)) + arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcul); + else + arm64_strx(arm64_type_size(svtt), intr(r), 29, svcul); + return; + } + + if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) { + if (IS_FREG(r)) + arm64_strv(arm64_type_size(svtt), fltr(r), intr(svrv), 0); + else + arm64_strx(arm64_type_size(svtt), intr(r), intr(svrv), 0); + return; + } + + if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { + arm64_sym(30, sv->sym, svcul); // use x30 for address + if (IS_FREG(r)) + arm64_strv(arm64_type_size(svtt), fltr(r), 30, 0); + else + arm64_strx(arm64_type_size(svtt), intr(r), 30, 0); + return; + } + + printf("store(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul); + assert(0); +} + +static void arm64_gen_bl_or_b(int b) +{ + if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { + assert(!b && (vtop->r & VT_SYM)); + greloca(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26, 0); + o(0x94000000); // bl . + } + else + o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr +} + +static int arm64_hfa_aux(CType *type, int *fsize, int num) +{ + if (is_float(type->t)) { + int a, n = type_size(type, &a); + if (num >= 4 || (*fsize && *fsize != n)) + return -1; + *fsize = n; + return num + 1; + } + else if ((type->t & VT_BTYPE) == VT_STRUCT) { + int is_struct = 0; // rather than union + Sym *field; + for (field = type->ref->next; field; field = field->next) + if (field->c) { + is_struct = 1; + break; + } + if (is_struct) { + int num0 = num; + for (field = type->ref->next; field; field = field->next) { + if (field->c != (num - num0) * *fsize) + return -1; + num = arm64_hfa_aux(&field->type, fsize, num); + if (num == -1) + return -1; + } + if (type->ref->c != (num - num0) * *fsize) + return -1; + return num; + } + else { // union + int num0 = num; + for (field = type->ref->next; field; field = field->next) { + int num1 = arm64_hfa_aux(&field->type, fsize, num0); + if (num1 == -1) + return -1; + num = num1 < num ? num : num1; + } + if (type->ref->c != (num - num0) * *fsize) + return -1; + return num; + } + } + else if (type->t & VT_ARRAY) { + int num1; + if (!type->ref->c) + return num; + num1 = arm64_hfa_aux(&type->ref->type, fsize, num); + if (num1 == -1 || (num1 != num && type->ref->c > 4)) + return -1; + num1 = num + type->ref->c * (num1 - num); + if (num1 > 4) + return -1; + return num1; + } + return -1; +} + +static int arm64_hfa(CType *type, int *fsize) +{ + if ((type->t & VT_BTYPE) == VT_STRUCT || (type->t & VT_ARRAY)) { + int sz = 0; + int n = arm64_hfa_aux(type, &sz, 0); + if (0 < n && n <= 4) { + if (fsize) + *fsize = sz; + return n; + } + } + return 0; +} + +static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a) +{ + int nx = 0; // next integer register + int nv = 0; // next vector register + unsigned long ns = 32; // next stack offset + int i; + + for (i = 0; i < n; i++) { + int hfa = arm64_hfa(type[i], 0); + int size, align; + + if ((type[i]->t & VT_ARRAY) || + (type[i]->t & VT_BTYPE) == VT_FUNC) + size = align = 8; + else + size = type_size(type[i], &align); + + if (hfa) + // B.2 + ; + else if (size > 16) { + // B.3: replace with pointer + if (nx < 8) + a[i] = nx++ << 1 | 1; + else { + ns = (ns + 7) & ~7; + a[i] = ns | 1; + ns += 8; + } + continue; + } + else if ((type[i]->t & VT_BTYPE) == VT_STRUCT) + // B.4 + size = (size + 7) & ~7; + + // C.1 + if (is_float(type[i]->t) && nv < 8) { + a[i] = 16 + (nv++ << 1); + continue; + } + + // C.2 + if (hfa && nv + hfa <= 8) { + a[i] = 16 + (nv << 1); + nv += hfa; + continue; + } + + // C.3 + if (hfa) { + nv = 8; + size = (size + 7) & ~7; + } + + // C.4 + if (hfa || (type[i]->t & VT_BTYPE) == VT_LDOUBLE) { + ns = (ns + 7) & ~7; + ns = (ns + align - 1) & -align; + } + + // C.5 + if ((type[i]->t & VT_BTYPE) == VT_FLOAT) + size = 8; + + // C.6 + if (hfa || is_float(type[i]->t)) { + a[i] = ns; + ns += size; + continue; + } + + // C.7 + if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size <= 8 && nx < 8) { + a[i] = nx++ << 1; + continue; + } + + // C.8 + if (align == 16) + nx = (nx + 1) & ~1; + + // C.9 + if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size == 16 && nx < 7) { + a[i] = nx << 1; + nx += 2; + continue; + } + + // C.10 + if ((type[i]->t & VT_BTYPE) == VT_STRUCT && size <= (8 - nx) * 8) { + a[i] = nx << 1; + nx += (size + 7) >> 3; + continue; + } + + // C.11 + nx = 8; + + // C.12 + ns = (ns + 7) & ~7; + ns = (ns + align - 1) & -align; + + // C.13 + if ((type[i]->t & VT_BTYPE) == VT_STRUCT) { + a[i] = ns; + ns += size; + continue; + } + + // C.14 + if (size < 8) + size = 8; + + // C.15 + a[i] = ns; + ns += size; + } + + return ns - 32; +} + +static unsigned long arm64_pcs(int n, CType **type, unsigned long *a) +{ + unsigned long stack; + + // Return type: + if ((type[0]->t & VT_BTYPE) == VT_VOID) + a[0] = -1; + else { + arm64_pcs_aux(1, type, a); + assert(a[0] == 0 || a[0] == 1 || a[0] == 16); + } + + // Argument types: + stack = arm64_pcs_aux(n, type + 1, a + 1); + + if (0) { + int i; + for (i = 0; i <= n; i++) { + if (!i) + printf("arm64_pcs return: "); + else + printf("arm64_pcs arg %d: ", i); + if (a[i] == (unsigned long)-1) + printf("void\n"); + else if (a[i] == 1 && !i) + printf("X8 pointer\n"); + else if (a[i] < 16) + printf("X%lu%s\n", a[i] / 2, a[i] & 1 ? " pointer" : ""); + else if (a[i] < 32) + printf("V%lu\n", a[i] / 2 - 8); + else + printf("stack %lu%s\n", + (a[i] - 32) & ~1, a[i] & 1 ? " pointer" : ""); + } + } + + return stack; +} + +ST_FUNC void gfunc_call(int nb_args) +{ + CType *return_type; + CType **t; + unsigned long *a, *a1; + unsigned long stack; + int i; + + return_type = &vtop[-nb_args].type.ref->type; + if ((return_type->t & VT_BTYPE) == VT_STRUCT) + --nb_args; + + t = tcc_malloc((nb_args + 1) * sizeof(*t)); + a = tcc_malloc((nb_args + 1) * sizeof(*a)); + a1 = tcc_malloc((nb_args + 1) * sizeof(*a1)); + + t[0] = return_type; + for (i = 0; i < nb_args; i++) + t[nb_args - i] = &vtop[-i].type; + + stack = arm64_pcs(nb_args, t, a); + + // Allocate space for structs replaced by pointer: + for (i = nb_args; i; i--) + if (a[i] & 1) { + SValue *arg = &vtop[i - nb_args]; + int align, size = type_size(&arg->type, &align); + assert((arg->type.t & VT_BTYPE) == VT_STRUCT); + stack = (stack + align - 1) & -align; + a1[i] = stack; + stack += size; + } + + stack = (stack + 15) >> 4 << 4; + + assert(stack < 0x1000); + if (stack) + o(0xd10003ff | stack << 10); // sub sp,sp,#(n) + + // First pass: set all values on stack + for (i = nb_args; i; i--) { + vpushv(vtop - nb_args + i); + + if (a[i] & 1) { + // struct replaced by pointer + int r = get_reg(RC_INT); + arm64_spoff(intr(r), a1[i]); + vset(&vtop->type, r | VT_LVAL, 0); + vswap(); + vstore(); + if (a[i] >= 32) { + // pointer on stack + r = get_reg(RC_INT); + arm64_spoff(intr(r), a1[i]); + arm64_strx(3, intr(r), 31, (a[i] - 32) >> 1 << 1); + } + } + else if (a[i] >= 32) { + // value on stack + if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { + int r = get_reg(RC_INT); + arm64_spoff(intr(r), a[i] - 32); + vset(&vtop->type, r | VT_LVAL, 0); + vswap(); + vstore(); + } + else if (is_float(vtop->type.t)) { + gv(RC_FLOAT); + arm64_strv(arm64_type_size(vtop[0].type.t), + fltr(vtop[0].r), 31, a[i] - 32); + } + else { + gv(RC_INT); + arm64_strx(arm64_type_size(vtop[0].type.t), + intr(vtop[0].r), 31, a[i] - 32); + } + } + + --vtop; + } + + // Second pass: assign values to registers + for (i = nb_args; i; i--, vtop--) { + if (a[i] < 16 && !(a[i] & 1)) { + // value in general-purpose registers + if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { + int align, size = type_size(&vtop->type, &align); + vtop->type.t = VT_PTR; + gaddrof(); + gv(RC_R(a[i] / 2)); + arm64_ldrs(a[i] / 2, size); + } + else + gv(RC_R(a[i] / 2)); + } + else if (a[i] < 16) + // struct replaced by pointer in register + arm64_spoff(a[i] / 2, a1[i]); + else if (a[i] < 32) { + // value in floating-point registers + if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { + uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz); + vtop->type.t = VT_PTR; + gaddrof(); + gv(RC_R30); + for (j = 0; j < n; j++) + o(0x3d4003c0 | + (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | + (a[i] / 2 - 8 + j) | + j << 10); // ldr ([sdq])(*),[x30,#(j * sz)] + } + else + gv(RC_F(a[i] / 2 - 8)); + } + } + + if ((return_type->t & VT_BTYPE) == VT_STRUCT) { + if (a[0] == 1) { + // indirect return: set x8 and discard the stack value + gv(RC_R(8)); + --vtop; + } + else + // return in registers: keep the address for after the call + vswap(); + } + + save_regs(0); + arm64_gen_bl_or_b(0); + --vtop; + if (stack) + o(0x910003ff | stack << 10); // add sp,sp,#(n) + + { + int rt = return_type->t; + int bt = rt & VT_BTYPE; + if (bt == VT_BYTE || bt == VT_SHORT) + // Promote small integers: + o(0x13001c00 | (bt == VT_SHORT) << 13 | + (uint32_t)!!(rt & VT_UNSIGNED) << 30); // [su]xt[bh] w0,w0 + else if (bt == VT_STRUCT && !(a[0] & 1)) { + // A struct was returned in registers, so write it out: + gv(RC_R(8)); + --vtop; + if (a[0] == 0) { + int align, size = type_size(return_type, &align); + assert(size <= 16); + if (size > 8) + o(0xa9000500); // stp x0,x1,[x8] + else if (size) + arm64_strx(size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0); + + } + else if (a[0] == 16) { + uint32_t j, sz, n = arm64_hfa(return_type, &sz); + for (j = 0; j < n; j++) + o(0x3d000100 | + (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | + (a[i] / 2 - 8 + j) | + j << 10); // str ([sdq])(*),[x8,#(j * sz)] + } + } + } + + tcc_free(a1); + tcc_free(a); + tcc_free(t); +} + +static unsigned long arm64_func_va_list_stack; +static int arm64_func_va_list_gr_offs; +static int arm64_func_va_list_vr_offs; +static int arm64_func_sub_sp_offset; + +ST_FUNC void gfunc_prolog(CType *func_type) +{ + int n = 0; + int i = 0; + Sym *sym; + CType **t; + unsigned long *a; + + // Why doesn't the caller (gen_function) set func_vt? + func_vt = func_type->ref->type; + func_vc = 144; // offset of where x8 is stored + + for (sym = func_type->ref; sym; sym = sym->next) + ++n; + t = tcc_malloc(n * sizeof(*t)); + a = tcc_malloc(n * sizeof(*a)); + + for (sym = func_type->ref; sym; sym = sym->next) + t[i++] = &sym->type; + + arm64_func_va_list_stack = arm64_pcs(n - 1, t, a); + + o(0xa9b27bfd); // stp x29,x30,[sp,#-224]! + o(0xad0087e0); // stp q0,q1,[sp,#16] + o(0xad018fe2); // stp q2,q3,[sp,#48] + o(0xad0297e4); // stp q4,q5,[sp,#80] + o(0xad039fe6); // stp q6,q7,[sp,#112] + o(0xa90923e8); // stp x8,x8,[sp,#144] + o(0xa90a07e0); // stp x0,x1,[sp,#160] + o(0xa90b0fe2); // stp x2,x3,[sp,#176] + o(0xa90c17e4); // stp x4,x5,[sp,#192] + o(0xa90d1fe6); // stp x6,x7,[sp,#208] + + arm64_func_va_list_gr_offs = -64; + arm64_func_va_list_vr_offs = -128; + + for (i = 1, sym = func_type->ref->next; sym; i++, sym = sym->next) { + int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 : + a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 : + 224 + ((a[i] - 32) >> 1 << 1)); + sym_push(sym->v & ~SYM_FIELD, &sym->type, + (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | lvalue_type(sym->type.t), + off); + + if (a[i] < 16) { + int align, size = type_size(&sym->type, &align); + arm64_func_va_list_gr_offs = (a[i] / 2 - 7 + + (!(a[i] & 1) && size > 8)) * 8; + } + else if (a[i] < 32) { + uint32_t hfa = arm64_hfa(&sym->type, 0); + arm64_func_va_list_vr_offs = (a[i] / 2 - 16 + + (hfa ? hfa : 1)) * 16; + } + + // HFAs of float and double need to be written differently: + if (16 <= a[i] && a[i] < 32 && (sym->type.t & VT_BTYPE) == VT_STRUCT) { + uint32_t j, sz, k = arm64_hfa(&sym->type, &sz); + if (sz < 16) + for (j = 0; j < k; j++) { + o(0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 | + ((a[i] - 16) / 2 + j) | (off / sz + j) << 10); + // str ([sdq])(*),[sp,#(j * sz)] + } + } + } + + tcc_free(a); + tcc_free(t); + + o(0x910003fd); // mov x29,sp + arm64_func_sub_sp_offset = ind; + // In gfunc_epilog these will be replaced with code to decrement SP: + o(0xd503201f); // nop + o(0xd503201f); // nop + loc = 0; +} + +ST_FUNC void gen_va_start(void) +{ + int r; + --vtop; // we don't need the "arg" + gaddrof(); + r = intr(gv(RC_INT)); + + if (arm64_func_va_list_stack) { + //xx could use add (immediate) here + arm64_movimm(30, arm64_func_va_list_stack + 224); + o(0x8b1e03be); // add x30,x29,x30 + } + else + o(0x910383be); // add x30,x29,#224 + o(0xf900001e | r << 5); // str x30,[x(r)] + + if (arm64_func_va_list_gr_offs) { + if (arm64_func_va_list_stack) + o(0x910383be); // add x30,x29,#224 + o(0xf900041e | r << 5); // str x30,[x(r),#8] + } + + if (arm64_func_va_list_vr_offs) { + o(0x910243be); // add x30,x29,#144 + o(0xf900081e | r << 5); // str x30,[x(r),#16] + } + + arm64_movimm(30, arm64_func_va_list_gr_offs); + o(0xb900181e | r << 5); // str w30,[x(r),#24] + + arm64_movimm(30, arm64_func_va_list_vr_offs); + o(0xb9001c1e | r << 5); // str w30,[x(r),#28] + + --vtop; +} + +ST_FUNC void gen_va_arg(CType *t) +{ + int align, size = type_size(t, &align); + int fsize, hfa = arm64_hfa(t, &fsize); + uint32_t r0, r1; + + if (is_float(t->t)) { + hfa = 1; + fsize = size; + } + + gaddrof(); + r0 = intr(gv(RC_INT)); + r1 = get_reg(RC_INT); + vtop[0].r = r1 | lvalue_type(t->t); + r1 = intr(r1); + + if (!hfa) { + uint32_t n = size > 16 ? 8 : (size + 7) & -8; + o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs + if (align == 16) { + assert(0); // this path untested but needed for __uint128_t + o(0x11003fde); // add w30,w30,#15 + o(0x121c6fde); // and w30,w30,#-16 + } + o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n) + o(0x540000ad); // b.le .+20 + o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack + o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n) + o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack + o(0x14000004); // b .+16 + o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs + o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top + o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw + if (size > 16) + o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)] + } + else { + uint32_t rsz = hfa << 4; + uint32_t ssz = (size + 7) & -(uint32_t)8; + uint32_t b1, b2; + o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs + o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz) + b1 = ind; o(0x5400000d); // b.le lab1 + o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack + if (fsize == 16) { + o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15 + o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16 + } + o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz) + o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack + b2 = ind; o(0x14000000); // b lab2 + // lab1: + write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3); + o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs + o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top + if (hfa == 1 || fsize == 16) + o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw + else { + // We need to change the layout of this HFA. + // Get some space on the stack using global variable "loc": + loc = (loc - size) & -(uint32_t)align; + o(0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw + arm64_movimm(r1, loc); + o(0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1) + o(0x4c402bdc | (uint32_t)fsize << 7 | + (uint32_t)(hfa == 2) << 15 | + (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30] + o(0x0d00801c | r1 << 5 | (fsize == 8) << 10 | + (uint32_t)(hfa != 2) << 13 | + (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)] + } + // lab2: + write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2); + } +} + +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, + int *align, int *regsize) +{ + return 0; +} + +ST_FUNC void gfunc_return(CType *func_type) +{ + CType *t = func_type; + unsigned long a; + + arm64_pcs(0, &t, &a); + switch (a) { + case -1: + break; + case 0: + if ((func_type->t & VT_BTYPE) == VT_STRUCT) { + int align, size = type_size(func_type, &align); + gaddrof(); + gv(RC_R(0)); + arm64_ldrs(0, size); + } + else + gv(RC_IRET); + break; + case 1: { + CType type = *func_type; + mk_pointer(&type); + vset(&type, VT_LOCAL | VT_LVAL, func_vc); + indir(); + vswap(); + vstore(); + break; + } + case 16: + if ((func_type->t & VT_BTYPE) == VT_STRUCT) { + uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz); + gaddrof(); + gv(RC_R(0)); + for (j = 0; j < n; j++) + o(0x3d400000 | + (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | + j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)] + } + else + gv(RC_FRET); + break; + default: + assert(0); + } + vtop--; +} + +ST_FUNC void gfunc_epilog(void) +{ + if (loc) { + // Insert instructions to subtract size of stack frame from SP. + unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset; + uint64_t diff = (-loc + 15) & ~15; + if (!(diff >> 24)) { + if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff) + write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10); + if (diff >> 12) // sub sp,sp,#(diff >> 12),lsl #12 + write32le(ptr + 4, 0xd14003ff | (diff >> 12) << 10); + } + else { + // In this case we may subtract more than necessary, + // but always less than 17/16 of what we were aiming for. + int i = 0; + int j = 0; + while (diff >> 20) { + diff = (diff + 0xffff) >> 16; + ++i; + } + while (diff >> 16) { + diff = (diff + 1) >> 1; + ++j; + } + write32le(ptr, 0xd2800010 | diff << 5 | i << 21); + // mov x16,#(diff),lsl #(16 * i) + write32le(ptr + 4, 0xcb3063ff | j << 10); + // sub sp,sp,x16,lsl #(j) + } + } + o(0x910003bf); // mov sp,x29 + o(0xa8ce7bfd); // ldp x29,x30,[sp],#224 + + o(0xd65f03c0); // ret +} + +// Generate forward branch to label: +ST_FUNC int gjmp(int t) +{ + int r = ind; + if (nocode_wanted) + return t; + o(t); + return r; +} + +// Generate branch to known address: +ST_FUNC void gjmp_addr(int a) +{ + assert(a - ind + 0x8000000 < 0x10000000); + o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff)); +} + +ST_FUNC int gtst(int inv, int t) +{ + int bt = vtop->type.t & VT_BTYPE; + if (bt == VT_LDOUBLE) { + uint32_t a, b, f = fltr(gv(RC_FLOAT)); + a = get_reg(RC_INT); + vpushi(0); + vtop[0].r = a; + b = get_reg(RC_INT); + a = intr(a); + b = intr(b); + o(0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0] + o(0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1] + o(0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1 + o(0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8 + --vtop; + } + else if (bt == VT_FLOAT || bt == VT_DOUBLE) { + uint32_t a = fltr(gv(RC_FLOAT)); + o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp + o(0x54000040 | !!inv); // b.eq/b.ne .+8 + } + else { + uint32_t ll = (bt == VT_PTR || bt == VT_LLONG); + uint32_t a = intr(gv(RC_INT)); + o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8 + } + --vtop; + return gjmp(t); +} + +static int arm64_iconst(uint64_t *val, SValue *sv) +{ + if ((sv->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) + return 0; + if (val) { + int t = sv->type.t; + int bt = t & VT_BTYPE; + *val = ((bt == VT_LLONG || bt == VT_PTR) ? sv->c.i : + (uint32_t)sv->c.i | + (t & VT_UNSIGNED ? 0 : -(sv->c.i & 0x80000000))); + } + return 1; +} + +static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, + uint32_t x, uint32_t a) +{ + if (op == '-' && !rev) { + val = -val; + op = '+'; + } + val = l ? val : (uint32_t)val; + + switch (op) { + + case '+': { + uint32_t s = l ? val >> 63 : val >> 31; + val = s ? -val : val; + val = l ? val : (uint32_t)val; + if (!(val & ~(uint64_t)0xfff)) + o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10); + else if (!(val & ~(uint64_t)0xfff000)) + o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10); + else { + arm64_movimm(30, val); // use x30 + o(0x0b1e0000 | l << 31 | s << 30 | x | a << 5); + } + return 1; + } + + case '-': + if (!val) + o(0x4b0003e0 | l << 31 | x | a << 16); // neg + else if (val == (l ? (uint64_t)-1 : (uint32_t)-1)) + o(0x2a2003e0 | l << 31 | x | a << 16); // mvn + else { + arm64_movimm(30, val); // use x30 + o(0x4b0003c0 | l << 31 | x | a << 16); // sub + } + return 1; + + case '^': + if (val == -1 || (val == 0xffffffff && !l)) { + o(0x2a2003e0 | l << 31 | x | a << 16); // mvn + return 1; + } + // fall through + case '&': + case '|': { + int e = arm64_encode_bimm64(l ? val : val | val << 32); + if (e < 0) + return 0; + o((op == '&' ? 0x12000000 : + op == '|' ? 0x32000000 : 0x52000000) | + l << 31 | x | a << 5 | (uint32_t)e << 10); + return 1; + } + + case TOK_SAR: + case TOK_SHL: + case TOK_SHR: { + uint32_t n = 32 << l; + val = val & (n - 1); + if (rev) + return 0; + if (!val) + assert(0); + else if (op == TOK_SHL) + o(0x53000000 | l << 31 | l << 22 | x | a << 5 | + (n - val) << 16 | (n - 1 - val) << 10); // lsl + else + o(0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 | + x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr + return 1; + } + + } + return 0; +} + +static void arm64_gen_opil(int op, uint32_t l) +{ + uint32_t x, a, b; + + // Special treatment for operations with a constant operand: + { + uint64_t val; + int rev = 1; + + if (arm64_iconst(0, &vtop[0])) { + vswap(); + rev = 0; + } + if (arm64_iconst(&val, &vtop[-1])) { + gv(RC_INT); + a = intr(vtop[0].r); + --vtop; + x = get_reg(RC_INT); + ++vtop; + if (arm64_gen_opic(op, l, rev, val, intr(x), a)) { + vtop[0].r = x; + vswap(); + --vtop; + return; + } + } + if (!rev) + vswap(); + } + + gv2(RC_INT, RC_INT); + assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST); + a = intr(vtop[-1].r); + b = intr(vtop[0].r); + vtop -= 2; + x = get_reg(RC_INT); + ++vtop; + vtop[0].r = x; + x = intr(x); + + switch (op) { + case '%': + // Use x30 for quotient: + o(0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv + o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 | + b << 16 | a << 10); // msub + break; + case '&': + o(0x0a000000 | l << 31 | x | a << 5 | b << 16); // and + break; + case '*': + o(0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul + break; + case '+': + o(0x0b000000 | l << 31 | x | a << 5 | b << 16); // add + break; + case '-': + o(0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub + break; + case '/': + o(0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv + break; + case '^': + o(0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor + break; + case '|': + o(0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr + break; + case TOK_EQ: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9f17e0 | x); // cset wA,eq + break; + case TOK_GE: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9fb7e0 | x); // cset wA,ge + break; + case TOK_GT: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9fd7e0 | x); // cset wA,gt + break; + case TOK_LE: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9fc7e0 | x); // cset wA,le + break; + case TOK_LT: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9fa7e0 | x); // cset wA,lt + break; + case TOK_NE: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9f07e0 | x); // cset wA,ne + break; + case TOK_SAR: + o(0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr + break; + case TOK_SHL: + o(0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl + break; + case TOK_SHR: + o(0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr + break; + case TOK_UDIV: + case TOK_PDIV: + o(0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv + break; + case TOK_UGE: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9f37e0 | x); // cset wA,cs + break; + case TOK_UGT: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9f97e0 | x); // cset wA,hi + break; + case TOK_ULT: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9f27e0 | x); // cset wA,cc + break; + case TOK_ULE: + o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp + o(0x1a9f87e0 | x); // cset wA,ls + break; + case TOK_UMOD: + // Use x30 for quotient: + o(0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv + o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 | + b << 16 | a << 10); // msub + break; + default: + assert(0); + } +} + +ST_FUNC void gen_opi(int op) +{ + arm64_gen_opil(op, 0); +} + +ST_FUNC void gen_opl(int op) +{ + arm64_gen_opil(op, 1); +} + +ST_FUNC void gen_opf(int op) +{ + uint32_t x, a, b, dbl; + + if (vtop[0].type.t == VT_LDOUBLE) { + CType type = vtop[0].type; + int func = 0; + int cond = -1; + switch (op) { + case '*': func = TOK___multf3; break; + case '+': func = TOK___addtf3; break; + case '-': func = TOK___subtf3; break; + case '/': func = TOK___divtf3; break; + case TOK_EQ: func = TOK___eqtf2; cond = 1; break; + case TOK_NE: func = TOK___netf2; cond = 0; break; + case TOK_LT: func = TOK___lttf2; cond = 10; break; + case TOK_GE: func = TOK___getf2; cond = 11; break; + case TOK_LE: func = TOK___letf2; cond = 12; break; + case TOK_GT: func = TOK___gttf2; cond = 13; break; + default: assert(0); break; + } + vpush_global_sym(&func_old_type, func); + vrott(3); + gfunc_call(2); + vpushi(0); + vtop->r = cond < 0 ? REG_FRET : REG_IRET; + if (cond < 0) + vtop->type = type; + else { + o(0x7100001f); // cmp w0,#0 + o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond) + } + return; + } + + dbl = vtop[0].type.t != VT_FLOAT; + gv2(RC_FLOAT, RC_FLOAT); + assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST); + a = fltr(vtop[-1].r); + b = fltr(vtop[0].r); + vtop -= 2; + switch (op) { + case TOK_EQ: case TOK_NE: + case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT: + x = get_reg(RC_INT); + ++vtop; + vtop[0].r = x; + x = intr(x); + break; + default: + x = get_reg(RC_FLOAT); + ++vtop; + vtop[0].r = x; + x = fltr(x); + break; + } + + switch (op) { + case '*': + o(0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul + break; + case '+': + o(0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd + break; + case '-': + o(0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub + break; + case '/': + o(0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv + break; + case TOK_EQ: + o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp + o(0x1a9f17e0 | x); // cset w(x),eq + break; + case TOK_GE: + o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp + o(0x1a9fb7e0 | x); // cset w(x),ge + break; + case TOK_GT: + o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp + o(0x1a9fd7e0 | x); // cset w(x),gt + break; + case TOK_LE: + o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp + o(0x1a9f87e0 | x); // cset w(x),ls + break; + case TOK_LT: + o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp + o(0x1a9f57e0 | x); // cset w(x),mi + break; + case TOK_NE: + o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp + o(0x1a9f07e0 | x); // cset w(x),ne + break; + default: + assert(0); + } +} + +// Generate sign extension from 32 to 64 bits: +ST_FUNC void gen_cvt_sxtw(void) +{ + uint32_t r = intr(gv(RC_INT)); + o(0x93407c00 | r | r << 5); // sxtw x(r),w(r) +} + +ST_FUNC void gen_cvt_itof(int t) +{ + if (t == VT_LDOUBLE) { + int f = vtop->type.t; + int func = (f & VT_BTYPE) == VT_LLONG ? + (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) : + (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf); + vpush_global_sym(&func_old_type, func); + vrott(2); + gfunc_call(1); + vpushi(0); + vtop->type.t = t; + vtop->r = REG_FRET; + return; + } + else { + int d, n = intr(gv(RC_INT)); + int s = !(vtop->type.t & VT_UNSIGNED); + uint32_t l = ((vtop->type.t & VT_BTYPE) == VT_LLONG); + --vtop; + d = get_reg(RC_FLOAT); + ++vtop; + vtop[0].r = d; + o(0x1e220000 | (uint32_t)!s << 16 | + (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) | + l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n) + } +} + +ST_FUNC void gen_cvt_ftoi(int t) +{ + if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { + int func = (t & VT_BTYPE) == VT_LLONG ? + (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) : + (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi); + vpush_global_sym(&func_old_type, func); + vrott(2); + gfunc_call(1); + vpushi(0); + vtop->type.t = t; + vtop->r = REG_IRET; + return; + } + else { + int d, n = fltr(gv(RC_FLOAT)); + uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT); + --vtop; + d = get_reg(RC_INT); + ++vtop; + vtop[0].r = d; + o(0x1e380000 | + (uint32_t)!!(t & VT_UNSIGNED) << 16 | + (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) | + l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n) + } +} + +ST_FUNC void gen_cvt_ftof(int t) +{ + int f = vtop[0].type.t; + assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE); + assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE); + if (t == f) + return; + + if (t == VT_LDOUBLE || f == VT_LDOUBLE) { + int func = (t == VT_LDOUBLE) ? + (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) : + (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2); + vpush_global_sym(&func_old_type, func); + vrott(2); + gfunc_call(1); + vpushi(0); + vtop->type.t = t; + vtop->r = REG_FRET; + } + else { + int x, a; + gv(RC_FLOAT); + assert(vtop[0].r < VT_CONST); + a = fltr(vtop[0].r); + --vtop; + x = get_reg(RC_FLOAT); + ++vtop; + vtop[0].r = x; + x = fltr(x); + + if (f == VT_FLOAT) + o(0x1e22c000 | x | a << 5); // fcvt d(x),s(a) + else + o(0x1e624000 | x | a << 5); // fcvt s(x),d(a) + } +} + +ST_FUNC void ggoto(void) +{ + arm64_gen_bl_or_b(1); + --vtop; +} + +ST_FUNC void gen_clear_cache(void) +{ + uint32_t beg, end, dsz, isz, p, lab1, b1; + gv2(RC_INT, RC_INT); + vpushi(0); + vtop->r = get_reg(RC_INT); + vpushi(0); + vtop->r = get_reg(RC_INT); + vpushi(0); + vtop->r = get_reg(RC_INT); + beg = intr(vtop[-4].r); // x0 + end = intr(vtop[-3].r); // x1 + dsz = intr(vtop[-2].r); // x2 + isz = intr(vtop[-1].r); // x3 + p = intr(vtop[0].r); // x4 + vtop -= 5; + + o(0xd53b0020 | isz); // mrs x(isz),ctr_el0 + o(0x52800080 | p); // mov w(p),#4 + o(0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#4 + o(0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz) + o(0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#15 + o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz) + o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1 + o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p) + b1 = ind; o(0x14000000); // b + lab1 = ind; + o(0xd50b7b20 | p); // dc cvau,x(p) + o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz) + write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2); + o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) + o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1 + o(0xd5033b9f); // dsb ish + o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#1 + o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p) + b1 = ind; o(0x14000000); // b + lab1 = ind; + o(0xd50b7520 | p); // ic ivau,x(p) + o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz) + write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2); + o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) + o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1 + o(0xd5033b9f); // dsb ish + o(0xd5033fdf); // isb +} + +ST_FUNC void gen_vla_sp_save(int addr) { + uint32_t r = intr(get_reg(RC_INT)); + o(0x910003e0 | r); // mov x(r),sp + arm64_strx(3, r, 29, addr); +} + +ST_FUNC void gen_vla_sp_restore(int addr) { + // Use x30 because this function can be called when there + // is a live return value in x0 but there is nothing on + // the value stack to prevent get_reg from returning x0. + uint32_t r = 30; + arm64_ldrx(0, 3, r, 29, addr); + o(0x9100001f | r << 5); // mov sp,x(r) +} + +ST_FUNC void gen_vla_alloc(CType *type, int align) { + uint32_t r = intr(gv(RC_INT)); + o(0x91003c00 | r | r << 5); // add x(r),x(r),#15 + o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15 + o(0xcb2063ff | r << 16); // sub sp,sp,x(r) + vpop(); +} + +/* end of A64 code generator */ +/*************************************************************/ +#endif +/*************************************************************/ diff --git a/tinyc/arm64-link.c b/tinyc/arm64-link.c new file mode 100644 index 000000000..73e503e6b --- /dev/null +++ b/tinyc/arm64-link.c @@ -0,0 +1,250 @@ +#ifdef TARGET_DEFS_ONLY + +#define EM_TCC_TARGET EM_AARCH64 + +#define R_DATA_32 R_AARCH64_ABS32 +#define R_DATA_PTR R_AARCH64_ABS64 +#define R_JMP_SLOT R_AARCH64_JUMP_SLOT +#define R_GLOB_DAT R_AARCH64_GLOB_DAT +#define R_COPY R_AARCH64_COPY +#define R_RELATIVE R_AARCH64_RELATIVE + +#define R_NUM R_AARCH64_NUM + +#define ELF_START_ADDR 0x00400000 +#define ELF_PAGE_SIZE 0x1000 + +#define PCRELATIVE_DLLPLT 1 +#define RELOCATE_DLLPLT 1 + +#else /* !TARGET_DEFS_ONLY */ + +#include "tcc.h" + +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_AARCH64_ABS32: + case R_AARCH64_ABS64: + case R_AARCH64_PREL32: + case R_AARCH64_MOVW_UABS_G0_NC: + case R_AARCH64_MOVW_UABS_G1_NC: + case R_AARCH64_MOVW_UABS_G2_NC: + case R_AARCH64_MOVW_UABS_G3: + case R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_ADR_GOT_PAGE: + case R_AARCH64_LD64_GOT_LO12_NC: + case R_AARCH64_GLOB_DAT: + case R_AARCH64_COPY: + return 0; + + case R_AARCH64_JUMP26: + case R_AARCH64_CALL26: + case R_AARCH64_JUMP_SLOT: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe whether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_AARCH64_PREL32: + case R_AARCH64_MOVW_UABS_G0_NC: + case R_AARCH64_MOVW_UABS_G1_NC: + case R_AARCH64_MOVW_UABS_G2_NC: + case R_AARCH64_MOVW_UABS_G3: + case R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_GLOB_DAT: + case R_AARCH64_JUMP_SLOT: + case R_AARCH64_COPY: + return NO_GOTPLT_ENTRY; + + case R_AARCH64_ABS32: + case R_AARCH64_ABS64: + case R_AARCH64_JUMP26: + case R_AARCH64_CALL26: + return AUTO_GOTPLT_ENTRY; + + case R_AARCH64_ADR_GOT_PAGE: + case R_AARCH64_LD64_GOT_LO12_NC: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) +{ + Section *plt = s1->plt; + uint8_t *p; + unsigned plt_offset; + + if (s1->output_type == TCC_OUTPUT_DLL) + tcc_error("DLLs unimplemented!"); + + if (plt->data_offset == 0) { + section_ptr_add(plt, 32); + } + plt_offset = plt->data_offset; + + p = section_ptr_add(plt, 16); + write32le(p, got_offset); + write32le(p + 4, (uint64_t) got_offset >> 32); + return plt_offset; +} + +/* relocate the PLT: compute addresses and offsets in the PLT now that final + address for PLT and GOT are known (see fill_program_header) */ +ST_FUNC void relocate_plt(TCCState *s1) +{ + uint8_t *p, *p_end; + + if (!s1->plt) + return; + + p = s1->plt->data; + p_end = p + s1->plt->data_offset; + + if (p < p_end) { + uint64_t plt = s1->plt->sh_addr; + uint64_t got = s1->got->sh_addr; + uint64_t off = (got >> 12) - (plt >> 12); + if ((off + ((uint32_t)1 << 20)) >> 21) + tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt); + write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]! + write32le(p + 4, (0x90000010 | // adrp x16,... + (off & 0x1ffffc) << 3 | (off & 3) << 29)); + write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...] + (got & 0xff8) << 7)); + write32le(p + 12, (0x91000210 | // add x16,x16,#... + (got & 0xfff) << 10)); + write32le(p + 16, 0xd61f0220); // br x17 + write32le(p + 20, 0xd503201f); // nop + write32le(p + 24, 0xd503201f); // nop + write32le(p + 28, 0xd503201f); // nop + p += 32; + while (p < p_end) { + uint64_t pc = plt + (p - s1->plt->data); + uint64_t addr = got + read64le(p); + uint64_t off = (addr >> 12) - (pc >> 12); + if ((off + ((uint32_t)1 << 20)) >> 21) + tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc); + write32le(p, (0x90000010 | // adrp x16,... + (off & 0x1ffffc) << 3 | (off & 3) << 29)); + write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...] + (addr & 0xff8) << 7)); + write32le(p + 8, (0x91000210 | // add x16,x16,#... + (addr & 0xfff) << 10)); + write32le(p + 12, 0xd61f0220); // br x17 + p += 16; + } + } +} + +void relocate_init(Section *sr) {} + +void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) +{ + int sym_index = ELFW(R_SYM)(rel->r_info); +#ifdef DEBUG_RELOC + ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; +#endif + + switch(type) { + case R_AARCH64_ABS64: + write64le(ptr, val); + return; + case R_AARCH64_ABS32: + write32le(ptr, val); + return; + case R_AARCH64_PREL32: + write32le(ptr, val - addr); + return; + case R_AARCH64_MOVW_UABS_G0_NC: + write32le(ptr, ((read32le(ptr) & 0xffe0001f) | + (val & 0xffff) << 5)); + return; + case R_AARCH64_MOVW_UABS_G1_NC: + write32le(ptr, ((read32le(ptr) & 0xffe0001f) | + (val >> 16 & 0xffff) << 5)); + return; + case R_AARCH64_MOVW_UABS_G2_NC: + write32le(ptr, ((read32le(ptr) & 0xffe0001f) | + (val >> 32 & 0xffff) << 5)); + return; + case R_AARCH64_MOVW_UABS_G3: + write32le(ptr, ((read32le(ptr) & 0xffe0001f) | + (val >> 48 & 0xffff) << 5)); + return; + case R_AARCH64_ADR_PREL_PG_HI21: { + uint64_t off = (val >> 12) - (addr >> 12); + if ((off + ((uint64_t)1 << 20)) >> 21) + tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); + write32le(ptr, ((read32le(ptr) & 0x9f00001f) | + (off & 0x1ffffc) << 3 | (off & 3) << 29)); + return; + } + case R_AARCH64_ADD_ABS_LO12_NC: + write32le(ptr, ((read32le(ptr) & 0xffc003ff) | + (val & 0xfff) << 10)); + return; + case R_AARCH64_JUMP26: + case R_AARCH64_CALL26: +#ifdef DEBUG_RELOC + printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val, + (char *) symtab_section->link->data + sym->st_name); +#endif + if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) + tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed" + " (val=%lx, addr=%lx)", val, addr); + write32le(ptr, (0x14000000 | + (uint32_t)(type == R_AARCH64_CALL26) << 31 | + ((val - addr) >> 2 & 0x3ffffff))); + return; + case R_AARCH64_ADR_GOT_PAGE: { + uint64_t off = + (((s1->got->sh_addr + + s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12)); + if ((off + ((uint64_t)1 << 20)) >> 21) + tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed"); + write32le(ptr, ((read32le(ptr) & 0x9f00001f) | + (off & 0x1ffffc) << 3 | (off & 3) << 29)); + return; + } + case R_AARCH64_LD64_GOT_LO12_NC: + write32le(ptr, + ((read32le(ptr) & 0xfff803ff) | + ((s1->got->sh_addr + + s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7)); + return; + case R_AARCH64_COPY: + return; + case R_AARCH64_GLOB_DAT: + case R_AARCH64_JUMP_SLOT: + /* They don't need addend */ +#ifdef DEBUG_RELOC + printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, + val - rel->r_addend, + (char *) symtab_section->link->data + sym->st_name); +#endif + write64le(ptr, val - rel->r_addend); + return; + default: + fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n", + type, (unsigned)addr, ptr, (unsigned)val); + return; + } +} + +#endif /* !TARGET_DEFS_ONLY */ diff --git a/tinyc/c67-gen.c b/tinyc/c67-gen.c index 77c68a279..bcb4b0e3e 100644 --- a/tinyc/c67-gen.c +++ b/tinyc/c67-gen.c @@ -18,7 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -//#define ASSEMBLY_LISTING_C67 +#ifdef TARGET_DEFS_ONLY + +/* #define ASSEMBLY_LISTING_C67 */ /* number of available registers */ #define NB_REGS 24 @@ -85,12 +87,38 @@ enum { TREG_C67_B13, }; -int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_FLOAT | RC_EAX, - // only allow even regs for floats (allow for doubles) +/* return registers for function */ +#define REG_IRET TREG_C67_A4 /* single word int return register */ +#define REG_LRET TREG_C67_A5 /* second word return register (for long long) */ +#define REG_FRET TREG_C67_A4 /* float return register */ + +/* defined if function parameters must be evaluated in reverse order */ +/* #define INVERT_FUNC_PARAMS */ + +/* defined if structures are passed as pointers. Otherwise structures + are directly pushed on stack. */ +/* #define FUNC_STRUCT_PARAM_AS_PTR */ + +/* pointer size, in bytes */ +#define PTR_SIZE 4 + +/* long double size and alignment, in bytes */ +#define LDOUBLE_SIZE 12 +#define LDOUBLE_ALIGN 4 +/* maximum alignment (for aligned attribute support) */ +#define MAX_ALIGN 8 + +/******************************************************/ +#else /* ! TARGET_DEFS_ONLY */ +/******************************************************/ +#include "tcc.h" + +ST_DATA const int reg_classes[NB_REGS] = { + /* eax */ RC_INT | RC_FLOAT | RC_EAX, + // only allow even regs for floats (allow for doubles) /* ecx */ RC_INT | RC_ECX, - /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX, - // only allow even regs for floats (allow for doubles) + /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX, + // only allow even regs for floats (allow for doubles) /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0, /* A4 */ RC_C67_A4, /* A5 */ RC_C67_A5, @@ -114,67 +142,36 @@ int reg_classes[NB_REGS] = { /* B13 */ RC_C67_B11 }; -/* return registers for function */ -#define REG_IRET TREG_C67_A4 /* single word int return register */ -#define REG_LRET TREG_C67_A5 /* second word return register (for long long) */ -#define REG_FRET TREG_C67_A4 /* float return register */ - - -#define ALWAYS_ASSERT(x) \ -do {\ - if (!(x))\ - error("internal compiler error file at %s:%d", __FILE__, __LINE__);\ -} while (0) - // although tcc thinks it is passing parameters on the stack, // the C67 really passes up to the first 10 params in special // regs or regs pairs (for 64 bit params). So keep track of // the stack offsets so we can translate to the appropriate // reg (pair) - #define NoCallArgsPassedOnStack 10 int NoOfCurFuncArgs; int TranslateStackToReg[NoCallArgsPassedOnStack]; int ParamLocOnStack[NoCallArgsPassedOnStack]; int TotalBytesPushedOnStack; -/* defined if function parameters must be evaluated in reverse order */ - -//#define INVERT_FUNC_PARAMS - -/* defined if structures are passed as pointers. Otherwise structures - are directly pushed on stack. */ -//#define FUNC_STRUCT_PARAM_AS_PTR - -/* pointer size, in bytes */ -#define PTR_SIZE 4 - -/* long double size and alignment, in bytes */ -#define LDOUBLE_SIZE 12 -#define LDOUBLE_ALIGN 4 -/* maximum alignment (for aligned attribute support) */ -#define MAX_ALIGN 8 - -/******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_C60 +#ifndef FALSE +# define FALSE 0 +# define TRUE 1 +#endif -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_C60_32 -#define R_JMP_SLOT R_C60_JMP_SLOT -#define R_COPY R_C60_COPY +#undef BOOL +#define BOOL int -#define ELF_START_ADDR 0x00000400 -#define ELF_PAGE_SIZE 0x1000 +#define ALWAYS_ASSERT(x) \ +do {\ + if (!(x))\ + tcc_error("internal compiler error file at %s:%d", __FILE__, __LINE__);\ +} while (0) /******************************************************/ - static unsigned long func_sub_sp_offset; static int func_ret_sub; - static BOOL C67_invert_test; static int C67_compare_reg; @@ -182,11 +179,11 @@ static int C67_compare_reg; FILE *f = NULL; #endif - void C67_g(int c) { int ind1; - + if (nocode_wanted) + return; #ifdef ASSEMBLY_LISTING_C67 fprintf(f, " %08X", c); #endif @@ -236,14 +233,14 @@ void gsym(int t) // these are regs that tcc doesn't really know about, // but assign them unique values so the mapping routines -// can distinquish them +// can distinguish them #define C67_A0 105 #define C67_SP 106 #define C67_B3 107 #define C67_FP 108 #define C67_B2 109 -#define C67_CREG_ZERO -1 // Special code for no condition reg test +#define C67_CREG_ZERO -1 /* Special code for no condition reg test */ int ConvertRegToRegClass(int r) @@ -1552,23 +1549,23 @@ void C67_SHR(int r, int v) void load(int r, SValue * sv) { int v, t, ft, fc, fr, size = 0, element; - BOOL Unsigned = false; + BOOL Unsigned = FALSE; SValue v1; fr = sv->r; ft = sv->type.t; - fc = sv->c.ul; + fc = sv->c.i; v = fr & VT_VALMASK; if (fr & VT_LVAL) { if (v == VT_LLOCAL) { v1.type.t = VT_INT; v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; + v1.c.i = fc; load(r, &v1); fr = r; } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - error("long double not supported"); + tcc_error("long double not supported"); } else if ((ft & VT_TYPE) == VT_BYTE) { size = 1; } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { @@ -1716,13 +1713,13 @@ void store(int r, SValue * v) int fr, bt, ft, fc, size, t, element; ft = v->type.t; - fc = v->c.ul; + fc = v->c.i; fr = v->r & VT_VALMASK; bt = ft & VT_BTYPE; /* XXX: incorrect if float reg to reg */ if (bt == VT_LDOUBLE) { - error("long double not supported"); + tcc_error("long double not supported"); } else { if (bt == VT_SHORT) size = 2; @@ -1869,6 +1866,13 @@ static void gcall_or_jmp(int is_jmp) } } +/* Return the number of registers needed to return the struct, or 0 if + returning via struct pointer. */ +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) { + *ret_align = 1; // Never have to re-align return values for x86-64 + return 0; +} + /* generate function call with address in (vtop->t, vtop->c) and free function context. Stack entry is popped */ void gfunc_call(int nb_args) @@ -1877,24 +1881,22 @@ void gfunc_call(int nb_args) int args_sizes[NoCallArgsPassedOnStack]; if (nb_args > NoCallArgsPassedOnStack) { - error("more than 10 function params not currently supported"); + tcc_error("more than 10 function params not currently supported"); // handle more than 10, put some on the stack } for (i = 0; i < nb_args; i++) { if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { ALWAYS_ASSERT(FALSE); - } else if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { - ALWAYS_ASSERT(FALSE); } else { /* simple type (currently always same size) */ /* XXX: implicit cast ? */ if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - error("long long not supported"); + tcc_error("long long not supported"); } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - error("long double not supported"); + tcc_error("long double not supported"); } else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { size = 8; } else { @@ -1949,11 +1951,12 @@ void gfunc_prolog(CType * func_type) CType *type; sym = func_type->ref; - func_call = sym->r; + func_call = sym->f.func_call; addr = 8; /* if the function returns a structure, then add an implicit pointer parameter */ func_vt = sym->type; + func_var = (sym->f.func_type == FUNC_ELLIPSIS); if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { func_vc = addr; addr += 4; @@ -2036,6 +2039,8 @@ void gfunc_epilog(void) int gjmp(int t) { int ind1 = ind; + if (nocode_wanted) + return t; C67_MVKL(C67_A0, t); //r=reg to load, constant C67_MVKH(C67_A0, t); //r=reg to load, constant @@ -2068,7 +2073,9 @@ int gtst(int inv, int t) int v, *p; v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { + if (nocode_wanted) { + ; + } else if (v == VT_CMP) { /* fast case : can jump directly since flags are set */ // C67 uses B2 sort of as flags register ind1 = ind; @@ -2090,13 +2097,12 @@ int gtst(int inv, int t) /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ - p = &vtop->c.i; // I guess the idea is to traverse to the // null at the end of the list and store t // there - n = *p; + n = vtop->c.i; while (n != 0) { p = (int *) (cur_text_section->data + n); @@ -2112,37 +2118,6 @@ int gtst(int inv, int t) t = gjmp(t); gsym(vtop->c.i); } - } else { - if (is_float(vtop->type.t)) { - vpushi(0); - gen_op(TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - } else { - // I think we need to get the value on the stack - // into a register, test it, and generate a branch - // return the address of the branch, so it can be - // later patched - - v = gv(RC_INT); // get value into a reg - ind1 = ind; - C67_MVKL(C67_A0, t); //r=reg to load, constant - C67_MVKH(C67_A0, t); //r=reg to load, constant - - if (v != TREG_EAX && // check if not already in a conditional test reg - v != TREG_EDX && v != TREG_ST0 && v != C67_B2) { - C67_MV(v, C67_B2); - v = C67_B2; - } - - C67_IREG_B_REG(inv, v, C67_A0); // [!R] B.S2x A0 - C67_NOP(5); - t = ind1; //return where we need to patch - ind1 = ind; - } } vtop--; return t; @@ -2178,34 +2153,34 @@ void gen_opi(int op) if (op == TOK_LT) { C67_CMPLT(r, fr, C67_B2); - C67_invert_test = false; + C67_invert_test = FALSE; } else if (op == TOK_GE) { C67_CMPLT(r, fr, C67_B2); - C67_invert_test = true; + C67_invert_test = TRUE; } else if (op == TOK_GT) { C67_CMPGT(r, fr, C67_B2); - C67_invert_test = false; + C67_invert_test = FALSE; } else if (op == TOK_LE) { C67_CMPGT(r, fr, C67_B2); - C67_invert_test = true; + C67_invert_test = TRUE; } else if (op == TOK_EQ) { C67_CMPEQ(r, fr, C67_B2); - C67_invert_test = false; + C67_invert_test = FALSE; } else if (op == TOK_NE) { C67_CMPEQ(r, fr, C67_B2); - C67_invert_test = true; + C67_invert_test = TRUE; } else if (op == TOK_ULT) { C67_CMPLTU(r, fr, C67_B2); - C67_invert_test = false; + C67_invert_test = FALSE; } else if (op == TOK_UGE) { C67_CMPLTU(r, fr, C67_B2); - C67_invert_test = true; + C67_invert_test = TRUE; } else if (op == TOK_UGT) { C67_CMPGTU(r, fr, C67_B2); - C67_invert_test = false; + C67_invert_test = FALSE; } else if (op == TOK_ULE) { C67_CMPGTU(r, fr, C67_B2); - C67_invert_test = true; + C67_invert_test = TRUE; } else if (op == '+') C67_ADD(fr, r); // ADD r,fr,r else if (op == '-') @@ -2250,7 +2225,7 @@ void gen_opi(int op) r = vtop[-1].r; fr = vtop[0].r; vtop--; - C67_MPYI(fr, r); // 32 bit bultiply fr,r,fr + C67_MPYI(fr, r); // 32 bit multiply fr,r,fr C67_NOP(8); // NOP 8 for worst case break; case TOK_SHL: @@ -2307,7 +2282,7 @@ void gen_opi(int op) } /* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ + two operands are guaranteed to have the same floating point type */ /* XXX: need to use ST1 too */ void gen_opf(int op) { @@ -2319,13 +2294,13 @@ void gen_opf(int op) gv2(RC_FLOAT, RC_FLOAT); // make sure src2 is on b side ft = vtop->type.t; - fc = vtop->c.ul; + fc = vtop->c.i; r = vtop->r; fr = vtop[-1].r; if ((ft & VT_BTYPE) == VT_LDOUBLE) - error("long doubles not supported"); + tcc_error("long doubles not supported"); if (op >= TOK_ULT && op <= TOK_GT) { @@ -2340,42 +2315,42 @@ void gen_opf(int op) else C67_CMPLTSP(r, fr, C67_B2); - C67_invert_test = false; + C67_invert_test = FALSE; } else if (op == TOK_GE) { if ((ft & VT_BTYPE) == VT_DOUBLE) C67_CMPLTDP(r, fr, C67_B2); else C67_CMPLTSP(r, fr, C67_B2); - C67_invert_test = true; + C67_invert_test = TRUE; } else if (op == TOK_GT) { if ((ft & VT_BTYPE) == VT_DOUBLE) C67_CMPGTDP(r, fr, C67_B2); else C67_CMPGTSP(r, fr, C67_B2); - C67_invert_test = false; + C67_invert_test = FALSE; } else if (op == TOK_LE) { if ((ft & VT_BTYPE) == VT_DOUBLE) C67_CMPGTDP(r, fr, C67_B2); else C67_CMPGTSP(r, fr, C67_B2); - C67_invert_test = true; + C67_invert_test = TRUE; } else if (op == TOK_EQ) { if ((ft & VT_BTYPE) == VT_DOUBLE) C67_CMPEQDP(r, fr, C67_B2); else C67_CMPEQSP(r, fr, C67_B2); - C67_invert_test = false; + C67_invert_test = FALSE; } else if (op == TOK_NE) { if ((ft & VT_BTYPE) == VT_DOUBLE) C67_CMPEQDP(r, fr, C67_B2); else C67_CMPEQSP(r, fr, C67_B2); - C67_invert_test = true; + C67_invert_test = TRUE; } else { ALWAYS_ASSERT(FALSE); } @@ -2477,7 +2452,7 @@ void gen_cvt_ftoi(int t) r = vtop->r; if (t != VT_INT) - error("long long not supported"); + tcc_error("long long not supported"); else { if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { C67_DPTRUNC(r, r); @@ -2544,5 +2519,22 @@ void ggoto(void) vtop--; } -/* end of X86 code generator */ +/* Save the stack pointer onto the stack and return the location of its address */ +ST_FUNC void gen_vla_sp_save(int addr) { + tcc_error("variable length arrays unsupported for this target"); +} + +/* Restore the SP from a location on the stack */ +ST_FUNC void gen_vla_sp_restore(int addr) { + tcc_error("variable length arrays unsupported for this target"); +} + +/* Subtract from the stack pointer, and push the resulting value onto the stack */ +ST_FUNC void gen_vla_alloc(CType *type, int align) { + tcc_error("variable length arrays unsupported for this target"); +} + +/* end of C67 code generator */ +/*************************************************************/ +#endif /*************************************************************/ diff --git a/tinyc/c67-link.c b/tinyc/c67-link.c new file mode 100644 index 000000000..de72e442f --- /dev/null +++ b/tinyc/c67-link.c @@ -0,0 +1,131 @@ +#ifdef TARGET_DEFS_ONLY + +#define EM_TCC_TARGET EM_C60 + +/* relocation type for 32 bit data relocation */ +#define R_DATA_32 R_C60_32 +#define R_DATA_PTR R_C60_32 +#define R_JMP_SLOT R_C60_JMP_SLOT +#define R_GLOB_DAT R_C60_GLOB_DAT +#define R_COPY R_C60_COPY +#define R_RELATIVE R_C60_RELATIVE + +#define R_NUM R_C60_NUM + +#define ELF_START_ADDR 0x00000400 +#define ELF_PAGE_SIZE 0x1000 + +#define PCRELATIVE_DLLPLT 0 +#define RELOCATE_DLLPLT 0 + +#else /* !TARGET_DEFS_ONLY */ + +#include "tcc.h" + +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_C60_32: + case R_C60LO16: + case R_C60HI16: + case R_C60_GOT32: + case R_C60_GOTOFF: + case R_C60_GOTPC: + case R_C60_COPY: + return 0; + + case R_C60_PLT32: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe whether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_C60_32: + case R_C60LO16: + case R_C60HI16: + case R_C60_COPY: + return NO_GOTPLT_ENTRY; + + case R_C60_GOTOFF: + case R_C60_GOTPC: + return BUILD_GOT_ONLY; + + case R_C60_PLT32: + case R_C60_GOT32: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) +{ + tcc_error("C67 got not implemented"); + return 0; +} + +/* relocate the PLT: compute addresses and offsets in the PLT now that final + address for PLT and GOT are known (see fill_program_header) */ +ST_FUNC void relocate_plt(TCCState *s1) +{ + uint8_t *p, *p_end; + + if (!s1->plt) + return; + + p = s1->plt->data; + p_end = p + s1->plt->data_offset; + + if (p < p_end) { + /* XXX: TODO */ + while (p < p_end) { + /* XXX: TODO */ + } + } +} + +void relocate_init(Section *sr) {} + +void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) +{ + switch(type) { + case R_C60_32: + *(int *)ptr += val; + break; + case R_C60LO16: + { + uint32_t orig; + + /* put the low 16 bits of the absolute address add to what is + already there */ + orig = ((*(int *)(ptr )) >> 7) & 0xffff; + orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16; + + /* patch both at once - assumes always in pairs Low - High */ + *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | + (((val+orig) & 0xffff) << 7); + *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | + ((((val+orig)>>16) & 0xffff) << 7); + } + break; + case R_C60HI16: + break; + default: + fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n", + type, (unsigned) addr, ptr, (unsigned) val); + break; + } +} + +#endif /* !TARGET_DEFS_ONLY */ diff --git a/tinyc/coff.h b/tinyc/coff.h index 38960b40f..e8e6185a6 100644 --- a/tinyc/coff.h +++ b/tinyc/coff.h @@ -22,7 +22,7 @@ struct filehdr { /*------------------------------------------------------------------------*/ #define F_RELFLG 0x01 /* relocation info stripped from file */ #define F_EXEC 0x02 /* file is executable (no unresolved refs) */ -#define F_LNNO 0x04 /* line nunbers stripped from file */ +#define F_LNNO 0x04 /* line numbers stripped from file */ #define F_LSYMS 0x08 /* local symbols stripped from file */ #define F_GSP10 0x10 /* 34010 version */ #define F_GSP20 0x20 /* 34020 version */ @@ -37,8 +37,8 @@ struct filehdr { #define F_BYTE_ORDER (F_LITTLE | F_BIG) #define FILHDR struct filehdr -//#define FILHSZ sizeof(FILHDR) -#define FILHSZ 22 // above rounds to align on 4 bytes which causes problems +/* #define FILHSZ sizeof(FILHDR) */ +#define FILHSZ 22 /* above rounds to align on 4 bytes which causes problems */ #define COFF_C67_MAGIC 0x00c2 @@ -150,7 +150,7 @@ struct scnhdr { /*------------------------------------------------------------------------*/ /* Define constants for names of "special" sections */ /*------------------------------------------------------------------------*/ -//#define _TEXT ".text" +/* #define _TEXT ".text" */ #define _DATA ".data" #define _BSS ".bss" #define _CINIT ".cinit" diff --git a/tinyc/config.h b/tinyc/config.h index 161a3e178..a27c7484a 100644 --- a/tinyc/config.h +++ b/tinyc/config.h @@ -1,6 +1,6 @@ /* Modified to not rely on a configure script: */ #define CONFIG_SYSROOT "" -#define TCC_VERSION "0.9.25" +#define TCC_VERSION "0.9.27" #if defined(WIN32) || defined(_WIN32) # define TCC_TARGET_PE 1 diff --git a/tinyc/config.mak b/tinyc/config.mak deleted file mode 100644 index 1722d20b3..000000000 --- a/tinyc/config.mak +++ /dev/null @@ -1,20 +0,0 @@ -# Automatically generated by configure - do not modify -prefix=/usr/local -bindir=/usr/local/bin -tccdir=/usr/local/lib/tcc -libdir=/usr/local/lib -includedir=/usr/local/include -mandir=/usr/local/man -docdir=/usr/local/share/doc/tcc -CC=gcc -GCC_MAJOR=4 -HOST_CC=gcc -AR=ar -STRIP=strip -s -R .comment -R .note -CFLAGS=-O2 -LDFLAGS= -LIBSUF=.a -EXESUF= -ARCH=x86-64 -VERSION=0.9.25 -SRC_PATH=/home/andreas/nimrod/tinyc diff --git a/tinyc/config.texi b/tinyc/config.texi deleted file mode 100644 index 2d90df0ee..000000000 --- a/tinyc/config.texi +++ /dev/null @@ -1 +0,0 @@ -@set VERSION 0.9.25 diff --git a/tinyc/config_edited.h b/tinyc/config_edited.h deleted file mode 100644 index edaf335bb..000000000 --- a/tinyc/config_edited.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Modified to not rely on a configure script: */ -#define CONFIG_SYSROOT "" -#define TCC_VERSION "0.9.25" - -#if defined(WIN32) || defined(_WIN32) -# define TCC_TARGET_PE 1 -# define TCC_TARGET_I386 -# define CONFIG_TCCDIR "." -#elif defined(__i386__) -# define TCC_TARGET_I386 -# define CONFIG_TCCDIR "/usr/local/lib/tcc" -# define GCC_MAJOR 4 -# define HOST_I386 1 -#else -# define TCC_TARGET_X86_64 -# define CONFIG_TCCDIR "/usr/local/lib/tcc" -# define GCC_MAJOR 4 -# define HOST_X86_64 1 -#endif - diff --git a/tinyc/conftest.c b/tinyc/conftest.c new file mode 100644 index 000000000..2824cc89d --- /dev/null +++ b/tinyc/conftest.c @@ -0,0 +1,87 @@ +#include <stdio.h> + +/* Define architecture */ +#if defined(__i386__) || defined _M_IX86 +# define TRIPLET_ARCH "i386" +#elif defined(__x86_64__) || defined _M_AMD64 +# define TRIPLET_ARCH "x86_64" +#elif defined(__arm__) +# define TRIPLET_ARCH "arm" +#elif defined(__aarch64__) +# define TRIPLET_ARCH "aarch64" +#else +# define TRIPLET_ARCH "unknown" +#endif + +/* Define OS */ +#if defined (__linux__) +# define TRIPLET_OS "linux" +#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) +# define TRIPLET_OS "kfreebsd" +#elif defined _WIN32 +# define TRIPLET_OS "win32" +#elif !defined (__GNU__) +# define TRIPLET_OS "unknown" +#endif + +/* Define calling convention and ABI */ +#if defined (__ARM_EABI__) +# if defined (__ARM_PCS_VFP) +# define TRIPLET_ABI "gnueabihf" +# else +# define TRIPLET_ABI "gnueabi" +# endif +#else +# define TRIPLET_ABI "gnu" +#endif + +#if defined _WIN32 +# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS +#elif defined __GNU__ +# define TRIPLET TRIPLET_ARCH "-" TRIPLET_ABI +#else +# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS "-" TRIPLET_ABI +#endif + +#if defined(_WIN32) +int _CRT_glob = 0; +#endif + +int main(int argc, char *argv[]) +{ + switch(argc == 2 ? argv[1][0] : 0) { + case 'b': + { + volatile unsigned foo = 0x01234567; + puts(*(unsigned char*)&foo == 0x67 ? "no" : "yes"); + break; + } +#ifdef __GNUC__ + case 'm': + printf("%d\n", __GNUC_MINOR__); + break; + case 'v': + printf("%d\n", __GNUC__); + break; +#elif defined __TINYC__ + case 'v': + puts("0"); + break; + case 'm': + printf("%d\n", __TINYC__); + break; +#else + case 'm': + case 'v': + puts("0"); + break; +#endif + case 't': + puts(TRIPLET); + break; + + default: + break; + } + return 0; +} diff --git a/tinyc/elf.h b/tinyc/elf.h index 82fd7ed91..9fed6eb73 100644 --- a/tinyc/elf.h +++ b/tinyc/elf.h @@ -1,25 +1,23 @@ /* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1995-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ian Lance Taylor <ian@cygnus.com>. The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _ELF_H -#define _ELF_H 1 +#define _ELF_H 1 #ifndef _WIN32 #include <inttypes.h> @@ -30,13 +28,12 @@ typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; typedef long long int int64_t; -#endif - typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned long long int uint64_t; #endif +#endif /* Standard ELF types. */ @@ -46,15 +43,15 @@ typedef uint16_t Elf64_Half; /* Types for signed and unsigned 32-bit quantities. */ typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; +typedef int32_t Elf32_Sword; typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; +typedef int32_t Elf64_Sword; /* Types for signed and unsigned 64-bit quantities. */ typedef uint64_t Elf32_Xword; -typedef int64_t Elf32_Sxword; +typedef int64_t Elf32_Sxword; typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; +typedef int64_t Elf64_Sxword; /* Type of addresses. */ typedef uint32_t Elf32_Addr; @@ -68,9 +65,9 @@ typedef uint64_t Elf64_Off; typedef uint16_t Elf32_Section; typedef uint16_t Elf64_Section; -/* Type of symbol indices. */ -typedef uint32_t Elf32_Symndx; -typedef uint64_t Elf64_Symndx; +/* Type for version symbol information. */ +typedef Elf32_Half Elf32_Versym; +typedef Elf64_Half Elf64_Versym; /* The ELF file header. This appears at the start of every ELF file. */ @@ -79,290 +76,337 @@ typedef uint64_t Elf64_Symndx; typedef struct { - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ } Elf32_Ehdr; typedef struct { - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf64_Half e_type; /* Object file type */ - Elf64_Half e_machine; /* Architecture */ - Elf64_Word e_version; /* Object file version */ - Elf64_Addr e_entry; /* Entry point virtual address */ - Elf64_Off e_phoff; /* Program header table file offset */ - Elf64_Off e_shoff; /* Section header table file offset */ - Elf64_Word e_flags; /* Processor-specific flags */ - Elf64_Half e_ehsize; /* ELF header size in bytes */ - Elf64_Half e_phentsize; /* Program header table entry size */ - Elf64_Half e_phnum; /* Program header table entry count */ - Elf64_Half e_shentsize; /* Section header table entry size */ - Elf64_Half e_shnum; /* Section header table entry count */ - Elf64_Half e_shstrndx; /* Section header string table index */ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ } Elf64_Ehdr; /* Fields in the e_ident array. The EI_* macros are indices into the array. The macros under each EI_* macro are the values the byte may have. */ -#define EI_MAG0 0 /* File identification byte 0 index */ -#define ELFMAG0 0x7f /* Magic number byte 0 */ +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ -#define EI_MAG1 1 /* File identification byte 1 index */ -#define ELFMAG1 'E' /* Magic number byte 1 */ +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ -#define EI_MAG2 2 /* File identification byte 2 index */ -#define ELFMAG2 'L' /* Magic number byte 2 */ +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ -#define EI_MAG3 3 /* File identification byte 3 index */ -#define ELFMAG3 'F' /* Magic number byte 3 */ +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ /* Conglomeration of the identification bytes, for easy testing as a word. */ -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASSNONE 0 /* Invalid class */ -#define ELFCLASS32 1 /* 32-bit objects */ -#define ELFCLASS64 2 /* 64-bit objects */ -#define ELFCLASSNUM 3 - -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATANONE 0 /* Invalid data encoding */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ELFDATA2MSB 2 /* 2's complement, big endian */ -#define ELFDATANUM 3 - -#define EI_VERSION 6 /* File version byte index */ - /* Value must be EV_CURRENT */ - -#define EI_OSABI 7 /* OS ABI identification */ -#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ -#define ELFOSABI_HPUX 1 /* HP-UX */ -#define ELFOSABI_FREEBSD 9 /* Free BSD */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -#define EI_ABIVERSION 8 /* ABI version */ - -#define EI_PAD 9 /* Byte index of padding bytes */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_SYSV 0 /* Alias. */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD. */ +#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ +#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +#define ELFOSABI_AIX 7 /* IBM AIX. */ +#define ELFOSABI_IRIX 8 /* SGI Irix. */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ /* Legal values for e_type (object file type). */ -#define ET_NONE 0 /* No file type */ -#define ET_REL 1 /* Relocatable file */ -#define ET_EXEC 2 /* Executable file */ -#define ET_DYN 3 /* Shared object file */ -#define ET_CORE 4 /* Core file */ -#define ET_NUM 5 /* Number of defined types */ -#define ET_LOPROC 0xff00 /* Processor-specific */ -#define ET_HIPROC 0xffff /* Processor-specific */ +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOOS 0xfe00 /* OS-specific range start */ +#define ET_HIOS 0xfeff /* OS-specific range end */ +#define ET_LOPROC 0xff00 /* Processor-specific range start */ +#define ET_HIPROC 0xffff /* Processor-specific range end */ /* Legal values for e_machine (architecture). */ -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 /* AT&T WE 32100 */ -#define EM_SPARC 2 /* SUN SPARC */ -#define EM_386 3 /* Intel 80386 */ -#define EM_68K 4 /* Motorola m68k family */ -#define EM_88K 5 /* Motorola m88k family */ -#define EM_486 6 /* Intel 80486 */ -#define EM_860 7 /* Intel 80860 */ -#define EM_MIPS 8 /* MIPS R3000 big-endian */ -#define EM_S370 9 /* Amdahl */ -#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ -#define EM_RS6000 11 /* RS6000 */ - -#define EM_PARISC 15 /* HPPA */ -#define EM_nCUBE 16 /* nCUBE */ -#define EM_VPP500 17 /* Fujitsu VPP500 */ -#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -#define EM_960 19 /* Intel 80960 */ -#define EM_PPC 20 /* PowerPC */ - -#define EM_V800 36 /* NEC V800 series */ -#define EM_FR20 37 /* Fujitsu FR20 */ -#define EM_RH32 38 /* TRW RH32 */ -#define EM_RCE 39 /* Motorola RCE */ -#define EM_ARM 40 /* ARM */ -#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -#define EM_SH 42 /* Hitachi SH */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -#define EM_TRICORE 44 /* Siemens Tricore */ -#define EM_ARC 45 /* Argonaut RISC Core */ -#define EM_H8_300 46 /* Hitachi H8/300 */ -#define EM_H8_300H 47 /* Hitachi H8/300H */ -#define EM_H8S 48 /* Hitachi H8S */ -#define EM_H8_500 49 /* Hitachi H8/500 */ -#define EM_IA_64 50 /* Intel Merced */ -#define EM_MIPS_X 51 /* Stanford MIPS-X */ -#define EM_COLDFIRE 52 /* Motorola Coldfire */ -#define EM_68HC12 53 /* Motorola M68HC12 */ -#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -#define EM_PCP 55 /* Siemens PCP */ -#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -#define EM_STARCORE 58 /* Motorola Start*Core processor */ -#define EM_ME16 59 /* Toyota ME16 processor */ -#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -#define EM_X86_64 62 /* AMD x86-64 architecture */ -#define EM_PDSP 63 /* Sony DSP Processor */ -#define EM_FX66 66 /* Siemens FX66 microcontroller */ -#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -#define EM_SVX 73 /* Silicon Graphics SVx */ -#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -#define EM_VAX 75 /* Digital VAX */ -#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -#define EM_HUANY 81 /* Harvard University machine-independent object files */ -#define EM_PRISM 82 /* SiTera Prism */ -#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -#define EM_FR30 84 /* Fujitsu FR30 */ -#define EM_D10V 85 /* Mitsubishi D10V */ -#define EM_D30V 86 /* Mitsubishi D30V */ -#define EM_V850 87 /* NEC v850 */ -#define EM_M32R 88 /* Mitsubishi M32R */ -#define EM_MN10300 89 /* Matsushita MN10300 */ -#define EM_MN10200 90 /* Matsushita MN10200 */ -#define EM_PJ 91 /* picoJava */ -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -#define EM_NUM 95 +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embedded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ + +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STMicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_AARCH64 183 /* ARM AARCH64 */ +#define EM_TILEPRO 188 /* Tilera TILEPro */ +#define EM_TILEGX 191 /* Tilera TILE-Gx */ +#define EM_NUM 192 /* If it is necessary to assign new unofficial EM_* values, please pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision with official or non-GNU unofficial values. */ -#define EM_ALPHA 0x9026 -#define EM_C60 0x9c60 +#define EM_ALPHA 0x9026 +#define EM_C60 0x9c60 /* Legal values for e_version (version). */ -#define EV_NONE 0 /* Invalid ELF version */ -#define EV_CURRENT 1 /* Current version */ -#define EV_NUM 2 +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 /* Section header. */ typedef struct { - Elf32_Word sh_name; /* Section name (string tbl index) */ - Elf32_Word sh_type; /* Section type */ - Elf32_Word sh_flags; /* Section flags */ - Elf32_Addr sh_addr; /* Section virtual addr at execution */ - Elf32_Off sh_offset; /* Section file offset */ - Elf32_Word sh_size; /* Section size in bytes */ - Elf32_Word sh_link; /* Link to another section */ - Elf32_Word sh_info; /* Additional section information */ - Elf32_Word sh_addralign; /* Section alignment */ - Elf32_Word sh_entsize; /* Entry size if section holds table */ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ } Elf32_Shdr; typedef struct { - Elf64_Word sh_name; /* Section name (string tbl index) */ - Elf64_Word sh_type; /* Section type */ - Elf64_Xword sh_flags; /* Section flags */ - Elf64_Addr sh_addr; /* Section virtual addr at execution */ - Elf64_Off sh_offset; /* Section file offset */ - Elf64_Xword sh_size; /* Section size in bytes */ - Elf64_Word sh_link; /* Link to another section */ - Elf64_Word sh_info; /* Additional section information */ - Elf64_Xword sh_addralign; /* Section alignment */ - Elf64_Xword sh_entsize; /* Entry size if section holds table */ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ } Elf64_Shdr; /* Special section indices. */ -#define SHN_UNDEF 0 /* Undefined section */ -#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -#define SHN_HIPROC 0xff1f /* End of processor-specific */ -#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -#define SHN_HIRESERVE 0xffff /* End of reserved indices */ +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_BEFORE 0xff00 /* Order section before all others + (Solaris). */ +#define SHN_AFTER 0xff01 /* Order section after all others + (Solaris). */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_LOOS 0xff20 /* Start of OS-specific */ +#define SHN_HIOS 0xff3f /* End of OS-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_XINDEX 0xffff /* Index is in extra table. */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ /* Legal values for sh_type (section type). */ -#define SHT_NULL 0 /* Section header table entry unused */ -#define SHT_PROGBITS 1 /* Program data */ -#define SHT_SYMTAB 2 /* Symbol table */ -#define SHT_STRTAB 3 /* String table */ -#define SHT_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* Symbol hash table */ -#define SHT_DYNAMIC 6 /* Dynamic linking information */ -#define SHT_NOTE 7 /* Notes */ -#define SHT_NOBITS 8 /* Program space with no data (bss) */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -#define SHT_NUM 12 /* Number of defined types. */ -#define SHT_LOOS 0x60000000 /* Start OS-specific */ -#define SHT_LOSUNW 0x6ffffffb /* Sun-specific low bound. */ -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table */ -#define SHT_ARM_PREEMPTMAP 0x70000002 /* dynamic linking pre-emption map */ -#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attrs */ -#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -#define SHT_HIUSER 0x8fffffff /* End of application-specific */ +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */ +#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific. */ +#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ +#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ +#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ /* Legal values for sh_flags (section flags). */ -#define SHF_WRITE (1 << 0) /* Writable */ -#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -#define SHF_EXECINSTR (1 << 2) /* Executable */ -#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling + required */ +#define SHF_GROUP (1 << 9) /* Section is member of a group. */ +#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_ORDERED (1 << 30) /* Special ordering requirement + (Solaris). */ +#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless + referenced or allocated (Solaris).*/ + +/* Section group handling. */ +#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ /* Symbol table entry. */ typedef struct { - Elf32_Word st_name; /* Symbol name (string tbl index) */ - Elf32_Addr st_value; /* Symbol value */ - Elf32_Word st_size; /* Symbol size */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* No defined meaning, 0 */ - Elf32_Section st_shndx; /* Section index */ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf32_Section st_shndx; /* Section index */ } Elf32_Sym; typedef struct { - Elf64_Word st_name; /* Symbol name (string tbl index) */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* No defined meaning, 0 */ - Elf64_Section st_shndx; /* Section index */ - Elf64_Addr st_value; /* Symbol value */ - Elf64_Xword st_size; /* Symbol size */ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ } Elf64_Sym; /* The syminfo section if available contains additional information about @@ -370,100 +414,100 @@ typedef struct typedef struct { - Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ - Elf32_Half si_flags; /* Per symbol flags */ + Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf32_Half si_flags; /* Per symbol flags */ } Elf32_Syminfo; typedef struct { - Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ - Elf64_Half si_flags; /* Per symbol flags */ + Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf64_Half si_flags; /* Per symbol flags */ } Elf64_Syminfo; /* Possible values for si_boundto. */ -#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ +#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ /* Possible bitmasks for si_flags. */ -#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy - loaded */ +#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy + loaded */ /* Syminfo version values. */ -#define SYMINFO_NONE 0 -#define SYMINFO_CURRENT 1 -#define SYMINFO_NUM 2 - +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 -/* Special section index. */ - -#define SHN_UNDEF 0 /* No section, undefined symbol. */ /* How to extract and insert information held in the st_info field. */ -#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -#define ELF32_ST_TYPE(val) ((val) & 0xf) -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) /* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) /* Legal values for ST_BIND subfield of st_info (symbol binding). */ -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* Weak symbol */ -#define STB_NUM 3 /* Number of defined types. */ -#define STB_LOOS 10 /* Start of OS-specific */ -#define STB_HIOS 12 /* End of OS-specific */ -#define STB_LOPROC 13 /* Start of processor-specific */ -#define STB_HIPROC 15 /* End of processor-specific */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_GNU_UNIQUE 10 /* Unique symbol. */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ /* Legal values for ST_TYPE subfield of st_info (symbol type). */ -#define STT_NOTYPE 0 /* Symbol type is unspecified */ -#define STT_OBJECT 1 /* Symbol is a data object */ -#define STT_FUNC 2 /* Symbol is a code object */ -#define STT_SECTION 3 /* Symbol associated with a section */ -#define STT_FILE 4 /* Symbol's name is file name */ -#define STT_NUM 5 /* Number of defined types. */ -#define STT_LOOS 11 /* Start of OS-specific */ -#define STT_HIOS 12 /* End of OS-specific */ -#define STT_LOPROC 13 /* Start of processor-specific */ -#define STT_HIPROC 15 /* End of processor-specific */ +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object*/ +#define STT_NUM 7 /* Number of defined types. */ +#define STT_LOOS 10 /* Start of OS-specific */ +#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ /* Symbol table indices are found in the hash buckets and chain table of a symbol hash table section. This special index value indicates the end of a chain, meaning no further symbols are found in that bucket. */ -#define STN_UNDEF 0 /* End of a chain. */ +#define STN_UNDEF 0 /* End of a chain. */ /* How to extract and insert information held in the st_other field. */ -#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) +#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) /* For ELF64 the definitions are the same. */ -#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) +#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) /* Symbol visibility specification encoded in the st_other field. */ -#define STV_DEFAULT 0 /* Default symbol visibility rules */ -#define STV_INTERNAL 1 /* Processor specific hidden class */ -#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -#define STV_PROTECTED 3 /* Not preemptible, not exported */ +#define STV_DEFAULT 0 /* Default symbol visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ /* Relocation table entry without addend (in section of type SHT_REL). */ typedef struct { - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ } Elf32_Rel; /* I have seen two different definitions of the Elf64_Rel and @@ -473,266 +517,374 @@ typedef struct typedef struct { - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ } Elf64_Rel; /* Relocation table entry with addend (in section of type SHT_RELA). */ typedef struct { - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ - Elf32_Sword r_addend; /* Addend */ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ } Elf32_Rela; typedef struct { - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ - Elf64_Sxword r_addend; /* Addend */ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ } Elf64_Rela; /* How to extract and insert information held in the r_info field. */ -#define ELF32_R_SYM(val) ((val) >> 8) -#define ELF32_R_TYPE(val) ((val) & 0xff) -#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) -#define ELF64_R_SYM(i) ((i) >> 32) -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -#define ELF64_R_INFO(sym,type) ((((Elf64_Xword)(sym)) << 32) + (type)) +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) /* Program segment header. */ typedef struct { - Elf32_Word p_type; /* Segment type */ - Elf32_Off p_offset; /* Segment file offset */ - Elf32_Addr p_vaddr; /* Segment virtual address */ - Elf32_Addr p_paddr; /* Segment physical address */ - Elf32_Word p_filesz; /* Segment size in file */ - Elf32_Word p_memsz; /* Segment size in memory */ - Elf32_Word p_flags; /* Segment flags */ - Elf32_Word p_align; /* Segment alignment */ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr; typedef struct { - Elf64_Word p_type; /* Segment type */ - Elf64_Word p_flags; /* Segment flags */ - Elf64_Off p_offset; /* Segment file offset */ - Elf64_Addr p_vaddr; /* Segment virtual address */ - Elf64_Addr p_paddr; /* Segment physical address */ - Elf64_Xword p_filesz; /* Segment size in file */ - Elf64_Xword p_memsz; /* Segment size in memory */ - Elf64_Xword p_align; /* Segment alignment */ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ } Elf64_Phdr; +/* Special value for e_phnum. This indicates that the real number of + program headers is too large to fit into e_phnum. Instead the real + value is in the field sh_info of section 0. */ + +#define PN_XNUM 0xffff + /* Legal values for p_type (segment type). */ -#define PT_NULL 0 /* Program header table entry unused */ -#define PT_LOAD 1 /* Loadable program segment */ -#define PT_DYNAMIC 2 /* Dynamic linking information */ -#define PT_INTERP 3 /* Program interpreter */ -#define PT_NOTE 4 /* Auxiliary information */ -#define PT_SHLIB 5 /* Reserved */ -#define PT_PHDR 6 /* Entry for header table itself */ -#define PT_NUM 7 /* Number of defined types. */ -#define PT_LOOS 0x60000000 /* Start of OS-specific */ -#define PT_HIOS 0x6fffffff /* End of OS-specific */ -#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -#define PT_HIPROC 0x7fffffff /* End of processor-specific */ +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ /* Legal values for p_flags (segment flags). */ -#define PF_X (1 << 0) /* Segment is executable */ -#define PF_W (1 << 1) /* Segment is writable */ -#define PF_R (1 << 2) /* Segment is readable */ -#define PF_MASKPROC 0xf0000000 /* Processor-specific */ +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKOS 0x0ff00000 /* OS-specific */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ /* Legal values for note segment descriptor types for core files. */ -#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -#define NT_AUXV 6 /* Contains copy of auxv array */ -#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -#define NT_PRCRED 14 /* Contains copy of prcred struct */ -#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ - -/* Legal values for the note segment descriptor types for object files. */ - -#define NT_VERSION 1 /* Contains a version string. */ +#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ +#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +#define NT_AUXV 6 /* Contains copy of auxv array */ +#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +#define NT_ASRS 8 /* Contains copy of asrset struct */ +#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +#define NT_PRCRED 14 /* Contains copy of prcred struct */ +#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ +#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ +#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ +#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ +#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ +#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ +#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ +#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ +#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ +#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ +#define NT_S390_TIMER 0x301 /* s390 timer register */ +#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ +#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ +#define NT_S390_CTRS 0x304 /* s390 control registers */ +#define NT_S390_PREFIX 0x305 /* s390 prefix register */ +#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ +#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ +#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ +#define NT_ARM_TLS 0x401 /* ARM TLS register */ +#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ +#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ + +/* Legal values for the note segment descriptor types for object files. */ + +#define NT_VERSION 1 /* Contains a version string. */ /* Dynamic section entry. */ typedef struct { - Elf32_Sword d_tag; /* Dynamic entry type */ + Elf32_Sword d_tag; /* Dynamic entry type */ union { - Elf32_Word d_val; /* Integer value */ - Elf32_Addr d_ptr; /* Address value */ + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ } d_un; } Elf32_Dyn; typedef struct { - Elf64_Sxword d_tag; /* Dynamic entry type */ + Elf64_Sxword d_tag; /* Dynamic entry type */ union { - Elf64_Xword d_val; /* Integer value */ - Elf64_Addr d_ptr; /* Address value */ + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ } d_un; } Elf64_Dyn; /* Legal values for d_tag (dynamic entry type). */ -#define DT_NULL 0 /* Marks end of dynamic section */ -#define DT_NEEDED 1 /* Name of needed library */ -#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -#define DT_PLTGOT 3 /* Processor defined value */ -#define DT_HASH 4 /* Address of symbol hash table */ -#define DT_STRTAB 5 /* Address of string table */ -#define DT_SYMTAB 6 /* Address of symbol table */ -#define DT_RELA 7 /* Address of Rela relocs */ -#define DT_RELASZ 8 /* Total size of Rela relocs */ -#define DT_RELAENT 9 /* Size of one Rela reloc */ -#define DT_STRSZ 10 /* Size of string table */ -#define DT_SYMENT 11 /* Size of one symbol table entry */ -#define DT_INIT 12 /* Address of init function */ -#define DT_FINI 13 /* Address of termination function */ -#define DT_SONAME 14 /* Name of shared object */ -#define DT_RPATH 15 /* Library search path */ -#define DT_SYMBOLIC 16 /* Start symbol search here */ -#define DT_REL 17 /* Address of Rel relocs */ -#define DT_RELSZ 18 /* Total size of Rel relocs */ -#define DT_RELENT 19 /* Size of one Rel reloc */ -#define DT_PLTREL 20 /* Type of reloc in PLT */ -#define DT_DEBUG 21 /* For debugging; unspecified */ -#define DT_TEXTREL 22 /* Reloc might modify .text */ -#define DT_JMPREL 23 /* Address of PLT relocs */ -#define DT_BIND_NOW 24 /* Process relocations of object */ -#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -#define DT_NUM 29 /* Number used */ -#define DT_LOOS 0x60000000 /* Start of OS-specific */ -#define DT_HIOS 0x6fffffff /* End of OS-specific */ -#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ /* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's approach. */ -#define DT_VALRNGLO 0x6ffffd00 -#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting - the following DT_* entry. */ -#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -#define DT_VALRNGHI 0x6ffffdff +#define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff +#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +#define DT_VALNUM 12 /* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the Dyn.d_un.d_ptr field of the Elf*_Dyn structure. If any adjustment is made to the ELF object after it has been built these entries will need to be adjusted. */ -#define DT_ADDRRNGLO 0x6ffffe00 -#define DT_SYMINFO 0x6ffffeff /* syminfo table */ -#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ +#define DT_TLSDESC_PLT 0x6ffffef6 +#define DT_TLSDESC_GOT 0x6ffffef7 +#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +#define DT_MOVETAB 0x6ffffefe /* Move table. */ +#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +#define DT_ADDRNUM 11 /* The versioning entry types. The next are defined as part of the GNU extension. */ -#define DT_VERSYM 0x6ffffff0 +#define DT_VERSYM 0x6ffffff0 + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa /* These were chosen by Sun. */ -#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -#define DT_VERDEF 0x6ffffffc /* Address of version definition - table */ -#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -#define DT_VERNEED 0x6ffffffe /* Address of table with needed - versions */ -#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ #define DT_VERSIONTAGNUM 16 /* Sun added these machine-independent extensions in the "processor-specific" range. Be compatible. */ #define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ #define DT_FILTER 0x7fffffff /* Shared object to get values from */ -#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -#define DT_EXTRANUM 3 +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + +/* Values of `d_un.d_val' in the DT_FLAGS entry. */ +#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ +#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ /* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry in the dynamic section. */ -#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ +#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ +#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ +#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ +#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ +#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ +#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ +#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ +#define DF_1_NODIRECT 0x00020000 /* Object has no-direct binding. */ +#define DF_1_IGNMULDEF 0x00040000 +#define DF_1_NOKSYMS 0x00080000 +#define DF_1_NOHDR 0x00100000 +#define DF_1_EDITED 0x00200000 /* Object is modified after built. */ +#define DF_1_NORELOC 0x00400000 +#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */ +#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */ +#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */ + +/* Flags for the feature selection in DT_FEATURE_1. */ +#define DTF_1_PARINIT 0x00000001 +#define DTF_1_CONFEXP 0x00000002 + +/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ +#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ +#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not + generally available. */ /* Version definition sections. */ typedef struct { - Elf32_Half vd_version; /* Version revision */ - Elf32_Half vd_flags; /* Version information */ - Elf32_Half vd_ndx; /* Version Index */ - Elf32_Half vd_cnt; /* Number of associated aux entries */ - Elf32_Word vd_hash; /* Version name hash value */ - Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ - Elf32_Word vd_next; /* Offset in bytes to next verdef - entry */ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ } Elf32_Verdef; typedef struct { - Elf64_Half vd_version; /* Version revision */ - Elf64_Half vd_flags; /* Version information */ - Elf64_Half vd_ndx; /* Version Index */ - Elf64_Half vd_cnt; /* Number of associated aux entries */ - Elf64_Word vd_hash; /* Version name hash value */ - Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ - Elf64_Word vd_next; /* Offset in bytes to next verdef - entry */ + Elf64_Half vd_version; /* Version revision */ + Elf64_Half vd_flags; /* Version information */ + Elf64_Half vd_ndx; /* Version Index */ + Elf64_Half vd_cnt; /* Number of associated aux entries */ + Elf64_Word vd_hash; /* Version name hash value */ + Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf64_Word vd_next; /* Offset in bytes to next verdef + entry */ } Elf64_Verdef; /* Legal values for vd_version (version revision). */ -#define VER_DEF_NONE 0 /* No version */ -#define VER_DEF_CURRENT 1 /* Current version */ -#define VER_DEF_NUM 2 /* Given version number */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ /* Legal values for vd_flags (version information flags). */ -#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Versym symbol index values. */ +#define VER_NDX_LOCAL 0 /* Symbol is local. */ +#define VER_NDX_GLOBAL 1 /* Symbol is global. */ +#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ +#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ -/* Auxialiary version information. */ +/* Auxiliary version information. */ typedef struct { - Elf32_Word vda_name; /* Version or dependency names */ - Elf32_Word vda_next; /* Offset in bytes to next verdaux - entry */ + Elf32_Word vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ } Elf32_Verdaux; typedef struct { - Elf64_Word vda_name; /* Version or dependency names */ - Elf64_Word vda_next; /* Offset in bytes to next verdaux - entry */ + Elf64_Word vda_name; /* Version or dependency names */ + Elf64_Word vda_next; /* Offset in bytes to next verdaux + entry */ } Elf64_Verdaux; @@ -740,57 +892,57 @@ typedef struct typedef struct { - Elf32_Half vn_version; /* Version of structure */ - Elf32_Half vn_cnt; /* Number of associated aux entries */ - Elf32_Word vn_file; /* Offset of filename for this - dependency */ - Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ - Elf32_Word vn_next; /* Offset in bytes to next verneed - entry */ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Word vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ } Elf32_Verneed; typedef struct { - Elf64_Half vn_version; /* Version of structure */ - Elf64_Half vn_cnt; /* Number of associated aux entries */ - Elf64_Word vn_file; /* Offset of filename for this - dependency */ - Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ - Elf64_Word vn_next; /* Offset in bytes to next verneed - entry */ + Elf64_Half vn_version; /* Version of structure */ + Elf64_Half vn_cnt; /* Number of associated aux entries */ + Elf64_Word vn_file; /* Offset of filename for this + dependency */ + Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf64_Word vn_next; /* Offset in bytes to next verneed + entry */ } Elf64_Verneed; /* Legal values for vn_version (version revision). */ -#define VER_NEED_NONE 0 /* No version */ -#define VER_NEED_CURRENT 1 /* Current version */ -#define VER_NEED_NUM 2 /* Given version number */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ /* Auxiliary needed version information. */ typedef struct { - Elf32_Word vna_hash; /* Hash value of dependency name */ - Elf32_Half vna_flags; /* Dependency specific information */ - Elf32_Half vna_other; /* Unused */ - Elf32_Word vna_name; /* Dependency name string offset */ - Elf32_Word vna_next; /* Offset in bytes to next vernaux - entry */ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Word vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ } Elf32_Vernaux; typedef struct { - Elf64_Word vna_hash; /* Hash value of dependency name */ - Elf64_Half vna_flags; /* Dependency specific information */ - Elf64_Half vna_other; /* Unused */ - Elf64_Word vna_name; /* Dependency name string offset */ - Elf64_Word vna_next; /* Offset in bytes to next vernaux - entry */ + Elf64_Word vna_hash; /* Hash value of dependency name */ + Elf64_Half vna_flags; /* Dependency specific information */ + Elf64_Half vna_other; /* Unused */ + Elf64_Word vna_name; /* Dependency name string offset */ + Elf64_Word vna_next; /* Offset in bytes to next vernaux + entry */ } Elf64_Vernaux; /* Legal values for vna_flags. */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ /* Auxiliary vector. */ @@ -804,84 +956,115 @@ typedef struct typedef struct { - int a_type; /* Entry type */ + uint32_t a_type; /* Entry type */ union { - long int a_val; /* Integer value */ - void *a_ptr; /* Pointer value */ - void (*a_fcn) (void); /* Function pointer value */ + uint32_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ } a_un; } Elf32_auxv_t; typedef struct { - long int a_type; /* Entry type */ + uint64_t a_type; /* Entry type */ union { - long int a_val; /* Integer value */ - void *a_ptr; /* Pointer value */ - void (*a_fcn) (void); /* Function pointer value */ + uint64_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ } a_un; } Elf64_auxv_t; /* Legal values for a_type (entry type). */ -#define AT_NULL 0 /* End of vector */ -#define AT_IGNORE 1 /* Entry should be ignored */ -#define AT_EXECFD 2 /* File descriptor of program */ -#define AT_PHDR 3 /* Program headers for program */ -#define AT_PHENT 4 /* Size of program header entry */ -#define AT_PHNUM 5 /* Number of program headers */ -#define AT_PAGESZ 6 /* System page size */ -#define AT_BASE 7 /* Base address of interpreter */ -#define AT_FLAGS 8 /* Flags */ -#define AT_ENTRY 9 /* Entry point of program */ -#define AT_NOTELF 10 /* Program is not ELF */ -#define AT_UID 11 /* Real uid */ -#define AT_EUID 12 /* Effective uid */ -#define AT_GID 13 /* Real gid */ -#define AT_EGID 14 /* Effective gid */ +#define AT_NULL 0 /* End of vector */ +#define AT_IGNORE 1 /* Entry should be ignored */ +#define AT_EXECFD 2 /* File descriptor of program */ +#define AT_PHDR 3 /* Program headers for program */ +#define AT_PHENT 4 /* Size of program header entry */ +#define AT_PHNUM 5 /* Number of program headers */ +#define AT_PAGESZ 6 /* System page size */ +#define AT_BASE 7 /* Base address of interpreter */ +#define AT_FLAGS 8 /* Flags */ +#define AT_ENTRY 9 /* Entry point of program */ +#define AT_NOTELF 10 /* Program is not ELF */ +#define AT_UID 11 /* Real uid */ +#define AT_EUID 12 /* Effective uid */ +#define AT_GID 13 /* Real gid */ +#define AT_EGID 14 /* Effective gid */ +#define AT_CLKTCK 17 /* Frequency of times() */ /* Some more special a_type values describing the hardware. */ -#define AT_PLATFORM 15 /* String identifying platform. */ -#define AT_HWCAP 16 /* Machine dependent hints about - processor capabilities. */ +#define AT_PLATFORM 15 /* String identifying platform. */ +#define AT_HWCAP 16 /* Machine dependent hints about + processor capabilities. */ /* This entry gives some information about the FPU initialization performed by the kernel. */ -#define AT_FPUCW 17 /* Used FPU control word. */ +#define AT_FPUCW 18 /* Used FPU control word. */ + +/* Cache block sizes. */ +#define AT_DCACHEBSIZE 19 /* Data cache block size. */ +#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ +#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ + +/* A special ignored value for PPC, used by the kernel to control the + interpretation of the AUXV. Must be > 16. */ +#define AT_IGNOREPPC 22 /* Entry should be ignored. */ + +#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ + +#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ + +#define AT_RANDOM 25 /* Address of 16 random bytes. */ + +#define AT_EXECFN 31 /* Filename of executable. */ +/* Pointer to the global system page used for system calls and other + nice things. */ +#define AT_SYSINFO 32 +#define AT_SYSINFO_EHDR 33 + +/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains + log2 of line size; mask those to get cache size. */ +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 +#define AT_L3_CACHESHAPE 37 /* Note section contents. Each entry in the note section begins with a header of a fixed form. */ typedef struct { - Elf32_Word n_namesz; /* Length of the note's name. */ - Elf32_Word n_descsz; /* Length of the note's descriptor. */ - Elf32_Word n_type; /* Type of the note. */ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ } Elf32_Nhdr; typedef struct { - Elf64_Word n_namesz; /* Length of the note's name. */ - Elf64_Word n_descsz; /* Length of the note's descriptor. */ - Elf64_Word n_type; /* Type of the note. */ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ } Elf64_Nhdr; /* Known names of notes. */ /* Solaris entries in the note section have this name. */ -#define ELF_NOTE_SOLARIS "SUNW Solaris" +#define ELF_NOTE_SOLARIS "SUNW Solaris" /* Note entries for GNU systems have this name. */ -#define ELF_NOTE_GNU "GNU" +#define ELF_NOTE_GNU "GNU" /* Defined types of notes for Solaris. */ /* Value of descriptor (one word) is desired pagesize for the binary. */ -#define ELF_NOTE_PAGESIZE_HINT 1 +#define ELF_NOTE_PAGESIZE_HINT 1 /* Defined note types for GNU systems. */ @@ -892,285 +1075,414 @@ typedef struct word 2: minor version of the ABI word 3: subminor version of the ABI */ -#define ELF_NOTE_ABI 1 +#define NT_GNU_ABI_TAG 1 +#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ + +/* Known OSes. These values can appear in word 0 of an + NT_GNU_ABI_TAG note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 +#define ELF_NOTE_OS_FREEBSD 3 + +/* Synthetic hwcap information. The descriptor begins with two words: + word 0: number of entries + word 1: bitmask of enabled entries + Then follow variable-length entries, one byte followed by a + '\0'-terminated hwcap name string. The byte gives the bit + number to test if enabled, (1U << bit) & bitmask. */ +#define NT_GNU_HWCAP 2 + +/* Build ID bits as generated by ld --build-id. + The descriptor consists of any nonzero number of bytes. */ +#define NT_GNU_BUILD_ID 3 -/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI - note section entry. */ -#define ELF_NOTE_OS_LINUX 0 -#define ELF_NOTE_OS_GNU 1 -#define ELF_NOTE_OS_SOLARIS2 2 +/* Version note generated by GNU gold containing a version string. */ +#define NT_GNU_GOLD_VERSION 4 + + +/* Move records. */ +typedef struct +{ + Elf32_Xword m_value; /* Symbol value. */ + Elf32_Word m_info; /* Size and index. */ + Elf32_Word m_poffset; /* Symbol offset. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Stride info. */ +} Elf32_Move; + +typedef struct +{ + Elf64_Xword m_value; /* Symbol value. */ + Elf64_Xword m_info; /* Size and index. */ + Elf64_Xword m_poffset; /* Symbol offset. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Stride info. */ +} Elf64_Move; + +/* Macro to construct move records. */ +#define ELF32_M_SYM(info) ((info) >> 8) +#define ELF32_M_SIZE(info) ((unsigned char) (info)) +#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) + +#define ELF64_M_SYM(info) ELF32_M_SYM (info) +#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) +#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) /* Motorola 68k specific definitions. */ +/* Values for Elf32_Ehdr.e_flags. */ +#define EF_CPU32 0x00810000 + /* m68k relocs. */ -#define R_68K_NONE 0 /* No reloc */ -#define R_68K_32 1 /* Direct 32 bit */ -#define R_68K_16 2 /* Direct 16 bit */ -#define R_68K_8 3 /* Direct 8 bit */ -#define R_68K_PC32 4 /* PC relative 32 bit */ -#define R_68K_PC16 5 /* PC relative 16 bit */ -#define R_68K_PC8 6 /* PC relative 8 bit */ -#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -#define R_68K_COPY 19 /* Copy symbol at runtime */ -#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -#define R_68K_RELATIVE 22 /* Adjust by program base */ +#define R_68K_NONE 0 /* No reloc */ +#define R_68K_32 1 /* Direct 32 bit */ +#define R_68K_16 2 /* Direct 16 bit */ +#define R_68K_8 3 /* Direct 8 bit */ +#define R_68K_PC32 4 /* PC relative 32 bit */ +#define R_68K_PC16 5 /* PC relative 16 bit */ +#define R_68K_PC8 6 /* PC relative 8 bit */ +#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +#define R_68K_COPY 19 /* Copy symbol at runtime */ +#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +#define R_68K_RELATIVE 22 /* Adjust by program base */ +#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ +#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ +#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ +#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ +#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ +#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ +#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ +#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ +#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ +#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ +#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ +#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ +#define R_68K_TLS_LE32 37 /* 32 bit offset relative to + static TLS block */ +#define R_68K_TLS_LE16 38 /* 16 bit offset relative to + static TLS block */ +#define R_68K_TLS_LE8 39 /* 8 bit offset relative to + static TLS block */ +#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ +#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ +#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ /* Keep this the last entry. */ -#define R_68K_NUM 23 +#define R_68K_NUM 43 /* Intel 80386 specific definitions. */ /* i386 relocs. */ -#define R_386_NONE 0 /* No reloc */ -#define R_386_32 1 /* Direct 32 bit */ -#define R_386_PC32 2 /* PC relative 32 bit */ -#define R_386_GOT32 3 /* 32 bit GOT entry */ -#define R_386_PLT32 4 /* 32 bit PLT address */ -#define R_386_COPY 5 /* Copy symbol at runtime */ -#define R_386_GLOB_DAT 6 /* Create GOT entry */ -#define R_386_JMP_SLOT 7 /* Create PLT entry */ -#define R_386_RELATIVE 8 /* Adjust by program base */ -#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS + block offset */ +#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block + offset */ +#define R_386_TLS_LE 17 /* Offset relative to static TLS + block */ +#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of + general dynamic thread local data */ +#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of + local dynamic thread local data + in LE code */ +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic + thread local data */ +#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +#define R_386_TLS_GD_CALL 26 /* Relocation for call to + __tls_get_addr() */ +#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic + thread local data in LE code */ +#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +#define R_386_TLS_LDM_CALL 30 /* Relocation for call to + __tls_get_addr() in LDM code */ +#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS + block offset */ +#define R_386_TLS_LE_32 34 /* Negated offset relative to static + TLS block */ +#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +/* 38? */ +#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ +#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS + descriptor for + relaxation. */ +#define R_386_TLS_DESC 41 /* TLS descriptor containing + pointer to code and to + argument, returning the TLS + offset for the symbol. */ +#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ +#define R_386_GOT32X 43 /* 32 bit GOT entry, relaxable */ /* Keep this the last entry. */ -#define R_386_NUM 11 +#define R_386_NUM 44 /* SUN SPARC specific definitions. */ +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ + /* Values for Elf64_Ehdr.e_flags. */ -#define EF_SPARCV9_MM 3 -#define EF_SPARCV9_TSO 0 -#define EF_SPARCV9_PSO 1 -#define EF_SPARCV9_RMO 2 -#define EF_SPARC_EXT_MASK 0xFFFF00 -#define EF_SPARC_SUN_US1 0x000200 -#define EF_SPARC_HAL_R1 0x000400 +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_LEDATA 0x800000 /* little endian data */ +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ +#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ +#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ +#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ /* SPARC relocs. */ -#define R_SPARC_NONE 0 /* No reloc */ -#define R_SPARC_8 1 /* Direct 8 bit */ -#define R_SPARC_16 2 /* Direct 16 bit */ -#define R_SPARC_32 3 /* Direct 32 bit */ -#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -#define R_SPARC_HI22 9 /* High 22 bit */ -#define R_SPARC_22 10 /* Direct 22 bit */ -#define R_SPARC_13 11 /* Direct 13 bit */ -#define R_SPARC_LO10 12 /* Truncated 10 bit */ -#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ /* Additional Sparc64 relocs. */ -#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -#define R_SPARC_10 30 /* Direct 10 bit */ -#define R_SPARC_11 31 /* Direct 11 bit */ -#define R_SPARC_64 32 /* Direct 64 bit */ -#define R_SPARC_OLO10 33 /* ?? */ -#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -#define R_SPARC_7 43 /* Direct 7 bit */ -#define R_SPARC_5 44 /* Direct 5 bit */ -#define R_SPARC_6 45 /* Direct 6 bit */ -#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -#define R_SPARC_REGISTER 53 /* Global register usage */ -#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +#define R_SPARC_10 30 /* Direct 10 bit */ +#define R_SPARC_11 31 /* Direct 11 bit */ +#define R_SPARC_64 32 /* Direct 64 bit */ +#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ +#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +#define R_SPARC_PC_LM22 39 /* Low middle 22 bits of ... */ +#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ +#define R_SPARC_7 43 /* Direct 7 bit */ +#define R_SPARC_5 44 /* Direct 5 bit */ +#define R_SPARC_6 45 /* Direct 6 bit */ +#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +#define R_SPARC_REGISTER 53 /* Global register usage */ +#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 +#define R_SPARC_GOTDATA_HIX22 80 +#define R_SPARC_GOTDATA_LOX10 81 +#define R_SPARC_GOTDATA_OP_HIX22 82 +#define R_SPARC_GOTDATA_OP_LOX10 83 +#define R_SPARC_GOTDATA_OP 84 +#define R_SPARC_H34 85 +#define R_SPARC_SIZE32 86 +#define R_SPARC_SIZE64 87 +#define R_SPARC_WDISP10 88 +#define R_SPARC_JMP_IREL 248 +#define R_SPARC_IRELATIVE 249 +#define R_SPARC_GNU_VTINHERIT 250 +#define R_SPARC_GNU_VTENTRY 251 +#define R_SPARC_REV32 252 /* Keep this the last entry. */ -#define R_SPARC_NUM 56 - -/* AMD x86-64 relocations. */ -#define R_X86_64_NONE 0 /* No reloc */ -#define R_X86_64_64 1 /* Direct 64 bit */ -#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative - offset to GOT */ -#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset - to two GOT entries for GD symbol */ -#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset - to two GOT entries for LD symbol */ -#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset - to GOT entry for IE symbol */ -#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ - -#define R_X86_64_NUM 24 +#define R_SPARC_NUM 253 /* For Sparc64, legal values for d_tag of Elf64_Dyn. */ #define DT_SPARC_REGISTER 0x70000001 -#define DT_SPARC_NUM 2 - -/* Bits present in AT_HWCAP, primarily for Sparc32. */ - -#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */ -#define HWCAP_SPARC_STBAR 2 -#define HWCAP_SPARC_SWAP 4 -#define HWCAP_SPARC_MULDIV 8 -#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */ +#define DT_SPARC_NUM 2 /* MIPS R3000 specific definitions. */ /* Legal values for e_flags field of Elf32_Ehdr. */ -#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ -#define EF_MIPS_PIC 2 /* Contains PIC code */ -#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ -#define EF_MIPS_XGOT 8 +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_XGOT 8 #define EF_MIPS_64BIT_WHIRL 16 -#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI2 32 #define EF_MIPS_ABI_ON32 64 -#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ /* Legal values for MIPS architecture level. */ -#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ /* The following are non-official names and should not be used. */ -#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ /* Special section indices. */ -#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ -#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ -#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ /* Legal values for sh_type field of Elf32_Shdr. */ #define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ -#define SHT_MIPS_MSYM 0x70000001 +#define SHT_MIPS_MSYM 0x70000001 #define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ -#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ -#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ #define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ #define SHT_MIPS_PACKAGE 0x70000007 #define SHT_MIPS_PACKSYM 0x70000008 -#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_RELD 0x70000009 #define SHT_MIPS_IFACE 0x7000000b #define SHT_MIPS_CONTENT 0x7000000c #define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -#define SHT_MIPS_SHDR 0x70000010 -#define SHT_MIPS_FDESC 0x70000011 -#define SHT_MIPS_EXTSYM 0x70000012 -#define SHT_MIPS_DENSE 0x70000013 -#define SHT_MIPS_PDESC 0x70000014 -#define SHT_MIPS_LOCSYM 0x70000015 -#define SHT_MIPS_AUXSYM 0x70000016 -#define SHT_MIPS_OPTSYM 0x70000017 -#define SHT_MIPS_LOCSTR 0x70000018 -#define SHT_MIPS_LINE 0x70000019 -#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a #define SHT_MIPS_DELTASYM 0x7000001b #define SHT_MIPS_DELTAINST 0x7000001c #define SHT_MIPS_DELTACLASS 0x7000001d #define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ #define SHT_MIPS_DELTADECL 0x7000001f #define SHT_MIPS_SYMBOL_LIB 0x70000020 -#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ #define SHT_MIPS_TRANSLATE 0x70000022 -#define SHT_MIPS_PIXIE 0x70000023 -#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 #define SHT_MIPS_XLATE_DEBUG 0x70000025 -#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_WHIRL 0x70000026 #define SHT_MIPS_EH_REGION 0x70000027 #define SHT_MIPS_XLATE_OLD 0x70000028 #define SHT_MIPS_PDR_EXCEPTION 0x70000029 /* Legal values for sh_flags field of Elf32_Shdr. */ -#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ -#define SHF_MIPS_MERGE 0x20000000 -#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 #define SHF_MIPS_STRINGS 0x80000000 #define SHF_MIPS_NOSTRIP 0x08000000 -#define SHF_MIPS_LOCAL 0x04000000 -#define SHF_MIPS_NAMES 0x02000000 -#define SHF_MIPS_NODUPE 0x01000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPE 0x01000000 /* Symbol tables. */ /* MIPS specific values for `st_other'. */ -#define STO_MIPS_DEFAULT 0x0 -#define STO_MIPS_INTERNAL 0x1 -#define STO_MIPS_HIDDEN 0x2 -#define STO_MIPS_PROTECTED 0x3 -#define STO_MIPS_SC_ALIGN_UNUSED 0xff +#define STO_MIPS_DEFAULT 0x0 +#define STO_MIPS_INTERNAL 0x1 +#define STO_MIPS_HIDDEN 0x2 +#define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_PLT 0x8 +#define STO_MIPS_SC_ALIGN_UNUSED 0xff /* MIPS specific values for `st_info'. */ -#define STB_MIPS_SPLIT_COMMON 13 +#define STB_MIPS_SPLIT_COMMON 13 /* Entries found in sections of type SHT_MIPS_GPTAB. */ @@ -1178,176 +1490,192 @@ typedef union { struct { - Elf32_Word gt_current_g_value; /* -G value used for compilation */ - Elf32_Word gt_unused; /* Not used */ - } gt_header; /* First entry in section */ + Elf32_Word gt_current_g_value; /* -G value used for compilation */ + Elf32_Word gt_unused; /* Not used */ + } gt_header; /* First entry in section */ struct { - Elf32_Word gt_g_value; /* If this value were used for -G */ - Elf32_Word gt_bytes; /* This many bytes would be used */ - } gt_entry; /* Subsequent entries in section */ + Elf32_Word gt_g_value; /* If this value were used for -G */ + Elf32_Word gt_bytes; /* This many bytes would be used */ + } gt_entry; /* Subsequent entries in section */ } Elf32_gptab; /* Entry found in sections of type SHT_MIPS_REGINFO. */ typedef struct { - Elf32_Word ri_gprmask; /* General registers used */ - Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ - Elf32_Sword ri_gp_value; /* $gp register value */ + Elf32_Word ri_gprmask; /* General registers used */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ + Elf32_Sword ri_gp_value; /* $gp register value */ } Elf32_RegInfo; /* Entries found in sections of type SHT_MIPS_OPTIONS. */ typedef struct { - unsigned char kind; /* Determines interpretation of the - variable part of descriptor. */ - unsigned char size; /* Size of descriptor, including header. */ - Elf32_Section section; /* Section header index of section affected, - 0 for global options. */ - Elf32_Word info; /* Kind-specific information. */ + unsigned char kind; /* Determines interpretation of the + variable part of descriptor. */ + unsigned char size; /* Size of descriptor, including header. */ + Elf32_Section section; /* Section header index of section affected, + 0 for global options. */ + Elf32_Word info; /* Kind-specific information. */ } Elf_Options; /* Values for `kind' field in Elf_Options. */ -#define ODK_NULL 0 /* Undefined. */ -#define ODK_REGINFO 1 /* Register usage information. */ -#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -#define ODK_PAD 3 /* Section padding options. */ -#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -#define ODK_FILL 5 /* record the fill value used by the linker. */ -#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ +#define ODK_NULL 0 /* Undefined. */ +#define ODK_REGINFO 1 /* Register usage information. */ +#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +#define ODK_PAD 3 /* Section padding options. */ +#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +#define ODK_FILL 5 /* record the fill value used by the linker. */ +#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ /* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ -#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -#define OEX_PRECISEFP OEX_FPDBUG -#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ +#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +#define OEX_PRECISEFP OEX_FPDBUG +#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ -#define OEX_FPU_INVAL 0x10 -#define OEX_FPU_DIV0 0x08 -#define OEX_FPU_OFLO 0x04 -#define OEX_FPU_UFLO 0x02 -#define OEX_FPU_INEX 0x01 +#define OEX_FPU_INVAL 0x10 +#define OEX_FPU_DIV0 0x08 +#define OEX_FPU_OFLO 0x04 +#define OEX_FPU_UFLO 0x02 +#define OEX_FPU_INEX 0x01 /* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ -#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ +#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ -#define OPAD_PREFIX 0x1 -#define OPAD_POSTFIX 0x2 -#define OPAD_SYMBOL 0x4 +#define OPAD_PREFIX 0x1 +#define OPAD_POSTFIX 0x2 +#define OPAD_SYMBOL 0x4 /* Entry found in `.options' section. */ typedef struct { - Elf32_Word hwp_flags1; /* Extra flags. */ - Elf32_Word hwp_flags2; /* Extra flags. */ + Elf32_Word hwp_flags1; /* Extra flags. */ + Elf32_Word hwp_flags2; /* Extra flags. */ } Elf_Options_Hw; /* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ -#define OHWA0_R4KEOP_CHECKED 0x00000001 -#define OHWA1_R4KEOP_CLEAN 0x00000002 +#define OHWA0_R4KEOP_CHECKED 0x00000001 +#define OHWA1_R4KEOP_CLEAN 0x00000002 /* MIPS relocs. */ -#define R_MIPS_NONE 0 /* No reloc */ -#define R_MIPS_16 1 /* Direct 16 bit */ -#define R_MIPS_32 2 /* Direct 32 bit */ -#define R_MIPS_REL32 3 /* PC relative 32 bit */ -#define R_MIPS_26 4 /* Direct 26 bit shifted */ -#define R_MIPS_HI16 5 /* High 16 bit */ -#define R_MIPS_LO16 6 /* Low 16 bit */ -#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -#define R_MIPS_PC16 10 /* PC relative 16 bit */ -#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ - -#define R_MIPS_SHIFT5 16 -#define R_MIPS_SHIFT6 17 -#define R_MIPS_64 18 -#define R_MIPS_GOT_DISP 19 -#define R_MIPS_GOT_PAGE 20 -#define R_MIPS_GOT_OFST 21 -#define R_MIPS_GOT_HI16 22 -#define R_MIPS_GOT_LO16 23 -#define R_MIPS_SUB 24 -#define R_MIPS_INSERT_A 25 -#define R_MIPS_INSERT_B 26 -#define R_MIPS_DELETE 27 -#define R_MIPS_HIGHER 28 -#define R_MIPS_HIGHEST 29 -#define R_MIPS_CALL_HI16 30 -#define R_MIPS_CALL_LO16 31 -#define R_MIPS_SCN_DISP 32 -#define R_MIPS_REL16 33 -#define R_MIPS_ADD_IMMEDIATE 34 -#define R_MIPS_PJUMP 35 -#define R_MIPS_RELGOT 36 -#define R_MIPS_JALR 37 +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_CALL_HI16 30 +#define R_MIPS_CALL_LO16 31 +#define R_MIPS_SCN_DISP 32 +#define R_MIPS_REL16 33 +#define R_MIPS_ADD_IMMEDIATE 34 +#define R_MIPS_PJUMP 35 +#define R_MIPS_RELGOT 36 +#define R_MIPS_JALR 37 +#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ +#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ +#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ +#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ +#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ +#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ +#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ +#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ +#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ +#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ +#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ +#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ +#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ +#define R_MIPS_GLOB_DAT 51 +#define R_MIPS_COPY 126 +#define R_MIPS_JUMP_SLOT 127 /* Keep this the last entry. */ -#define R_MIPS_NUM 38 +#define R_MIPS_NUM 128 /* Legal values for p_type field of Elf32_Phdr. */ -#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ -#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ #define PT_MIPS_OPTIONS 0x70000002 /* Special program header types. */ -#define PF_MIPS_LOCAL 0x10000000 +#define PF_MIPS_LOCAL 0x10000000 /* Legal values for d_tag field of Elf32_Dyn. */ -#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -#define DT_MIPS_MSYM 0x70000007 -#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_MSYM 0x70000007 +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ #define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in - DT_MIPS_DELTA_CLASS. */ + DT_MIPS_DELTA_CLASS. */ #define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in - DT_MIPS_DELTA_INSTANCE. */ + DT_MIPS_DELTA_INSTANCE. */ #define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ #define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in - DT_MIPS_DELTA_RELOC. */ + DT_MIPS_DELTA_RELOC. */ #define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta - relocations refer to. */ + relocations refer to. */ #define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in - DT_MIPS_DELTA_SYM. */ + DT_MIPS_DELTA_SYM. */ #define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the - class declaration. */ + class declaration. */ #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in - DT_MIPS_DELTA_CLASSSYM. */ + DT_MIPS_DELTA_CLASSSYM. */ #define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ #define DT_MIPS_PIXIE_INIT 0x70000023 #define DT_MIPS_SYMBOL_LIB 0x70000024 @@ -1355,68 +1683,74 @@ typedef struct #define DT_MIPS_LOCAL_GOTIDX 0x70000026 #define DT_MIPS_HIDDEN_GOTIDX 0x70000027 #define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ #define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ #define DT_MIPS_DYNSTR_ALIGN 0x7000002b #define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve - function stored in GOT. */ + function stored in GOT. */ #define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added - by rld on dlopen() calls. */ + by rld on dlopen() calls. */ #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ #define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ #define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -#define DT_MIPS_NUM 0x32 +/* The address of .got.plt in an executable using the new non-PIC ABI. */ +#define DT_MIPS_PLTGOT 0x70000032 +/* The base of the PLT in an executable using the new non-PIC ABI if that + PLT is writable. For a non-writable PLT, this is omitted or has a zero + value. */ +#define DT_MIPS_RWPLT 0x70000034 +#define DT_MIPS_NUM 0x35 /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ -#define RHF_NONE 0 /* No flags */ -#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -#define RHF_NO_MOVE (1 << 3) -#define RHF_SGI_ONLY (1 << 4) -#define RHF_GUARANTEE_INIT (1 << 5) -#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +#define RHF_NO_MOVE (1 << 3) +#define RHF_SGI_ONLY (1 << 4) +#define RHF_GUARANTEE_INIT (1 << 5) +#define RHF_DELTA_C_PLUS_PLUS (1 << 6) #define RHF_GUARANTEE_START_INIT (1 << 7) -#define RHF_PIXIE (1 << 8) -#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -#define RHF_REQUICKSTART (1 << 10) -#define RHF_REQUICKSTARTED (1 << 11) -#define RHF_CORD (1 << 12) -#define RHF_NO_UNRES_UNDEF (1 << 13) -#define RHF_RLD_ORDER_SAFE (1 << 14) +#define RHF_PIXIE (1 << 8) +#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +#define RHF_REQUICKSTART (1 << 10) +#define RHF_REQUICKSTARTED (1 << 11) +#define RHF_CORD (1 << 12) +#define RHF_NO_UNRES_UNDEF (1 << 13) +#define RHF_RLD_ORDER_SAFE (1 << 14) /* Entries found in sections of type SHT_MIPS_LIBLIST. */ typedef struct { - Elf32_Word l_name; /* Name (string table index) */ - Elf32_Word l_time_stamp; /* Timestamp */ - Elf32_Word l_checksum; /* Checksum */ - Elf32_Word l_version; /* Interface version */ - Elf32_Word l_flags; /* Flags */ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ } Elf32_Lib; typedef struct { - Elf64_Word l_name; /* Name (string table index) */ - Elf64_Word l_time_stamp; /* Timestamp */ - Elf64_Word l_checksum; /* Checksum */ - Elf64_Word l_version; /* Interface version */ - Elf64_Word l_flags; /* Flags */ + Elf64_Word l_name; /* Name (string table index) */ + Elf64_Word l_time_stamp; /* Timestamp */ + Elf64_Word l_checksum; /* Checksum */ + Elf64_Word l_version; /* Interface version */ + Elf64_Word l_flags; /* Flags */ } Elf64_Lib; /* Legal values for l_flags. */ -#define LL_NONE 0 -#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +#define LL_NONE 0 +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ #define LL_REQUIRE_MINOR (1 << 2) -#define LL_EXPORTS (1 << 3) -#define LL_DELAY_LOAD (1 << 4) -#define LL_DELTA (1 << 5) +#define LL_EXPORTS (1 << 3) +#define LL_DELAY_LOAD (1 << 4) +#define LL_DELTA (1 << 5) /* Entries found in sections of type SHT_MIPS_CONFLICT. */ @@ -1427,265 +1761,784 @@ typedef Elf32_Addr Elf32_Conflict; /* Legal values for e_flags field of Elf32_Ehdr. */ -#define EF_PARISC_TRAPNL 1 /* Trap nil pointer dereference. */ -#define EF_PARISC_EXT 2 /* Program uses arch. extensions. */ -#define EF_PARISC_ARCH 0xffff0000 /* Architecture version. */ -/* Defined values are: - 0x020b PA-RISC 1.0 big-endian - 0x0210 PA-RISC 1.1 big-endian - 0x028b PA-RISC 1.0 little-endian - 0x0290 PA-RISC 1.1 little-endian -*/ +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indices. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tentatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ /* Legal values for sh_type field of Elf32_Shdr. */ -#define SHT_PARISC_GOT 0x70000000 /* GOT for external data. */ -#define SHT_PARISC_ARCH 0x70000001 /* Architecture extensions. */ -#define SHT_PARISC_GLOBAL 0x70000002 /* Definition of $global$. */ -#define SHT_PARISC_MILLI 0x70000003 /* Millicode routines. */ -#define SHT_PARISC_UNWIND 0x70000004 /* Unwind information. */ -#define SHT_PARISC_PLT 0x70000005 /* Procedure linkage table. */ -#define SHT_PARISC_SDATA 0x70000006 /* Short initialized data. */ -#define SHT_PARISC_SBSS 0x70000007 /* Short uninitialized data. */ -#define SHT_PARISC_SYMEXTN 0x70000008 /* Argument/relocation info. */ -#define SHT_PARISC_STUBS 0x70000009 /* Linker stubs. */ +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ /* Legal values for sh_flags field of Elf32_Shdr. */ -#define SHF_PARISC_GLOBAL 0x10000000 /* Section defines dp. */ -#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ /* Legal values for ST_TYPE subfield of st_info (symbol type). */ -#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) /* HPPA relocs. */ -#define R_PARISC_NONE 0 /* No reloc. */ -#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -#define R_PARISC_DIR14R 4 /* Right 14 bits of eff. address. */ -#define R_PARISC_PCREL21L 5 /* PC-relative, left 21 bits. */ -#define R_PARISC_PCREL14R 6 /* PC-relative, right 14 bits. */ -#define R_PARISC_PCREL17C 7 /* Conditional PC-relative, ignore - if displacement > 17bits. */ -#define R_PARISC_PCREL17F 8 /* Conditional PC-relative, must - fit in 17bits. */ -#define R_PARISC_DPREL21L 9 /* DP-relative, left 21 bits. */ -#define R_PARISC_DPREL14R 10 /* DP-relative, right 14 bits. */ -#define R_PARISC_DPREL14F 11 /* DP-relative, must bit in 14 bits. */ -#define R_PARISC_DLTREL21L 12 /* DLT-relative, left 21 bits. */ -#define R_PARISC_DLTREL14R 13 /* DLT-relative, right 14 bits. */ -#define R_PARISC_DLTREL14F 14 /* DLT-relative, must fit in 14 bits.*/ -#define R_PARISC_DLTIND21L 15 /* DLT-relative indirect, left - 21 bits. */ -#define R_PARISC_DLTIND14R 16 /* DLT-relative indirect, right - 14 bits. */ -#define R_PARISC_DLTIND14F 17 /* DLT-relative indirect, must fit - int 14 bits. */ -#define R_PARISC_PLABEL32 18 /* Direct 32-bit reference to proc. */ +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ +#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_GNU_VTENTRY 232 +#define R_PARISC_GNU_VTINHERIT 233 +#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ +#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ +#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ +#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ +#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ +#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ +#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ +#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ +#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ +#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ +#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L +#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R +#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L +#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R +#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 +#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + /* Alpha specific definitions. */ /* Legal values for e_flags field of Elf64_Ehdr. */ -#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ /* Legal values for sh_type field of Elf64_Shdr. */ -/* These two are primerily concerned with ECOFF debugging info. */ -#define SHT_ALPHA_DEBUG 0x70000001 -#define SHT_ALPHA_REGINFO 0x70000002 +/* These two are primarily concerned with ECOFF debugging info. */ +#define SHT_ALPHA_DEBUG 0x70000001 +#define SHT_ALPHA_REGINFO 0x70000002 /* Legal values for sh_flags field of Elf64_Shdr. */ -#define SHF_ALPHA_GPREL 0x10000000 +#define SHF_ALPHA_GPREL 0x10000000 /* Legal values for st_other field of Elf64_Sym. */ -#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ +#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ /* Alpha relocs. */ -#define R_ALPHA_NONE 0 /* No reloc */ -#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -#define R_ALPHA_OP_PUSH 12 /* OP stack push */ -#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ -#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ -#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ -#define R_ALPHA_GPVALUE 16 -#define R_ALPHA_GPRELHIGH 17 -#define R_ALPHA_GPRELLOW 18 -#define R_ALPHA_IMMED_GP_16 19 -#define R_ALPHA_IMMED_GP_HI32 20 -#define R_ALPHA_IMMED_SCN_HI32 21 -#define R_ALPHA_IMMED_BR_HI32 22 -#define R_ALPHA_IMMED_LO32 23 -#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ +#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ +#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_TLS_GD_HI 28 +#define R_ALPHA_TLSGD 29 +#define R_ALPHA_TLS_LDM 30 +#define R_ALPHA_DTPMOD64 31 +#define R_ALPHA_GOTDTPREL 32 +#define R_ALPHA_DTPREL64 33 +#define R_ALPHA_DTPRELHI 34 +#define R_ALPHA_DTPRELLO 35 +#define R_ALPHA_DTPREL16 36 +#define R_ALPHA_GOTTPREL 37 +#define R_ALPHA_TPREL64 38 +#define R_ALPHA_TPRELHI 39 +#define R_ALPHA_TPRELLO 40 +#define R_ALPHA_TPREL16 41 /* Keep this the last entry. */ -#define R_ALPHA_NUM 28 +#define R_ALPHA_NUM 46 +/* Magic values of the LITUSE relocation addend. */ +#define LITUSE_ALPHA_ADDR 0 +#define LITUSE_ALPHA_BASE 1 +#define LITUSE_ALPHA_BYTOFF 2 +#define LITUSE_ALPHA_JSR 3 +#define LITUSE_ALPHA_TLS_GD 4 +#define LITUSE_ALPHA_TLS_LDM 5 + +/* Legal values for d_tag of Elf64_Dyn. */ +#define DT_ALPHA_PLTRO (DT_LOPROC + 0) +#define DT_ALPHA_NUM 1 /* PowerPC specific declarations */ +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + /* PowerPC relocations defined by the ABIs */ -#define R_PPC_NONE 0 -#define R_PPC_ADDR32 1 /* 32bit absolute address */ -#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -#define R_PPC_ADDR16 3 /* 16bit absolute address */ -#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -#define R_PPC_ADDR14_BRTAKEN 8 -#define R_PPC_ADDR14_BRNTAKEN 9 -#define R_PPC_REL24 10 /* PC relative 26 bit */ -#define R_PPC_REL14 11 /* PC relative 16 bit */ -#define R_PPC_REL14_BRTAKEN 12 -#define R_PPC_REL14_BRNTAKEN 13 -#define R_PPC_GOT16 14 -#define R_PPC_GOT16_LO 15 -#define R_PPC_GOT16_HI 16 -#define R_PPC_GOT16_HA 17 -#define R_PPC_PLTREL24 18 -#define R_PPC_COPY 19 -#define R_PPC_GLOB_DAT 20 -#define R_PPC_JMP_SLOT 21 -#define R_PPC_RELATIVE 22 -#define R_PPC_LOCAL24PC 23 -#define R_PPC_UADDR32 24 -#define R_PPC_UADDR16 25 -#define R_PPC_REL32 26 -#define R_PPC_PLT32 27 -#define R_PPC_PLTREL32 28 -#define R_PPC_PLT16_LO 29 -#define R_PPC_PLT16_HI 30 -#define R_PPC_PLT16_HA 31 -#define R_PPC_SDAREL16 32 -#define R_PPC_SECTOFF 33 -#define R_PPC_SECTOFF_LO 34 -#define R_PPC_SECTOFF_HI 35 -#define R_PPC_SECTOFF_HA 36 -/* Keep this the last entry. */ -#define R_PPC_NUM 37 +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 + +/* PowerPC relocations defined for the TLS access ABI. */ +#define R_PPC_TLS 67 /* none (sym+add)@tls */ +#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ +#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ +#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ +#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ +#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ +#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ +#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ +#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ +#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ /* The remaining relocs are from the Embedded ELF ABI, and are not in the SVR4 ELF ABI. */ -#define R_PPC_EMB_NADDR32 101 -#define R_PPC_EMB_NADDR16 102 -#define R_PPC_EMB_NADDR16_LO 103 -#define R_PPC_EMB_NADDR16_HI 104 -#define R_PPC_EMB_NADDR16_HA 105 -#define R_PPC_EMB_SDAI16 106 -#define R_PPC_EMB_SDA2I16 107 -#define R_PPC_EMB_SDA2REL 108 -#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -#define R_PPC_EMB_MRKREF 110 -#define R_PPC_EMB_RELSEC16 111 -#define R_PPC_EMB_RELST_LO 112 -#define R_PPC_EMB_RELST_HI 113 -#define R_PPC_EMB_RELST_HA 114 -#define R_PPC_EMB_BIT_FLD 115 -#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ /* Diab tool relocations. */ -#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* GNU extension to support local ifunc. */ +#define R_PPC_IRELATIVE 248 + +/* GNU relocs used in PIC code sequences. */ +#define R_PPC_REL16 249 /* half16 (sym+add-.) */ +#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ +#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ +#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ /* This is a phony reloc to handle any old fashioned TOC16 references that may still be in object files. */ -#define R_PPC_TOC16 255 +#define R_PPC_TOC16 255 + +/* PowerPC specific values for the Dyn d_tag field. */ +#define DT_PPC_GOT (DT_LOPROC + 0) +#define DT_PPC_NUM 1 + +/* PowerPC64 relocations defined by the ABIs */ +#define R_PPC64_NONE R_PPC_NONE +#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ +#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ +#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ +#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ +#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ +#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ +#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ +#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ +#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +#define R_PPC64_GOT16 R_PPC_GOT16 +#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +#define R_PPC64_GOT16_HA R_PPC_GOT16_HA + +#define R_PPC64_COPY R_PPC_COPY +#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +#define R_PPC64_RELATIVE R_PPC_RELATIVE + +#define R_PPC64_UADDR32 R_PPC_UADDR32 +#define R_PPC64_UADDR16 R_PPC_UADDR16 +#define R_PPC64_REL32 R_PPC_REL32 +#define R_PPC64_PLT32 R_PPC_PLT32 +#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +#define R_PPC64_PLT16_HA R_PPC_PLT16_HA + +#define R_PPC64_SECTOFF R_PPC_SECTOFF +#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ +#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ +#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ +#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ +#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ +#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ +#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ +#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ +#define R_PPC64_PLT64 45 /* doubleword64 L + A */ +#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ +#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ +#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ +#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ +#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ +#define R_PPC64_TOC 51 /* doubleword64 .TOC */ +#define R_PPC64_PLTGOT16 52 /* half16* M + A */ +#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ +#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ +#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ + +#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ +#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ +#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ +#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ +#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ +#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ +#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ +#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ +#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ +#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ +#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ + +/* PowerPC64 relocations defined for the TLS access ABI. */ +#define R_PPC64_TLS 67 /* none (sym+add)@tls */ +#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ +#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ +#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ +#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ +#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ +#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ +#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ +#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ +#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ +#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ +#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ +#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ +#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ +#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ +#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ +#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ +#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ + +/* GNU extension to support local ifunc. */ +#define R_PPC64_JMP_IREL 247 +#define R_PPC64_IRELATIVE 248 +#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ +#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ +#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ +#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ + +/* PowerPC64 specific values for the Dyn d_tag field. */ +#define DT_PPC64_GLINK (DT_LOPROC + 0) +#define DT_PPC64_OPD (DT_LOPROC + 1) +#define DT_PPC64_OPDSZ (DT_LOPROC + 2) +#define DT_PPC64_NUM 3 /* ARM specific declarations */ /* Processor specific flags for the ELF header e_flags field. */ -#define EF_ARM_RELEXEC 0x01 -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_INTERWORK 0x04 -#define EF_ARM_APCS_26 0x08 -#define EF_ARM_APCS_FLOAT 0x10 -#define EF_ARM_PIC 0x20 -#define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -#define EF_NEW_ABI 0x80 -#define EF_OLD_ABI 0x100 - -/* Additional symbol types for Thumb */ -#define STT_ARM_TFUNC 0xd +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_ARM_NEW_ABI 0x80 +#define EF_ARM_OLD_ABI 0x100 +#define EF_ARM_SOFT_FLOAT 0x200 +#define EF_ARM_VFP_FLOAT 0x400 +#define EF_ARM_MAVERICK_FLOAT 0x800 + +#define EF_ARM_ABI_FLOAT_SOFT 0x200 /* NB conflicts with EF_ARM_SOFT_FLOAT */ +#define EF_ARM_ABI_FLOAT_HARD 0x400 /* NB conflicts with EF_ARM_VFP_FLOAT */ + + +/* Other constants defined in the ARM ELF spec. version B-01. */ +/* NB. These conflict with values defined above. */ +#define EF_ARM_SYMSARESORTED 0x04 +#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +#define EF_ARM_MAPSYMSFIRST 0x10 +#define EF_ARM_EABIMASK 0XFF000000 + +/* Constants defined in AAELF. */ +#define EF_ARM_BE8 0x00800000 +#define EF_ARM_LE8 0x00400000 + +#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 +#define EF_ARM_EABI_VER3 0x03000000 +#define EF_ARM_EABI_VER4 0x04000000 +#define EF_ARM_EABI_VER5 0x05000000 + +/* Additional symbol types for Thumb. */ +#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ +#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ /* ARM-specific values for sh_flags */ -#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined - in the input to a link step */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step. */ /* ARM-specific program header flags */ -#define PF_ARM_SB 0x10000000 /* Segment contains the location - addressed by the static base */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base. */ +#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ +#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ +#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ +#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ + + +/* AArch64 relocs. */ + +#define R_AARCH64_NONE 0 /* No relocation. */ +#define R_AARCH64_ABS64 257 /* Direct 64 bit. */ +#define R_AARCH64_ABS32 258 /* Direct 32 bit. */ +#define R_AARCH64_ABS16 259 /* Direct 16-bit. */ +#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */ +#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */ +#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */ +#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */ +#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */ +#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */ +#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */ +#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */ +#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */ +#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */ +#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */ +#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */ +#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */ +#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */ +#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */ +#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */ +#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */ +#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */ +#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */ +#define R_AARCH64_CALL26 283 /* Likewise for CALL. */ +#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */ +#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */ +#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */ +#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */ +#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */ +#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */ +#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */ +#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */ +#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */ +#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */ +#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */ +#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */ +#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */ +#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */ +#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */ +#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */ +#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */ +#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */ +#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */ +#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */ +#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */ +#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */ +#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */ +#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */ +#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */ +#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */ +#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */ +#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */ +#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */ +#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */ +#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */ +#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */ +#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */ +#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */ +#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */ +#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */ +#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */ +#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */ +#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */ +#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */ +#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */ +#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */ +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */ +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */ +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */ +#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */ +#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ +#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ +#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ +#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */ +#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */ +#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */ +#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ +#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ +/* Keep this the last entry. */ +#define R_AARCH64_NUM 1033 /* ARM relocs. */ -#define R_ARM_NONE 0 /* No reloc */ -#define R_ARM_PC24 1 /* PC relative 26 bit branch */ -#define R_ARM_ABS32 2 /* Direct 32 bit */ -#define R_ARM_REL32 3 /* PC relative 32 bit */ -#define R_ARM_PC13 4 -#define R_ARM_ABS16 5 /* Direct 16 bit */ -#define R_ARM_ABS12 6 /* Direct 12 bit */ -#define R_ARM_THM_ABS5 7 -#define R_ARM_ABS8 8 /* Direct 8 bit */ -#define R_ARM_SBREL32 9 -#define R_ARM_THM_PC22 10 -#define R_ARM_THM_PC8 11 -#define R_ARM_AMP_VCALL9 12 -#define R_ARM_SWI24 13 -#define R_ARM_THM_SWI8 14 -#define R_ARM_XPC25 15 -#define R_ARM_THM_XPC22 16 -#define R_ARM_COPY 20 /* Copy symbol at runtime */ -#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -#define R_ARM_RELATIVE 23 /* Adjust by program base */ -#define R_ARM_GOTOFF32 24 /* 32 bit offset to GOT */ -#define R_ARM_BASE_PREL 25 /* 32 bit PC relative offset to GOT */ -#define R_ARM_GOT_BREL 26 /* 32 bit GOT entry */ -#define R_ARM_PLT32 27 /* 32 bit PLT address */ -#define R_ARM_CALL 28 -#define R_ARM_JUMP24 29 -#define R_ARM_PREL31 42 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ -#define R_ARM_THM_PC9 103 /* thumb conditional branch */ -#define R_ARM_RXPC25 249 -#define R_ARM_RSBREL32 250 -#define R_ARM_THM_RPC22 251 -#define R_ARM_RREL32 252 -#define R_ARM_RABS22 253 -#define R_ARM_RPC24 254 -#define R_ARM_RBASE 255 + +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 /* Obsolete static relocation. */ +#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ +#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ +#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* 32 bit PLT address */ +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 +#define R_ARM_THM_JUMP24 30 +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0 35 +#define R_ARM_ALU_SBREL_19_12 36 +#define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_V4BX 40 +#define R_ARM_PREL31 42 +#define R_ARM_MOVW_ABS_NC 43 +#define R_ARM_MOVT_ABS 44 +#define R_ARM_THM_MOVW_ABS_NC 47 +#define R_ARM_THM_MOVT_ABS 48 +#define R_ARM_TLS_GOTDESC 90 +#define R_ARM_TLS_CALL 91 +#define R_ARM_TLS_DESCSEQ 92 +#define R_ARM_THM_TLS_CALL 93 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic + thread local data */ +#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic + thread local data */ +#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS + block */ +#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of + static TLS block offset */ +#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static + TLS block */ +#define R_ARM_THM_TLS_DESCSEQ 129 +#define R_ARM_IRELATIVE 160 +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 /* Keep this the last entry. */ -#define R_ARM_NUM 256 +#define R_ARM_NUM 256 /* TMS320C67xx specific declarations */ -/* XXX: no ELF standard yet */ + +/* XXX: no ELF standard yet*/ /* TMS320C67xx relocs. */ #define R_C60_32 1 @@ -1698,17 +2551,687 @@ typedef Elf32_Addr Elf32_Conflict; #define R_C60_GOTOFF 9 /* 32 bit offset to GOT */ #define R_C60_GOTPC 10 /* 32 bit PC relative offset to GOT */ -#define R_C60HI16 0x55 // high 16 bit MVKH embedded -#define R_C60LO16 0x54 // low 16 bit MVKL embedded +#define R_C60LO16 0x54 /* low 16 bit MVKL embedded */ +#define R_C60HI16 0x55 /* high 16 bit MVKH embedded */ +/* Keep this the last entry. */ +#define R_C60_NUM 0x56 + +/* IA-64 specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ +#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ +#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ +#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ +#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) +#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) +#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) + +/* Processor specific flags for the Phdr p_flags field. */ +#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ +#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ + +/* Processor specific flags for the Shdr sh_flags field. */ +#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ +#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Dyn d_tag field. */ +#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) +#define DT_IA_64_NUM 1 + +/* IA-64 relocations. */ +#define R_IA64_NONE 0x00 /* none */ +#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ +#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ +#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ +#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ +#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ +#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ +#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ +#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ +#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ +#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ +#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ +#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ +#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ +#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ +#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ +#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ +#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ +#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ +#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ +#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ +#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ +#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ +#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ +#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ +#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ +#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ +#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ +#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ +#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ +#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ +#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ +#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ +#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ +#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ +#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ +#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ +#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ +#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ +#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ +#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ +#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ +#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ +#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ +#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ +#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ +#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ +#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ +#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ +#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ +#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ +#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ +#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ +#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ +#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ +#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ +#define R_IA64_COPY 0x84 /* copy relocation */ +#define R_IA64_SUB 0x85 /* Addend and symbol difference */ +#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ +#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ +#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ +#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ +#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ +#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ +#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ +#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ +#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ +#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ +#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ +#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ +#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ +#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ +#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ +#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ + +/* SH specific declarations */ -#ifdef TCC_TARGET_X86_64 -#define TCC_ELFCLASS ELFCLASS64 -#define ElfW(type) Elf##64##_##type -#define ELFW(type) ELF##64##_##type -#else -#define TCC_ELFCLASS ELFCLASS32 -#define ElfW(type) Elf##32##_##type -#define ELFW(type) ELF##32##_##type -#endif +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_SH_MACH_MASK 0x1f +#define EF_SH_UNKNOWN 0x0 +#define EF_SH1 0x1 +#define EF_SH2 0x2 +#define EF_SH3 0x3 +#define EF_SH_DSP 0x4 +#define EF_SH3_DSP 0x5 +#define EF_SH4AL_DSP 0x6 +#define EF_SH3E 0x8 +#define EF_SH4 0x9 +#define EF_SH2E 0xb +#define EF_SH4A 0xc +#define EF_SH2A 0xd +#define EF_SH4_NOFPU 0x10 +#define EF_SH4A_NOFPU 0x11 +#define EF_SH4_NOMMU_NOFPU 0x12 +#define EF_SH2A_NOFPU 0x13 +#define EF_SH3_NOMMU 0x14 +#define EF_SH2A_SH4_NOFPU 0x15 +#define EF_SH2A_SH3_NOFPU 0x16 +#define EF_SH2A_SH4 0x17 +#define EF_SH2A_SH3E 0x18 + +/* SH relocs. */ +#define R_SH_NONE 0 +#define R_SH_DIR32 1 +#define R_SH_REL32 2 +#define R_SH_DIR8WPN 3 +#define R_SH_IND12W 4 +#define R_SH_DIR8WPL 5 +#define R_SH_DIR8WPZ 6 +#define R_SH_DIR8BP 7 +#define R_SH_DIR8W 8 +#define R_SH_DIR8L 9 +#define R_SH_SWITCH16 25 +#define R_SH_SWITCH32 26 +#define R_SH_USES 27 +#define R_SH_COUNT 28 +#define R_SH_ALIGN 29 +#define R_SH_CODE 30 +#define R_SH_DATA 31 +#define R_SH_LABEL 32 +#define R_SH_SWITCH8 33 +#define R_SH_GNU_VTINHERIT 34 +#define R_SH_GNU_VTENTRY 35 +#define R_SH_TLS_GD_32 144 +#define R_SH_TLS_LD_32 145 +#define R_SH_TLS_LDO_32 146 +#define R_SH_TLS_IE_32 147 +#define R_SH_TLS_LE_32 148 +#define R_SH_TLS_DTPMOD32 149 +#define R_SH_TLS_DTPOFF32 150 +#define R_SH_TLS_TPOFF32 151 +#define R_SH_GOT32 160 +#define R_SH_PLT32 161 +#define R_SH_COPY 162 +#define R_SH_GLOB_DAT 163 +#define R_SH_JMP_SLOT 164 +#define R_SH_RELATIVE 165 +#define R_SH_GOTOFF 166 +#define R_SH_GOTPC 167 +/* Keep this the last entry. */ +#define R_SH_NUM 256 + +/* S/390 specific definitions. */ + +/* Valid values for the e_flags field. */ + +#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ + +/* Additional s390 relocs */ + +#define R_390_NONE 0 /* No reloc. */ +#define R_390_8 1 /* Direct 8 bit. */ +#define R_390_12 2 /* Direct 12 bit. */ +#define R_390_16 3 /* Direct 16 bit. */ +#define R_390_32 4 /* Direct 32 bit. */ +#define R_390_PC32 5 /* PC relative 32 bit. */ +#define R_390_GOT12 6 /* 12 bit GOT offset. */ +#define R_390_GOT32 7 /* 32 bit GOT offset. */ +#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +#define R_390_COPY 9 /* Copy symbol at runtime. */ +#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +#define R_390_RELATIVE 12 /* Adjust by program base. */ +#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ +#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +#define R_390_GOT16 15 /* 16 bit GOT offset. */ +#define R_390_PC16 16 /* PC relative 16 bit. */ +#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +#define R_390_64 22 /* Direct 64 bit. */ +#define R_390_PC64 23 /* PC relative 64 bit. */ +#define R_390_GOT64 24 /* 64 bit GOT offset. */ +#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ +#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ +#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ +#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ +#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ +#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ +#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ +#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ +#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ +#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ +#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ +#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ +#define R_390_TLS_GDCALL 38 /* Tag for function call in general + dynamic TLS code. */ +#define R_390_TLS_LDCALL 39 /* Tag for function call in local + dynamic TLS code. */ +#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic + thread local data. */ +#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic + thread local data. */ +#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS + block. */ +#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS + block. */ +#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ +#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ +#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS + block. */ +#define R_390_20 57 /* Direct 20 bit. */ +#define R_390_GOT20 58 /* 20 bit GOT offset. */ +#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ +#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS + block offset. */ +#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ +/* Keep this the last entry. */ +#define R_390_NUM 62 + + +/* CRIS relocations. */ +#define R_CRIS_NONE 0 +#define R_CRIS_8 1 +#define R_CRIS_16 2 +#define R_CRIS_32 3 +#define R_CRIS_8_PCREL 4 +#define R_CRIS_16_PCREL 5 +#define R_CRIS_32_PCREL 6 +#define R_CRIS_GNU_VTINHERIT 7 +#define R_CRIS_GNU_VTENTRY 8 +#define R_CRIS_COPY 9 +#define R_CRIS_GLOB_DAT 10 +#define R_CRIS_JUMP_SLOT 11 +#define R_CRIS_RELATIVE 12 +#define R_CRIS_16_GOT 13 +#define R_CRIS_32_GOT 14 +#define R_CRIS_16_GOTPLT 15 +#define R_CRIS_32_GOTPLT 16 +#define R_CRIS_32_GOTREL 17 +#define R_CRIS_32_PLT_GOTREL 18 +#define R_CRIS_32_PLT_PCREL 19 + +#define R_CRIS_NUM 20 -#endif /* elf.h */ + +/* AMD x86-64 relocations. */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative + offset to GOT */ +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset + to two GOT entries for GD symbol */ +#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset + to two GOT entries for LD symbol */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset + to GOT entry for IE symbol */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ +#define R_X86_64_PC64 24 /* PC relative 64 bit */ +#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ +#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative + offset to GOT */ +#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ +#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset + to GOT entry */ +#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ +#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ +#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset + to PLT entry */ +#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ +#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ +#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ +#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS + descriptor. */ +#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ +#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ +#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ +#define R_X86_64_GOTPCRELX 41 /* like GOTPCREL, but optionally with + linker optimizations */ +#define R_X86_64_REX_GOTPCRELX 42 /* like GOTPCRELX, but a REX prefix + is present */ + +#define R_X86_64_NUM 43 + + +/* AM33 relocations. */ +#define R_MN10300_NONE 0 /* No reloc. */ +#define R_MN10300_32 1 /* Direct 32 bit. */ +#define R_MN10300_16 2 /* Direct 16 bit. */ +#define R_MN10300_8 3 /* Direct 8 bit. */ +#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ +#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ +#define R_MN10300_24 9 /* Direct 24 bit. */ +#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ +#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ +#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ +#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ +#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ +#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ +#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ +#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ +#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ +#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ +#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ +#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ +#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ +#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ +#define R_MN10300_TLS_GD 24 /* 32-bit offset for global dynamic. */ +#define R_MN10300_TLS_LD 25 /* 32-bit offset for local dynamic. */ +#define R_MN10300_TLS_LDO 26 /* Module-relative offset. */ +#define R_MN10300_TLS_GOTIE 27 /* GOT offset for static TLS block + offset. */ +#define R_MN10300_TLS_IE 28 /* GOT address for static TLS block + offset. */ +#define R_MN10300_TLS_LE 29 /* Offset relative to static TLS + block. */ +#define R_MN10300_TLS_DTPMOD 30 /* ID of module containing symbol. */ +#define R_MN10300_TLS_DTPOFF 31 /* Offset in module TLS block. */ +#define R_MN10300_TLS_TPOFF 32 /* Offset in static TLS block. */ +#define R_MN10300_SYM_DIFF 33 /* Adjustment for next reloc as needed + by linker relaxation. */ +#define R_MN10300_ALIGN 34 /* Alignment requirement for linker + relaxation. */ +#define R_MN10300_NUM 35 + + +/* M32R relocs. */ +#define R_M32R_NONE 0 /* No reloc. */ +#define R_M32R_16 1 /* Direct 16 bit. */ +#define R_M32R_32 2 /* Direct 32 bit. */ +#define R_M32R_24 3 /* Direct 24 bit. */ +#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ +#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ +#define R_M32R_LO16 9 /* Low 16 bit. */ +#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ +#define R_M32R_GNU_VTINHERIT 11 +#define R_M32R_GNU_VTENTRY 12 +/* M32R relocs use SHT_RELA. */ +#define R_M32R_16_RELA 33 /* Direct 16 bit. */ +#define R_M32R_32_RELA 34 /* Direct 32 bit. */ +#define R_M32R_24_RELA 35 /* Direct 24 bit. */ +#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ +#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ +#define R_M32R_LO16_RELA 41 /* Low 16 bit */ +#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ +#define R_M32R_RELA_GNU_VTINHERIT 43 +#define R_M32R_RELA_GNU_VTENTRY 44 +#define R_M32R_REL32 45 /* PC relative 32 bit. */ + +#define R_M32R_GOT24 48 /* 24 bit GOT entry */ +#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ +#define R_M32R_COPY 50 /* Copy symbol at runtime */ +#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ +#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ +#define R_M32R_RELATIVE 53 /* Adjust by program base */ +#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ +#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ +#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned + low */ +#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed + low */ +#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ +#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to + GOT with unsigned low */ +#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to + GOT with signed low */ +#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to + GOT */ +#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT + with unsigned low */ +#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT + with signed low */ +#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ +#define R_M32R_NUM 256 /* Keep this the last entry. */ + + +/* TILEPro relocations. */ +#define R_TILEPRO_NONE 0 /* No reloc */ +#define R_TILEPRO_32 1 /* Direct 32 bit */ +#define R_TILEPRO_16 2 /* Direct 16 bit */ +#define R_TILEPRO_8 3 /* Direct 8 bit */ +#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ +#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ +#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ +#define R_TILEPRO_LO16 7 /* Low 16 bit */ +#define R_TILEPRO_HI16 8 /* High 16 bit */ +#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ +#define R_TILEPRO_COPY 10 /* Copy relocation */ +#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ +#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ +#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ +#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ +#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ +#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ +#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ +#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ +#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ +#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ +#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ +#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ +#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ +#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ +#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ +#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ +#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ +#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ +#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ +#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ +#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ +#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ +#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ +#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ +#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ +#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ +#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ +#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ +#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ +#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ +#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ +#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ +#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ +#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ +#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ +#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ +#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ +#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ +/* Relocs 56-59 are currently not defined. */ +#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ +#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ +#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ +#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ +#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ +#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ +#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ +#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ + +#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ +#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ + +#define R_TILEPRO_NUM 130 + + +/* TILE-Gx relocations. */ +#define R_TILEGX_NONE 0 /* No reloc */ +#define R_TILEGX_64 1 /* Direct 64 bit */ +#define R_TILEGX_32 2 /* Direct 32 bit */ +#define R_TILEGX_16 3 /* Direct 16 bit */ +#define R_TILEGX_8 4 /* Direct 8 bit */ +#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ +#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ +#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ +#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ +#define R_TILEGX_HW0 9 /* hword 0 16-bit */ +#define R_TILEGX_HW1 10 /* hword 1 16-bit */ +#define R_TILEGX_HW2 11 /* hword 2 16-bit */ +#define R_TILEGX_HW3 12 /* hword 3 16-bit */ +#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ +#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ +#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ +#define R_TILEGX_COPY 16 /* Copy relocation */ +#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ +#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ +#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ +#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ +#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ +#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ +#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ +#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ +#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ +#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ +#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ +#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ +#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ +#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ +#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ +#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ +#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ +#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ +#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ +#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ +#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ +#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ +#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ +#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ +#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ +#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ +#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ +#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ +#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ +#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ +#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ +#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ +#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ +#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ +#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ +#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ +#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */ +#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */ +#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ +#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ +/* Relocs 90-91 are currently not defined. */ +#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ +#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ +/* Relocs 104-105 are currently not defined. */ +#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ +#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ +#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ +#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ +#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ +#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ +#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ +#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ +#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ +#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ + +#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ +#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ + +#define R_TILEGX_NUM 130 + + +#endif /* elf.h */ diff --git a/tinyc/examples/ex1.c b/tinyc/examples/ex1.c index 28139f92e..3d2a3e18f 100644 --- a/tinyc/examples/ex1.c +++ b/tinyc/examples/ex1.c @@ -1,4 +1,4 @@ -#! /usr/local/bin/tcc -run +#!/usr/local/bin/tcc -run #include <tcclib.h> int main() diff --git a/tinyc/examples/ex3.c b/tinyc/examples/ex3.c index 7c466ad54..5556a4bcd 100644 --- a/tinyc/examples/ex3.c +++ b/tinyc/examples/ex3.c @@ -1,5 +1,4 @@ -#include <stdlib.h> -#include <stdio.h> +#include <tcclib.h> int fib(n) { diff --git a/tinyc/examples/ex4.c b/tinyc/examples/ex4.c index b33b0331d..f92c0da9f 100644 --- a/tinyc/examples/ex4.c +++ b/tinyc/examples/ex4.c @@ -1,4 +1,4 @@ -#!./tcc -run -L/usr/X11R6/lib -lX11 +#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11 #include <stdlib.h> #include <stdio.h> #include <X11/Xlib.h> diff --git a/tinyc/i386-asm.c b/tinyc/i386-asm.c index 12ff8f2ba..2e184974e 100644 --- a/tinyc/i386-asm.c +++ b/tinyc/i386-asm.c @@ -1,7 +1,8 @@ /* * i386 specific functions for TCC assembler - * + * * Copyright (c) 2001, 2002 Fabrice Bellard + * Copyright (c) 2009 Frédéric Feret (x86_64 support) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,66 +19,88 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "tcc.h" + #define MAX_OPERANDS 3 -typedef struct ASMInstr { - uint16_t sym; - uint16_t opcode; - uint16_t instr_type; -#define OPC_JMP 0x01 /* jmp operand */ -#define OPC_B 0x02 /* only used zith OPC_WL */ -#define OPC_WL 0x04 /* accepts w, l or no suffix */ -#define OPC_BWL (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */ -#define OPC_REG 0x08 /* register is added to opcode */ -#define OPC_MODRM 0x10 /* modrm encoding */ -#define OPC_FWAIT 0x20 /* add fwait opcode */ -#define OPC_TEST 0x40 /* test opcodes */ -#define OPC_SHIFT 0x80 /* shift opcodes */ -#define OPC_D16 0x0100 /* generate data16 prefix */ -#define OPC_ARITH 0x0200 /* arithmetic opcodes */ -#define OPC_SHORTJMP 0x0400 /* short jmp operand */ -#define OPC_FARITH 0x0800 /* FPU arithmetic opcodes */ +#define TOK_ASM_first TOK_ASM_clc +#define TOK_ASM_last TOK_ASM_emms +#define TOK_ASM_alllast TOK_ASM_subps + +#define OPC_B 0x01 /* only used with OPC_WL */ +#define OPC_WL 0x02 /* accepts w, l or no suffix */ +#define OPC_BWL (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */ +#define OPC_REG 0x04 /* register is added to opcode */ +#define OPC_MODRM 0x08 /* modrm encoding */ + +#define OPCT_MASK 0x70 +#define OPC_FWAIT 0x10 /* add fwait opcode */ +#define OPC_SHIFT 0x20 /* shift opcodes */ +#define OPC_ARITH 0x30 /* arithmetic opcodes */ +#define OPC_FARITH 0x40 /* FPU arithmetic opcodes */ +#define OPC_TEST 0x50 /* test opcodes */ +#define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i)) + +#define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */ +#define OPC_48 0x200 /* Always has REX prefix */ +#ifdef TCC_TARGET_X86_64 +# define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */ +# define OPC_BWLQ (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */ +# define OPC_WLX OPC_WLQ +# define OPC_BWLX OPC_BWLQ +#else +# define OPC_WLX OPC_WL +# define OPC_BWLX OPC_BWL +#endif + #define OPC_GROUP_SHIFT 13 /* in order to compress the operand type, we use specific operands and - we or only with EA */ -#define OPT_REG8 0 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_MMX 3 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_SSE 4 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_CR 5 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_TR 6 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_DB 7 /* warning: value is hardcoded from TOK_ASM_xxx */ -#define OPT_SEG 8 -#define OPT_ST 9 -#define OPT_IM8 10 -#define OPT_IM8S 11 -#define OPT_IM16 12 -#define OPT_IM32 13 -#define OPT_EAX 14 /* %al, %ax or %eax register */ -#define OPT_ST0 15 /* %st(0) register */ -#define OPT_CL 16 /* %cl register */ -#define OPT_DX 17 /* %dx register */ -#define OPT_ADDR 18 /* OP_EA with only offset */ -#define OPT_INDIR 19 /* *(expr) */ - -/* composite types */ -#define OPT_COMPOSITE_FIRST 20 -#define OPT_IM 20 /* IM8 | IM16 | IM32 */ -#define OPT_REG 21 /* REG8 | REG16 | REG32 */ -#define OPT_REGW 22 /* REG16 | REG32 */ -#define OPT_IMW 23 /* IM16 | IM32 */ - -/* can be ored with any OPT_xxx */ -#define OPT_EA 0x80 - - uint8_t nb_ops; - uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */ -} ASMInstr; + we or only with EA */ +enum { + OPT_REG8=0, /* warning: value is hardcoded from TOK_ASM_xxx */ + OPT_REG16, /* warning: value is hardcoded from TOK_ASM_xxx */ + OPT_REG32, /* warning: value is hardcoded from TOK_ASM_xxx */ +#ifdef TCC_TARGET_X86_64 + OPT_REG64, /* warning: value is hardcoded from TOK_ASM_xxx */ +#endif + OPT_MMX, /* warning: value is hardcoded from TOK_ASM_xxx */ + OPT_SSE, /* warning: value is hardcoded from TOK_ASM_xxx */ + OPT_CR, /* warning: value is hardcoded from TOK_ASM_xxx */ + OPT_TR, /* warning: value is hardcoded from TOK_ASM_xxx */ + OPT_DB, /* warning: value is hardcoded from TOK_ASM_xxx */ + OPT_SEG, + OPT_ST, +#ifdef TCC_TARGET_X86_64 + OPT_REG8_LOW, /* %spl,%bpl,%sil,%dil, encoded like ah,ch,dh,bh, but + with REX prefix, not used in insn templates */ +#endif + OPT_IM8, + OPT_IM8S, + OPT_IM16, + OPT_IM32, +#ifdef TCC_TARGET_X86_64 + OPT_IM64, +#endif + OPT_EAX, /* %al, %ax, %eax or %rax register */ + OPT_ST0, /* %st(0) register */ + OPT_CL, /* %cl register */ + OPT_DX, /* %dx register */ + OPT_ADDR, /* OP_EA with only offset */ + OPT_INDIR, /* *(expr) */ + /* composite types */ + OPT_COMPOSITE_FIRST, + OPT_IM, /* IM8 | IM16 | IM32 */ + OPT_REG, /* REG8 | REG16 | REG32 | REG64 */ + OPT_REGW, /* REG16 | REG32 | REG64 */ + OPT_IMW, /* IM16 | IM32 */ + OPT_MMXSSE, /* MMX | SSE */ + OPT_DISP, /* Like OPT_ADDR, but emitted as displacement (for jumps) */ + OPT_DISP8, /* Like OPT_ADDR, but only 8bit (short jumps) */ + /* can be ored with any OPT_xxx */ + OPT_EA = 0x80 +}; -typedef struct Operand { - uint32_t type; #define OP_REG8 (1 << OPT_REG8) #define OP_REG16 (1 << OPT_REG16) #define OP_REG32 (1 << OPT_REG32) @@ -98,26 +121,58 @@ typedef struct Operand { #define OP_DX (1 << OPT_DX) #define OP_ADDR (1 << OPT_ADDR) #define OP_INDIR (1 << OPT_INDIR) +#ifdef TCC_TARGET_X86_64 +# define OP_REG64 (1 << OPT_REG64) +# define OP_REG8_LOW (1 << OPT_REG8_LOW) +# define OP_IM64 (1 << OPT_IM64) +# define OP_EA32 (OP_EA << 1) +#else +# define OP_REG64 0 +# define OP_REG8_LOW 0 +# define OP_IM64 0 +# define OP_EA32 0 +#endif #define OP_EA 0x40000000 -#define OP_REG (OP_REG8 | OP_REG16 | OP_REG32) -#define OP_IM OP_IM32 +#define OP_REG (OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64) + +#ifdef TCC_TARGET_X86_64 +# define TREG_XAX TREG_RAX +# define TREG_XCX TREG_RCX +# define TREG_XDX TREG_RDX +#else +# define TREG_XAX TREG_EAX +# define TREG_XCX TREG_ECX +# define TREG_XDX TREG_EDX +#endif + +typedef struct ASMInstr { + uint16_t sym; + uint16_t opcode; + uint16_t instr_type; + uint8_t nb_ops; + uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */ +} ASMInstr; + +typedef struct Operand { + uint32_t type; int8_t reg; /* register, -1 if none */ int8_t reg2; /* second register, -1 if none */ uint8_t shift; ExprValue e; } Operand; -static const uint8_t reg_to_size[5] = { +static const uint8_t reg_to_size[9] = { /* [OP_REG8] = 0, [OP_REG16] = 1, [OP_REG32] = 2, +#ifdef TCC_TARGET_X86_64 + [OP_REG64] = 3, +#endif */ - 0, 0, 1, 0, 2 + 0, 0, 1, 0, 2, 0, 0, 0, 3 }; - -#define WORD_PREFIX_OPCODE 0x66 #define NB_TEST_OPCODES 30 @@ -165,13 +220,20 @@ static const uint8_t segment_prefixes[] = { static const ASMInstr asm_instrs[] = { #define ALT(x) x +/* This removes a 0x0f in the second byte */ +#define O(o) ((uint64_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o))) +/* This constructs instr_type from opcode, type and group. */ +#define T(o,i,g) ((i) | ((g) << OPC_GROUP_SHIFT) | ((((o) & 0xff00) == 0x0f00) ? OPC_0F : 0)) #define DEF_ASM_OP0(name, opcode) -#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 }, -#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }}, -#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }}, -#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }}, -#include "i386-asm.h" - +#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 0, { 0 } }, +#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 1, { op0 }}, +#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 2, { op0, op1 }}, +#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 3, { op0, op1, op2 }}, +#ifdef TCC_TARGET_X86_64 +# include "x86_64-asm.h" +#else +# include "i386-asm.h" +#endif /* last operation */ { 0, }, }; @@ -183,13 +245,16 @@ static const uint16_t op0_codes[] = { #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) -#include "i386-asm.h" +#ifdef TCC_TARGET_X86_64 +# include "x86_64-asm.h" +#else +# include "i386-asm.h" +#endif }; static inline int get_reg_shift(TCCState *s1) { int shift, v; - v = asm_int_expr(s1); switch(v) { case 1: @@ -212,21 +277,73 @@ static inline int get_reg_shift(TCCState *s1) return shift; } -static int asm_parse_reg(void) +#ifdef TCC_TARGET_X86_64 +static int asm_parse_numeric_reg(int t, unsigned int *type) { - int reg; + int reg = -1; + if (t >= TOK_IDENT && t < tok_ident) { + const char *s = table_ident[t - TOK_IDENT]->str; + char c; + *type = OP_REG64; + if (*s == 'c') { + s++; + *type = OP_CR; + } + if (*s++ != 'r') + return -1; + /* Don't allow leading '0'. */ + if ((c = *s++) >= '1' && c <= '9') + reg = c - '0'; + else + return -1; + if ((c = *s) >= '0' && c <= '5') + s++, reg = reg * 10 + c - '0'; + if (reg > 15) + return -1; + if ((c = *s) == 0) + ; + else if (*type != OP_REG64) + return -1; + else if (c == 'b' && !s[1]) + *type = OP_REG8; + else if (c == 'w' && !s[1]) + *type = OP_REG16; + else if (c == 'd' && !s[1]) + *type = OP_REG32; + else + return -1; + } + return reg; +} +#endif + +static int asm_parse_reg(unsigned int *type) +{ + int reg = 0; + *type = 0; if (tok != '%') goto error_32; next(); if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) { reg = tok - TOK_ASM_eax; - next(); - return reg; + *type = OP_REG32; +#ifdef TCC_TARGET_X86_64 + } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) { + reg = tok - TOK_ASM_rax; + *type = OP_REG64; + } else if (tok == TOK_ASM_rip) { + reg = -2; /* Probably should use different escape code. */ + *type = OP_REG64; + } else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0 + && (*type == OP_REG32 || *type == OP_REG64)) { + ; +#endif } else { error_32: - expect("32 bit register"); - return 0; + expect("register"); } + next(); + return reg; } static void parse_operand(TCCState *s1, Operand *op) @@ -247,11 +364,11 @@ static void parse_operand(TCCState *s1, Operand *op) reg = tok - TOK_ASM_al; op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */ op->reg = reg & 7; - if ((op->type & OP_REG) && op->reg == TREG_EAX) + if ((op->type & OP_REG) && op->reg == TREG_XAX) op->type |= OP_EAX; - else if (op->type == OP_REG8 && op->reg == TREG_ECX) + else if (op->type == OP_REG8 && op->reg == TREG_XCX) op->type |= OP_CL; - else if (op->type == OP_REG16 && op->reg == TREG_EDX) + else if (op->type == OP_REG16 && op->reg == TREG_XDX) op->type |= OP_DX; } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) { op->type = OP_DB; @@ -267,7 +384,7 @@ static void parse_operand(TCCState *s1, Operand *op) next(); if (tok != TOK_PPNUM) goto reg_error; - p = tokc.cstr->data; + p = tokc.str.data; reg = p[0] - '0'; if ((unsigned)reg >= 8 || p[1] != '\0') goto reg_error; @@ -278,9 +395,16 @@ static void parse_operand(TCCState *s1, Operand *op) if (op->reg == 0) op->type |= OP_ST0; goto no_skip; +#ifdef TCC_TARGET_X86_64 + } else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) { + op->type = OP_REG8 | OP_REG8_LOW; + op->reg = 4 + tok - TOK_ASM_spl; + } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) { + ; +#endif } else { reg_error: - error("unknown register"); + tcc_error("unknown register %%%s", get_tok_str(tok, &tokc)); } next(); no_skip: ; @@ -289,8 +413,7 @@ static void parse_operand(TCCState *s1, Operand *op) next(); asm_expr(s1, &e); op->type = OP_IM32; - op->e.v = e.v; - op->e.sym = e.sym; + op->e = e; if (!op->e.sym) { if (op->e.v == (uint8_t)op->e.v) op->type |= OP_IM8; @@ -298,6 +421,10 @@ static void parse_operand(TCCState *s1, Operand *op) op->type |= OP_IM8S; if (op->e.v == (uint16_t)op->e.v) op->type |= OP_IM16; +#ifdef TCC_TARGET_X86_64 + if (op->e.v != (int32_t)op->e.v && op->e.v != (uint32_t)op->e.v) + op->type = OP_IM64; +#endif } } else { /* address(reg,reg2,shift) with all variants */ @@ -307,27 +434,42 @@ static void parse_operand(TCCState *s1, Operand *op) op->shift = 0; if (tok != '(') { asm_expr(s1, &e); - op->e.v = e.v; - op->e.sym = e.sym; + op->e = e; } else { - op->e.v = 0; - op->e.sym = NULL; + next(); + if (tok == '%') { + unget_tok('('); + op->e.v = 0; + op->e.sym = NULL; + } else { + /* bracketed offset expression */ + asm_expr(s1, &e); + if (tok != ')') + expect(")"); + next(); + op->e.v = e.v; + op->e.sym = e.sym; + } + op->e.pcrel = 0; } if (tok == '(') { + unsigned int type = 0; next(); if (tok != ',') { - op->reg = asm_parse_reg(); + op->reg = asm_parse_reg(&type); } if (tok == ',') { next(); if (tok != ',') { - op->reg2 = asm_parse_reg(); - } + op->reg2 = asm_parse_reg(&type); + } if (tok == ',') { next(); op->shift = get_reg_shift(s1); } } + if (type & OP_REG32) + op->type |= OP_EA32; skip(')'); } if (op->reg == -1 && op->reg2 == -1) @@ -337,46 +479,44 @@ static void parse_operand(TCCState *s1, Operand *op) } /* XXX: unify with C code output ? */ -static void gen_expr32(ExprValue *pe) +ST_FUNC void gen_expr32(ExprValue *pe) +{ + if (pe->pcrel) + /* If PC-relative, always set VT_SYM, even without symbol, + so as to force a relocation to be emitted. */ + gen_addrpc32(VT_SYM, pe->sym, pe->v); + else + gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v); +} + +#ifdef TCC_TARGET_X86_64 +ST_FUNC void gen_expr64(ExprValue *pe) { - if (pe->sym) - greloc(cur_text_section, pe->sym, ind, R_386_32); - gen_le32(pe->v); + gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v); } +#endif /* XXX: unify with C code output ? */ static void gen_disp32(ExprValue *pe) { - Sym *sym; - sym = pe->sym; - if (sym) { - if (sym->r == cur_text_section->sh_num) { - /* same section: we can output an absolute value. Note - that the TCC compiler behaves differently here because - it always outputs a relocation to ease (future) code - elimination in the linker */ - gen_le32(pe->v + (long)sym->next - ind - 4); - } else { - greloc(cur_text_section, sym, ind, R_386_PC32); - gen_le32(pe->v - 4); - } + Sym *sym = pe->sym; + if (sym && sym->r == cur_text_section->sh_num) { + /* same section: we can output an absolute value. Note + that the TCC compiler behaves differently here because + it always outputs a relocation to ease (future) code + elimination in the linker */ + gen_le32(pe->v + sym->jnext - ind - 4); } else { - /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind, R_386_PC32, 0); - gen_le32(pe->v - 4); + if (sym && sym->type.t == VT_VOID) { + sym->type.t = VT_FUNC; + sym->type.ref = NULL; + } + gen_addrpc32(VT_SYM, sym, pe->v); } } - -static void gen_le16(int v) -{ - g(v); - g(v >> 8); -} - /* generate the modrm operand */ -static inline void asm_modrm(int reg, Operand *op) +static inline int asm_modrm(int reg, Operand *op) { int mod, reg1, reg2, sib_reg1; @@ -384,8 +524,20 @@ static inline void asm_modrm(int reg, Operand *op) g(0xc0 + (reg << 3) + op->reg); } else if (op->reg == -1 && op->reg2 == -1) { /* displacement only */ +#ifdef TCC_TARGET_X86_64 + g(0x04 + (reg << 3)); + g(0x25); +#else + g(0x05 + (reg << 3)); +#endif + gen_expr32(&op->e); +#ifdef TCC_TARGET_X86_64 + } else if (op->reg == -2) { + ExprValue *pe = &op->e; g(0x05 + (reg << 3)); - gen_expr32(&op->e); + gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v); + return ind; +#endif } else { sib_reg1 = op->reg; /* fist compute displacement encoding */ @@ -411,44 +563,158 @@ static inline void asm_modrm(int reg, Operand *op) reg2 = 4; /* indicate no index */ g((op->shift << 6) + (reg2 << 3) + sib_reg1); } - /* add offset */ if (mod == 0x40) { g(op->e.v); } else if (mod == 0x80 || op->reg == -1) { - gen_expr32(&op->e); + gen_expr32(&op->e); + } + } + return 0; +} + +#ifdef TCC_TARGET_X86_64 +#define REX_W 0x48 +#define REX_R 0x44 +#define REX_X 0x42 +#define REX_B 0x41 + +static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type, + int regi, int rmi) +{ + unsigned char rex = width64 ? 0x48 : 0; + int saw_high_8bit = 0; + int i; + if (rmi == -1) { + /* No mod/rm byte, but we might have a register op nevertheless + (we will add it to the opcode later). */ + for(i = 0; i < nb_ops; i++) { + if (op_type[i] & (OP_REG | OP_ST)) { + if (ops[i].reg >= 8) { + rex |= REX_B; + ops[i].reg -= 8; + } else if (ops[i].type & OP_REG8_LOW) + rex |= 0x40; + else if (ops[i].type & OP_REG8 && ops[i].reg >= 4) + /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */ + saw_high_8bit = ops[i].reg; + break; + } + } + } else { + if (regi != -1) { + if (ops[regi].reg >= 8) { + rex |= REX_R; + ops[regi].reg -= 8; + } else if (ops[regi].type & OP_REG8_LOW) + rex |= 0x40; + else if (ops[regi].type & OP_REG8 && ops[regi].reg >= 4) + /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */ + saw_high_8bit = ops[regi].reg; + } + if (ops[rmi].type & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_EA)) { + if (ops[rmi].reg >= 8) { + rex |= REX_B; + ops[rmi].reg -= 8; + } else if (ops[rmi].type & OP_REG8_LOW) + rex |= 0x40; + else if (ops[rmi].type & OP_REG8 && ops[rmi].reg >= 4) + /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */ + saw_high_8bit = ops[rmi].reg; + } + if (ops[rmi].type & OP_EA && ops[rmi].reg2 >= 8) { + rex |= REX_X; + ops[rmi].reg2 -= 8; + } + } + if (rex) { + if (saw_high_8bit) + tcc_error("can't encode register %%%ch when REX prefix is required", + "acdb"[saw_high_8bit-4]); + g(rex); + } +} +#endif + +static void maybe_print_stats (void) +{ + static int already = 1; + if (!already) + /* print stats about opcodes */ + { + const struct ASMInstr *pa; + int freq[4]; + int op_vals[500]; + int nb_op_vals, i, j; + + already = 1; + nb_op_vals = 0; + memset(freq, 0, sizeof(freq)); + for(pa = asm_instrs; pa->sym != 0; pa++) { + freq[pa->nb_ops]++; + //for(i=0;i<pa->nb_ops;i++) { + for(j=0;j<nb_op_vals;j++) { + //if (pa->op_type[i] == op_vals[j]) + if (pa->instr_type == op_vals[j]) + goto found; + } + //op_vals[nb_op_vals++] = pa->op_type[i]; + op_vals[nb_op_vals++] = pa->instr_type; + found: ; + //} + } + for(i=0;i<nb_op_vals;i++) { + int v = op_vals[i]; + //if ((v & (v - 1)) != 0) + printf("%3d: %08x\n", i, v); } + printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n", + (int)sizeof(asm_instrs), + (int)sizeof(asm_instrs) / (int)sizeof(ASMInstr), + freq[0], freq[1], freq[2], freq[3]); } } -static void asm_opcode(TCCState *s1, int opcode) +ST_FUNC void asm_opcode(TCCState *s1, int opcode) { const ASMInstr *pa; - int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix; - int nb_ops, s, ss; + int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc; + int nb_ops, s; Operand ops[MAX_OPERANDS], *pop; int op_type[3]; /* decoded op type */ + int alltypes; /* OR of all operand types */ + int autosize; + int p66; +#ifdef TCC_TARGET_X86_64 + int rex64; +#endif + + maybe_print_stats(); + /* force synthetic ';' after prefix instruction, so we can handle */ + /* one-line things like "rep stosb" instead of only "rep\nstosb" */ + if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz) + unget_tok(';'); /* get operands */ pop = ops; nb_ops = 0; seg_prefix = 0; + alltypes = 0; for(;;) { if (tok == ';' || tok == TOK_LINEFEED) break; if (nb_ops >= MAX_OPERANDS) { - error("incorrect number of operands"); + tcc_error("incorrect number of operands"); } parse_operand(s1, pop); if (tok == ':') { - if (pop->type != OP_SEG || seg_prefix) { - error("incorrect prefix"); - } + if (pop->type != OP_SEG || seg_prefix) + tcc_error("incorrect prefix"); seg_prefix = segment_prefixes[pop->reg]; next(); parse_operand(s1, pop); if (!(pop->type & OP_EA)) { - error("segment prefix must be followed by memory reference"); + tcc_error("segment prefix must be followed by memory reference"); } } pop++; @@ -458,35 +724,55 @@ static void asm_opcode(TCCState *s1, int opcode) next(); } - is_short_jmp = 0; s = 0; /* avoid warning */ - + /* optimize matching by using a lookup table (no hashing is needed !) */ for(pa = asm_instrs; pa->sym != 0; pa++) { + int it = pa->instr_type & OPCT_MASK; s = 0; - if (pa->instr_type & OPC_FARITH) { + if (it == OPC_FARITH) { v = opcode - pa->sym; if (!((unsigned)v < 8 * 6 && (v % 6) == 0)) continue; - } else if (pa->instr_type & OPC_ARITH) { - if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4)) + } else if (it == OPC_ARITH) { + if (!(opcode >= pa->sym && opcode < pa->sym + 8*NBWLX)) continue; - goto compute_size; - } else if (pa->instr_type & OPC_SHIFT) { - if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4)) + s = (opcode - pa->sym) % NBWLX; + if ((pa->instr_type & OPC_BWLX) == OPC_WLX) + { + /* We need to reject the xxxb opcodes that we accepted above. + Note that pa->sym for WLX opcodes is the 'w' token, + to get the 'b' token subtract one. */ + if (((opcode - pa->sym + 1) % NBWLX) == 0) + continue; + s++; + } + } else if (it == OPC_SHIFT) { + if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX)) continue; - goto compute_size; - } else if (pa->instr_type & OPC_TEST) { + s = (opcode - pa->sym) % NBWLX; + } else if (it == OPC_TEST) { if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES)) continue; + /* cmovxx is a test opcode but accepts multiple sizes. + TCC doesn't accept the suffixed mnemonic, instead we + simply force size autodetection always. */ + if (pa->instr_type & OPC_WLX) + s = NBWLX - 1; } else if (pa->instr_type & OPC_B) { - if (!(opcode >= pa->sym && opcode <= pa->sym + 3)) +#ifdef TCC_TARGET_X86_64 + /* Some instructions don't have the full size but only + bwl form. insb e.g. */ + if ((pa->instr_type & OPC_WLQ) != OPC_WLQ + && !(opcode >= pa->sym && opcode < pa->sym + NBWLX-1)) + continue; +#endif + if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX)) continue; - compute_size: - s = (opcode - pa->sym) & 3; - } else if (pa->instr_type & OPC_WL) { - if (!(opcode >= pa->sym && opcode <= pa->sym + 2)) + s = opcode - pa->sym; + } else if (pa->instr_type & OPC_WLX) { + if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX-1)) continue; s = opcode - pa->sym + 1; } else { @@ -495,7 +781,17 @@ static void asm_opcode(TCCState *s1, int opcode) } if (pa->nb_ops != nb_ops) continue; +#ifdef TCC_TARGET_X86_64 + /* Special case for moves. Selecting the IM64->REG64 form + should only be done if we really have an >32bit imm64, and that + is hardcoded. Ignore it here. */ + if (pa->opcode == 0xb0 && ops[0].type != OP_IM64 + && (ops[1].type & OP_REG) == OP_REG64 + && !(pa->instr_type & OPC_0F)) + continue; +#endif /* now decode and check each operand */ + alltypes = 0; for(i = 0; i < nb_ops; i++) { int op1, op2; op1 = pa->op_type[i]; @@ -505,73 +801,146 @@ static void asm_opcode(TCCState *s1, int opcode) v = OP_IM8 | OP_IM16 | OP_IM32; break; case OPT_REG: - v = OP_REG8 | OP_REG16 | OP_REG32; + v = OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64; break; case OPT_REGW: - v = OP_REG16 | OP_REG32; + v = OP_REG16 | OP_REG32 | OP_REG64; break; case OPT_IMW: v = OP_IM16 | OP_IM32; break; + case OPT_MMXSSE: + v = OP_MMX | OP_SSE; + break; + case OPT_DISP: + case OPT_DISP8: + v = OP_ADDR; + break; default: v = 1 << op2; break; } if (op1 & OPT_EA) v |= OP_EA; - op_type[i] = v; + op_type[i] = v; if ((ops[i].type & v) == 0) goto next; + alltypes |= ops[i].type; } /* all is matching ! */ break; next: ; } if (pa->sym == 0) { - if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) { + if (opcode >= TOK_ASM_first && opcode <= TOK_ASM_last) { int b; - b = op0_codes[opcode - TOK_ASM_pusha]; + b = op0_codes[opcode - TOK_ASM_first]; if (b & 0xff00) g(b >> 8); g(b); return; + } else if (opcode <= TOK_ASM_alllast) { + tcc_error("bad operand with opcode '%s'", + get_tok_str(opcode, NULL)); } else { - error("unknown opcode '%s'", + tcc_error("unknown opcode '%s'", get_tok_str(opcode, NULL)); } } /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */ - if (s == 3) { - for(i = 0; s == 3 && i < nb_ops; i++) { + autosize = NBWLX-1; +#ifdef TCC_TARGET_X86_64 + /* XXX the autosize should rather be zero, to not have to adjust this + all the time. */ + if ((pa->instr_type & OPC_BWLQ) == OPC_B) + autosize = NBWLX-2; +#endif + if (s == autosize) { + /* Check for register operands providing hints about the size. + Start from the end, i.e. destination operands. This matters + only for opcodes accepting different sized registers, lar and lsl + are such opcodes. */ + for(i = nb_ops - 1; s == autosize && i >= 0; i--) { if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX))) s = reg_to_size[ops[i].type & OP_REG]; } - if (s == 3) { - if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && + if (s == autosize) { + if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32))) s = 2; + else if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && + (ops[0].type & OP_EA)) + s = NBWLX - 2; else - error("cannot infer opcode suffix"); + tcc_error("cannot infer opcode suffix"); } } +#ifdef TCC_TARGET_X86_64 + /* Generate addr32 prefix if needed */ + for(i = 0; i < nb_ops; i++) { + if (ops[i].type & OP_EA32) { + g(0x67); + break; + } + } +#endif /* generate data16 prefix if needed */ - ss = s; - if (s == 1 || (pa->instr_type & OPC_D16)) - g(WORD_PREFIX_OPCODE); - else if (s == 2) - s = 1; + p66 = 0; + if (s == 1) + p66 = 1; + else { + /* accepting mmx+sse in all operands --> needs 0x66 to + switch to sse mode. Accepting only sse in an operand --> is + already SSE insn and needs 0x66/f2/f3 handling. */ + for (i = 0; i < nb_ops; i++) + if ((op_type[i] & (OP_MMX | OP_SSE)) == (OP_MMX | OP_SSE) + && ops[i].type & OP_SSE) + p66 = 1; + } + if (p66) + g(0x66); +#ifdef TCC_TARGET_X86_64 + rex64 = 0; + if (pa->instr_type & OPC_48) + rex64 = 1; + else if (s == 3 || (alltypes & OP_REG64)) { + /* generate REX prefix */ + int default64 = 0; + for(i = 0; i < nb_ops; i++) { + if (op_type[i] == OP_REG64 && pa->opcode != 0xb8) { + /* If only 64bit regs are accepted in one operand + this is a default64 instruction without need for + REX prefixes, except for movabs(0xb8). */ + default64 = 1; + break; + } + } + /* XXX find better encoding for the default64 instructions. */ + if (((opcode != TOK_ASM_push && opcode != TOK_ASM_pop + && opcode != TOK_ASM_pushw && opcode != TOK_ASM_pushl + && opcode != TOK_ASM_pushq && opcode != TOK_ASM_popw + && opcode != TOK_ASM_popl && opcode != TOK_ASM_popq + && opcode != TOK_ASM_call && opcode != TOK_ASM_jmp)) + && !default64) + rex64 = 1; + } +#endif + /* now generates the operation */ - if (pa->instr_type & OPC_FWAIT) + if (OPCT_IS(pa->instr_type, OPC_FWAIT)) g(0x9b); if (seg_prefix) g(seg_prefix); v = pa->opcode; - if (v == 0x69 || v == 0x69) { + if (pa->instr_type & OPC_0F) + v = ((v & ~0xff) << 8) | 0x0f00 | (v & 0xff); + if ((v == 0x69 || v == 0x6b) && nb_ops == 2) { /* kludge for imul $im, %reg */ nb_ops = 3; ops[2] = ops[1]; + op_type[2] = op_type[1]; } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) { v--; /* int $3 case */ nb_ops = 0; @@ -585,27 +954,69 @@ static void asm_opcode(TCCState *s1, int opcode) nb_ops = 0; } else if (v <= 0x05) { /* arith case */ - v += ((opcode - TOK_ASM_addb) >> 2) << 3; - } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) { + v += ((opcode - TOK_ASM_addb) / NBWLX) << 3; + } else if ((pa->instr_type & (OPCT_MASK | OPC_MODRM)) == OPC_FARITH) { /* fpu arith case */ v += ((opcode - pa->sym) / 6) << 3; } + + /* search which operand will be used for modrm */ + modrm_index = -1; + modreg_index = -1; + if (pa->instr_type & OPC_MODRM) { + if (!nb_ops) { + /* A modrm opcode without operands is a special case (e.g. mfence). + It has a group and acts as if there's an register operand 0 + (ax). */ + i = 0; + ops[i].type = OP_REG; + ops[i].reg = 0; + goto modrm_found; + } + /* first look for an ea operand */ + for(i = 0;i < nb_ops; i++) { + if (op_type[i] & OP_EA) + goto modrm_found; + } + /* then if not found, a register or indirection (shift instructions) */ + for(i = 0;i < nb_ops; i++) { + if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR)) + goto modrm_found; + } +#ifdef ASM_DEBUG + tcc_error("bad op table"); +#endif + modrm_found: + modrm_index = i; + /* if a register is used in another operand then it is + used instead of group */ + for(i = 0;i < nb_ops; i++) { + int t = op_type[i]; + if (i != modrm_index && + (t & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) { + modreg_index = i; + break; + } + } + } +#ifdef TCC_TARGET_X86_64 + asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index); +#endif + if (pa->instr_type & OPC_REG) { + /* mov $im, %reg case */ + if (v == 0xb0 && s >= 1) + v += 7; for(i = 0; i < nb_ops; i++) { if (op_type[i] & (OP_REG | OP_ST)) { v += ops[i].reg; break; } } - /* mov $im, %reg case */ - if (pa->opcode == 0xb0 && s >= 1) - v += 7; } if (pa->instr_type & OPC_B) - v += s; - if (pa->instr_type & OPC_TEST) - v += test_bits[opcode - pa->sym]; - if (pa->instr_type & OPC_SHORTJMP) { + v += s >= 1; + if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) { Sym *sym; int jmp_disp; @@ -615,122 +1026,106 @@ static void asm_opcode(TCCState *s1, int opcode) goto no_short_jump; if (sym->r != cur_text_section->sh_num) goto no_short_jump; - jmp_disp = ops[0].e.v + (long)sym->next - ind - 2; + jmp_disp = ops[0].e.v + sym->jnext - ind - 2 - (v >= 0xff); if (jmp_disp == (int8_t)jmp_disp) { /* OK to generate jump */ - is_short_jmp = 1; + ops[0].e.sym = 0; ops[0].e.v = jmp_disp; + op_type[0] = OP_IM8S; } else { no_short_jump: - if (pa->instr_type & OPC_JMP) { - /* long jump will be allowed. need to modify the - opcode slightly */ - if (v == 0xeb) - v = 0xe9; - else - v += 0x0f10; - } else { - error("invalid displacement"); - } + /* long jump will be allowed. need to modify the + opcode slightly */ + if (v == 0xeb) /* jmp */ + v = 0xe9; + else if (v == 0x70) /* jcc */ + v += 0x0f10; + else + tcc_error("invalid displacement"); } } - op1 = v >> 8; + if (OPCT_IS(pa->instr_type, OPC_TEST)) + v += test_bits[opcode - pa->sym]; + op1 = v >> 16; + if (op1) + g(op1); + op1 = (v >> 8) & 0xff; if (op1) g(op1); g(v); - - /* search which operand will used for modrm */ - modrm_index = 0; - if (pa->instr_type & OPC_SHIFT) { - reg = (opcode - pa->sym) >> 2; + + if (OPCT_IS(pa->instr_type, OPC_SHIFT)) { + reg = (opcode - pa->sym) / NBWLX; if (reg == 6) reg = 7; - } else if (pa->instr_type & OPC_ARITH) { - reg = (opcode - pa->sym) >> 2; - } else if (pa->instr_type & OPC_FARITH) { + } else if (OPCT_IS(pa->instr_type, OPC_ARITH)) { + reg = (opcode - pa->sym) / NBWLX; + } else if (OPCT_IS(pa->instr_type, OPC_FARITH)) { reg = (opcode - pa->sym) / 6; } else { reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7; } + + pc = 0; if (pa->instr_type & OPC_MODRM) { - /* first look for an ea operand */ - for(i = 0;i < nb_ops; i++) { - if (op_type[i] & OP_EA) - goto modrm_found; - } - /* then if not found, a register or indirection (shift instructions) */ - for(i = 0;i < nb_ops; i++) { - if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR)) - goto modrm_found; - } -#ifdef ASM_DEBUG - error("bad op table"); -#endif - modrm_found: - modrm_index = i; /* if a register is used in another operand then it is used instead of group */ - for(i = 0;i < nb_ops; i++) { - v = op_type[i]; - if (i != modrm_index && - (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) { - reg = ops[i].reg; - break; - } - } - - asm_modrm(reg, &ops[modrm_index]); + if (modreg_index >= 0) + reg = ops[modreg_index].reg; + pc = asm_modrm(reg, &ops[modrm_index]); } /* emit constants */ - if (pa->opcode == 0x9a || pa->opcode == 0xea) { +#ifndef TCC_TARGET_X86_64 + if (!(pa->instr_type & OPC_0F) + && (pa->opcode == 0x9a || pa->opcode == 0xea)) { /* ljmp or lcall kludge */ - gen_expr32(&ops[1].e); + gen_expr32(&ops[1].e); if (ops[0].e.sym) - error("cannot relocate"); + tcc_error("cannot relocate"); gen_le16(ops[0].e.v); - } else { - for(i = 0;i < nb_ops; i++) { - v = op_type[i]; - if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) { - /* if multiple sizes are given it means we must look - at the op size */ - if (v == (OP_IM8 | OP_IM16 | OP_IM32) || - v == (OP_IM16 | OP_IM32)) { - if (ss == 0) - v = OP_IM8; - else if (ss == 1) - v = OP_IM16; - else - v = OP_IM32; - } - if (v & (OP_IM8 | OP_IM8S)) { - if (ops[i].e.sym) - goto error_relocate; - g(ops[i].e.v); - } else if (v & OP_IM16) { - if (ops[i].e.sym) { - error_relocate: - error("cannot relocate"); - } - gen_le16(ops[i].e.v); - } else { - if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) { - if (is_short_jmp) - g(ops[i].e.v); - else - gen_disp32(&ops[i].e); - } else { - gen_expr32(&ops[i].e); - } - } + return; + } +#endif + for(i = 0;i < nb_ops; i++) { + v = op_type[i]; + if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64 | OP_IM8S | OP_ADDR)) { + /* if multiple sizes are given it means we must look + at the op size */ + if ((v | OP_IM8 | OP_IM64) == (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64)) { + if (s == 0) + v = OP_IM8; + else if (s == 1) + v = OP_IM16; + else if (s == 2 || (v & OP_IM64) == 0) + v = OP_IM32; + else + v = OP_IM64; + } + + if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym) + tcc_error("cannot relocate"); + + if (v & (OP_IM8 | OP_IM8S)) { + g(ops[i].e.v); + } else if (v & OP_IM16) { + gen_le16(ops[i].e.v); +#ifdef TCC_TARGET_X86_64 + } else if (v & OP_IM64) { + gen_expr64(&ops[i].e); +#endif + } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) { + gen_disp32(&ops[i].e); + } else { + gen_expr32(&ops[i].e); } } } -} -#define NB_SAVED_REGS 3 -#define NB_ASM_REGS 8 + /* after immediate operands, adjust pc-relative address */ + if (pc) + add32le(cur_text_section->data + pc - 4, pc - ind); +} /* return the constraint priority (we allocate first the lowest numbered constraints) */ @@ -761,18 +1156,21 @@ static inline int constraint_priority(const char *str) pr = 2; break; case 'r': + case 'R': + case 'p': pr = 3; break; case 'N': case 'M': case 'I': + case 'e': case 'i': case 'm': case 'g': pr = 4; break; default: - error("unknown constraint '%c'", c); + tcc_error("unknown constraint '%c'", c); pr = 0; } if (pr > priority) @@ -788,13 +1186,35 @@ static const char *skip_constraint_modifiers(const char *p) return p; } +/* If T (a token) is of the form "%reg" returns the register + number and type, otherwise return -1. */ +ST_FUNC int asm_parse_regvar (int t) +{ + const char *s; + Operand op; + if (t < TOK_IDENT) + return -1; + s = table_ident[t - TOK_IDENT]->str; + if (s[0] != '%') + return -1; + t = tok_alloc(s+1, strlen(s)-1)->tok; + unget_tok(t); + unget_tok('%'); + parse_operand(tcc_state, &op); + /* Accept only integer regs for now. */ + if (op.type & OP_REG) + return op.reg; + else + return -1; +} + #define REG_OUT_MASK 0x01 #define REG_IN_MASK 0x02 #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) -static void asm_compute_constraints(ASMOperand *operands, - int nb_operands, int nb_outputs, +ST_FUNC void asm_compute_constraints(ASMOperand *operands, + int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg) { @@ -803,7 +1223,7 @@ static void asm_compute_constraints(ASMOperand *operands, int i, j, k, p1, p2, tmp, reg, c, reg_mask; const char *str; uint8_t regs_allocated[NB_ASM_REGS]; - + /* init fields */ for(i=0;i<nb_operands;i++) { op = &operands[i]; @@ -823,24 +1243,29 @@ static void asm_compute_constraints(ASMOperand *operands, /* this is a reference to another constraint */ k = find_constraint(operands, nb_operands, str, NULL); if ((unsigned)k >= i || i < nb_outputs) - error("invalid reference in constraint %d ('%s')", + tcc_error("invalid reference in constraint %d ('%s')", i, str); op->ref_index = k; if (operands[k].input_index >= 0) - error("cannot reference twice the same operand"); + tcc_error("cannot reference twice the same operand"); operands[k].input_index = i; op->priority = 5; + } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL + && op->vt->sym + && (reg = op->vt->sym->r & VT_VALMASK) < VT_CONST) { + op->priority = 1; + op->reg = reg; } else { op->priority = constraint_priority(str); } } - + /* sort operands according to their priority */ for(i=0;i<nb_operands;i++) sorted_op[i] = i; for(i=0;i<nb_operands - 1;i++) { for(j=i+1;j<nb_operands;j++) { - p1 = operands[sorted_op[i]].priority; + p1 = operands[sorted_op[i]].priority; p2 = operands[sorted_op[j]].priority; if (p2 < p1) { tmp = sorted_op[i]; @@ -857,9 +1282,9 @@ static void asm_compute_constraints(ASMOperand *operands, regs_allocated[i] = 0; } /* esp cannot be used */ - regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK; + regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK; /* ebp cannot be used yet */ - regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK; + regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK; /* allocate registers and generate corresponding asm moves */ for(i=0;i<nb_operands;i++) { @@ -877,6 +1302,12 @@ static void asm_compute_constraints(ASMOperand *operands, } else { reg_mask = REG_IN_MASK; } + if (op->reg >= 0) { + if (is_reg_allocated(op->reg)) + tcc_error("asm regvar requests register that's taken already"); + reg = op->reg; + goto reg_found; + } try_next: c = *str++; switch(c) { @@ -887,30 +1318,30 @@ static void asm_compute_constraints(ASMOperand *operands, /* FALL THRU */ case '&': if (j >= nb_outputs) - error("'%c' modifier can only be applied to outputs", c); + tcc_error("'%c' modifier can only be applied to outputs", c); reg_mask = REG_IN_MASK | REG_OUT_MASK; goto try_next; case 'A': /* allocate both eax and edx */ - if (is_reg_allocated(TREG_EAX) || - is_reg_allocated(TREG_EDX)) + if (is_reg_allocated(TREG_XAX) || + is_reg_allocated(TREG_XDX)) goto try_next; op->is_llong = 1; - op->reg = TREG_EAX; - regs_allocated[TREG_EAX] |= reg_mask; - regs_allocated[TREG_EDX] |= reg_mask; + op->reg = TREG_XAX; + regs_allocated[TREG_XAX] |= reg_mask; + regs_allocated[TREG_XDX] |= reg_mask; break; case 'a': - reg = TREG_EAX; + reg = TREG_XAX; goto alloc_reg; case 'b': reg = 3; goto alloc_reg; case 'c': - reg = TREG_ECX; + reg = TREG_XCX; goto alloc_reg; case 'd': - reg = TREG_EDX; + reg = TREG_XDX; goto alloc_reg; case 'S': reg = 6; @@ -929,6 +1360,8 @@ static void asm_compute_constraints(ASMOperand *operands, } goto try_next; case 'r': + case 'R': + case 'p': /* A general address, for x86(64) any register is acceptable*/ /* any general register */ for(reg = 0; reg < 8; reg++) { if (!is_reg_allocated(reg)) @@ -941,6 +1374,7 @@ static void asm_compute_constraints(ASMOperand *operands, op->reg = reg; regs_allocated[reg] |= reg_mask; break; + case 'e': case 'i': if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)) goto try_next; @@ -978,7 +1412,7 @@ static void asm_compute_constraints(ASMOperand *operands, } break; default: - error("asm constraint %d ('%s') could not be satisfied", + tcc_error("asm constraint %d ('%s') could not be satisfied", j, op->constraint); break; } @@ -988,34 +1422,34 @@ static void asm_compute_constraints(ASMOperand *operands, operands[op->input_index].is_llong = op->is_llong; } } - + /* compute out_reg. It is used to store outputs registers to memory locations references by pointers (VT_LLOCAL case) */ *pout_reg = -1; for(i=0;i<nb_operands;i++) { op = &operands[i]; - if (op->reg >= 0 && + if (op->reg >= 0 && (op->vt->r & VT_VALMASK) == VT_LLOCAL && !op->is_memory) { for(reg = 0; reg < 8; reg++) { if (!(regs_allocated[reg] & REG_OUT_MASK)) goto reg_found2; } - error("could not find free output register for reloading"); + tcc_error("could not find free output register for reloading"); reg_found2: *pout_reg = reg; break; } } - + /* print sorted constraints */ #ifdef ASM_DEBUG for(i=0;i<nb_operands;i++) { j = sorted_op[i]; op = &operands[j]; - printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", - j, - op->id ? get_tok_str(op->id, NULL) : "", + printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", + j, + op->id ? get_tok_str(op->id, NULL) : "", op->constraint, op->vt->r, op->reg); @@ -1025,7 +1459,7 @@ static void asm_compute_constraints(ASMOperand *operands, #endif } -static void subst_asm_operand(CString *add_str, +ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) { int r, reg, size, val; @@ -1033,42 +1467,70 @@ static void subst_asm_operand(CString *add_str, r = sv->r; if ((r & VT_VALMASK) == VT_CONST) { - if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n') + if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' && + modifier != 'P') cstr_ccat(add_str, '$'); if (r & VT_SYM) { - cstr_cat(add_str, get_tok_str(sv->sym->v, NULL)); - if (sv->c.i != 0) { - cstr_ccat(add_str, '+'); - } else { - return; - } + const char *name = get_tok_str(sv->sym->v, NULL); + if (sv->sym->v >= SYM_FIRST_ANOM) { + /* In case of anonymous symbols ("L.42", used + for static data labels) we can't find them + in the C symbol table when later looking up + this name. So enter them now into the asm label + list when we still know the symbol. */ + get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym); + } + cstr_cat(add_str, name, -1); + if ((uint32_t)sv->c.i == 0) + goto no_offset; + cstr_ccat(add_str, '+'); } val = sv->c.i; if (modifier == 'n') val = -val; - snprintf(buf, sizeof(buf), "%d", sv->c.i); - cstr_cat(add_str, buf); + snprintf(buf, sizeof(buf), "%d", (int)sv->c.i); + cstr_cat(add_str, buf, -1); + no_offset:; +#ifdef TCC_TARGET_X86_64 + if (r & VT_LVAL) + cstr_cat(add_str, "(%rip)", -1); +#endif } else if ((r & VT_VALMASK) == VT_LOCAL) { - snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i); - cstr_cat(add_str, buf); +#ifdef TCC_TARGET_X86_64 + snprintf(buf, sizeof(buf), "%d(%%rbp)", (int)sv->c.i); +#else + snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i); +#endif + cstr_cat(add_str, buf, -1); } else if (r & VT_LVAL) { reg = r & VT_VALMASK; if (reg >= VT_CONST) - error("internal compiler error"); - snprintf(buf, sizeof(buf), "(%%%s)", - get_tok_str(TOK_ASM_eax + reg, NULL)); - cstr_cat(add_str, buf); + tcc_error("internal compiler error"); + snprintf(buf, sizeof(buf), "(%%%s)", +#ifdef TCC_TARGET_X86_64 + get_tok_str(TOK_ASM_rax + reg, NULL) +#else + get_tok_str(TOK_ASM_eax + reg, NULL) +#endif + ); + cstr_cat(add_str, buf, -1); } else { /* register case */ reg = r & VT_VALMASK; if (reg >= VT_CONST) - error("internal compiler error"); + tcc_error("internal compiler error"); /* choose register operand size */ - if ((sv->type.t & VT_BTYPE) == VT_BYTE) + if ((sv->type.t & VT_BTYPE) == VT_BYTE || + (sv->type.t & VT_BTYPE) == VT_BOOL) size = 1; else if ((sv->type.t & VT_BTYPE) == VT_SHORT) size = 2; +#ifdef TCC_TARGET_X86_64 + else if ((sv->type.t & VT_BTYPE) == VT_LLONG || + (sv->type.t & VT_BTYPE) == VT_PTR) + size = 8; +#endif else size = 4; if (size == 1 && reg >= 4) @@ -1076,14 +1538,20 @@ static void subst_asm_operand(CString *add_str, if (modifier == 'b') { if (reg >= 4) - error("cannot use byte register"); + tcc_error("cannot use byte register"); size = 1; } else if (modifier == 'h') { if (reg >= 4) - error("cannot use byte register"); + tcc_error("cannot use byte register"); size = -1; } else if (modifier == 'w') { size = 2; + } else if (modifier == 'k') { + size = 4; +#ifdef TCC_TARGET_X86_64 + } else if (modifier == 'q') { + size = 8; +#endif } switch(size) { @@ -1099,14 +1567,19 @@ static void subst_asm_operand(CString *add_str, default: reg = TOK_ASM_eax + reg; break; +#ifdef TCC_TARGET_X86_64 + case 8: + reg = TOK_ASM_rax + reg; + break; +#endif } snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL)); - cstr_cat(add_str, buf); + cstr_cat(add_str, buf, -1); } } /* generate prolog and epilog code for asm statement */ -static void asm_gen_code(ASMOperand *operands, int nb_operands, +ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg) @@ -1114,7 +1587,18 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands, uint8_t regs_allocated[NB_ASM_REGS]; ASMOperand *op; int i, reg; - static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 }; + + /* Strictly speaking %Xbp and %Xsp should be included in the + call-preserved registers, but currently it doesn't matter. */ +#ifdef TCC_TARGET_X86_64 +#ifdef TCC_TARGET_PE + static uint8_t reg_saved[] = { 3, 6, 7, 12, 13, 14, 15 }; +#else + static uint8_t reg_saved[] = { 3, 12, 13, 14, 15 }; +#endif +#else + static uint8_t reg_saved[] = { 3, 6, 7 }; +#endif /* mark all used registers */ memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated)); @@ -1125,10 +1609,13 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands, } if (!is_output) { /* generate reg save code */ - for(i = 0; i < NB_SAVED_REGS; i++) { + for(i = 0; i < sizeof(reg_saved)/sizeof(reg_saved[0]); i++) { reg = reg_saved[i]; - if (regs_allocated[reg]) + if (regs_allocated[reg]) { + if (reg >= 8) + g(0x41), reg-=8; g(0x50 + reg); + } } /* generate load code */ @@ -1141,7 +1628,8 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands, output cases) */ SValue sv; sv = *op->vt; - sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; + sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL; + sv.type.t = VT_PTR; load(op->reg, &sv); } else if (i >= nb_outputs || op->is_rw) { /* load value in register */ @@ -1149,8 +1637,8 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands, if (op->is_llong) { SValue sv; sv = *op->vt; - sv.c.ul += 4; - load(TREG_EDX, &sv); + sv.c.i += 4; + load(TREG_XDX, &sv); } } } @@ -1165,8 +1653,10 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands, SValue sv; sv = *op->vt; sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; + sv.type.t = VT_PTR; load(out_reg, &sv); + sv = *op->vt; sv.r = (sv.r & ~VT_VALMASK) | out_reg; store(op->reg, &sv); } @@ -1175,28 +1665,35 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands, if (op->is_llong) { SValue sv; sv = *op->vt; - sv.c.ul += 4; - store(TREG_EDX, &sv); + sv.c.i += 4; + store(TREG_XDX, &sv); } } } } /* generate reg restore code */ - for(i = NB_SAVED_REGS - 1; i >= 0; i--) { + for(i = sizeof(reg_saved)/sizeof(reg_saved[0]) - 1; i >= 0; i--) { reg = reg_saved[i]; - if (regs_allocated[reg]) + if (regs_allocated[reg]) { + if (reg >= 8) + g(0x41), reg-=8; g(0x58 + reg); + } } } } -static void asm_clobber(uint8_t *clobber_regs, const char *str) +ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) { int reg; TokenSym *ts; +#ifdef TCC_TARGET_X86_64 + unsigned int type; +#endif - if (!strcmp(str, "memory") || - !strcmp(str, "cc")) + if (!strcmp(str, "memory") || + !strcmp(str, "cc") || + !strcmp(str, "flags")) return; ts = tok_alloc(str, strlen(str)); reg = ts->tok; @@ -1204,8 +1701,14 @@ static void asm_clobber(uint8_t *clobber_regs, const char *str) reg -= TOK_ASM_eax; } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) { reg -= TOK_ASM_ax; +#ifdef TCC_TARGET_X86_64 + } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) { + reg -= TOK_ASM_rax; + } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) { + ; +#endif } else { - error("invalid clobber register '%s'", str); + tcc_error("invalid clobber register '%s'", str); } clobber_regs[reg] = 1; } diff --git a/tinyc/i386-asm.h b/tinyc/i386-asm.h index a3b28d4d9..65d517955 100644 --- a/tinyc/i386-asm.h +++ b/tinyc/i386-asm.h @@ -1,12 +1,12 @@ - DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */ - DEF_ASM_OP0(popa, 0x61) - DEF_ASM_OP0(clc, 0xf8) + DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */ DEF_ASM_OP0(cld, 0xfc) DEF_ASM_OP0(cli, 0xfa) DEF_ASM_OP0(clts, 0x0f06) DEF_ASM_OP0(cmc, 0xf5) DEF_ASM_OP0(lahf, 0x9f) DEF_ASM_OP0(sahf, 0x9e) + DEF_ASM_OP0(pusha, 0x60) + DEF_ASM_OP0(popa, 0x61) DEF_ASM_OP0(pushfl, 0x9c) DEF_ASM_OP0(popfl, 0x9d) DEF_ASM_OP0(pushf, 0x9c) @@ -33,50 +33,52 @@ DEF_ASM_OP0(iret, 0xcf) DEF_ASM_OP0(rsm, 0x0faa) DEF_ASM_OP0(hlt, 0xf4) - DEF_ASM_OP0(wait, 0x9b) DEF_ASM_OP0(nop, 0x90) + DEF_ASM_OP0(pause, 0xf390) DEF_ASM_OP0(xlat, 0xd7) /* strings */ -ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) +ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX)) ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) +ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX)) -ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) +ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX)) -ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) +ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX)) -ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) -ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) +ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX)) /* bits */ -ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA)) /* prefixes */ + DEF_ASM_OP0(wait, 0x9b) + DEF_ASM_OP0(fwait, 0x9b) DEF_ASM_OP0(aword, 0x67) DEF_ASM_OP0(addr16, 0x67) - DEF_ASM_OP0(word, 0x66) + ALT(DEF_ASM_OP0(word, 0x66)) DEF_ASM_OP0(data16, 0x66) DEF_ASM_OP0(lock, 0xf0) DEF_ASM_OP0(rep, 0xf3) @@ -95,43 +97,43 @@ ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA) DEF_ASM_OP0(ud2, 0x0f0b) /* NOTE: we took the same order as gas opcode definition order */ -ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX)) -ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) -ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) -ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) - -ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) -ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) -ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) -ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) +ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX)) +ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR)) +ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG)) +ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG)) +ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA)) + +ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG)) + +ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG32)) +ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG32)) +ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLX, OPT_TR, OPT_REG32)) +ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_CR)) +ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_DB)) +ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_TR)) ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) +ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16)) ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW)) ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) -ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) -ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) -ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) +ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REGW)) +ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WLX, OPT_IM8S)) +ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32)) +ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG)) -ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) -ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) +ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REGW)) +ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG)) -ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) -ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) -ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) +ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX)) +ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW)) +ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG)) ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) @@ -143,7 +145,7 @@ ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) -ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG)) +ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG)) ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) @@ -152,77 +154,80 @@ ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) /* arith */ -ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ -ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) -ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) -ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) -ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) - -ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) -ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) - -ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) -ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) -ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) -ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) - -ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) -ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) -ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) +ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ +ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG)) +ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX)) +ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG)) + +ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG)) +ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX)) +ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG)) + +ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLX, OPT_REGW)) +ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLX, OPT_REGW)) +ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) + +ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) + +ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) + +ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG)) +ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW)) +ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW)) + +ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX)) +ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX)) /* shifts */ -ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG)) -ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) -ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) +ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP)) ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) +ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8)) ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) -ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) +ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA)) ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) -ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) +ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA)) ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) +ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) DEF_ASM_OP0(leave, 0xc9) DEF_ASM_OP0(ret, 0xc3) + DEF_ASM_OP0(retl,0xc3) +ALT(DEF_ASM_OP1(retl,0xc2, 0, 0, OPT_IM16)) ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) DEF_ASM_OP0(lret, 0xcb) ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) -ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) - DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) +ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8)) + DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8) + DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8) /* float */ /* specific fcomp handling */ @@ -230,6 +235,8 @@ ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) +ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) +ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) @@ -272,7 +279,6 @@ ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) DEF_ASM_OP0(fninit, 0xdbe3) DEF_ASM_OP0(fnclex, 0xdbe2) DEF_ASM_OP0(fnop, 0xd9d0) - DEF_ASM_OP0(fwait, 0x9b) /* fp load */ DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) @@ -335,12 +341,12 @@ ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) /* segments */ DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) - DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) +ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG)) DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) -ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) +ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG)) DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) @@ -352,19 +358,18 @@ ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) /* 486 */ DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) -ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) -ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) +ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA )) +ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA )) DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) - DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) + DEF_ASM_OP2(boundw, 0x6662, 0, OPC_MODRM, OPT_REG16, OPT_EA) /* pentium */ DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) /* pentium pro */ - ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) - +ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW)) DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) @@ -381,62 +386,91 @@ ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT /* mmx */ DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ - DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) -ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) + DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE ) DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) +ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 )) ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) - DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) -ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) - DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) - DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) +ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE )) +ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )) + + DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + + /* sse */ + DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) +ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) + DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) +ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) + DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) +ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) + DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE ) + DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX ) + DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX ) + DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) #undef ALT #undef DEF_ASM_OP0 diff --git a/tinyc/i386-gen.c b/tinyc/i386-gen.c index f958ab547..b9c3599fd 100644 --- a/tinyc/i386-gen.c +++ b/tinyc/i386-gen.c @@ -18,8 +18,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifdef TARGET_DEFS_ONLY + /* number of available registers */ -#define NB_REGS 4 +#define NB_REGS 5 +#define NB_ASM_REGS 8 +#define CONFIG_TCC_ASM /* a register can belong to several classes. The classes must be sorted from more general to more precise (see gv2() code which does @@ -30,6 +34,8 @@ #define RC_ST0 0x0008 #define RC_ECX 0x0010 #define RC_EDX 0x0020 +#define RC_EBX 0x0040 + #define RC_IRET RC_EAX /* function return: integer register */ #define RC_LRET RC_EDX /* function return: second integer register */ #define RC_FRET RC_ST0 /* function return: float register */ @@ -39,14 +45,9 @@ enum { TREG_EAX = 0, TREG_ECX, TREG_EDX, + TREG_EBX, TREG_ST0, -}; - -int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_EAX, - /* ecx */ RC_INT | RC_ECX, - /* edx */ RC_INT | RC_EDX, - /* st0 */ RC_FLOAT | RC_ST0, + TREG_ESP = 4 }; /* return registers for function */ @@ -59,7 +60,7 @@ int reg_classes[NB_REGS] = { /* defined if structures are passed as pointers. Otherwise structures are directly pushed on stack. */ -//#define FUNC_STRUCT_PARAM_AS_PTR +/* #define FUNC_STRUCT_PARAM_AS_PTR */ /* pointer size, in bytes */ #define PTR_SIZE 4 @@ -71,28 +72,34 @@ int reg_classes[NB_REGS] = { #define MAX_ALIGN 8 /******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_386 - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_386_32 -#define R_JMP_SLOT R_386_JMP_SLOT -#define R_COPY R_386_COPY +#else /* ! TARGET_DEFS_ONLY */ +/******************************************************/ +#include "tcc.h" -#define ELF_START_ADDR 0x08048000 -#define ELF_PAGE_SIZE 0x1000 +/* define to 1/0 to [not] have EBX as 4th register */ +#define USE_EBX 0 -/******************************************************/ +ST_DATA const int reg_classes[NB_REGS] = { + /* eax */ RC_INT | RC_EAX, + /* ecx */ RC_INT | RC_ECX, + /* edx */ RC_INT | RC_EDX, + /* ebx */ (RC_INT | RC_EBX) * USE_EBX, + /* st0 */ RC_FLOAT | RC_ST0, +}; static unsigned long func_sub_sp_offset; -static unsigned long func_bound_offset; static int func_ret_sub; +#ifdef CONFIG_TCC_BCHECK +static addr_t func_bound_offset; +static unsigned long func_bound_ind; +#endif /* XXX: make it faster ? */ -void g(int c) +ST_FUNC void g(int c) { int ind1; + if (nocode_wanted) + return; ind1 = ind + 1; if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); @@ -100,7 +107,7 @@ void g(int c) ind = ind1; } -void o(unsigned int c) +ST_FUNC void o(unsigned int c) { while (c) { g(c); @@ -108,7 +115,13 @@ void o(unsigned int c) } } -void gen_le32(int c) +ST_FUNC void gen_le16(int v) +{ + g(v); + g(v >> 8); +} + +ST_FUNC void gen_le32(int c) { g(c); g(c >> 8); @@ -117,50 +130,52 @@ void gen_le32(int c) } /* output a symbol and patch all calls to it */ -void gsym_addr(int t, int a) +ST_FUNC void gsym_addr(int t, int a) { - int n, *ptr; while (t) { - ptr = (int *)(cur_text_section->data + t); - n = *ptr; /* next value */ - *ptr = a - t - 4; + unsigned char *ptr = cur_text_section->data + t; + uint32_t n = read32le(ptr); /* next value */ + write32le(ptr, a - t - 4); t = n; } } -void gsym(int t) +ST_FUNC void gsym(int t) { gsym_addr(t, ind); } -/* psym is used to put an instruction with a data field which is a - reference to a symbol. It is in fact the same as oad ! */ -#define psym oad - /* instruction + 4 bytes data. Return the address of the data */ static int oad(int c, int s) { - int ind1; - + int t; + if (nocode_wanted) + return s; o(c); - ind1 = ind + 4; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - *(int *)(cur_text_section->data + ind) = s; - s = ind; - ind = ind1; - return s; + t = ind; + gen_le32(s); + return t; } +/* generate jmp to a label */ +#define gjmp2(instr,lbl) oad(instr,lbl) + /* output constant with relocation if 'r & VT_SYM' is true */ -static void gen_addr32(int r, Sym *sym, int c) +ST_FUNC void gen_addr32(int r, Sym *sym, int c) { if (r & VT_SYM) greloc(cur_text_section, sym, ind, R_386_32); gen_le32(c); } -/* generate a modrm reference. 'op_reg' contains the addtionnal 3 +ST_FUNC void gen_addrpc32(int r, Sym *sym, int c) +{ + if (r & VT_SYM) + greloc(cur_text_section, sym, ind, R_386_PC32); + gen_le32(c - 4); +} + +/* generate a modrm reference. 'op_reg' contains the additional 3 opcode bits */ static void gen_modrm(int op_reg, int r, Sym *sym, int c) { @@ -183,25 +198,33 @@ static void gen_modrm(int op_reg, int r, Sym *sym, int c) } } - /* load 'r' from value 'sv' */ -void load(int r, SValue *sv) +ST_FUNC void load(int r, SValue *sv) { int v, t, ft, fc, fr; SValue v1; +#ifdef TCC_TARGET_PE + SValue v2; + sv = pe_getimport(sv, &v2); +#endif + fr = sv->r; - ft = sv->type.t; - fc = sv->c.ul; + ft = sv->type.t & ~VT_DEFSIGN; + fc = sv->c.i; + + ft &= ~(VT_VOLATILE | VT_CONSTANT); v = fr & VT_VALMASK; if (fr & VT_LVAL) { if (v == VT_LLOCAL) { v1.type.t = VT_INT; v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; - load(r, &v1); + v1.c.i = fc; fr = r; + if (!(reg_classes[fr] & RC_INT)) + fr = get_reg(RC_INT); + load(fr, &v1); } if ((ft & VT_BTYPE) == VT_FLOAT) { o(0xd9); /* flds */ @@ -212,7 +235,7 @@ void load(int r, SValue *sv) } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { o(0xdb); /* fldt */ r = 5; - } else if ((ft & VT_TYPE) == VT_BYTE) { + } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) { o(0xbe0f); /* movsbl */ } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { o(0xb60f); /* movzbl */ @@ -229,8 +252,13 @@ void load(int r, SValue *sv) o(0xb8 + r); /* mov $xx, r */ gen_addr32(fr, sv->sym, fc); } else if (v == VT_LOCAL) { - o(0x8d); /* lea xxx(%ebp), r */ - gen_modrm(r, VT_LOCAL, sv->sym, fc); + if (fc) { + o(0x8d); /* lea xxx(%ebp), r */ + gen_modrm(r, VT_LOCAL, sv->sym, fc); + } else { + o(0x89); + o(0xe8 + r); /* mov %ebp, r */ + } } else if (v == VT_CMP) { oad(0xb8 + r, 0); /* mov $0, r */ o(0x0f); /* setxx %br */ @@ -250,13 +278,19 @@ void load(int r, SValue *sv) } /* store register 'r' in lvalue 'v' */ -void store(int r, SValue *v) +ST_FUNC void store(int r, SValue *v) { int fr, bt, ft, fc; +#ifdef TCC_TARGET_PE + SValue v2; + v = pe_getimport(v, &v2); +#endif + ft = v->type.t; - fc = v->c.ul; + fc = v->c.i; fr = v->r & VT_VALMASK; + ft &= ~(VT_VOLATILE | VT_CONSTANT); bt = ft & VT_BTYPE; /* XXX: incorrect if float reg to reg */ if (bt == VT_FLOAT) { @@ -296,37 +330,94 @@ static void gadd_sp(int val) } } +#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE +static void gen_static_call(int v) +{ + Sym *sym; + + sym = external_global_sym(v, &func_old_type, 0); + oad(0xe8, -4); + greloc(cur_text_section, sym, ind-4, R_386_PC32); +} +#endif + /* 'is_jmp' is '1' if it is a jump */ static void gcall_or_jmp(int is_jmp) { int r; - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - /* constant case */ - if (vtop->r & VT_SYM) { - /* relocation case */ - greloc(cur_text_section, vtop->sym, - ind + 1, R_386_PC32); - } else { - /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind + 1, R_386_PC32, 0); - } - oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */ + if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) { + /* constant and relocation case */ + greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32); + oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */ } else { /* otherwise, indirect call */ r = gv(RC_INT); o(0xff); /* call/jmp *r */ o(0xd0 + r + (is_jmp << 4)); } + if (!is_jmp) { + int rt; + /* extend the return value to the whole register if necessary + visual studio and gcc do not always set the whole eax register + when assigning the return value of a function */ + rt = vtop->type.ref->type.t; + switch (rt & VT_BTYPE) { + case VT_BYTE: + if (rt & VT_UNSIGNED) { + o(0xc0b60f); /* movzx %al, %eax */ + } + else { + o(0xc0be0f); /* movsx %al, %eax */ + } + break; + case VT_SHORT: + if (rt & VT_UNSIGNED) { + o(0xc0b70f); /* movzx %ax, %eax */ + } + else { + o(0xc0bf0f); /* movsx %ax, %eax */ + } + break; + default: + break; + } + } } static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX }; static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX }; +/* Return the number of registers needed to return the struct, or 0 if + returning via struct pointer. */ +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) +{ +#ifdef TCC_TARGET_PE + int size, align; + *ret_align = 1; // Never have to re-align return values for x86 + *regsize = 4; + size = type_size(vt, &align); + if (size > 8 || (size & (size - 1))) + return 0; + if (size == 8) + ret->t = VT_LLONG; + else if (size == 4) + ret->t = VT_INT; + else if (size == 2) + ret->t = VT_SHORT; + else + ret->t = VT_BYTE; + ret->ref = NULL; + return 1; +#else + *ret_align = 1; // Never have to re-align return values for x86 + return 0; +#endif +} + /* Generate function call. The function address is pushed first, then all the parameters in call order. This functions pops all the parameters and the function address. */ -void gfunc_call(int nb_args) +ST_FUNC void gfunc_call(int nb_args) { int size, align, r, args_size, i, func_call; Sym *func_sym; @@ -380,7 +471,7 @@ void gfunc_call(int nb_args) } save_regs(0); /* save used temporary registers */ func_sym = vtop->type.ref; - func_call = FUNC_CALL(func_sym->r); + func_call = func_sym->f.func_call; /* fast call case */ if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) || func_call == FUNC_FASTCALLW) { @@ -401,20 +492,25 @@ void gfunc_call(int nb_args) args_size -= 4; } } +#ifndef TCC_TARGET_PE + else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT) + args_size -= 4; +#endif gcall_or_jmp(0); - if (args_size && func_call != FUNC_STDCALL) + + if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW) gadd_sp(args_size); vtop--; } #ifdef TCC_TARGET_PE -#define FUNC_PROLOG_SIZE 10 +#define FUNC_PROLOG_SIZE (10 + USE_EBX) #else -#define FUNC_PROLOG_SIZE 9 +#define FUNC_PROLOG_SIZE (9 + USE_EBX) #endif /* generate function prolog of type 't' */ -void gfunc_prolog(CType *func_type) +ST_FUNC void gfunc_prolog(CType *func_type) { int addr, align, size, func_call, fastcall_nb_regs; int param_index, param_addr; @@ -423,9 +519,11 @@ void gfunc_prolog(CType *func_type) CType *type; sym = func_type->ref; - func_call = FUNC_CALL(sym->r); + func_call = sym->f.func_call; addr = 8; loc = 0; + func_vc = 0; + if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1; fastcall_regs_ptr = fastcall_regs; @@ -443,7 +541,14 @@ void gfunc_prolog(CType *func_type) /* if the function returns a structure, then add an implicit pointer parameter */ func_vt = sym->type; + func_var = (sym->f.func_type == FUNC_ELLIPSIS); +#ifdef TCC_TARGET_PE + size = type_size(&func_vt,&align); + if (((func_vt.t & VT_BTYPE) == VT_STRUCT) + && (size > 8 || (size & (size - 1)))) { +#else if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { +#endif /* XXX: fastcall case ? */ func_vc = addr; addr += 4; @@ -475,57 +580,69 @@ void gfunc_prolog(CType *func_type) param_index++; } func_ret_sub = 0; - /* pascal type call ? */ - if (func_call == FUNC_STDCALL) + /* pascal type call or fastcall ? */ + if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW) func_ret_sub = addr - 8; +#ifndef TCC_TARGET_PE + else if (func_vc) + func_ret_sub = 4; +#endif +#ifdef CONFIG_TCC_BCHECK /* leave some room for bound checking code */ if (tcc_state->do_bounds_check) { + func_bound_offset = lbounds_section->data_offset; + func_bound_ind = ind; oad(0xb8, 0); /* lbound section pointer */ oad(0xb8, 0); /* call to function */ - func_bound_offset = lbounds_section->data_offset; } +#endif } /* generate function epilog */ -void gfunc_epilog(void) +ST_FUNC void gfunc_epilog(void) { - int v, saved_ind; + addr_t v, saved_ind; #ifdef CONFIG_TCC_BCHECK if (tcc_state->do_bounds_check && func_bound_offset != lbounds_section->data_offset) { - int saved_ind; - int *bounds_ptr; - Sym *sym, *sym_data; + addr_t saved_ind; + addr_t *bounds_ptr; + Sym *sym_data; + /* add end of table info */ - bounds_ptr = section_ptr_add(lbounds_section, sizeof(int)); + bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); *bounds_ptr = 0; + /* generate bound local allocation */ saved_ind = ind; - ind = func_sub_sp_offset; + ind = func_bound_ind; sym_data = get_sym_ref(&char_pointer_type, lbounds_section, func_bound_offset, lbounds_section->data_offset); greloc(cur_text_section, sym_data, ind + 1, R_386_32); oad(0xb8, 0); /* mov %eax, xxx */ - sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); + gen_static_call(TOK___bound_local_new); ind = saved_ind; + /* generate bound check local freeing */ o(0x5250); /* save returned value, if any */ - greloc(cur_text_section, sym_data, - ind + 1, R_386_32); + greloc(cur_text_section, sym_data, ind + 1, R_386_32); oad(0xb8, 0); /* mov %eax, xxx */ - sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); + gen_static_call(TOK___bound_local_delete); o(0x585a); /* restore returned value, if any */ } #endif + + /* align local size to word & save local variables */ + v = (-loc + 3) & -4; + +#if USE_EBX + o(0x8b); + gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4)); +#endif + o(0xc9); /* leave */ if (func_ret_sub == 0) { o(0xc3); /* ret */ @@ -534,38 +651,34 @@ void gfunc_epilog(void) g(func_ret_sub); g(func_ret_sub >> 8); } - /* align local size to word & save local variables */ - - v = (-loc + 3) & -4; saved_ind = ind; ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; #ifdef TCC_TARGET_PE if (v >= 4096) { - Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); oad(0xb8, v); /* mov stacksize, %eax */ - oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ - greloc(cur_text_section, sym, ind-4, R_386_PC32); + gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */ } else #endif { o(0xe58955); /* push %ebp, mov %esp, %ebp */ o(0xec81); /* sub esp, stacksize */ gen_le32(v); -#if FUNC_PROLOG_SIZE == 10 +#ifdef TCC_TARGET_PE o(0x90); /* adjust to FUNC_PROLOG_SIZE */ #endif } + o(0x53 * USE_EBX); /* push ebx */ ind = saved_ind; } /* generate a jump to a label */ -int gjmp(int t) +ST_FUNC int gjmp(int t) { - return psym(0xe9, t); + return gjmp2(0xe9, t); } /* generate a jump to a fixed address */ -void gjmp_addr(int a) +ST_FUNC void gjmp_addr(int a) { int r; r = a - ind - 2; @@ -577,53 +690,64 @@ void gjmp_addr(int a) } } -/* generate a test. set 'inv' to invert test. Stack entry is popped */ -int gtst(int inv, int t) +ST_FUNC void gtst_addr(int inv, int a) { - int v, *p; - - v = vtop->r & VT_VALMASK; + int v = vtop->r & VT_VALMASK; if (v == VT_CMP) { + inv ^= (vtop--)->c.i; + a -= ind + 2; + if (a == (char)a) { + g(inv - 32); + g(a); + } else { + g(0x0f); + oad(inv - 16, a - 4); + } + } else if ((v & ~1) == VT_JMP) { + if ((v & 1) != inv) { + gjmp_addr(a); + gsym(vtop->c.i); + } else { + gsym(vtop->c.i); + o(0x05eb); + gjmp_addr(a); + } + vtop--; + } +} + +/* generate a test. set 'inv' to invert test. Stack entry is popped */ +ST_FUNC int gtst(int inv, int t) +{ + int v = vtop->r & VT_VALMASK; + if (nocode_wanted) { + ; + } else if (v == VT_CMP) { /* fast case : can jump directly since flags are set */ g(0x0f); - t = psym((vtop->c.i - 16) ^ inv, t); + t = gjmp2((vtop->c.i - 16) ^ inv, t); } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ - p = &vtop->c.i; - while (*p != 0) - p = (int *)(cur_text_section->data + *p); - *p = t; - t = vtop->c.i; + uint32_t n1, n = vtop->c.i; + if (n) { + while ((n1 = read32le(cur_text_section->data + n))) + n = n1; + write32le(cur_text_section->data + n, t); + t = vtop->c.i; + } } else { t = gjmp(t); gsym(vtop->c.i); } - } else { - if (is_float(vtop->type.t) || - (vtop->type.t & VT_BTYPE) == VT_LLONG) { - vpushi(0); - gen_op(TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - } else { - v = gv(RC_INT); - o(0x85); - o(0xc0 + v * 9); - g(0x0f); - t = psym(0x85 ^ inv, t); - } } vtop--; return t; } /* generate an integer binary operation */ -void gen_opi(int op) +ST_FUNC void gen_opi(int op) { int r, fr, opc, c; @@ -639,10 +763,16 @@ void gen_opi(int op) vswap(); c = vtop->c.i; if (c == (char)c) { - /* XXX: generate inc and dec for smaller code ? */ - o(0x83); - o(0xc0 | (opc << 3) | r); - g(c); + /* generate inc and dec for smaller code */ + if (c==1 && opc==0 && op != TOK_ADDC1) { + o (0x40 | r); // inc + } else if (c==1 && opc==5 && op != TOK_SUBC1) { + o (0x48 | r); // dec + } else { + o(0x83); + o(0xc0 | (opc << 3) | r); + g(c); + } } else { o(0x81); oad(0xc0 | (opc << 3) | r, c); @@ -728,6 +858,8 @@ void gen_opi(int op) fr = vtop[0].r; vtop--; save_reg(TREG_EDX); + /* save EAX too if used otherwise */ + save_reg_upstack(TREG_EAX, 1); if (op == TOK_UMULL) { o(0xf7); /* mul fr */ o(0xe0 + fr); @@ -755,9 +887,9 @@ void gen_opi(int op) } /* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ + two operands are guaranteed to have the same floating point type */ /* XXX: need to use ST1 too */ -void gen_opf(int op) +ST_FUNC void gen_opf(int op) { int a, ft, fc, swapped, r; @@ -794,7 +926,10 @@ void gen_opf(int op) swapped = 0; if (swapped) o(0xc9d9); /* fxch %st(1) */ - o(0xe9da); /* fucompp */ + if (op == TOK_EQ || op == TOK_NE) + o(0xe9da); /* fucompp */ + else + o(0xd9de); /* fcompp */ o(0xe0df); /* fnstsw %ax */ if (op == TOK_EQ) { o(0x45e480); /* and $0x45, %ah */ @@ -840,7 +975,7 @@ void gen_opf(int op) break; } ft = vtop->type.t; - fc = vtop->c.ul; + fc = vtop->c.i; if ((ft & VT_BTYPE) == VT_LDOUBLE) { o(0xde); /* fxxxp %st, %st(1) */ o(0xc1 + (a << 3)); @@ -852,7 +987,7 @@ void gen_opf(int op) r = get_reg(RC_INT); v1.type.t = VT_INT; v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; + v1.c.i = fc; load(r, &v1); fc = 0; } @@ -869,7 +1004,7 @@ void gen_opf(int op) /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' and 'long long' cases. */ -void gen_cvt_itof(int t) +ST_FUNC void gen_cvt_itof(int t) { save_reg(TREG_ST0); gv(RC_INT); @@ -898,65 +1033,31 @@ void gen_cvt_itof(int t) } /* convert fp to int 't' type */ -/* XXX: handle long long case */ -void gen_cvt_ftoi(int t) +ST_FUNC void gen_cvt_ftoi(int t) { - int r, r2, size; - Sym *sym; - CType ushort_type; - - ushort_type.t = VT_SHORT | VT_UNSIGNED; - - gv(RC_FLOAT); - if (t != VT_INT) - size = 8; - else - size = 4; - - o(0x2dd9); /* ldcw xxx */ - sym = external_global_sym(TOK___tcc_int_fpu_control, - &ushort_type, VT_LVAL); - greloc(cur_text_section, sym, - ind, R_386_32); - gen_le32(0); - - oad(0xec81, size); /* sub $xxx, %esp */ - if (size == 4) - o(0x1cdb); /* fistpl */ + int bt = vtop->type.t & VT_BTYPE; + if (bt == VT_FLOAT) + vpush_global_sym(&func_old_type, TOK___fixsfdi); + else if (bt == VT_LDOUBLE) + vpush_global_sym(&func_old_type, TOK___fixxfdi); else - o(0x3cdf); /* fistpll */ - o(0x24); - o(0x2dd9); /* ldcw xxx */ - sym = external_global_sym(TOK___tcc_fpu_control, - &ushort_type, VT_LVAL); - greloc(cur_text_section, sym, - ind, R_386_32); - gen_le32(0); - - r = get_reg(RC_INT); - o(0x58 + r); /* pop r */ - if (size == 8) { - if (t == VT_LLONG) { - vtop->r = r; /* mark reg as used */ - r2 = get_reg(RC_INT); - o(0x58 + r2); /* pop r2 */ - vtop->r2 = r2; - } else { - o(0x04c483); /* add $4, %esp */ - } - } - vtop->r = r; + vpush_global_sym(&func_old_type, TOK___fixdfdi); + vswap(); + gfunc_call(1); + vpushi(0); + vtop->r = REG_IRET; + vtop->r2 = REG_LRET; } /* convert from one floating point type to another */ -void gen_cvt_ftof(int t) +ST_FUNC void gen_cvt_ftof(int t) { /* all we have to do on i386 is to put the float in a register */ gv(RC_FLOAT); } /* computed goto support */ -void ggoto(void) +ST_FUNC void ggoto(void) { gcall_or_jmp(1); vtop--; @@ -966,33 +1067,28 @@ void ggoto(void) #ifdef CONFIG_TCC_BCHECK /* generate a bounded pointer addition */ -void gen_bounded_ptr_add(void) +ST_FUNC void gen_bounded_ptr_add(void) { - Sym *sym; - /* prepare fast i386 function call (args in eax and edx) */ gv2(RC_EAX, RC_EDX); /* save all temporary registers */ vtop -= 2; save_regs(0); /* do a fast function call */ - sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0); - greloc(cur_text_section, sym, - ind + 1, R_386_PC32); - oad(0xe8, -4); + gen_static_call(TOK___bound_ptr_add); /* returned pointer is in eax */ vtop++; vtop->r = TREG_EAX | VT_BOUNDED; /* address of bounding function call point */ - vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); + vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); } /* patch pointer addition in vtop so that pointer dereferencing is also tested */ -void gen_bounded_ptr_deref(void) +ST_FUNC void gen_bounded_ptr_deref(void) { - int func; - int size, align; + addr_t func; + int size, align; Elf32_Rel *rel; Sym *sym; @@ -1014,14 +1110,14 @@ void gen_bounded_ptr_deref(void) case 12: func = TOK___bound_ptr_indir12; break; case 16: func = TOK___bound_ptr_indir16; break; default: - error("unhandled size when derefencing bounded pointer"); + tcc_error("unhandled size when dereferencing bounded pointer"); func = 0; break; } /* patch relocation */ /* XXX: find a better solution ? */ - rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul); + rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i); sym = external_global_sym(func, &func_old_type, 0); if (!sym->c) put_extern_sym(sym, NULL, 0, 0); @@ -1029,6 +1125,40 @@ void gen_bounded_ptr_deref(void) } #endif +/* Save the stack pointer onto the stack */ +ST_FUNC void gen_vla_sp_save(int addr) { + /* mov %esp,addr(%ebp)*/ + o(0x89); + gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr); +} + +/* Restore the SP from a location on the stack */ +ST_FUNC void gen_vla_sp_restore(int addr) { + o(0x8b); + gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr); +} + +/* Subtract from the stack pointer, and push the resulting value onto the stack */ +ST_FUNC void gen_vla_alloc(CType *type, int align) { +#ifdef TCC_TARGET_PE + /* alloca does more than just adjust %rsp on Windows */ + vpush_global_sym(&func_old_type, TOK_alloca); + vswap(); /* Move alloca ref past allocation size */ + gfunc_call(1); +#else + int r; + r = gv(RC_INT); /* allocation size */ + /* sub r,%rsp */ + o(0x2b); + o(0xe0 | r); + /* We align to 16 bytes rather than align */ + /* and ~15, %esp */ + o(0xf0e483); + vpop(); +#endif +} + /* end of X86 code generator */ /*************************************************************/ - +#endif +/*************************************************************/ diff --git a/tinyc/i386-link.c b/tinyc/i386-link.c new file mode 100644 index 000000000..b44664404 --- /dev/null +++ b/tinyc/i386-link.c @@ -0,0 +1,244 @@ +#ifdef TARGET_DEFS_ONLY + +#define EM_TCC_TARGET EM_386 + +/* relocation type for 32 bit data relocation */ +#define R_DATA_32 R_386_32 +#define R_DATA_PTR R_386_32 +#define R_JMP_SLOT R_386_JMP_SLOT +#define R_GLOB_DAT R_386_GLOB_DAT +#define R_COPY R_386_COPY +#define R_RELATIVE R_386_RELATIVE + +#define R_NUM R_386_NUM + +#define ELF_START_ADDR 0x08048000 +#define ELF_PAGE_SIZE 0x1000 + +#define PCRELATIVE_DLLPLT 0 +#define RELOCATE_DLLPLT 0 + +#else /* !TARGET_DEFS_ONLY */ + +#include "tcc.h" + +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_386_RELATIVE: + case R_386_16: + case R_386_32: + case R_386_GOTPC: + case R_386_GOTOFF: + case R_386_GOT32: + case R_386_GOT32X: + case R_386_GLOB_DAT: + case R_386_COPY: + return 0; + + case R_386_PC16: + case R_386_PC32: + case R_386_PLT32: + case R_386_JMP_SLOT: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe whether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_386_RELATIVE: + case R_386_16: + case R_386_GLOB_DAT: + case R_386_JMP_SLOT: + case R_386_COPY: + return NO_GOTPLT_ENTRY; + + case R_386_32: + /* This relocations shouldn't normally need GOT or PLT + slots if it weren't for simplicity in the code generator. + See our caller for comments. */ + return AUTO_GOTPLT_ENTRY; + + case R_386_PC16: + case R_386_PC32: + return AUTO_GOTPLT_ENTRY; + + case R_386_GOTPC: + case R_386_GOTOFF: + return BUILD_GOT_ONLY; + + case R_386_GOT32: + case R_386_GOT32X: + case R_386_PLT32: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) +{ + Section *plt = s1->plt; + uint8_t *p; + int modrm; + unsigned plt_offset, relofs; + + /* on i386 if we build a DLL, we add a %ebx offset */ + if (s1->output_type == TCC_OUTPUT_DLL) + modrm = 0xa3; + else + modrm = 0x25; + + /* empty PLT: create PLT0 entry that pushes the library identifier + (GOT + PTR_SIZE) and jumps to ld.so resolution routine + (GOT + 2 * PTR_SIZE) */ + if (plt->data_offset == 0) { + p = section_ptr_add(plt, 16); + p[0] = 0xff; /* pushl got + PTR_SIZE */ + p[1] = modrm + 0x10; + write32le(p + 2, PTR_SIZE); + p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */ + p[7] = modrm; + write32le(p + 8, PTR_SIZE * 2); + } + plt_offset = plt->data_offset; + + /* The PLT slot refers to the relocation entry it needs via offset. + The reloc entry is created below, so its offset is the current + data_offset */ + relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0; + + /* Jump to GOT entry where ld.so initially put the address of ip + 4 */ + p = section_ptr_add(plt, 16); + p[0] = 0xff; /* jmp *(got + x) */ + p[1] = modrm; + write32le(p + 2, got_offset); + p[6] = 0x68; /* push $xxx */ + write32le(p + 7, relofs); + p[11] = 0xe9; /* jmp plt_start */ + write32le(p + 12, -(plt->data_offset)); + return plt_offset; +} + +/* relocate the PLT: compute addresses and offsets in the PLT now that final + address for PLT and GOT are known (see fill_program_header) */ +ST_FUNC void relocate_plt(TCCState *s1) +{ + uint8_t *p, *p_end; + + if (!s1->plt) + return; + + p = s1->plt->data; + p_end = p + s1->plt->data_offset; + + if (p < p_end) { + add32le(p + 2, s1->got->sh_addr); + add32le(p + 8, s1->got->sh_addr); + p += 16; + while (p < p_end) { + add32le(p + 2, s1->got->sh_addr); + p += 16; + } + } +} + +static ElfW_Rel *qrel; /* ptr to next reloc entry reused */ + +void relocate_init(Section *sr) +{ + qrel = (ElfW_Rel *) sr->data; +} + +void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) +{ + int sym_index, esym_index; + + sym_index = ELFW(R_SYM)(rel->r_info); + + switch (type) { + case R_386_32: + if (s1->output_type == TCC_OUTPUT_DLL) { + esym_index = s1->sym_attrs[sym_index].dyn_index; + qrel->r_offset = rel->r_offset; + if (esym_index) { + qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32); + qrel++; + return; + } else { + qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE); + qrel++; + } + } + add32le(ptr, val); + return; + case R_386_PC32: + if (s1->output_type == TCC_OUTPUT_DLL) { + /* DLL relocation */ + esym_index = s1->sym_attrs[sym_index].dyn_index; + if (esym_index) { + qrel->r_offset = rel->r_offset; + qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32); + qrel++; + return; + } + } + add32le(ptr, val - addr); + return; + case R_386_PLT32: + add32le(ptr, val - addr); + return; + case R_386_GLOB_DAT: + case R_386_JMP_SLOT: + write32le(ptr, val); + return; + case R_386_GOTPC: + add32le(ptr, s1->got->sh_addr - addr); + return; + case R_386_GOTOFF: + add32le(ptr, val - s1->got->sh_addr); + return; + case R_386_GOT32: + case R_386_GOT32X: + /* we load the got offset */ + add32le(ptr, s1->sym_attrs[sym_index].got_offset); + return; + case R_386_16: + if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { + output_file: + tcc_error("can only produce 16-bit binary files"); + } + write16le(ptr, read16le(ptr) + val); + return; + case R_386_PC16: + if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) + goto output_file; + write16le(ptr, read16le(ptr) + val - addr); + return; + case R_386_RELATIVE: + /* do nothing */ + return; + case R_386_COPY: + /* This relocation must copy initialized data from the library + to the program .bss segment. Currently made like for ARM + (to remove noise of default case). Is this true? + */ + return; + default: + fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n", + type, (unsigned)addr, ptr, (unsigned)val); + return; + } +} + +#endif /* !TARGET_DEFS_ONLY */ diff --git a/tinyc/i386-tok.h b/tinyc/i386-tok.h new file mode 100644 index 000000000..8c25af09d --- /dev/null +++ b/tinyc/i386-tok.h @@ -0,0 +1,253 @@ +/* ------------------------------------------------------------------ */ +/* WARNING: relative order of tokens is important. */ + +/* register */ + DEF_ASM(al) + DEF_ASM(cl) + DEF_ASM(dl) + DEF_ASM(bl) + DEF_ASM(ah) + DEF_ASM(ch) + DEF_ASM(dh) + DEF_ASM(bh) + DEF_ASM(ax) + DEF_ASM(cx) + DEF_ASM(dx) + DEF_ASM(bx) + DEF_ASM(sp) + DEF_ASM(bp) + DEF_ASM(si) + DEF_ASM(di) + DEF_ASM(eax) + DEF_ASM(ecx) + DEF_ASM(edx) + DEF_ASM(ebx) + DEF_ASM(esp) + DEF_ASM(ebp) + DEF_ASM(esi) + DEF_ASM(edi) +#ifdef TCC_TARGET_X86_64 + DEF_ASM(rax) + DEF_ASM(rcx) + DEF_ASM(rdx) + DEF_ASM(rbx) + DEF_ASM(rsp) + DEF_ASM(rbp) + DEF_ASM(rsi) + DEF_ASM(rdi) +#endif + DEF_ASM(mm0) + DEF_ASM(mm1) + DEF_ASM(mm2) + DEF_ASM(mm3) + DEF_ASM(mm4) + DEF_ASM(mm5) + DEF_ASM(mm6) + DEF_ASM(mm7) + DEF_ASM(xmm0) + DEF_ASM(xmm1) + DEF_ASM(xmm2) + DEF_ASM(xmm3) + DEF_ASM(xmm4) + DEF_ASM(xmm5) + DEF_ASM(xmm6) + DEF_ASM(xmm7) + DEF_ASM(cr0) + DEF_ASM(cr1) + DEF_ASM(cr2) + DEF_ASM(cr3) + DEF_ASM(cr4) + DEF_ASM(cr5) + DEF_ASM(cr6) + DEF_ASM(cr7) + DEF_ASM(tr0) + DEF_ASM(tr1) + DEF_ASM(tr2) + DEF_ASM(tr3) + DEF_ASM(tr4) + DEF_ASM(tr5) + DEF_ASM(tr6) + DEF_ASM(tr7) + DEF_ASM(db0) + DEF_ASM(db1) + DEF_ASM(db2) + DEF_ASM(db3) + DEF_ASM(db4) + DEF_ASM(db5) + DEF_ASM(db6) + DEF_ASM(db7) + DEF_ASM(dr0) + DEF_ASM(dr1) + DEF_ASM(dr2) + DEF_ASM(dr3) + DEF_ASM(dr4) + DEF_ASM(dr5) + DEF_ASM(dr6) + DEF_ASM(dr7) + DEF_ASM(es) + DEF_ASM(cs) + DEF_ASM(ss) + DEF_ASM(ds) + DEF_ASM(fs) + DEF_ASM(gs) + DEF_ASM(st) + DEF_ASM(rip) + +#ifdef TCC_TARGET_X86_64 + /* The four low parts of sp/bp/si/di that exist only on + x86-64 (encoding aliased to ah,ch,dh,dh when not using REX). */ + DEF_ASM(spl) + DEF_ASM(bpl) + DEF_ASM(sil) + DEF_ASM(dil) +#endif + /* generic two operands */ + DEF_BWLX(mov) + + DEF_BWLX(add) + DEF_BWLX(or) + DEF_BWLX(adc) + DEF_BWLX(sbb) + DEF_BWLX(and) + DEF_BWLX(sub) + DEF_BWLX(xor) + DEF_BWLX(cmp) + + /* unary ops */ + DEF_BWLX(inc) + DEF_BWLX(dec) + DEF_BWLX(not) + DEF_BWLX(neg) + DEF_BWLX(mul) + DEF_BWLX(imul) + DEF_BWLX(div) + DEF_BWLX(idiv) + + DEF_BWLX(xchg) + DEF_BWLX(test) + + /* shifts */ + DEF_BWLX(rol) + DEF_BWLX(ror) + DEF_BWLX(rcl) + DEF_BWLX(rcr) + DEF_BWLX(shl) + DEF_BWLX(shr) + DEF_BWLX(sar) + + DEF_WLX(shld) + DEF_WLX(shrd) + + DEF_ASM(pushw) + DEF_ASM(pushl) +#ifdef TCC_TARGET_X86_64 + DEF_ASM(pushq) +#endif + DEF_ASM(push) + + DEF_ASM(popw) + DEF_ASM(popl) +#ifdef TCC_TARGET_X86_64 + DEF_ASM(popq) +#endif + DEF_ASM(pop) + + DEF_BWL(in) + DEF_BWL(out) + + DEF_WLX(movzb) + DEF_ASM(movzwl) + DEF_ASM(movsbw) + DEF_ASM(movsbl) + DEF_ASM(movswl) +#ifdef TCC_TARGET_X86_64 + DEF_ASM(movsbq) + DEF_ASM(movswq) + DEF_ASM(movzwq) + DEF_ASM(movslq) +#endif + + DEF_WLX(lea) + + DEF_ASM(les) + DEF_ASM(lds) + DEF_ASM(lss) + DEF_ASM(lfs) + DEF_ASM(lgs) + + DEF_ASM(call) + DEF_ASM(jmp) + DEF_ASM(lcall) + DEF_ASM(ljmp) + + DEF_ASMTEST(j,) + + DEF_ASMTEST(set,) + DEF_ASMTEST(set,b) + DEF_ASMTEST(cmov,) + + DEF_WLX(bsf) + DEF_WLX(bsr) + DEF_WLX(bt) + DEF_WLX(bts) + DEF_WLX(btr) + DEF_WLX(btc) + + DEF_WLX(lar) + DEF_WLX(lsl) + + /* generic FP ops */ + DEF_FP(add) + DEF_FP(mul) + + DEF_ASM(fcom) + DEF_ASM(fcom_1) /* non existent op, just to have a regular table */ + DEF_FP1(com) + + DEF_FP(comp) + DEF_FP(sub) + DEF_FP(subr) + DEF_FP(div) + DEF_FP(divr) + + DEF_BWLX(xadd) + DEF_BWLX(cmpxchg) + + /* string ops */ + DEF_BWLX(cmps) + DEF_BWLX(scmp) + DEF_BWL(ins) + DEF_BWL(outs) + DEF_BWLX(lods) + DEF_BWLX(slod) + DEF_BWLX(movs) + DEF_BWLX(smov) + DEF_BWLX(scas) + DEF_BWLX(ssca) + DEF_BWLX(stos) + DEF_BWLX(ssto) + + /* generic asm ops */ +#define ALT(x) +#define DEF_ASM_OP0(name, opcode) DEF_ASM(name) +#define DEF_ASM_OP0L(name, opcode, group, instr_type) +#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) +#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) +#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) +#ifdef TCC_TARGET_X86_64 +# include "x86_64-asm.h" +#else +# include "i386-asm.h" +#endif + +#define ALT(x) +#define DEF_ASM_OP0(name, opcode) +#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name) +#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name) +#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name) +#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name) +#ifdef TCC_TARGET_X86_64 +# include "x86_64-asm.h" +#else +# include "i386-asm.h" +#endif diff --git a/tinyc/il-gen.c b/tinyc/il-gen.c index 29f052655..bb670ccb0 100644 --- a/tinyc/il-gen.c +++ b/tinyc/il-gen.c @@ -18,6 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#error this code has bit-rotted since 2003 + /* number of available registers */ #define NB_REGS 3 @@ -41,7 +43,7 @@ enum { REG_ST2, }; -int reg_classes[NB_REGS] = { +const int reg_classes[NB_REGS] = { /* ST0 */ RC_ST | RC_ST0, /* ST1 */ RC_ST | RC_ST1, /* ST2 */ RC_ST, @@ -53,11 +55,11 @@ int reg_classes[NB_REGS] = { #define REG_FRET REG_ST0 /* float return register */ /* defined if function parameters must be evaluated in reverse order */ -//#define INVERT_FUNC_PARAMS +/* #define INVERT_FUNC_PARAMS */ /* defined if structures are passed as pointers. Otherwise structures are directly pushed on stack. */ -//#define FUNC_STRUCT_PARAM_AS_PTR +/* #define FUNC_STRUCT_PARAM_AS_PTR */ /* pointer size, in bytes */ #define PTR_SIZE 4 @@ -193,7 +195,7 @@ static void il_type_to_str(char *buf, int buf_size, pstrcat(buf, buf_size, tstr); break; case VT_STRUCT: - error("structures not handled yet"); + tcc_error("structures not handled yet"); break; case VT_FUNC: s = sym_find((unsigned)t >> VT_STRUCT_SHIFT); @@ -387,7 +389,7 @@ void gfunc_start(GFuncContext *c, int func_call) void gfunc_param(GFuncContext *c) { if ((vtop->t & VT_BTYPE) == VT_STRUCT) { - error("structures passed as value not handled yet"); + tcc_error("structures passed as value not handled yet"); } else { /* simply push on stack */ gv(RC_ST0); @@ -441,6 +443,7 @@ void gfunc_prolog(int t) /* if the function returns a structure, then add an implicit pointer parameter */ func_vt = sym->t; + func_var = (sym->c == FUNC_ELLIPSIS); if ((func_vt & VT_BTYPE) == VT_STRUCT) { func_vc = addr; addr++; @@ -528,19 +531,6 @@ int gtst(int inv, int t) t = gjmp(t); gsym(vtop->c.i); } - } else { - if (is_float(vtop->t)) { - vpushi(0); - gen_op(TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - } else { - v = gv(RC_INT); - t = out_opj(IL_OP_BRTRUE - inv, t); - } } vtop--; return t; @@ -612,7 +602,7 @@ void gen_opi(int op) } /* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ + two operands are guaranteed to have the same floating point type */ void gen_opf(int op) { /* same as integer */ diff --git a/tinyc/include/float.h b/tinyc/include/float.h index 5f1c6f73c..f16f1f0cb 100644 --- a/tinyc/include/float.h +++ b/tinyc/include/float.h @@ -27,7 +27,7 @@ #define DBL_MAX_10_EXP 308 /* horrible intel long double */ -#ifdef __i386__ +#if defined __i386__ || defined __x86_64__ #define LDBL_MANT_DIG 64 #define LDBL_DIG 18 diff --git a/tinyc/include/stdarg.h b/tinyc/include/stdarg.h index 86e556ca3..10ce733b4 100644 --- a/tinyc/include/stdarg.h +++ b/tinyc/include/stdarg.h @@ -2,10 +2,11 @@ #define _STDARG_H #ifdef __x86_64__ -#include <stdlib.h> +#ifndef _WIN64 +//This should be in sync with the declaration on our lib/libtcc1.c /* GCC compatible definition of va_list. */ -struct __va_list_struct { +typedef struct { unsigned int gp_offset; unsigned int fp_offset; union { @@ -13,51 +14,62 @@ struct __va_list_struct { char *overflow_arg_area; }; char *reg_save_area; -}; +} __va_list_struct; -typedef struct __va_list_struct *va_list; +typedef __va_list_struct va_list[1]; -/* we use __builtin_(malloc|free) to avoid #define malloc tcc_malloc */ -/* XXX: this lacks the support of aggregated types. */ -#define va_start(ap, last) \ - (ap = (va_list)__builtin_malloc(sizeof(struct __va_list_struct)), \ - *ap = *(struct __va_list_struct*)( \ - (char*)__builtin_frame_address(0) - 16), \ - ap->overflow_arg_area = ((char *)__builtin_frame_address(0) + \ - ap->overflow_offset), \ - ap->reg_save_area = (char *)__builtin_frame_address(0) - 176 - 16 \ - ) -#define va_arg(ap, type) \ - (*(type*)(__builtin_types_compatible_p(type, long double) \ - ? (ap->overflow_arg_area += 16, \ - ap->overflow_arg_area - 16) \ - : __builtin_types_compatible_p(type, double) \ - ? (ap->fp_offset < 128 + 48 \ - ? (ap->fp_offset += 16, \ - ap->reg_save_area + ap->fp_offset - 16) \ - : (ap->overflow_arg_area += 8, \ - ap->overflow_arg_area - 8)) \ - : (ap->gp_offset < 48 \ - ? (ap->gp_offset += 8, \ - ap->reg_save_area + ap->gp_offset - 8) \ - : (ap->overflow_arg_area += 8, \ - ap->overflow_arg_area - 8)) \ - )) -#define va_copy(dest, src) \ - ((dest) = (va_list)malloc(sizeof(struct __va_list_struct)), \ - *(dest) = *(src)) -#define va_end(ap) __builtin_free(ap) +void __va_start(__va_list_struct *ap, void *fp); +void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align); -#else +#define va_start(ap, last) __va_start(ap, __builtin_frame_address(0)) +#define va_arg(ap, type) \ + (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type)))) +#define va_copy(dest, src) (*(dest) = *(src)) +#define va_end(ap) + +/* avoid conflicting definition for va_list on Macs. */ +#define _VA_LIST_T +#else /* _WIN64 */ typedef char *va_list; +#define va_start(ap,last) __builtin_va_start(ap,last) +#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \ + ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8)) +#define va_copy(dest, src) ((dest) = (src)) +#define va_end(ap) +#endif +#elif __arm__ +typedef char *va_list; +#define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x) +#define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \ + & ~(_tcc_alignof(type) - 1)) +#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) +#define va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \ + &~3), *(type *)(ap - ((sizeof(type)+3)&~3))) +#define va_copy(dest, src) (dest) = (src) +#define va_end(ap) + +#elif defined(__aarch64__) +typedef struct { + void *__stack; + void *__gr_top; + void *__vr_top; + int __gr_offs; + int __vr_offs; +} va_list; +#define va_start(ap, last) __va_start(ap, last) +#define va_arg(ap, type) __va_arg(ap, type) +#define va_end(ap) +#define va_copy(dest, src) ((dest) = (src)) + +#else /* __i386__ */ +typedef char *va_list; /* only correct for i386 */ #define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) #define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3))) #define va_copy(dest, src) (dest) = (src) #define va_end(ap) - #endif /* fix a buggy dependency on GCC in libio.h */ diff --git a/tinyc/include/stdbool.h b/tinyc/include/stdbool.h index 6ed13a611..d2ee446e7 100644 --- a/tinyc/include/stdbool.h +++ b/tinyc/include/stdbool.h @@ -6,5 +6,6 @@ #define bool _Bool #define true 1 #define false 0 +#define __bool_true_false_are_defined 1 #endif /* _STDBOOL_H */ diff --git a/tinyc/include/stddef.h b/tinyc/include/stddef.h index aef5b3923..694d50375 100644 --- a/tinyc/include/stddef.h +++ b/tinyc/include/stddef.h @@ -1,20 +1,54 @@ #ifndef _STDDEF_H #define _STDDEF_H -#define NULL ((void *)0) typedef __SIZE_TYPE__ size_t; +typedef __PTRDIFF_TYPE__ ssize_t; typedef __WCHAR_TYPE__ wchar_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; -#define offsetof(type, field) ((size_t) &((type *)0)->field) +typedef __PTRDIFF_TYPE__ intptr_t; +typedef __SIZE_TYPE__ uintptr_t; #ifndef __int8_t_defined #define __int8_t_defined -typedef char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long long int int64_t; +typedef signed char int8_t; +typedef signed short int int16_t; +typedef signed int int32_t; +#ifdef __LP64__ +typedef signed long int int64_t; +#else +typedef signed long long int int64_t; +#endif +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +#ifdef __LP64__ +typedef unsigned long int uint64_t; +#else +typedef unsigned long long int uint64_t; +#endif +#endif + +#ifndef NULL +#define NULL ((void*)0) #endif +#define offsetof(type, field) ((size_t)&((type *)0)->field) + void *alloca(size_t size); #endif + +/* Older glibc require a wint_t from <stddef.h> (when requested + by __need_wint_t, as otherwise stddef.h isn't allowed to + define this type). Note that this must be outside the normal + _STDDEF_H guard, so that it works even when we've included the file + already (without requiring wint_t). Some other libs define _WINT_T + if they've already provided that type, so we can use that as guard. + TCC defines __WINT_TYPE__ for us. */ +#if defined (__need_wint_t) +#ifndef _WINT_T +#define _WINT_T +typedef __WINT_TYPE__ wint_t; +#endif +#undef __need_wint_t +#endif diff --git a/tinyc/include/varargs.h b/tinyc/include/varargs.h index daee29e87..d614366ed 100644 --- a/tinyc/include/varargs.h +++ b/tinyc/include/varargs.h @@ -1,11 +1,12 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ #ifndef _VARARGS_H #define _VARARGS_H -#include <stdarg.h> - -#define va_dcl -#define va_alist __va_alist -#undef va_start -#define va_start(ap) ap = __builtin_varargs_start +#error "TinyCC no longer implements <varargs.h>." +#error "Revise your code to use <stdarg.h>." #endif diff --git a/tinyc/lib/alloca-arm.S b/tinyc/lib/alloca-arm.S new file mode 100644 index 000000000..68556e36d --- /dev/null +++ b/tinyc/lib/alloca-arm.S @@ -0,0 +1,17 @@ + .text + .align 2 + .global alloca + .type alloca, %function +alloca: +#ifdef __TINYC__ + .int 0xe060d00d + .int 0xe3cdd007 + .int 0xe1a0000d + .int 0xe1a0f00e +#else + rsb sp, r0, sp + bic sp, sp, #7 + mov r0, sp + mov pc, lr +#endif + .size alloca, .-alloca diff --git a/tinyc/lib/alloca86-bt.S b/tinyc/lib/alloca86-bt.S index 994da2042..4f95cf134 100644 --- a/tinyc/lib/alloca86-bt.S +++ b/tinyc/lib/alloca86-bt.S @@ -1,7 +1,5 @@ /* ---------------------------------------------- */ -/* alloca86b.S */ - -#include "../config.h" +/* alloca86-bt.S */ .globl __bound_alloca @@ -13,13 +11,13 @@ __bound_alloca: and $-4,%eax jz p6 -#ifdef TCC_TARGET_PE +#ifdef _WIN32 p4: cmp $4096,%eax - jle p5 + jbe p5 + test %eax,-4096(%esp) sub $4096,%esp sub $4096,%eax - test %eax,(%esp) jmp p4 p5: @@ -42,4 +40,8 @@ p6: push %edx ret +/* mark stack as nonexecutable */ +#if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",@progbits +#endif /* ---------------------------------------------- */ diff --git a/tinyc/lib/alloca86.S b/tinyc/lib/alloca86.S index fb208a0ba..bb7a2c24a 100644 --- a/tinyc/lib/alloca86.S +++ b/tinyc/lib/alloca86.S @@ -1,8 +1,6 @@ /* ---------------------------------------------- */ /* alloca86.S */ -#include "../config.h" - .globl alloca alloca: @@ -12,13 +10,13 @@ alloca: and $-4,%eax jz p3 -#ifdef TCC_TARGET_PE +#ifdef _WIN32 p1: cmp $4096,%eax - jle p2 + jbe p2 + test %eax,-4096(%esp) sub $4096,%esp sub $4096,%eax - test %eax,(%esp) jmp p1 p2: #endif diff --git a/tinyc/lib/alloca86_64-bt.S b/tinyc/lib/alloca86_64-bt.S new file mode 100644 index 000000000..4cbad90f8 --- /dev/null +++ b/tinyc/lib/alloca86_64-bt.S @@ -0,0 +1,56 @@ +/* ---------------------------------------------- */ +/* alloca86_64.S */ + +.globl __bound_alloca +__bound_alloca: + +#ifdef _WIN32 + # bound checking is not implemented + pop %rdx + mov %rcx,%rax + add $15,%rax + and $-16,%rax + jz p3 + +p1: + cmp $4096,%rax + jbe p2 + test %rax,-4096(%rsp) + sub $4096,%rsp + sub $4096,%rax + jmp p1 +p2: + + sub %rax,%rsp + mov %rsp,%rax + add $32,%rax + +p3: + push %rdx + ret +#else + pop %rdx + mov %rdi,%rax + mov %rax,%rsi # size, a second parm to the __bound_new_region + + add $15,%rax + and $-16,%rax + jz p3 + + + sub %rax,%rsp + mov %rsp,%rdi # pointer, a first parm to the __bound_new_region + mov %rsp,%rax + + push %rdx + push %rax + call __bound_new_region + pop %rax + pop %rdx + +p3: + push %rdx + ret +#endif + +/* ---------------------------------------------- */ diff --git a/tinyc/lib/alloca86_64.S b/tinyc/lib/alloca86_64.S new file mode 100644 index 000000000..ae3c97de3 --- /dev/null +++ b/tinyc/lib/alloca86_64.S @@ -0,0 +1,34 @@ +/* ---------------------------------------------- */ +/* alloca86_64.S */ + +.globl alloca + +alloca: + pop %rdx +#ifdef _WIN32 + mov %rcx,%rax +#else + mov %rdi,%rax +#endif + add $15,%rax + and $-16,%rax + jz p3 + +#ifdef _WIN32 +p1: + cmp $4096,%rax + jbe p2 + test %rax,-4096(%rsp) + sub $4096,%rsp + sub $4096,%rax + jmp p1 +p2: +#endif + + sub %rax,%rsp + mov %rsp,%rax +p3: + push %rdx + ret + +/* ---------------------------------------------- */ diff --git a/tinyc/lib/armeabi.c b/tinyc/lib/armeabi.c new file mode 100644 index 000000000..a59640dd0 --- /dev/null +++ b/tinyc/lib/armeabi.c @@ -0,0 +1,501 @@ +/* TCC ARM runtime EABI + Copyright (C) 2013 Thomas Preud'homme + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.*/ + +#ifdef __TINYC__ +#define INT_MIN (-2147483647 - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 0xffffffff +#define LONG_MIN (-2147483647L - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 0xffffffffUL +#define LLONG_MAX 9223372036854775807LL +#define LLONG_MIN (-9223372036854775807LL - 1) +#define ULLONG_MAX 0xffffffffffffffffULL +#else +#include <limits.h> +#endif + +/* We rely on the little endianness and EABI calling convention for this to + work */ + +typedef struct double_unsigned_struct { + unsigned low; + unsigned high; +} double_unsigned_struct; + +typedef struct unsigned_int_struct { + unsigned low; + int high; +} unsigned_int_struct; + +#define REGS_RETURN(name, type) \ + void name ## _return(type ret) {} + + +/* Float helper functions */ + +#define FLOAT_EXP_BITS 8 +#define FLOAT_FRAC_BITS 23 + +#define DOUBLE_EXP_BITS 11 +#define DOUBLE_FRAC_BITS 52 + +#define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1) + +REGS_RETURN(unsigned_int_struct, unsigned_int_struct) +REGS_RETURN(double_unsigned_struct, double_unsigned_struct) + +/* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */ + + +/* float to [unsigned] long long conversion */ +#define DEFINE__AEABI_F2XLZ(name, with_sign) \ +void __aeabi_ ## name(unsigned val) \ +{ \ + int exp, high_shift, sign; \ + double_unsigned_struct ret; \ + \ + /* compute sign */ \ + sign = val >> 31; \ + \ + /* compute real exponent */ \ + exp = val >> FLOAT_FRAC_BITS; \ + exp &= (1 << FLOAT_EXP_BITS) - 1; \ + exp -= ONE_EXP(FLOAT); \ + \ + /* undefined behavior if truncated value cannot be represented */ \ + if (with_sign) { \ + if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \ + return; \ + } else { \ + if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \ + return; \ + } \ + \ + val &= (1 << FLOAT_FRAC_BITS) - 1; \ + if (exp >= 32) { \ + ret.high = 1 << (exp - 32); \ + if (exp - 32 >= FLOAT_FRAC_BITS) { \ + ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS); \ + ret.low = 0; \ + } else { \ + high_shift = FLOAT_FRAC_BITS - (exp - 32); \ + ret.high |= val >> high_shift; \ + ret.low = val << (32 - high_shift); \ + } \ + } else { \ + ret.high = 0; \ + ret.low = 1 << exp; \ + if (exp > FLOAT_FRAC_BITS) \ + ret.low |= val << (exp - FLOAT_FRAC_BITS); \ + else \ + ret.low |= val >> (FLOAT_FRAC_BITS - exp); \ + } \ + \ + /* encode negative integer using 2's complement */ \ + if (with_sign && sign) { \ + ret.low = ~ret.low; \ + ret.high = ~ret.high; \ + if (ret.low == UINT_MAX) { \ + ret.low = 0; \ + ret.high++; \ + } else \ + ret.low++; \ + } \ + \ + double_unsigned_struct_return(ret); \ +} + +/* float to unsigned long long conversion */ +DEFINE__AEABI_F2XLZ(f2ulz, 0) + +/* float to long long conversion */ +DEFINE__AEABI_F2XLZ(f2lz, 1) + +/* double to [unsigned] long long conversion */ +#define DEFINE__AEABI_D2XLZ(name, with_sign) \ +void __aeabi_ ## name(double_unsigned_struct val) \ +{ \ + int exp, high_shift, sign; \ + double_unsigned_struct ret; \ + \ + /* compute sign */ \ + sign = val.high >> 31; \ + \ + /* compute real exponent */ \ + exp = (val.high >> (DOUBLE_FRAC_BITS - 32)); \ + exp &= (1 << DOUBLE_EXP_BITS) - 1; \ + exp -= ONE_EXP(DOUBLE); \ + \ + /* undefined behavior if truncated value cannot be represented */ \ + if (with_sign) { \ + if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \ + return; \ + } else { \ + if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */ \ + return; \ + } \ + \ + val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1; \ + if (exp >= 32) { \ + ret.high = 1 << (exp - 32); \ + if (exp >= DOUBLE_FRAC_BITS) { \ + high_shift = exp - DOUBLE_FRAC_BITS; \ + ret.high |= val.high << high_shift; \ + ret.high |= val.low >> (32 - high_shift); \ + ret.low = val.low << high_shift; \ + } else { \ + high_shift = DOUBLE_FRAC_BITS - exp; \ + ret.high |= val.high >> high_shift; \ + ret.low = val.high << (32 - high_shift); \ + ret.low |= val.low >> high_shift; \ + } \ + } else { \ + ret.high = 0; \ + ret.low = 1 << exp; \ + if (exp > DOUBLE_FRAC_BITS - 32) { \ + high_shift = exp - DOUBLE_FRAC_BITS - 32; \ + ret.low |= val.high << high_shift; \ + ret.low |= val.low >> (32 - high_shift); \ + } else \ + ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp); \ + } \ + \ + /* encode negative integer using 2's complement */ \ + if (with_sign && sign) { \ + ret.low = ~ret.low; \ + ret.high = ~ret.high; \ + if (ret.low == UINT_MAX) { \ + ret.low = 0; \ + ret.high++; \ + } else \ + ret.low++; \ + } \ + \ + double_unsigned_struct_return(ret); \ +} + +/* double to unsigned long long conversion */ +DEFINE__AEABI_D2XLZ(d2ulz, 0) + +/* double to long long conversion */ +DEFINE__AEABI_D2XLZ(d2lz, 1) + +/* long long to float conversion */ +#define DEFINE__AEABI_XL2F(name, with_sign) \ +unsigned __aeabi_ ## name(unsigned long long v) \ +{ \ + int s /* shift */, flb /* first lost bit */, sign = 0; \ + unsigned p = 0 /* power */, ret; \ + double_unsigned_struct val; \ + \ + /* fraction in negative float is encoded in 1's complement */ \ + if (with_sign && (v & (1ULL << 63))) { \ + sign = 1; \ + v = ~v + 1; \ + } \ + val.low = v; \ + val.high = v >> 32; \ + /* fill fraction bits */ \ + for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \ + if (p) { \ + ret = val.high & (p - 1); \ + if (s < FLOAT_FRAC_BITS) { \ + ret <<= FLOAT_FRAC_BITS - s; \ + ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s)); \ + flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1; \ + } else { \ + flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \ + ret >>= s - FLOAT_FRAC_BITS; \ + } \ + s += 32; \ + } else { \ + for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \ + if (p) { \ + ret = val.low & (p - 1); \ + if (s <= FLOAT_FRAC_BITS) { \ + ret <<= FLOAT_FRAC_BITS - s; \ + flb = 0; \ + } else { \ + flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1; \ + ret >>= s - FLOAT_FRAC_BITS; \ + } \ + } else \ + return 0; \ + } \ + if (flb) \ + ret++; \ + \ + /* fill exponent bits */ \ + ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS; \ + \ + /* fill sign bit */ \ + ret |= sign << 31; \ + \ + return ret; \ +} + +/* unsigned long long to float conversion */ +DEFINE__AEABI_XL2F(ul2f, 0) + +/* long long to float conversion */ +DEFINE__AEABI_XL2F(l2f, 1) + +/* long long to double conversion */ +#define __AEABI_XL2D(name, with_sign) \ +void __aeabi_ ## name(unsigned long long v) \ +{ \ + int s /* shift */, high_shift, sign = 0; \ + unsigned tmp, p = 0; \ + double_unsigned_struct val, ret; \ + \ + /* fraction in negative float is encoded in 1's complement */ \ + if (with_sign && (v & (1ULL << 63))) { \ + sign = 1; \ + v = ~v + 1; \ + } \ + val.low = v; \ + val.high = v >> 32; \ + \ + /* fill fraction bits */ \ + for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1); \ + if (p) { \ + tmp = val.high & (p - 1); \ + if (s < DOUBLE_FRAC_BITS - 32) { \ + high_shift = DOUBLE_FRAC_BITS - 32 - s; \ + ret.high = tmp << high_shift; \ + ret.high |= val.low >> (32 - high_shift); \ + ret.low = val.low << high_shift; \ + } else { \ + high_shift = s - (DOUBLE_FRAC_BITS - 32); \ + ret.high = tmp >> high_shift; \ + ret.low = tmp << (32 - high_shift); \ + ret.low |= val.low >> high_shift; \ + if ((val.low >> (high_shift - 1)) & 1) { \ + if (ret.low == UINT_MAX) { \ + ret.high++; \ + ret.low = 0; \ + } else \ + ret.low++; \ + } \ + } \ + s += 32; \ + } else { \ + for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1); \ + if (p) { \ + tmp = val.low & (p - 1); \ + if (s <= DOUBLE_FRAC_BITS - 32) { \ + high_shift = DOUBLE_FRAC_BITS - 32 - s; \ + ret.high = tmp << high_shift; \ + ret.low = 0; \ + } else { \ + high_shift = s - (DOUBLE_FRAC_BITS - 32); \ + ret.high = tmp >> high_shift; \ + ret.low = tmp << (32 - high_shift); \ + } \ + } else { \ + ret.high = ret.low = 0; \ + double_unsigned_struct_return(ret); \ + } \ + } \ + \ + /* fill exponent bits */ \ + ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32); \ + \ + /* fill sign bit */ \ + ret.high |= sign << 31; \ + \ + double_unsigned_struct_return(ret); \ +} + +/* unsigned long long to double conversion */ +__AEABI_XL2D(ul2d, 0) + +/* long long to double conversion */ +__AEABI_XL2D(l2d, 1) + + +/* Long long helper functions */ + +/* TODO: add error in case of den == 0 (see §4.3.1 and §4.3.2) */ + +#define define_aeabi_xdivmod_signed_type(basetype, type) \ +typedef struct type { \ + basetype quot; \ + unsigned basetype rem; \ +} type + +#define define_aeabi_xdivmod_unsigned_type(basetype, type) \ +typedef struct type { \ + basetype quot; \ + basetype rem; \ +} type + +#define AEABI_UXDIVMOD(name,type, rettype, typemacro) \ +static inline rettype aeabi_ ## name (type num, type den) \ +{ \ + rettype ret; \ + type quot = 0; \ + \ + /* Increase quotient while it is less than numerator */ \ + while (num >= den) { \ + type q = 1; \ + \ + /* Find closest power of two */ \ + while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \ + q <<= 1; \ + \ + /* Compute difference between current quotient and numerator */ \ + num -= q * den; \ + quot += q; \ + } \ + ret.quot = quot; \ + ret.rem = num; \ + return ret; \ +} + +#define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro) \ +void __aeabi_ ## name(type numerator, type denominator) \ +{ \ + unsigned type num, den; \ + urettype uxdiv_ret; \ + rettype ret; \ + \ + if (numerator >= 0) \ + num = numerator; \ + else \ + num = 0 - numerator; \ + if (denominator >= 0) \ + den = denominator; \ + else \ + den = 0 - denominator; \ + uxdiv_ret = aeabi_ ## uiname(num, den); \ + /* signs differ */ \ + if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \ + ret.quot = 0 - uxdiv_ret.quot; \ + else \ + ret.quot = uxdiv_ret.quot; \ + if (numerator < 0) \ + ret.rem = 0 - uxdiv_ret.rem; \ + else \ + ret.rem = uxdiv_ret.rem; \ + \ + rettype ## _return(ret); \ +} + +define_aeabi_xdivmod_signed_type(long long, lldiv_t); +define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t); +define_aeabi_xdivmod_signed_type(int, idiv_t); +define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t); + +REGS_RETURN(lldiv_t, lldiv_t) +REGS_RETURN(ulldiv_t, ulldiv_t) +REGS_RETURN(idiv_t, idiv_t) +REGS_RETURN(uidiv_t, uidiv_t) + +AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG) + +__AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG) + +void __aeabi_uldivmod(unsigned long long num, unsigned long long den) +{ + ulldiv_t_return(aeabi_uldivmod(num, den)); +} + +void __aeabi_llsl(double_unsigned_struct val, int shift) +{ + double_unsigned_struct ret; + + if (shift >= 32) { + val.high = val.low; + val.low = 0; + shift -= 32; + } + if (shift > 0) { + ret.low = val.low << shift; + ret.high = (val.high << shift) | (val.low >> (32 - shift)); + double_unsigned_struct_return(ret); + return; + } + double_unsigned_struct_return(val); +} + +#define aeabi_lsr(val, shift, fill, type) \ + type ## _struct ret; \ + \ + if (shift >= 32) { \ + val.low = val.high; \ + val.high = fill; \ + shift -= 32; \ + } \ + if (shift > 0) { \ + ret.high = val.high >> shift; \ + ret.low = (val.high << (32 - shift)) | (val.low >> shift); \ + type ## _struct_return(ret); \ + return; \ + } \ + type ## _struct_return(val); + +void __aeabi_llsr(double_unsigned_struct val, int shift) +{ + aeabi_lsr(val, shift, 0, double_unsigned); +} + +void __aeabi_lasr(unsigned_int_struct val, int shift) +{ + aeabi_lsr(val, shift, val.high >> 31, unsigned_int); +} + + +/* Integer division functions */ + +AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT) + +int __aeabi_idiv(int numerator, int denominator) +{ + unsigned num, den; + uidiv_t ret; + + if (numerator >= 0) + num = numerator; + else + num = 0 - numerator; + if (denominator >= 0) + den = denominator; + else + den = 0 - denominator; + ret = aeabi_uidivmod(num, den); + if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */ + ret.quot *= -1; + return ret.quot; +} + +unsigned __aeabi_uidiv(unsigned num, unsigned den) +{ + return aeabi_uidivmod(num, den).quot; +} + +__AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT) + +void __aeabi_uidivmod(unsigned num, unsigned den) +{ + uidiv_t_return(aeabi_uidivmod(num, den)); +} diff --git a/tinyc/lib/armflush.c b/tinyc/lib/armflush.c new file mode 100644 index 000000000..eae32605f --- /dev/null +++ b/tinyc/lib/armflush.c @@ -0,0 +1,58 @@ +/* armflush.c - flush the instruction cache + + __clear_cache is used in tccrun.c, It is a built-in + intrinsic with gcc. However tcc in order to compile + itself needs this function */ + +#ifdef __TINYC__ + +/* syscall wrapper */ +unsigned syscall(unsigned syscall_nr, ...); + +/* arm-tcc supports only fake asm currently */ +__asm__( + ".global syscall\n" + "syscall:\n" + ".int 0xe92d4080\n" // push {r7, lr} + ".int 0xe1a07000\n" // mov r7, r0 + ".int 0xe1a00001\n" // mov r0, r1 + ".int 0xe1a01002\n" // mov r1, r2 + ".int 0xe1a02003\n" // mov r2, r3 + ".int 0xef000000\n" // svc 0x00000000 + ".int 0xe8bd8080\n" // pop {r7, pc} + ); + +/* from unistd.h: */ +#if defined(__thumb__) || defined(__ARM_EABI__) +# define __NR_SYSCALL_BASE 0x0 +#else +# define __NR_SYSCALL_BASE 0x900000 +#endif +#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000) +#define __ARM_NR_cacheflush (__ARM_NR_BASE+2) + +#else + +#define _GNU_SOURCE +#include <unistd.h> +#include <sys/syscall.h> +#include <stdio.h> + +#endif + +/* Flushing for tccrun */ +void __clear_cache(void *beginning, void *end) +{ +/* __ARM_NR_cacheflush is kernel private and should not be used in user space. + * However, there is no ARM asm parser in tcc so we use it for now */ +#if 1 + syscall(__ARM_NR_cacheflush, beginning, end, 0); +#else + __asm__ ("push {r7}\n\t" + "mov r7, #0xf0002\n\t" + "mov r2, #0\n\t" + "swi 0\n\t" + "pop {r7}\n\t" + "ret"); +#endif +} diff --git a/tinyc/lib/bcheck.c b/tinyc/lib/bcheck.c index c59d04eb8..90f0ad2c3 100644 --- a/tinyc/lib/bcheck.c +++ b/tinyc/lib/bcheck.c @@ -21,60 +21,83 @@ #include <stdio.h> #include <stdarg.h> #include <string.h> -#if !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__OpenBSD__) + +#if !defined(__FreeBSD__) \ + && !defined(__FreeBSD_kernel__) \ + && !defined(__DragonFly__) \ + && !defined(__OpenBSD__) \ + && !defined(__NetBSD__) #include <malloc.h> #endif -//#define BOUND_DEBUG +#if !defined(_WIN32) +#include <unistd.h> +#endif + +/* #define BOUND_DEBUG */ + +#ifdef BOUND_DEBUG + #define dprintf(a...) fprintf(a) +#else + #define dprintf(a...) +#endif /* define so that bound array is static (faster, but use memory if bound checking not used) */ -//#define BOUND_STATIC +/* #define BOUND_STATIC */ /* use malloc hooks. Currently the code cannot be reliable if no hooks */ #define CONFIG_TCC_MALLOC_HOOKS - #define HAVE_MEMALIGN -#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__dietlibc__) \ - || defined(__UCLIBC__) || defined(__OpenBSD__) -#warning Bound checking not fully supported in this environment. +#if defined(__FreeBSD__) \ + || defined(__FreeBSD_kernel__) \ + || defined(__DragonFly__) \ + || defined(__OpenBSD__) \ + || defined(__NetBSD__) \ + || defined(__dietlibc__) \ + || defined(_WIN32) +//#warning Bound checking does not support malloc (etc.) in this environment. #undef CONFIG_TCC_MALLOC_HOOKS #undef HAVE_MEMALIGN #endif #define BOUND_T1_BITS 13 #define BOUND_T2_BITS 11 -#define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS) +#define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS) +#define BOUND_E_BITS (sizeof(size_t)) -#define BOUND_T1_SIZE (1 << BOUND_T1_BITS) -#define BOUND_T2_SIZE (1 << BOUND_T2_BITS) -#define BOUND_T3_SIZE (1 << BOUND_T3_BITS) -#define BOUND_E_BITS 4 +#define BOUND_T1_SIZE ((size_t)1 << BOUND_T1_BITS) +#define BOUND_T2_SIZE ((size_t)1 << BOUND_T2_BITS) +#define BOUND_T3_SIZE ((size_t)1 << BOUND_T3_BITS) #define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS) -#define BOUND_T23_SIZE (1 << BOUND_T23_BITS) +#define BOUND_T23_SIZE ((size_t)1 << BOUND_T23_BITS) /* this pointer is generated when bound check is incorrect */ #define INVALID_POINTER ((void *)(-2)) /* size of an empty region */ -#define EMPTY_SIZE 0xffffffff +#define EMPTY_SIZE ((size_t)(-1)) /* size of an invalid region */ #define INVALID_SIZE 0 typedef struct BoundEntry { - unsigned long start; - unsigned long size; + size_t start; + size_t size; struct BoundEntry *next; - unsigned long is_invalid; /* true if pointers outside region are invalid */ + size_t is_invalid; /* true if pointers outside region are invalid */ } BoundEntry; /* external interface */ void __bound_init(void); -void __bound_new_region(void *p, unsigned long size); +void __bound_new_region(void *p, size_t size); int __bound_delete_region(void *p); +#ifdef __attribute__ + /* an __attribute__ macro is defined in the system headers */ + #undef __attribute__ +#endif #define FASTCALL __attribute__((regparm(3))) void *__bound_malloc(size_t size, const void *caller); @@ -93,16 +116,13 @@ static void *saved_realloc_hook; static void *saved_memalign_hook; #endif -/* linker definitions */ -extern char _end; - /* TCC definitions */ extern char __bounds_start; /* start of static bounds table */ /* error message, just for TCC */ const char *__bound_error_msg; /* runtime error output */ -extern void rt_error(unsigned long pc, const char *fmt, ...); +extern void rt_error(size_t pc, const char *fmt, ...); #ifdef BOUND_STATIC static BoundEntry *__bound_t1[BOUND_T1_SIZE]; /* page table */ @@ -114,12 +134,12 @@ static BoundEntry *__bound_invalid_t2; /* invalid page, for invalid pointers */ static BoundEntry *__bound_find_region(BoundEntry *e1, void *p) { - unsigned long addr, tmp; + size_t addr, tmp; BoundEntry *e; e = e1; while (e != NULL) { - addr = (unsigned long)p; + addr = (size_t)p; addr -= e->start; if (addr <= e->size) { /* put region at the head */ @@ -144,7 +164,8 @@ static BoundEntry *__bound_find_region(BoundEntry *e1, void *p) static void bound_error(const char *fmt, ...) { __bound_error_msg = fmt; - *(int *)0 = 0; /* force a runtime error */ + fprintf(stderr,"%s %s: %s\n", __FILE__, __FUNCTION__, fmt); + *(void **)0 = 0; /* force a runtime error */ } static void bound_alloc_error(void) @@ -152,18 +173,17 @@ static void bound_alloc_error(void) bound_error("not enough memory for bound checking code"); } -/* currently, tcc cannot compile that because we use GNUC extensions */ -#if !defined(__TINYC__) - /* return '(p + offset)' for pointer arithmetic (a pointer can reach the end of a region in this case */ -void * FASTCALL __bound_ptr_add(void *p, int offset) +void * FASTCALL __bound_ptr_add(void *p, size_t offset) { - unsigned long addr = (unsigned long)p; + size_t addr = (size_t)p; BoundEntry *e; -#if defined(BOUND_DEBUG) - printf("add: 0x%x %d\n", (int)p, offset); -#endif + + dprintf(stderr, "%s %s: %p %x\n", + __FILE__, __FUNCTION__, p, (unsigned)offset); + + __bound_init(); e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; e = (BoundEntry *)((char *)e + @@ -172,22 +192,29 @@ void * FASTCALL __bound_ptr_add(void *p, int offset) addr -= e->start; if (addr > e->size) { e = __bound_find_region(e, p); - addr = (unsigned long)p - e->start; + addr = (size_t)p - e->start; } addr += offset; - if (addr > e->size) + if (addr >= e->size) { + fprintf(stderr,"%s %s: %p is outside of the region\n", + __FILE__, __FUNCTION__, p + offset); return INVALID_POINTER; /* return an invalid pointer */ + } return p + offset; } /* return '(p + offset)' for pointer indirection (the resulting must be strictly inside the region */ #define BOUND_PTR_INDIR(dsize) \ -void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset) \ +void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \ { \ - unsigned long addr = (unsigned long)p; \ + size_t addr = (size_t)p; \ BoundEntry *e; \ \ + dprintf(stderr, "%s %s: %p %x start\n", \ + __FILE__, __FUNCTION__, p, (unsigned)offset); \ + \ + __bound_init(); \ e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; \ e = (BoundEntry *)((char *)e + \ ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & \ @@ -195,30 +222,47 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset) \ addr -= e->start; \ if (addr > e->size) { \ e = __bound_find_region(e, p); \ - addr = (unsigned long)p - e->start; \ + addr = (size_t)p - e->start; \ } \ addr += offset + dsize; \ - if (addr > e->size) \ + if (addr > e->size) { \ + fprintf(stderr,"%s %s: %p is outside of the region\n", \ + __FILE__, __FUNCTION__, p + offset); \ return INVALID_POINTER; /* return an invalid pointer */ \ + } \ + dprintf(stderr, "%s %s: return p+offset = %p\n", \ + __FILE__, __FUNCTION__, p + offset); \ return p + offset; \ } -#ifdef __i386__ +BOUND_PTR_INDIR(1) +BOUND_PTR_INDIR(2) +BOUND_PTR_INDIR(4) +BOUND_PTR_INDIR(8) +BOUND_PTR_INDIR(12) +BOUND_PTR_INDIR(16) + +#if defined(__GNUC__) && (__GNUC__ >= 6) +/* + * At least gcc 6.2 complains when __builtin_frame_address is used with + * nonzero argument. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-address" +#endif + /* return the frame pointer of the caller */ #define GET_CALLER_FP(fp)\ {\ - unsigned long *fp1;\ - __asm__ __volatile__ ("movl %%ebp,%0" :"=g" (fp1));\ - fp = fp1[0];\ + fp = (size_t)__builtin_frame_address(1);\ } -#else -#error put code to extract the calling frame pointer -#endif /* called when entering a function to add all the local regions */ void FASTCALL __bound_local_new(void *p1) { - unsigned long addr, size, fp, *p = p1; + size_t addr, size, fp, *p = p1; + + dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p); GET_CALLER_FP(fp); for(;;) { addr = p[0]; @@ -229,12 +273,13 @@ void FASTCALL __bound_local_new(void *p1) p += 2; __bound_new_region((void *)addr, size); } + dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); } /* called when leaving a function to delete all the local regions */ void FASTCALL __bound_local_delete(void *p1) { - unsigned long addr, fp, *p = p1; + size_t addr, fp, *p = p1; GET_CALLER_FP(fp); for(;;) { addr = p[0]; @@ -246,38 +291,14 @@ void FASTCALL __bound_local_delete(void *p1) } } -#else - -void __bound_local_new(void *p) -{ -} -void __bound_local_delete(void *p) -{ -} - -void *__bound_ptr_add(void *p, int offset) -{ - return p + offset; -} - -#define BOUND_PTR_INDIR(dsize) \ -void *__bound_ptr_indir ## dsize (void *p, int offset) \ -{ \ - return p + offset; \ -} +#if defined(__GNUC__) && (__GNUC__ >= 6) +#pragma GCC diagnostic pop #endif -BOUND_PTR_INDIR(1) -BOUND_PTR_INDIR(2) -BOUND_PTR_INDIR(4) -BOUND_PTR_INDIR(8) -BOUND_PTR_INDIR(12) -BOUND_PTR_INDIR(16) - static BoundEntry *__bound_new_page(void) { BoundEntry *page; - int i; + size_t i; page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE); if (!page) @@ -305,11 +326,11 @@ static void bound_free_entry(BoundEntry *e) libc_free(e); } -static inline BoundEntry *get_page(int index) +static BoundEntry *get_page(size_t index) { BoundEntry *page; page = __bound_t1[index]; - if (page == __bound_empty_t2 || page == __bound_invalid_t2) { + if (!page || page == __bound_empty_t2 || page == __bound_invalid_t2) { /* create a new page if necessary */ page = __bound_new_page(); __bound_t1[index] = page; @@ -318,11 +339,11 @@ static inline BoundEntry *get_page(int index) } /* mark a region as being invalid (can only be used during init) */ -static void mark_invalid(unsigned long addr, unsigned long size) +static void mark_invalid(size_t addr, size_t size) { - unsigned long start, end; + size_t start, end; BoundEntry *page; - int t1_start, t1_end, i, j, t2_start, t2_end; + size_t t1_start, t1_end, i, j, t2_start, t2_end; start = addr; end = addr + size; @@ -334,7 +355,7 @@ static void mark_invalid(unsigned long addr, unsigned long size) t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS); #if 0 - printf("mark_invalid: start = %x %x\n", t2_start, t2_end); + dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end); #endif /* first we handle full pages */ @@ -373,10 +394,18 @@ static void mark_invalid(unsigned long addr, unsigned long size) void __bound_init(void) { - int i; + size_t i; BoundEntry *page; - unsigned long start, size; - int *p; + size_t start, size; + size_t *p; + + static int inited; + if (inited) + return; + + inited = 1; + + dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__); /* save malloc hooks and install bound check hooks */ install_malloc_hooks(); @@ -402,29 +431,71 @@ void __bound_init(void) __bound_invalid_t2 = page; /* invalid pointer zone */ - start = (unsigned long)INVALID_POINTER & ~(BOUND_T23_SIZE - 1); + start = (size_t)INVALID_POINTER & ~(BOUND_T23_SIZE - 1); size = BOUND_T23_SIZE; mark_invalid(start, size); -#if !defined(__TINYC__) && defined(CONFIG_TCC_MALLOC_HOOKS) +#if defined(CONFIG_TCC_MALLOC_HOOKS) /* malloc zone is also marked invalid. can only use that with - hooks because all libs should use the same malloc. The solution - would be to build a new malloc for tcc. */ - start = (unsigned long)&_end; + * hooks because all libs should use the same malloc. The solution + * would be to build a new malloc for tcc. + * + * usually heap (= malloc zone) comes right after bss, i.e. after _end, but + * not always - either if we are running from under `tcc -b -run`, or if + * address space randomization is turned on(a), heap start will be separated + * from bss end. + * + * So sbrk(0) will be a good approximation for start_brk: + * + * - if we are a separately compiled program, __bound_init() runs early, + * and sbrk(0) should be equal or very near to start_brk(b) (in case other + * constructors malloc something), or + * + * - if we are running from under `tcc -b -run`, sbrk(0) will return + * start of heap portion which is under this program control, and not + * mark as invalid earlier allocated memory. + * + * + * (a) /proc/sys/kernel/randomize_va_space = 2, on Linux; + * usually turned on by default. + * + * (b) on Linux >= v3.3, the alternative is to read + * start_brk from /proc/self/stat + */ + start = (size_t)sbrk(0); size = 128 * 0x100000; mark_invalid(start, size); #endif /* add all static bound check values */ - p = (int *)&__bounds_start; + p = (size_t *)&__bounds_start; while (p[0] != 0) { __bound_new_region((void *)p[0], p[1]); p += 2; } + + dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__); +} + +void __bound_main_arg(void **p) +{ + void *start = p; + while (*p++); + + dprintf(stderr, "%s, %s calling __bound_new_region(%p %x)\n", + __FILE__, __FUNCTION__, start, (unsigned)((void *)p - start)); + + __bound_new_region(start, (void *) p - start); +} + +void __bound_exit(void) +{ + dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__); + restore_malloc_hooks(); } static inline void add_region(BoundEntry *e, - unsigned long start, unsigned long size) + size_t start, size_t size) { BoundEntry *e1; if (e->start == 0) { @@ -444,13 +515,18 @@ static inline void add_region(BoundEntry *e, } /* create a new region. It should not already exist in the region list */ -void __bound_new_region(void *p, unsigned long size) +void __bound_new_region(void *p, size_t size) { - unsigned long start, end; + size_t start, end; BoundEntry *page, *e, *e2; - int t1_start, t1_end, i, t2_start, t2_end; + size_t t1_start, t1_end, i, t2_start, t2_end; + + dprintf(stderr, "%s, %s(%p, %x) start\n", + __FILE__, __FUNCTION__, p, (unsigned)size); - start = (unsigned long)p; + __bound_init(); + + start = (size_t)p; end = start + size; t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS); @@ -461,10 +537,7 @@ void __bound_new_region(void *p, unsigned long size) ((BOUND_T2_SIZE - 1) << BOUND_E_BITS); t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & ((BOUND_T2_SIZE - 1) << BOUND_E_BITS); -#ifdef BOUND_DEBUG - printf("new %lx %lx %x %x %x %x\n", - start, end, t1_start, t1_end, t2_start, t2_end); -#endif + e = (BoundEntry *)((char *)page + t2_start); add_region(e, start, size); @@ -506,16 +579,17 @@ void __bound_new_region(void *p, unsigned long size) } add_region(e, start, size); } + + dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__); } /* delete a region */ -static inline void delete_region(BoundEntry *e, - void *p, unsigned long empty_size) +static inline void delete_region(BoundEntry *e, void *p, size_t empty_size) { - unsigned long addr; + size_t addr; BoundEntry *e1; - addr = (unsigned long)p; + addr = (size_t)p; addr -= e->start; if (addr <= e->size) { /* region found is first one */ @@ -539,7 +613,7 @@ static inline void delete_region(BoundEntry *e, /* region not found: do nothing */ if (e == NULL) break; - addr = (unsigned long)p - e->start; + addr = (size_t)p - e->start; if (addr <= e->size) { /* found: remove entry */ e1->next = e->next; @@ -554,11 +628,15 @@ static inline void delete_region(BoundEntry *e, /* return non zero if error */ int __bound_delete_region(void *p) { - unsigned long start, end, addr, size, empty_size; + size_t start, end, addr, size, empty_size; BoundEntry *page, *e, *e2; - int t1_start, t1_end, t2_start, t2_end, i; + size_t t1_start, t1_end, t2_start, t2_end, i; - start = (unsigned long)p; + dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__); + + __bound_init(); + + start = (size_t)p; t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & ((BOUND_T2_SIZE - 1) << BOUND_E_BITS); @@ -570,7 +648,7 @@ int __bound_delete_region(void *p) if (addr > e->size) e = __bound_find_region(e, p); /* test if invalid region */ - if (e->size == EMPTY_SIZE || (unsigned long)p != e->start) + if (e->size == EMPTY_SIZE || (size_t)p != e->start) return -1; /* compute the size we put in invalid regions */ if (e->is_invalid) @@ -616,7 +694,7 @@ int __bound_delete_region(void *p) } } /* last page */ - page = get_page(t2_end); + page = get_page(t1_end); e2 = (BoundEntry *)((char *)page + t2_end); for(e=page;e<e2;e++) { e->start = 0; @@ -624,14 +702,17 @@ int __bound_delete_region(void *p) } delete_region(e, p, empty_size); } + + dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__); + return 0; } /* return the size of the region starting at p, or EMPTY_SIZE if non existent region. */ -static unsigned long get_region_size(void *p) +static size_t get_region_size(void *p) { - unsigned long addr = (unsigned long)p; + size_t addr = (size_t)p; BoundEntry *e; e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; @@ -641,13 +722,16 @@ static unsigned long get_region_size(void *p) addr -= e->start; if (addr > e->size) e = __bound_find_region(e, p); - if (e->start != (unsigned long)p) + if (e->start != (size_t)p) return EMPTY_SIZE; return e->size; } /* patched memory functions */ +/* force compiler to perform stores coded up to this point */ +#define barrier() __asm__ __volatile__ ("": : : "memory") + static void install_malloc_hooks(void) { #ifdef CONFIG_TCC_MALLOC_HOOKS @@ -659,6 +743,8 @@ static void install_malloc_hooks(void) __free_hook = __bound_free; __realloc_hook = __bound_realloc; __memalign_hook = __bound_memalign; + + barrier(); #endif } @@ -669,6 +755,8 @@ static void restore_malloc_hooks(void) __free_hook = saved_free_hook; __realloc_hook = saved_realloc_hook; __memalign_hook = saved_memalign_hook; + + barrier(); #endif } @@ -702,6 +790,10 @@ void *__bound_malloc(size_t size, const void *caller) if (!ptr) return NULL; + + dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n", + __FILE__, __FUNCTION__, ptr, (unsigned)size); + __bound_new_region(ptr, size); return ptr; } @@ -731,6 +823,10 @@ void *__bound_memalign(size_t size, size_t align, const void *caller) if (!ptr) return NULL; + + dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n", + __FILE__, __FUNCTION__, ptr, (unsigned)size); + __bound_new_region(ptr, size); return ptr; } @@ -748,7 +844,7 @@ void __bound_free(void *ptr, const void *caller) void *__bound_realloc(void *ptr, size_t size, const void *caller) { void *ptr1; - int old_size; + size_t old_size; if (size == 0) { __bound_free(ptr, caller); @@ -783,23 +879,23 @@ void *__bound_calloc(size_t nmemb, size_t size) static void bound_dump(void) { BoundEntry *page, *e; - int i, j; + size_t i, j; - printf("region dump:\n"); + fprintf(stderr, "region dump:\n"); for(i=0;i<BOUND_T1_SIZE;i++) { page = __bound_t1[i]; for(j=0;j<BOUND_T2_SIZE;j++) { e = page + j; /* do not print invalid or empty entries */ if (e->size != EMPTY_SIZE && e->start != 0) { - printf("%08x:", + fprintf(stderr, "%08x:", (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + (j << BOUND_T3_BITS)); do { - printf(" %08lx:%08lx", e->start, e->start + e->size); + fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size); e = e->next; } while (e != NULL); - printf("\n"); + fprintf(stderr, "\n"); } } } @@ -813,19 +909,28 @@ static void __bound_check(const void *p, size_t size) { if (size == 0) return; - p = __bound_ptr_add((void *)p, size); + p = __bound_ptr_add((void *)p, size - 1); if (p == INVALID_POINTER) bound_error("invalid pointer"); } void *__bound_memcpy(void *dst, const void *src, size_t size) { + void* p; + + dprintf(stderr, "%s %s: start, dst=%p src=%p size=%x\n", + __FILE__, __FUNCTION__, dst, src, (unsigned)size); + __bound_check(dst, size); __bound_check(src, size); /* check also region overlap */ if (src >= dst && src < dst + size) bound_error("overlapping regions in memcpy()"); - return memcpy(dst, src, size); + + p = memcpy(dst, src, size); + + dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p); + return p; } void *__bound_memmove(void *dst, const void *src, size_t size) @@ -845,7 +950,7 @@ void *__bound_memset(void *dst, int c, size_t size) int __bound_strlen(const char *s) { const char *p; - int len; + size_t len; len = 0; for(;;) { @@ -861,8 +966,14 @@ int __bound_strlen(const char *s) char *__bound_strcpy(char *dst, const char *src) { - int len; + size_t len; + void *p; + + dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n", + __FILE__, __FUNCTION__, dst, src); len = __bound_strlen(src); - return __bound_memcpy(dst, src, len + 1); + p = __bound_memcpy(dst, src, len + 1); + dprintf(stderr, "%s %s: strcpy end, p = %p\n", + __FILE__, __FUNCTION__, p); + return p; } - diff --git a/tinyc/lib/lib-arm64.c b/tinyc/lib/lib-arm64.c new file mode 100644 index 000000000..b8fd9e85a --- /dev/null +++ b/tinyc/lib/lib-arm64.c @@ -0,0 +1,664 @@ +/* + * TCC runtime library for arm64. + * + * Copyright (c) 2015 Edmund Grimley Evans + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#ifdef __TINYC__ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; +void *memcpy(void*,void*,__SIZE_TYPE__); +#else +#include <stdint.h> +#include <string.h> +#endif + +void __clear_cache(void *beg, void *end) +{ + __arm64_clear_cache(beg, end); +} + +typedef struct { + uint64_t x0, x1; +} u128_t; + +static long double f3_zero(int sgn) +{ + long double f; + u128_t x = { 0, (uint64_t)sgn << 63 }; + memcpy(&f, &x, 16); + return f; +} + +static long double f3_infinity(int sgn) +{ + long double f; + u128_t x = { 0, (uint64_t)sgn << 63 | 0x7fff000000000000 }; + memcpy(&f, &x, 16); + return f; +} + +static long double f3_NaN(void) +{ + long double f; +#if 0 + // ARM's default NaN usually has just the top fraction bit set: + u128_t x = { 0, 0x7fff800000000000 }; +#else + // GCC's library sets all fraction bits: + u128_t x = { -1, 0x7fffffffffffffff }; +#endif + memcpy(&f, &x, 16); + return f; +} + +static int fp3_convert_NaN(long double *f, int sgn, u128_t mnt) +{ + u128_t x = { mnt.x0, + mnt.x1 | 0x7fff800000000000 | (uint64_t)sgn << 63 }; + memcpy(f, &x, 16); + return 1; +} + +static int fp3_detect_NaNs(long double *f, + int a_sgn, int a_exp, u128_t a, + int b_sgn, int b_exp, u128_t b) +{ + // Detect signalling NaNs: + if (a_exp == 32767 && (a.x0 | a.x1 << 16) && !(a.x1 >> 47 & 1)) + return fp3_convert_NaN(f, a_sgn, a); + if (b_exp == 32767 && (b.x0 | b.x1 << 16) && !(b.x1 >> 47 & 1)) + return fp3_convert_NaN(f, b_sgn, b); + + // Detect quiet NaNs: + if (a_exp == 32767 && (a.x0 | a.x1 << 16)) + return fp3_convert_NaN(f, a_sgn, a); + if (b_exp == 32767 && (b.x0 | b.x1 << 16)) + return fp3_convert_NaN(f, b_sgn, b); + + return 0; +} + +static void f3_unpack(int *sgn, int32_t *exp, u128_t *mnt, long double f) +{ + u128_t x; + memcpy(&x, &f, 16); + *sgn = x.x1 >> 63; + *exp = x.x1 >> 48 & 32767; + x.x1 = x.x1 << 16 >> 16; + if (*exp) + x.x1 |= (uint64_t)1 << 48; + else + *exp = 1; + *mnt = x; +} + +static u128_t f3_normalise(int32_t *exp, u128_t mnt) +{ + int sh; + if (!(mnt.x0 | mnt.x1)) + return mnt; + if (!mnt.x1) { + mnt.x1 = mnt.x0; + mnt.x0 = 0; + *exp -= 64; + } + for (sh = 32; sh; sh >>= 1) { + if (!(mnt.x1 >> (64 - sh))) { + mnt.x1 = mnt.x1 << sh | mnt.x0 >> (64 - sh); + mnt.x0 = mnt.x0 << sh; + *exp -= sh; + } + } + return mnt; +} + +static u128_t f3_sticky_shift(int32_t sh, u128_t x) +{ + if (sh >= 128) { + x.x0 = !!(x.x0 | x.x1); + x.x1 = 0; + return x; + } + if (sh >= 64) { + x.x0 = x.x1 | !!x.x0; + x.x1 = 0; + sh -= 64; + } + if (sh > 0) { + x.x0 = x.x0 >> sh | x.x1 << (64 - sh) | !!(x.x0 << (64 - sh)); + x.x1 = x.x1 >> sh; + } + return x; +} + +static long double f3_round(int sgn, int32_t exp, u128_t x) +{ + long double f; + int error; + + if (exp > 0) { + x = f3_sticky_shift(13, x); + } + else { + x = f3_sticky_shift(14 - exp, x); + exp = 0; + } + + error = x.x0 & 3; + x.x0 = x.x0 >> 2 | x.x1 << 62; + x.x1 = x.x1 >> 2; + + if (error == 3 || ((error == 2) & (x.x0 & 1))) { + if (!++x.x0) { + ++x.x1; + if (x.x1 == (uint64_t)1 << 48) + exp = 1; + else if (x.x1 == (uint64_t)1 << 49) { + ++exp; + x.x0 = x.x0 >> 1 | x.x1 << 63; + x.x1 = x.x1 >> 1; + } + } + } + + if (exp >= 32767) + return f3_infinity(sgn); + + x.x1 = x.x1 << 16 >> 16 | (uint64_t)exp << 48 | (uint64_t)sgn << 63; + memcpy(&f, &x, 16); + return f; +} + +static long double f3_add(long double fa, long double fb, int neg) +{ + u128_t a, b, x; + int32_t a_exp, b_exp, x_exp; + int a_sgn, b_sgn, x_sgn; + long double fx; + + f3_unpack(&a_sgn, &a_exp, &a, fa); + f3_unpack(&b_sgn, &b_exp, &b, fb); + + if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b)) + return fx; + + b_sgn ^= neg; + + // Handle infinities and zeroes: + if (a_exp == 32767 && b_exp == 32767 && a_sgn != b_sgn) + return f3_NaN(); + if (a_exp == 32767) + return f3_infinity(a_sgn); + if (b_exp == 32767) + return f3_infinity(b_sgn); + if (!(a.x0 | a.x1 | b.x0 | b.x1)) + return f3_zero(a_sgn & b_sgn); + + a.x1 = a.x1 << 3 | a.x0 >> 61; + a.x0 = a.x0 << 3; + b.x1 = b.x1 << 3 | b.x0 >> 61; + b.x0 = b.x0 << 3; + + if (a_exp <= b_exp) { + a = f3_sticky_shift(b_exp - a_exp, a); + a_exp = b_exp; + } + else { + b = f3_sticky_shift(a_exp - b_exp, b); + b_exp = a_exp; + } + + x_sgn = a_sgn; + x_exp = a_exp; + if (a_sgn == b_sgn) { + x.x0 = a.x0 + b.x0; + x.x1 = a.x1 + b.x1 + (x.x0 < a.x0); + } + else { + x.x0 = a.x0 - b.x0; + x.x1 = a.x1 - b.x1 - (x.x0 > a.x0); + if (x.x1 >> 63) { + x_sgn ^= 1; + x.x0 = -x.x0; + x.x1 = -x.x1 - !!x.x0; + } + } + + if (!(x.x0 | x.x1)) + return f3_zero(0); + + x = f3_normalise(&x_exp, x); + + return f3_round(x_sgn, x_exp + 12, x); +} + +long double __addtf3(long double a, long double b) +{ + return f3_add(a, b, 0); +} + +long double __subtf3(long double a, long double b) +{ + return f3_add(a, b, 1); +} + +long double __multf3(long double fa, long double fb) +{ + u128_t a, b, x; + int32_t a_exp, b_exp, x_exp; + int a_sgn, b_sgn, x_sgn; + long double fx; + + f3_unpack(&a_sgn, &a_exp, &a, fa); + f3_unpack(&b_sgn, &b_exp, &b, fb); + + if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b)) + return fx; + + // Handle infinities and zeroes: + if ((a_exp == 32767 && !(b.x0 | b.x1)) || + (b_exp == 32767 && !(a.x0 | a.x1))) + return f3_NaN(); + if (a_exp == 32767 || b_exp == 32767) + return f3_infinity(a_sgn ^ b_sgn); + if (!(a.x0 | a.x1) || !(b.x0 | b.x1)) + return f3_zero(a_sgn ^ b_sgn); + + a = f3_normalise(&a_exp, a); + b = f3_normalise(&b_exp, b); + + x_sgn = a_sgn ^ b_sgn; + x_exp = a_exp + b_exp - 16352; + + { + // Convert to base (1 << 30), discarding bottom 6 bits, which are zero, + // so there are (32, 30, 30, 30) bits in (a3, a2, a1, a0): + uint64_t a0 = a.x0 << 28 >> 34; + uint64_t b0 = b.x0 << 28 >> 34; + uint64_t a1 = a.x0 >> 36 | a.x1 << 62 >> 34; + uint64_t b1 = b.x0 >> 36 | b.x1 << 62 >> 34; + uint64_t a2 = a.x1 << 32 >> 34; + uint64_t b2 = b.x1 << 32 >> 34; + uint64_t a3 = a.x1 >> 32; + uint64_t b3 = b.x1 >> 32; + // Use 16 small multiplications and additions that do not overflow: + uint64_t x0 = a0 * b0; + uint64_t x1 = (x0 >> 30) + a0 * b1 + a1 * b0; + uint64_t x2 = (x1 >> 30) + a0 * b2 + a1 * b1 + a2 * b0; + uint64_t x3 = (x2 >> 30) + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + uint64_t x4 = (x3 >> 30) + a1 * b3 + a2 * b2 + a3 * b1; + uint64_t x5 = (x4 >> 30) + a2 * b3 + a3 * b2; + uint64_t x6 = (x5 >> 30) + a3 * b3; + // We now have (64, 30, 30, ...) bits in (x6, x5, x4, ...). + // Take the top 128 bits, setting bottom bit if any lower bits were set: + uint64_t y0 = (x5 << 34 | x4 << 34 >> 30 | x3 << 34 >> 60 | + !!(x3 << 38 | (x2 | x1 | x0) << 34)); + uint64_t y1 = x6; + // Top bit may be zero. Renormalise: + if (!(y1 >> 63)) { + y1 = y1 << 1 | y0 >> 63; + y0 = y0 << 1; + --x_exp; + } + x.x0 = y0; + x.x1 = y1; + } + + return f3_round(x_sgn, x_exp, x); +} + +long double __divtf3(long double fa, long double fb) +{ + u128_t a, b, x; + int32_t a_exp, b_exp, x_exp; + int a_sgn, b_sgn, x_sgn, i; + long double fx; + + f3_unpack(&a_sgn, &a_exp, &a, fa); + f3_unpack(&b_sgn, &b_exp, &b, fb); + + if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b)) + return fx; + + // Handle infinities and zeroes: + if ((a_exp == 32767 && b_exp == 32767) || + (!(a.x0 | a.x1) && !(b.x0 | b.x1))) + return f3_NaN(); + if (a_exp == 32767 || !(b.x0 | b.x1)) + return f3_infinity(a_sgn ^ b_sgn); + if (!(a.x0 | a.x1) || b_exp == 32767) + return f3_zero(a_sgn ^ b_sgn); + + a = f3_normalise(&a_exp, a); + b = f3_normalise(&b_exp, b); + + x_sgn = a_sgn ^ b_sgn; + x_exp = a_exp - b_exp + 16395; + + a.x0 = a.x0 >> 1 | a.x1 << 63; + a.x1 = a.x1 >> 1; + b.x0 = b.x0 >> 1 | b.x1 << 63; + b.x1 = b.x1 >> 1; + x.x0 = 0; + x.x1 = 0; + for (i = 0; i < 116; i++) { + x.x1 = x.x1 << 1 | x.x0 >> 63; + x.x0 = x.x0 << 1; + if (a.x1 > b.x1 || (a.x1 == b.x1 && a.x0 >= b.x0)) { + a.x1 = a.x1 - b.x1 - (a.x0 < b.x0); + a.x0 = a.x0 - b.x0; + x.x0 |= 1; + } + a.x1 = a.x1 << 1 | a.x0 >> 63; + a.x0 = a.x0 << 1; + } + x.x0 |= !!(a.x0 | a.x1); + + x = f3_normalise(&x_exp, x); + + return f3_round(x_sgn, x_exp, x); +} + +long double __extendsftf2(float f) +{ + long double fx; + u128_t x; + uint32_t a; + uint64_t aa; + memcpy(&a, &f, 4); + aa = a; + x.x0 = 0; + if (!(a << 1)) + x.x1 = aa << 32; + else if (a << 1 >> 24 == 255) + x.x1 = (0x7fff000000000000 | aa >> 31 << 63 | aa << 41 >> 16 | + (uint64_t)!!(a << 9) << 47); + else + x.x1 = (aa >> 31 << 63 | ((aa >> 23 & 255) + 16256) << 48 | + aa << 41 >> 16); + memcpy(&fx, &x, 16); + return fx; +} + +long double __extenddftf2(double f) +{ + long double fx; + u128_t x; + uint64_t a; + memcpy(&a, &f, 8); + x.x0 = a << 60; + if (!(a << 1)) + x.x1 = a; + else if (a << 1 >> 53 == 2047) + x.x1 = (0x7fff000000000000 | a >> 63 << 63 | a << 12 >> 16 | + (uint64_t)!!(a << 12) << 47); + else + x.x1 = a >> 63 << 63 | ((a >> 52 & 2047) + 15360) << 48 | a << 12 >> 16; + memcpy(&fx, &x, 16); + return fx; +} + +float __trunctfsf2(long double f) +{ + u128_t mnt; + int32_t exp; + int sgn; + uint32_t x; + float fx; + + f3_unpack(&sgn, &exp, &mnt, f); + + if (exp == 32767 && (mnt.x0 | mnt.x1 << 16)) + x = 0x7fc00000 | (uint32_t)sgn << 31 | (mnt.x1 >> 25 & 0x007fffff); + else if (exp > 16510) + x = 0x7f800000 | (uint32_t)sgn << 31; + else if (exp < 16233) + x = (uint32_t)sgn << 31; + else { + exp -= 16257; + x = mnt.x1 >> 23 | !!(mnt.x0 | mnt.x1 << 41); + if (exp < 0) { + x = x >> -exp | !!(x << (32 + exp)); + exp = 0; + } + if ((x & 3) == 3 || (x & 7) == 6) + x += 4; + x = ((x >> 2) + (exp << 23)) | (uint32_t)sgn << 31; + } + memcpy(&fx, &x, 4); + return fx; +} + +double __trunctfdf2(long double f) +{ + u128_t mnt; + int32_t exp; + int sgn; + uint64_t x; + double fx; + + f3_unpack(&sgn, &exp, &mnt, f); + + if (exp == 32767 && (mnt.x0 | mnt.x1 << 16)) + x = (0x7ff8000000000000 | (uint64_t)sgn << 63 | + mnt.x1 << 16 >> 12 | mnt.x0 >> 60); + else if (exp > 17406) + x = 0x7ff0000000000000 | (uint64_t)sgn << 63; + else if (exp < 15308) + x = (uint64_t)sgn << 63; + else { + exp -= 15361; + x = mnt.x1 << 6 | mnt.x0 >> 58 | !!(mnt.x0 << 6); + if (exp < 0) { + x = x >> -exp | !!(x << (64 + exp)); + exp = 0; + } + if ((x & 3) == 3 || (x & 7) == 6) + x += 4; + x = ((x >> 2) + ((uint64_t)exp << 52)) | (uint64_t)sgn << 63; + } + memcpy(&fx, &x, 8); + return fx; +} + +int32_t __fixtfsi(long double fa) +{ + u128_t a; + int32_t a_exp; + int a_sgn; + int32_t x; + f3_unpack(&a_sgn, &a_exp, &a, fa); + if (a_exp < 16369) + return 0; + if (a_exp > 16413) + return a_sgn ? -0x80000000 : 0x7fffffff; + x = a.x1 >> (16431 - a_exp); + return a_sgn ? -x : x; +} + +int64_t __fixtfdi(long double fa) +{ + u128_t a; + int32_t a_exp; + int a_sgn; + int64_t x; + f3_unpack(&a_sgn, &a_exp, &a, fa); + if (a_exp < 16383) + return 0; + if (a_exp > 16445) + return a_sgn ? -0x8000000000000000 : 0x7fffffffffffffff; + x = (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp); + return a_sgn ? -x : x; +} + +uint32_t __fixunstfsi(long double fa) +{ + u128_t a; + int32_t a_exp; + int a_sgn; + f3_unpack(&a_sgn, &a_exp, &a, fa); + if (a_sgn || a_exp < 16369) + return 0; + if (a_exp > 16414) + return -1; + return a.x1 >> (16431 - a_exp); +} + +uint64_t __fixunstfdi(long double fa) +{ + u128_t a; + int32_t a_exp; + int a_sgn; + f3_unpack(&a_sgn, &a_exp, &a, fa); + if (a_sgn || a_exp < 16383) + return 0; + if (a_exp > 16446) + return -1; + return (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp); +} + +long double __floatsitf(int32_t a) +{ + int sgn = 0; + int exp = 16414; + uint32_t mnt = a; + u128_t x = { 0, 0 }; + long double f; + int i; + if (a) { + if (a < 0) { + sgn = 1; + mnt = -mnt; + } + for (i = 16; i; i >>= 1) + if (!(mnt >> (32 - i))) { + mnt <<= i; + exp -= i; + } + x.x1 = ((uint64_t)sgn << 63 | (uint64_t)exp << 48 | + (uint64_t)(mnt << 1) << 16); + } + memcpy(&f, &x, 16); + return f; +} + +long double __floatditf(int64_t a) +{ + int sgn = 0; + int exp = 16446; + uint64_t mnt = a; + u128_t x = { 0, 0 }; + long double f; + int i; + if (a) { + if (a < 0) { + sgn = 1; + mnt = -mnt; + } + for (i = 32; i; i >>= 1) + if (!(mnt >> (64 - i))) { + mnt <<= i; + exp -= i; + } + x.x0 = mnt << 49; + x.x1 = (uint64_t)sgn << 63 | (uint64_t)exp << 48 | mnt << 1 >> 16; + } + memcpy(&f, &x, 16); + return f; +} + +long double __floatunsitf(uint32_t a) +{ + int exp = 16414; + uint32_t mnt = a; + u128_t x = { 0, 0 }; + long double f; + int i; + if (a) { + for (i = 16; i; i >>= 1) + if (!(mnt >> (32 - i))) { + mnt <<= i; + exp -= i; + } + x.x1 = (uint64_t)exp << 48 | (uint64_t)(mnt << 1) << 16; + } + memcpy(&f, &x, 16); + return f; +} + +long double __floatunditf(uint64_t a) +{ + int exp = 16446; + uint64_t mnt = a; + u128_t x = { 0, 0 }; + long double f; + int i; + if (a) { + for (i = 32; i; i >>= 1) + if (!(mnt >> (64 - i))) { + mnt <<= i; + exp -= i; + } + x.x0 = mnt << 49; + x.x1 = (uint64_t)exp << 48 | mnt << 1 >> 16; + } + memcpy(&f, &x, 16); + return f; +} + +static int f3_cmp(long double fa, long double fb) +{ + u128_t a, b; + memcpy(&a, &fa, 16); + memcpy(&b, &fb, 16); + return (!(a.x0 | a.x1 << 1 | b.x0 | b.x1 << 1) ? 0 : + ((a.x1 << 1 >> 49 == 0x7fff && (a.x0 | a.x1 << 16)) || + (b.x1 << 1 >> 49 == 0x7fff && (b.x0 | b.x1 << 16))) ? 2 : + a.x1 >> 63 != b.x1 >> 63 ? (int)(b.x1 >> 63) - (int)(a.x1 >> 63) : + a.x1 < b.x1 ? (int)(a.x1 >> 63 << 1) - 1 : + a.x1 > b.x1 ? 1 - (int)(a.x1 >> 63 << 1) : + a.x0 < b.x0 ? (int)(a.x1 >> 63 << 1) - 1 : + b.x0 < a.x0 ? 1 - (int)(a.x1 >> 63 << 1) : 0); +} + +int __eqtf2(long double a, long double b) +{ + return !!f3_cmp(a, b); +} + +int __netf2(long double a, long double b) +{ + return !!f3_cmp(a, b); +} + +int __lttf2(long double a, long double b) +{ + return f3_cmp(a, b); +} + +int __letf2(long double a, long double b) +{ + return f3_cmp(a, b); +} + +int __gttf2(long double a, long double b) +{ + return -f3_cmp(b, a); +} + +int __getf2(long double a, long double b) +{ + return -f3_cmp(b, a); +} diff --git a/tinyc/lib/libtcc1.c b/tinyc/lib/libtcc1.c index b079477e4..0e466180c 100644 --- a/tinyc/lib/libtcc1.c +++ b/tinyc/lib/libtcc1.c @@ -103,14 +103,14 @@ union double_long { union float_long { float f; - long l; + unsigned int l; }; /* XXX: we don't support several builtin supports for now */ -#ifndef __x86_64__ +#if !defined __x86_64__ && !defined __arm__ /* XXX: use gcc/tcc intrinsic ? */ -#if defined(__i386__) +#if defined __i386__ #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ : "=r" ((USItype) (sh)), \ @@ -162,7 +162,7 @@ static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) n0 = nn.s.low; n1 = nn.s.high; -#if !UDIV_NEEDS_NORMALIZATION +#if !defined(UDIV_NEEDS_NORMALIZATION) if (d1 == 0) { if (d0 > n1) @@ -478,13 +478,6 @@ long long __ashldi3(long long a, int b) #endif } -#if defined(__i386__) -/* FPU control word for rounding to nearest mode */ -unsigned short __tcc_fpu_control = 0x137f; -/* FPU control word for round to zero mode for int conversion */ -unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00; -#endif - #endif /* !__x86_64__ */ /* XXX: fix tcc's code generator to do this instead */ @@ -557,6 +550,13 @@ unsigned long long __fixunssfdi (float a1) return 0; } +long long __fixsfdi (float a1) +{ + long long ret; int s; + ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + unsigned long long __fixunsdfdi (double a1) { register union double_long dl1; @@ -582,6 +582,14 @@ unsigned long long __fixunsdfdi (double a1) return 0; } +long long __fixdfdi (double a1) +{ + long long ret; int s; + ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + +#ifndef __arm__ unsigned long long __fixunsxfdi (long double a1) { register union ldouble_long dl1; @@ -605,3 +613,10 @@ unsigned long long __fixunsxfdi (long double a1) return 0; } +long long __fixxfdi (long double a1) +{ + long long ret; int s; + ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} +#endif /* !ARM */ diff --git a/tinyc/lib/va_list.c b/tinyc/lib/va_list.c new file mode 100644 index 000000000..8749f46f8 --- /dev/null +++ b/tinyc/lib/va_list.c @@ -0,0 +1,65 @@ +/* va_list.c - tinycc support for va_list on X86_64 */ + +#if defined __x86_64__ + +/* Avoid include files, they may not be available when cross compiling */ +extern void *memset(void *s, int c, __SIZE_TYPE__ n); +extern void abort(void); + +/* This should be in sync with our include/stdarg.h */ +enum __va_arg_type { + __va_gen_reg, __va_float_reg, __va_stack +}; + +/* GCC compatible definition of va_list. */ +typedef struct { + unsigned int gp_offset; + unsigned int fp_offset; + union { + unsigned int overflow_offset; + char *overflow_arg_area; + }; + char *reg_save_area; +} __va_list_struct; + +void __va_start(__va_list_struct *ap, void *fp) +{ + memset(ap, 0, sizeof(__va_list_struct)); + *ap = *(__va_list_struct *)((char *)fp - 16); + ap->overflow_arg_area = (char *)fp + ap->overflow_offset; + ap->reg_save_area = (char *)fp - 176 - 16; +} + +void *__va_arg(__va_list_struct *ap, + enum __va_arg_type arg_type, + int size, int align) +{ + size = (size + 7) & ~7; + align = (align + 7) & ~7; + switch (arg_type) { + case __va_gen_reg: + if (ap->gp_offset + size <= 48) { + ap->gp_offset += size; + return ap->reg_save_area + ap->gp_offset - size; + } + goto use_overflow_area; + + case __va_float_reg: + if (ap->fp_offset < 128 + 48) { + ap->fp_offset += 16; + return ap->reg_save_area + ap->fp_offset - 16; + } + size = 8; + goto use_overflow_area; + + case __va_stack: + use_overflow_area: + ap->overflow_arg_area += size; + ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align); + return ap->overflow_arg_area - size; + + default: /* should never happen */ + abort(); + } +} +#endif diff --git a/tinyc/libtcc.c b/tinyc/libtcc.c index 0d8702b5f..092c0ba32 100644 --- a/tinyc/libtcc.c +++ b/tinyc/libtcc.c @@ -1,6 +1,6 @@ /* * TCC - Tiny C Compiler - * + * * Copyright (c) 2001-2004 Fabrice Bellard * * This library is free software; you can redistribute it and/or @@ -23,310 +23,115 @@ /********************************************************/ /* global variables */ -/* display benchmark infos */ -int total_lines; -int total_bytes; - -/* parser */ -static struct BufferedFile *file; -static int ch, tok; -static CValue tokc; -static CString tokcstr; /* current parsed string, if any */ -/* additional informations about token */ -static int tok_flags; -#define TOK_FLAG_BOL 0x0001 /* beginning of line before */ -#define TOK_FLAG_BOF 0x0002 /* beginning of file before */ -#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ -#define TOK_FLAG_EOF 0x0008 /* end of file */ - -static int *macro_ptr, *macro_ptr_allocated; -static int *unget_saved_macro_ptr; -static int unget_saved_buffer[TOK_MAX_SIZE + 1]; -static int unget_buffer_enabled; -static int parse_flags; -#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */ -#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */ -#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a - token. line feed is also - returned at eof */ -#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */ -#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */ - -static Section *text_section, *data_section, *bss_section; /* predefined sections */ -static Section *cur_text_section; /* current section where function code is - generated */ -#ifdef CONFIG_TCC_ASM -static Section *last_text_section; /* to handle .previous asm directive */ -#endif -/* bound check related sections */ -static Section *bounds_section; /* contains global data bound description */ -static Section *lbounds_section; /* contains local data bound description */ -/* symbol sections */ -static Section *symtab_section, *strtab_section; - -/* debug sections */ -static Section *stab_section, *stabstr_section; - -/* loc : local variable index - ind : output code index - rsym: return symbol - anon_sym: anonymous symbol index -*/ -static int rsym, anon_sym, ind, loc; -/* expression generation modifiers */ -static int const_wanted; /* true if constant wanted */ -static int nocode_wanted; /* true if no code generation wanted for an expression */ -static int global_expr; /* true if compound literals must be allocated - globally (used during initializers parsing */ -static CType func_vt; /* current function return type (used by return - instruction) */ -static int func_vc; -static int last_line_num, last_ind, func_ind; /* debug last line number and pc */ -static int tok_ident; -static TokenSym **table_ident; -static TokenSym *hash_ident[TOK_HASH_SIZE]; -static char token_buf[STRING_MAX_SIZE + 1]; -static char *funcname; -static Sym *global_stack, *local_stack; -static Sym *define_stack; -static Sym *global_label_stack, *local_label_stack; -/* symbol allocator */ -#define SYM_POOL_NB (8192 / sizeof(Sym)) -static Sym *sym_free_first; -static void **sym_pools; -static int nb_sym_pools; - -static SValue vstack[VSTACK_SIZE], *vtop; -/* some predefined types */ -static CType char_pointer_type, func_old_type, int_type; - /* use GNU C extensions */ -static int gnu_ext = 1; +ST_DATA int gnu_ext = 1; -/* use Tiny C extensions */ -static int tcc_ext = 1; - -/* max number of callers shown if error */ -#ifdef CONFIG_TCC_BACKTRACE -int num_callers = 6; -const char **rt_bound_error_msg; -#endif +/* use TinyCC extensions */ +ST_DATA int tcc_ext = 1; /* XXX: get rid of this ASAP */ -static struct TCCState *tcc_state; +ST_DATA struct TCCState *tcc_state; -/********************************************************/ -/* function prototypes */ - -/* tccpp.c */ -static void next(void); -char *get_tok_str(int v, CValue *cv); - -/* tccgen.c */ -static void parse_expr_type(CType *type); -static void expr_type(CType *type); -static void unary_type(CType *type); -static void block(int *bsym, int *csym, int *case_sym, int *def_sym, - int case_reg, int is_expr); -static int expr_const(void); -static void expr_eq(void); -static void gexpr(void); -static void gen_inline_functions(void); -static void decl(int l); -static void decl_initializer(CType *type, Section *sec, unsigned long c, - int first, int size_only); -static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, - int has_init, int v, int scope); -int gv(int rc); -void gv2(int rc1, int rc2); -void move_reg(int r, int s); -void save_regs(int n); -void save_reg(int r); -void vpop(void); -void vswap(void); -void vdup(void); -int get_reg(int rc); -int get_reg_ex(int rc,int rc2); - -void gen_op(int op); -void force_charshort_cast(int t); -static void gen_cast(CType *type); -void vstore(void); -static Sym *sym_find(int v); -static Sym *sym_push(int v, CType *type, int r, int c); - -/* type handling */ -static int type_size(CType *type, int *a); -static inline CType *pointed_type(CType *type); -static int pointed_size(CType *type); -static int lvalue_type(int t); -static int parse_btype(CType *type, AttributeDef *ad); -static void type_decl(CType *type, AttributeDef *ad, int *v, int td); -static int compare_types(CType *type1, CType *type2, int unqualified); -static int is_compatible_types(CType *type1, CType *type2); -static int is_compatible_parameter_types(CType *type1, CType *type2); - -int ieee_finite(double d); -void vpushi(int v); -void vpushll(long long v); -void vrott(int n); -void vnrott(int n); -void lexpand_nr(void); -static void vpush_global_sym(CType *type, int v); -void vset(CType *type, int r, int v); -void type_to_str(char *buf, int buf_size, - CType *type, const char *varstr); -static Sym *get_sym_ref(CType *type, Section *sec, - unsigned long offset, unsigned long size); -static Sym *external_global_sym(int v, CType *type, int r); - -/* section generation */ -static void section_realloc(Section *sec, unsigned long new_size); -static void *section_ptr_add(Section *sec, unsigned long size); -static void put_extern_sym(Sym *sym, Section *section, - unsigned long value, unsigned long size); -static void greloc(Section *s, Sym *sym, unsigned long addr, int type); -static int put_elf_str(Section *s, const char *sym); -static int put_elf_sym(Section *s, - unsigned long value, unsigned long size, - int info, int other, int shndx, const char *name); -static int add_elf_sym(Section *s, unsigned long value, unsigned long size, - int info, int other, int sh_num, const char *name); -static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, - int type, int symbol); -static void put_stabs(const char *str, int type, int other, int desc, - unsigned long value); -static void put_stabs_r(const char *str, int type, int other, int desc, - unsigned long value, Section *sec, int sym_index); -static void put_stabn(int type, int other, int desc, int value); -static void put_stabd(int type, int other, int desc); -static int tcc_add_dll(TCCState *s, const char *filename, int flags); - -#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */ -#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */ -#define AFF_PREPROCESS 0x0004 /* preprocess file */ -static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); - -/* tcccoff.c */ -int tcc_output_coff(TCCState *s1, FILE *f); - -/* tccpe.c */ -void *resolve_sym(TCCState *s1, const char *sym, int type); -int pe_load_def_file(struct TCCState *s1, int fd); -int pe_test_res_file(void *v, int size); -int pe_load_res_file(struct TCCState *s1, int fd); -void pe_add_runtime(struct TCCState *s1); -void pe_guess_outfile(char *objfilename, int output_type); -int pe_output_file(struct TCCState *s1, const char *filename); - -/* tccasm.c */ -#ifdef CONFIG_TCC_ASM -static void asm_expr(TCCState *s1, ExprValue *pe); -static int asm_int_expr(TCCState *s1); -static int find_constraint(ASMOperand *operands, int nb_operands, - const char *name, const char **pp); - -static int tcc_assemble(TCCState *s1, int do_preprocess); -#endif - -static void asm_instr(void); -static void asm_global_instr(void); +static int nb_states; /********************************************************/ -/* global variables */ +#if ONE_SOURCE +#include "tccpp.c" +#include "tccgen.c" +#include "tccelf.c" +#include "tccrun.c" #ifdef TCC_TARGET_I386 #include "i386-gen.c" +#include "i386-link.c" +#include "i386-asm.c" #endif - #ifdef TCC_TARGET_ARM #include "arm-gen.c" +#include "arm-link.c" +#include "arm-asm.c" +#endif +#ifdef TCC_TARGET_ARM64 +#include "arm64-gen.c" +#include "arm64-link.c" #endif - #ifdef TCC_TARGET_C67 #include "c67-gen.c" +#include "c67-link.c" +#include "tcccoff.c" #endif - #ifdef TCC_TARGET_X86_64 #include "x86_64-gen.c" +#include "x86_64-link.c" +#include "i386-asm.c" #endif +#ifdef CONFIG_TCC_ASM +#include "tccasm.c" +#endif +#ifdef TCC_TARGET_PE +#include "tccpe.c" +#endif +#endif /* ONE_SOURCE */ -#ifdef CONFIG_TCC_STATIC - -#define RTLD_LAZY 0x001 -#define RTLD_NOW 0x002 -#define RTLD_GLOBAL 0x100 -#define RTLD_DEFAULT NULL - -/* dummy function for profiling */ -void *dlopen(const char *filename, int flag) +/********************************************************/ +#ifndef CONFIG_TCC_ASM +ST_FUNC void asm_instr(void) { - return NULL; + tcc_error("inline asm() not supported"); } - -void dlclose(void *p) +ST_FUNC void asm_global_instr(void) { + tcc_error("inline asm() not supported"); } +#endif -const char *dlerror(void) +/********************************************************/ +#ifdef _WIN32 +ST_FUNC char *normalize_slashes(char *path) { - return "error"; + char *p; + for (p = path; *p; ++p) + if (*p == '\\') + *p = '/'; + return path; } -typedef struct TCCSyms { - char *str; - void *ptr; -} TCCSyms; - -#define TCCSYM(a) { #a, &a, }, +static HMODULE tcc_module; -/* add the symbol you want here if no dynamic linking is done */ -static TCCSyms tcc_syms[] = { -#if !defined(CONFIG_TCCBOOT) - TCCSYM(printf) - TCCSYM(fprintf) - TCCSYM(fopen) - TCCSYM(fclose) -#endif - { NULL, NULL }, -}; - -void *resolve_sym(TCCState *s1, const char *symbol, int type) +/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */ +static void tcc_set_lib_path_w32(TCCState *s) { - TCCSyms *p; - p = tcc_syms; - while (p->str != NULL) { - if (!strcmp(p->str, symbol)) - return p->ptr; - p++; - } - return NULL; + char path[1024], *p; + GetModuleFileNameA(tcc_module, path, sizeof path); + p = tcc_basename(normalize_slashes(strlwr(path))); + if (p > path) + --p; + *p = 0; + tcc_set_lib_path(s, path); } -#elif !defined(_WIN32) - -#include <dlfcn.h> - -void *resolve_sym(TCCState *s1, const char *sym, int type) +#ifdef TCC_TARGET_PE +static void tcc_add_systemdir(TCCState *s) { - return dlsym(RTLD_DEFAULT, sym); + char buf[1000]; + GetSystemDirectory(buf, sizeof buf); + tcc_add_library_path(s, normalize_slashes(buf)); } - #endif -/********************************************************/ - -/* we use our own 'finite' function to avoid potential problems with - non standard math libs */ -/* XXX: endianness dependent */ -int ieee_finite(double d) +#ifdef LIBTCC_AS_DLL +BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) { - int *p = (int *)&d; - return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; + if (DLL_PROCESS_ATTACH == dwReason) + tcc_module = hDll; + return TRUE; } +#endif +#endif +/********************************************************/ /* copy a string and truncate it. */ -char *pstrcpy(char *buf, int buf_size, const char *s) +ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s) { char *q, *q_end; int c; @@ -346,101 +151,66 @@ char *pstrcpy(char *buf, int buf_size, const char *s) } /* strcat and truncate. */ -char *pstrcat(char *buf, int buf_size, const char *s) +ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s) { int len; len = strlen(buf); - if (len < buf_size) + if (len < buf_size) pstrcpy(buf + len, buf_size - len, s); return buf; } +ST_FUNC char *pstrncpy(char *out, const char *in, size_t num) +{ + memcpy(out, in, num); + out[num] = '\0'; + return out; +} + /* extract the basename of a file */ -char *tcc_basename(const char *name) +PUB_FUNC char *tcc_basename(const char *name) { char *p = strchr(name, 0); - while (p > name && !IS_PATHSEP(p[-1])) + while (p > name && !IS_DIRSEP(p[-1])) --p; return p; } -char *tcc_fileextension (const char *name) +/* extract extension part of a file + * + * (if no extension, return pointer to end-of-string) + */ +PUB_FUNC char *tcc_fileextension (const char *name) { char *b = tcc_basename(name); char *e = strrchr(b, '.'); return e ? e : strchr(b, 0); } -#ifdef _WIN32 -char *normalize_slashes(char *path) -{ - char *p; - for (p = path; *p; ++p) - if (*p == '\\') - *p = '/'; - return path; -} - -void tcc_set_lib_path_w32(TCCState *s) -{ - /* on win32, we suppose the lib and includes are at the location - of 'tcc.exe' */ - char path[1024], *p; - GetModuleFileNameA(NULL, path, sizeof path); - p = tcc_basename(normalize_slashes(strlwr(path))); - if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5)) - p -= 5; - else if (p > path) - p--; - *p = 0; - tcc_set_lib_path(s, path); -} -#endif +/********************************************************/ +/* memory management */ -void set_pages_executable(void *ptr, unsigned long length) -{ -#ifdef _WIN32 - unsigned long old_protect; - VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); -#else - unsigned long start, end; - start = (unsigned long)ptr & ~(PAGESIZE - 1); - end = (unsigned long)ptr + length; - end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); - mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC); -#endif -} +#undef free +#undef malloc +#undef realloc -/* memory management */ -#ifdef MEM_DEBUG -int mem_cur_size; -int mem_max_size; -unsigned malloc_usable_size(void*); -#endif +#ifndef MEM_DEBUG -void tcc_free(void *ptr) +PUB_FUNC void tcc_free(void *ptr) { -#ifdef MEM_DEBUG - mem_cur_size -= malloc_usable_size(ptr); -#endif free(ptr); } -void *tcc_malloc(unsigned long size) +PUB_FUNC void *tcc_malloc(unsigned long size) { void *ptr; ptr = malloc(size); if (!ptr && size) - error("memory full"); -#ifdef MEM_DEBUG - mem_cur_size += malloc_usable_size(ptr); - if (mem_cur_size > mem_max_size) - mem_max_size = mem_cur_size; -#endif + tcc_error("memory full (malloc)"); return ptr; } -void *tcc_mallocz(unsigned long size) +PUB_FUNC void *tcc_mallocz(unsigned long size) { void *ptr; ptr = tcc_malloc(size); @@ -448,23 +218,16 @@ void *tcc_mallocz(unsigned long size) return ptr; } -void *tcc_realloc(void *ptr, unsigned long size) +PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) { void *ptr1; -#ifdef MEM_DEBUG - mem_cur_size -= malloc_usable_size(ptr); -#endif ptr1 = realloc(ptr, size); -#ifdef MEM_DEBUG - /* NOTE: count not correct if alloc error, but not critical */ - mem_cur_size += malloc_usable_size(ptr1); - if (mem_cur_size > mem_max_size) - mem_max_size = mem_cur_size; -#endif + if (!ptr1 && size) + tcc_error("memory full (realloc)"); return ptr1; } -char *tcc_strdup(const char *str) +PUB_FUNC char *tcc_strdup(const char *str) { char *ptr; ptr = tcc_malloc(strlen(str) + 1); @@ -472,299 +235,229 @@ char *tcc_strdup(const char *str) return ptr; } -#define free(p) use_tcc_free(p) -#define malloc(s) use_tcc_malloc(s) -#define realloc(p, s) use_tcc_realloc(p, s) - -void dynarray_add(void ***ptab, int *nb_ptr, void *data) +PUB_FUNC void tcc_memcheck(void) { - int nb, nb_alloc; - void **pp; - - nb = *nb_ptr; - pp = *ptab; - /* every power of two we double array size */ - if ((nb & (nb - 1)) == 0) { - if (!nb) - nb_alloc = 1; - else - nb_alloc = nb * 2; - pp = tcc_realloc(pp, nb_alloc * sizeof(void *)); - if (!pp) - error("memory full"); - *ptab = pp; - } - pp[nb++] = data; - *nb_ptr = nb; } -void dynarray_reset(void *pp, int *n) -{ - void **p; - for (p = *(void***)pp; *n; ++p, --*n) - if (*p) - tcc_free(*p); - tcc_free(*(void**)pp); - *(void**)pp = NULL; -} +#else -/* symbol allocator */ -static Sym *__sym_malloc(void) -{ - Sym *sym_pool, *sym, *last_sym; - int i; +#define MEM_DEBUG_MAGIC1 0xFEEDDEB1 +#define MEM_DEBUG_MAGIC2 0xFEEDDEB2 +#define MEM_DEBUG_MAGIC3 0xFEEDDEB3 +#define MEM_DEBUG_FILE_LEN 40 +#define MEM_DEBUG_CHECK3(header) \ + ((mem_debug_header_t*)((char*)header + header->size))->magic3 +#define MEM_USER_PTR(header) \ + ((char *)header + offsetof(mem_debug_header_t, magic3)) +#define MEM_HEADER_PTR(ptr) \ + (mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3)) + +struct mem_debug_header { + unsigned magic1; + unsigned size; + struct mem_debug_header *prev; + struct mem_debug_header *next; + int line_num; + char file_name[MEM_DEBUG_FILE_LEN + 1]; + unsigned magic2; + ALIGNED(16) unsigned magic3; +}; - sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym)); - dynarray_add(&sym_pools, &nb_sym_pools, sym_pool); +typedef struct mem_debug_header mem_debug_header_t; - last_sym = sym_free_first; - sym = sym_pool; - for(i = 0; i < SYM_POOL_NB; i++) { - sym->next = last_sym; - last_sym = sym; - sym++; - } - sym_free_first = last_sym; - return last_sym; -} +static mem_debug_header_t *mem_debug_chain; +static unsigned mem_cur_size; +static unsigned mem_max_size; -static inline Sym *sym_malloc(void) +static mem_debug_header_t *malloc_check(void *ptr, const char *msg) { - Sym *sym; - sym = sym_free_first; - if (!sym) - sym = __sym_malloc(); - sym_free_first = sym->next; - return sym; + mem_debug_header_t * header = MEM_HEADER_PTR(ptr); + if (header->magic1 != MEM_DEBUG_MAGIC1 || + header->magic2 != MEM_DEBUG_MAGIC2 || + MEM_DEBUG_CHECK3(header) != MEM_DEBUG_MAGIC3 || + header->size == (unsigned)-1) { + fprintf(stderr, "%s check failed\n", msg); + if (header->magic1 == MEM_DEBUG_MAGIC1) + fprintf(stderr, "%s:%u: block allocated here.\n", + header->file_name, header->line_num); + exit(1); + } + return header; } -static inline void sym_free(Sym *sym) +PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) { - sym->next = sym_free_first; - sym_free_first = sym; -} + int ofs; + mem_debug_header_t *header; -Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) -{ - Section *sec; + header = malloc(sizeof(mem_debug_header_t) + size); + if (!header) + tcc_error("memory full (malloc)"); - sec = tcc_mallocz(sizeof(Section) + strlen(name)); - strcpy(sec->name, name); - sec->sh_type = sh_type; - sec->sh_flags = sh_flags; - switch(sh_type) { - case SHT_HASH: - case SHT_REL: - case SHT_RELA: - case SHT_DYNSYM: - case SHT_SYMTAB: - case SHT_DYNAMIC: - sec->sh_addralign = 4; - break; - case SHT_STRTAB: - sec->sh_addralign = 1; - break; - default: - sec->sh_addralign = 32; /* default conservative alignment */ - break; - } + header->magic1 = MEM_DEBUG_MAGIC1; + header->magic2 = MEM_DEBUG_MAGIC2; + header->size = size; + MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3; + header->line_num = line; + ofs = strlen(file) - MEM_DEBUG_FILE_LEN; + strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN); + header->file_name[MEM_DEBUG_FILE_LEN] = 0; - if (sh_flags & SHF_PRIVATE) { - dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec); - } else { - sec->sh_num = s1->nb_sections; - dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec); - } + header->next = mem_debug_chain; + header->prev = NULL; + if (header->next) + header->next->prev = header; + mem_debug_chain = header; - return sec; -} + mem_cur_size += size; + if (mem_cur_size > mem_max_size) + mem_max_size = mem_cur_size; -static void free_section(Section *s) -{ - tcc_free(s->data); + return MEM_USER_PTR(header); } -/* realloc section and set its content to zero */ -static void section_realloc(Section *sec, unsigned long new_size) +PUB_FUNC void tcc_free_debug(void *ptr) { - unsigned long size; - unsigned char *data; - - size = sec->data_allocated; - if (size == 0) - size = 1; - while (size < new_size) - size = size * 2; - data = tcc_realloc(sec->data, size); - if (!data) - error("memory full"); - memset(data + sec->data_allocated, 0, size - sec->data_allocated); - sec->data = data; - sec->data_allocated = size; + mem_debug_header_t *header; + if (!ptr) + return; + header = malloc_check(ptr, "tcc_free"); + mem_cur_size -= header->size; + header->size = (unsigned)-1; + if (header->next) + header->next->prev = header->prev; + if (header->prev) + header->prev->next = header->next; + if (header == mem_debug_chain) + mem_debug_chain = header->next; + free(header); } -/* reserve at least 'size' bytes in section 'sec' from - sec->data_offset. */ -static void *section_ptr_add(Section *sec, unsigned long size) +PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line) { - unsigned long offset, offset1; + void *ptr; + ptr = tcc_malloc_debug(size,file,line); + memset(ptr, 0, size); + return ptr; +} - offset = sec->data_offset; - offset1 = offset + size; - if (offset1 > sec->data_allocated) - section_realloc(sec, offset1); - sec->data_offset = offset1; - return sec->data + offset; +PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line) +{ + mem_debug_header_t *header; + int mem_debug_chain_update = 0; + if (!ptr) + return tcc_malloc_debug(size, file, line); + header = malloc_check(ptr, "tcc_realloc"); + mem_cur_size -= header->size; + mem_debug_chain_update = (header == mem_debug_chain); + header = realloc(header, sizeof(mem_debug_header_t) + size); + if (!header) + tcc_error("memory full (realloc)"); + header->size = size; + MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3; + if (header->next) + header->next->prev = header; + if (header->prev) + header->prev->next = header; + if (mem_debug_chain_update) + mem_debug_chain = header; + mem_cur_size += size; + if (mem_cur_size > mem_max_size) + mem_max_size = mem_cur_size; + return MEM_USER_PTR(header); } -/* return a reference to a section, and create it if it does not - exists */ -Section *find_section(TCCState *s1, const char *name) +PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line) { - Section *sec; - int i; - for(i = 1; i < s1->nb_sections; i++) { - sec = s1->sections[i]; - if (!strcmp(name, sec->name)) - return sec; - } - /* sections are created as PROGBITS */ - return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC); + char *ptr; + ptr = tcc_malloc_debug(strlen(str) + 1, file, line); + strcpy(ptr, str); + return ptr; } -/* update sym->c so that it points to an external symbol in section - 'section' with value 'value' */ -static void put_extern_sym2(Sym *sym, Section *section, - unsigned long value, unsigned long size, - int can_add_underscore) +PUB_FUNC void tcc_memcheck(void) { - int sym_type, sym_bind, sh_num, info, other, attr; - ElfW(Sym) *esym; - const char *name; - char buf1[256]; - - if (section == NULL) - sh_num = SHN_UNDEF; - else if (section == SECTION_ABS) - sh_num = SHN_ABS; - else - sh_num = section->sh_num; - - other = attr = 0; - - if ((sym->type.t & VT_BTYPE) == VT_FUNC) { - sym_type = STT_FUNC; -#ifdef TCC_TARGET_PE - if (sym->type.ref) - attr = sym->type.ref->r; - if (FUNC_EXPORT(attr)) - other |= 1; - if (FUNC_CALL(attr) == FUNC_STDCALL) - other |= 2; -#endif - } else { - sym_type = STT_OBJECT; - } - - if (sym->type.t & VT_STATIC) - sym_bind = STB_LOCAL; - else - sym_bind = STB_GLOBAL; - - if (!sym->c) { - name = get_tok_str(sym->v, NULL); -#ifdef CONFIG_TCC_BCHECK - if (tcc_state->do_bounds_check) { - char buf[32]; - - /* XXX: avoid doing that for statics ? */ - /* if bound checking is activated, we change some function - names by adding the "__bound" prefix */ - switch(sym->v) { -#if 0 - /* XXX: we rely only on malloc hooks */ - case TOK_malloc: - case TOK_free: - case TOK_realloc: - case TOK_memalign: - case TOK_calloc: -#endif - case TOK_memcpy: - case TOK_memmove: - case TOK_memset: - case TOK_strlen: - case TOK_strcpy: - case TOK_alloca: - strcpy(buf, "__bound_"); - strcat(buf, name); - name = buf; - break; - } + if (mem_cur_size) { + mem_debug_header_t *header = mem_debug_chain; + fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n", + mem_cur_size, mem_max_size); + while (header) { + fprintf(stderr, "%s:%u: error: %u bytes leaked\n", + header->file_name, header->line_num, header->size); + header = header->next; } +#if MEM_DEBUG-0 == 2 + exit(2); #endif - -#ifdef TCC_TARGET_PE - if ((other & 2) && can_add_underscore) { - sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr)); - name = buf1; - } else -#endif - if (tcc_state->leading_underscore && can_add_underscore) { - buf1[0] = '_'; - pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); - name = buf1; - } - info = ELFW(ST_INFO)(sym_bind, sym_type); - sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name); - } else { - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - esym->st_value = value; - esym->st_size = size; - esym->st_shndx = sh_num; - esym->st_other |= other; } } +#endif /* MEM_DEBUG */ -static void put_extern_sym(Sym *sym, Section *section, - unsigned long value, unsigned long size) -{ - put_extern_sym2(sym, section, value, size, 1); -} +#define free(p) use_tcc_free(p) +#define malloc(s) use_tcc_malloc(s) +#define realloc(p, s) use_tcc_realloc(p, s) -/* add a new relocation entry to symbol 'sym' in section 's' */ -static void greloc(Section *s, Sym *sym, unsigned long offset, int type) -{ - if (!sym->c) - put_extern_sym(sym, NULL, 0, 0); - /* now we can add ELF relocation info */ - put_elf_reloc(symtab_section, s, offset, type, sym->c); -} +/********************************************************/ +/* dynarrays */ -static inline int isid(int c) +ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data) { - return (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - c == '_'; -} + int nb, nb_alloc; + void **pp; -static inline int isnum(int c) -{ - return c >= '0' && c <= '9'; + nb = *nb_ptr; + pp = *(void ***)ptab; + /* every power of two we double array size */ + if ((nb & (nb - 1)) == 0) { + if (!nb) + nb_alloc = 1; + else + nb_alloc = nb * 2; + pp = tcc_realloc(pp, nb_alloc * sizeof(void *)); + *(void***)ptab = pp; + } + pp[nb++] = data; + *nb_ptr = nb; } -static inline int isoct(int c) +ST_FUNC void dynarray_reset(void *pp, int *n) { - return c >= '0' && c <= '7'; + void **p; + for (p = *(void***)pp; *n; ++p, --*n) + if (*p) + tcc_free(*p); + tcc_free(*(void**)pp); + *(void**)pp = NULL; } -static inline int toup(int c) +static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in) { - if (c >= 'a' && c <= 'z') - return c - 'a' + 'A'; - else - return c; + const char *p; + do { + int c; + CString str; + + cstr_new(&str); + for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) { + if (c == '{' && p[1] && p[2] == '}') { + c = p[1], p += 2; + if (c == 'B') + cstr_cat(&str, s->tcc_lib_path, -1); + } else { + cstr_ccat(&str, c); + } + } + if (str.size) { + cstr_ccat(&str, '\0'); + dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data)); + } + cstr_free(&str); + in = p+1; + } while (*p); } +/********************************************************/ + static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) { int len; @@ -780,42 +473,51 @@ static void strcat_printf(char *buf, int buf_size, const char *fmt, ...) va_end(ap); } -void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) +static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) { char buf[2048]; - BufferedFile **f; - + BufferedFile **pf, *f; + buf[0] = '\0'; - if (file) { - for(f = s1->include_stack; f < s1->include_stack_ptr; f++) - strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", - (*f)->filename, (*f)->line_num); - if (file->line_num > 0) { - strcat_printf(buf, sizeof(buf), - "%s:%d: ", file->filename, file->line_num); + /* use upper file if inline ":asm:" or token ":paste:" */ + for (f = file; f && f->filename[0] == ':'; f = f->prev) + ; + if (f) { + for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++) + strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", + (*pf)->filename, (*pf)->line_num); + if (f->line_num > 0) { + strcat_printf(buf, sizeof(buf), "%s:%d: ", + f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL)); } else { - strcat_printf(buf, sizeof(buf), - "%s: ", file->filename); + strcat_printf(buf, sizeof(buf), "%s: ", + f->filename); } } else { - strcat_printf(buf, sizeof(buf), - "tcc: "); + strcat_printf(buf, sizeof(buf), "tcc: "); } if (is_warning) strcat_printf(buf, sizeof(buf), "warning: "); + else + strcat_printf(buf, sizeof(buf), "error: "); strcat_vprintf(buf, sizeof(buf), fmt, ap); if (!s1->error_func) { /* default case: stderr */ + if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout) + /* print a newline during tcc -E */ + printf("\n"), fflush(stdout); + fflush(stdout); /* flush -v output */ fprintf(stderr, "%s\n", buf); - } - if (!is_warning || s1->warn_error) { + fflush(stderr); /* print error/warning now (win32) */ + } else { s1->error_func(s1->error_opaque, buf); - s1->nb_errors++; } + if (!is_warning || s1->warn_error) + s1->nb_errors++; } -void tcc_set_error_func(TCCState *s, void *error_opaque, +LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, void (*error_func)(void *opaque, const char *msg)) { s->error_opaque = error_opaque; @@ -823,7 +525,7 @@ void tcc_set_error_func(TCCState *s, void *error_opaque, } /* error without aborting current compilation */ -void error_noabort(const char *fmt, ...) +PUB_FUNC void tcc_error_noabort(const char *fmt, ...) { TCCState *s1 = tcc_state; va_list ap; @@ -833,7 +535,7 @@ void error_noabort(const char *fmt, ...) va_end(ap); } -void error(const char *fmt, ...) +PUB_FUNC void tcc_error(const char *fmt, ...) { TCCState *s1 = tcc_state; va_list ap; @@ -850,12 +552,7 @@ void error(const char *fmt, ...) } } -void expect(const char *msg) -{ - error("%s expected", msg); -} - -void warning(const char *fmt, ...) +PUB_FUNC void tcc_warning(const char *fmt, ...) { TCCState *s1 = tcc_state; va_list ap; @@ -868,435 +565,135 @@ void warning(const char *fmt, ...) va_end(ap); } -void skip(int c) -{ - if (tok != c) - error("'%c' expected", c); - next(); -} - -static void test_lvalue(void) -{ - if (!(vtop->r & VT_LVAL)) - expect("lvalue"); -} - -/* CString handling */ - -static void cstr_realloc(CString *cstr, int new_size) -{ - int size; - void *data; - - size = cstr->size_allocated; - if (size == 0) - size = 8; /* no need to allocate a too small first string */ - while (size < new_size) - size = size * 2; - data = tcc_realloc(cstr->data_allocated, size); - if (!data) - error("memory full"); - cstr->data_allocated = data; - cstr->size_allocated = size; - cstr->data = data; -} - -/* add a byte */ -static inline void cstr_ccat(CString *cstr, int ch) -{ - int size; - size = cstr->size + 1; - if (size > cstr->size_allocated) - cstr_realloc(cstr, size); - ((unsigned char *)cstr->data)[size - 1] = ch; - cstr->size = size; -} - -static void cstr_cat(CString *cstr, const char *str) -{ - int c; - for(;;) { - c = *str; - if (c == '\0') - break; - cstr_ccat(cstr, c); - str++; - } -} - -/* add a wide char */ -static void cstr_wccat(CString *cstr, int ch) -{ - int size; - size = cstr->size + sizeof(nwchar_t); - if (size > cstr->size_allocated) - cstr_realloc(cstr, size); - *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch; - cstr->size = size; -} - -static void cstr_new(CString *cstr) -{ - memset(cstr, 0, sizeof(CString)); -} - -/* free string and reset it to NULL */ -static void cstr_free(CString *cstr) -{ - tcc_free(cstr->data_allocated); - cstr_new(cstr); -} - -#define cstr_reset(cstr) cstr_free(cstr) - -/* XXX: unicode ? */ -static void add_char(CString *cstr, int c) -{ - if (c == '\'' || c == '\"' || c == '\\') { - /* XXX: could be more precise if char or string */ - cstr_ccat(cstr, '\\'); - } - if (c >= 32 && c <= 126) { - cstr_ccat(cstr, c); - } else { - cstr_ccat(cstr, '\\'); - if (c == '\n') { - cstr_ccat(cstr, 'n'); - } else { - cstr_ccat(cstr, '0' + ((c >> 6) & 7)); - cstr_ccat(cstr, '0' + ((c >> 3) & 7)); - cstr_ccat(cstr, '0' + (c & 7)); - } - } -} - -/* push, without hashing */ -static Sym *sym_push2(Sym **ps, int v, int t, long c) -{ - Sym *s; - s = sym_malloc(); - s->v = v; - s->type.t = t; - s->c = c; - s->next = NULL; - /* add in stack */ - s->prev = *ps; - *ps = s; - return s; -} - -/* find a symbol and return its associated structure. 's' is the top - of the symbol stack */ -static Sym *sym_find2(Sym *s, int v) -{ - while (s) { - if (s->v == v) - return s; - s = s->prev; - } - return NULL; -} - -/* structure lookup */ -static inline Sym *struct_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_struct; -} - -/* find an identifier */ -static inline Sym *sym_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_identifier; -} +/********************************************************/ +/* I/O layer */ -/* push a given symbol on the symbol stack */ -static Sym *sym_push(int v, CType *type, int r, int c) +ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) { - Sym *s, **ps; - TokenSym *ts; - - if (local_stack) - ps = &local_stack; - else - ps = &global_stack; - s = sym_push2(ps, v, type->t, c); - s->type.ref = type->ref; - s->r = r; - /* don't record fields or anonymous symbols */ - /* XXX: simplify */ - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { - /* record symbol in token array */ - ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; - if (v & SYM_STRUCT) - ps = &ts->sym_struct; - else - ps = &ts->sym_identifier; - s->prev_tok = *ps; - *ps = s; - } - return s; -} + BufferedFile *bf; + int buflen = initlen ? initlen : IO_BUF_SIZE; -/* push a global identifier */ -static Sym *global_identifier_push(int v, int t, int c) -{ - Sym *s, **ps; - s = sym_push2(&global_stack, v, t, c); - /* don't record anonymous symbol */ - if (v < SYM_FIRST_ANOM) { - ps = &table_ident[v - TOK_IDENT]->sym_identifier; - /* modify the top most local identifier, so that - sym_identifier will point to 's' when popped */ - while (*ps != NULL) - ps = &(*ps)->prev_tok; - s->prev_tok = NULL; - *ps = s; - } - return s; + bf = tcc_mallocz(sizeof(BufferedFile) + buflen); + bf->buf_ptr = bf->buffer; + bf->buf_end = bf->buffer + initlen; + bf->buf_end[0] = CH_EOB; /* put eob symbol */ + pstrcpy(bf->filename, sizeof(bf->filename), filename); + bf->true_filename = bf->filename; + bf->line_num = 1; + bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; + bf->fd = -1; + bf->prev = file; + file = bf; + tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; } -/* pop symbols until top reaches 'b' */ -static void sym_pop(Sym **ptop, Sym *b) +ST_FUNC void tcc_close(void) { - Sym *s, *ss, **ps; - TokenSym *ts; - int v; - - s = *ptop; - while(s != b) { - ss = s->prev; - v = s->v; - /* remove symbol in token array */ - /* XXX: simplify */ - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { - ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; - if (v & SYM_STRUCT) - ps = &ts->sym_struct; - else - ps = &ts->sym_identifier; - *ps = s->prev_tok; - } - sym_free(s); - s = ss; + BufferedFile *bf = file; + if (bf->fd > 0) { + close(bf->fd); + total_lines += bf->line_num; } - *ptop = b; + if (bf->true_filename != bf->filename) + tcc_free(bf->true_filename); + file = bf->prev; + tcc_free(bf); } -/* I/O layer */ - -BufferedFile *tcc_open(TCCState *s1, const char *filename) +ST_FUNC int tcc_open(TCCState *s1, const char *filename) { int fd; - BufferedFile *bf; - if (strcmp(filename, "-") == 0) - fd = 0, filename = "stdin"; + fd = 0, filename = "<stdin>"; else fd = open(filename, O_RDONLY | O_BINARY); if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3) printf("%s %*s%s\n", fd < 0 ? "nf":"->", - (s1->include_stack_ptr - s1->include_stack), "", filename); + (int)(s1->include_stack_ptr - s1->include_stack), "", filename); if (fd < 0) - return NULL; - bf = tcc_malloc(sizeof(BufferedFile)); - bf->fd = fd; - bf->buf_ptr = bf->buffer; - bf->buf_end = bf->buffer; - bf->buffer[0] = CH_EOB; /* put eob symbol */ - pstrcpy(bf->filename, sizeof(bf->filename), filename); + return -1; + tcc_open_bf(s1, filename, 0); #ifdef _WIN32 - normalize_slashes(bf->filename); + normalize_slashes(file->filename); #endif - bf->line_num = 1; - bf->ifndef_macro = 0; - bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; - // printf("opening '%s'\n", filename); - return bf; + file->fd = fd; + return fd; } -void tcc_close(BufferedFile *bf) -{ - total_lines += bf->line_num; - close(bf->fd); - tcc_free(bf); -} - -#include "tccpp.c" -#include "tccgen.c" - - -/* compile the C file opened in 'file'. Return non zero if errors. */ +/* compile the file opened in 'file'. Return non zero if errors. */ static int tcc_compile(TCCState *s1) { Sym *define_start; - char buf[512]; - volatile int section_sym; - -#ifdef INC_DEBUG - printf("%s: **** new file\n", file->filename); -#endif - preprocess_init(s1); - - cur_text_section = NULL; - funcname = ""; - anon_sym = SYM_FIRST_ANOM; - - /* file info: full path + filename */ - section_sym = 0; /* avoid warning */ - if (s1->do_debug) { - section_sym = put_elf_sym(symtab_section, 0, 0, - ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, - text_section->sh_num, NULL); - getcwd(buf, sizeof(buf)); -#ifdef _WIN32 - normalize_slashes(buf); -#endif - pstrcat(buf, sizeof(buf), "/"); - put_stabs_r(buf, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); - put_stabs_r(file->filename, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); - } - /* an elf symbol of type STT_FILE must be put so that STB_LOCAL - symbols can be safely used */ - put_elf_sym(symtab_section, 0, 0, - ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, - SHN_ABS, file->filename); - - /* define some often used types */ - int_type.t = VT_INT; - - char_pointer_type.t = VT_BYTE; - mk_pointer(&char_pointer_type); - - func_old_type.t = VT_FUNC; - func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); - -#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) - float_type.t = VT_FLOAT; - double_type.t = VT_DOUBLE; - - func_float_type.t = VT_FUNC; - func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD); - func_double_type.t = VT_FUNC; - func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD); -#endif - -#if 0 - /* define 'void *alloca(unsigned int)' builtin function */ - { - Sym *s1; - - p = anon_sym++; - sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW); - s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); - s1->next = NULL; - sym->next = s1; - sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); - } -#endif + int filetype, is_asm; define_start = define_stack; - nocode_wanted = 1; + filetype = s1->filetype; + is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP; if (setjmp(s1->error_jmp_buf) == 0) { s1->nb_errors = 0; s1->error_set_jmp_enabled = 1; - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM; - next(); - decl(VT_CONST); - if (tok != TOK_EOF) - expect("declaration"); - - /* end of translation unit info */ - if (s1->do_debug) { - put_stabs_r(NULL, N_SO, 0, 0, - text_section->data_offset, text_section, section_sym); + preprocess_start(s1, is_asm); + if (s1->output_type == TCC_OUTPUT_PREPROCESS) { + tcc_preprocess(s1); + } else if (is_asm) { +#ifdef CONFIG_TCC_ASM + tcc_assemble(s1, filetype == AFF_TYPE_ASMPP); +#else + tcc_error_noabort("asm not supported"); +#endif + } else { + tccgen_compile(s1); } } s1->error_set_jmp_enabled = 0; - /* reset define stack, but leave -Dsymbols (may be incorrect if - they are undefined) */ - free_defines(define_start); - - gen_inline_functions(); - - sym_pop(&global_stack, NULL); - sym_pop(&local_stack, NULL); - + preprocess_end(s1); + free_inline_functions(s1); + /* reset define stack, but keep -D and built-ins */ + free_defines(define_start); + sym_pop(&global_stack, NULL, 0); + sym_pop(&local_stack, NULL, 0); return s1->nb_errors != 0 ? -1 : 0; } -int tcc_compile_string(TCCState *s, const char *str) +LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) { - BufferedFile bf1, *bf = &bf1; - int ret, len; - char *buf; + int len, ret; - /* init file structure */ - bf->fd = -1; - /* XXX: avoid copying */ len = strlen(str); - buf = tcc_malloc(len + 1); - if (!buf) - return -1; - memcpy(buf, str, len); - buf[len] = CH_EOB; - bf->buf_ptr = buf; - bf->buf_end = buf + len; - pstrcpy(bf->filename, sizeof(bf->filename), "<string>"); - bf->line_num = 1; - file = bf; + tcc_open_bf(s, "<string>", len); + memcpy(file->buffer, str, len); ret = tcc_compile(s); - file = NULL; - tcc_free(buf); - - /* currently, no need to close */ + tcc_close(); return ret; } /* define a preprocessor symbol. A value can also be provided with the '=' operator */ -void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) +LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) { - BufferedFile bf1, *bf = &bf1; - - pstrcpy(bf->buffer, IO_BUF_SIZE, sym); - pstrcat(bf->buffer, IO_BUF_SIZE, " "); + int len1, len2; /* default value */ - if (!value) + if (!value) value = "1"; - pstrcat(bf->buffer, IO_BUF_SIZE, value); - + len1 = strlen(sym); + len2 = strlen(value); + /* init file structure */ - bf->fd = -1; - bf->buf_ptr = bf->buffer; - bf->buf_end = bf->buffer + strlen(bf->buffer); - *bf->buf_end = CH_EOB; - bf->filename[0] = '\0'; - bf->line_num = 1; - file = bf; - - s1->include_stack_ptr = s1->include_stack; + tcc_open_bf(s1, "<define>", len1 + len2 + 1); + memcpy(file->buffer, sym, len1); + file->buffer[len1] = ' '; + memcpy(file->buffer + len1 + 1, value, len2); /* parse with define parser */ - ch = file->buf_ptr[0]; next_nomacro(); parse_define(); - file = NULL; + tcc_close(); } /* undefine a preprocessor symbol */ -void tcc_undefine_symbol(TCCState *s1, const char *sym) +LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym) { TokenSym *ts; Sym *s; @@ -1307,458 +704,22 @@ void tcc_undefine_symbol(TCCState *s1, const char *sym) define_undef(s); } -#ifdef CONFIG_TCC_ASM - -#ifdef TCC_TARGET_I386 -#include "i386-asm.c" -#endif -#include "tccasm.c" - -#else -static void asm_instr(void) -{ - error("inline asm() not supported"); -} -static void asm_global_instr(void) -{ - error("inline asm() not supported"); -} -#endif - -#include "tccelf.c" - -#ifdef TCC_TARGET_COFF -#include "tcccoff.c" -#endif - -#ifdef TCC_TARGET_PE -#include "tccpe.c" -#endif - -#ifdef CONFIG_TCC_BACKTRACE -/* print the position in the source file of PC value 'pc' by reading - the stabs debug information */ -static void rt_printline(unsigned long wanted_pc) -{ - Stab_Sym *sym, *sym_end; - char func_name[128], last_func_name[128]; - unsigned long func_addr, last_pc, pc; - const char *incl_files[INCLUDE_STACK_SIZE]; - int incl_index, len, last_line_num, i; - const char *str, *p; - - fprintf(stderr, "0x%08lx:", wanted_pc); - - func_name[0] = '\0'; - func_addr = 0; - incl_index = 0; - last_func_name[0] = '\0'; - last_pc = 0xffffffff; - last_line_num = 1; - sym = (Stab_Sym *)stab_section->data + 1; - sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset); - while (sym < sym_end) { - switch(sym->n_type) { - /* function start or end */ - case N_FUN: - if (sym->n_strx == 0) { - /* we test if between last line and end of function */ - pc = sym->n_value + func_addr; - if (wanted_pc >= last_pc && wanted_pc < pc) - goto found; - func_name[0] = '\0'; - func_addr = 0; - } else { - str = stabstr_section->data + sym->n_strx; - p = strchr(str, ':'); - if (!p) { - pstrcpy(func_name, sizeof(func_name), str); - } else { - len = p - str; - if (len > sizeof(func_name) - 1) - len = sizeof(func_name) - 1; - memcpy(func_name, str, len); - func_name[len] = '\0'; - } - func_addr = sym->n_value; - } - break; - /* line number info */ - case N_SLINE: - pc = sym->n_value + func_addr; - if (wanted_pc >= last_pc && wanted_pc < pc) - goto found; - last_pc = pc; - last_line_num = sym->n_desc; - /* XXX: slow! */ - strcpy(last_func_name, func_name); - break; - /* include files */ - case N_BINCL: - str = stabstr_section->data + sym->n_strx; - add_incl: - if (incl_index < INCLUDE_STACK_SIZE) { - incl_files[incl_index++] = str; - } - break; - case N_EINCL: - if (incl_index > 1) - incl_index--; - break; - case N_SO: - if (sym->n_strx == 0) { - incl_index = 0; /* end of translation unit */ - } else { - str = stabstr_section->data + sym->n_strx; - /* do not add path */ - len = strlen(str); - if (len > 0 && str[len - 1] != '/') - goto add_incl; - } - break; - } - sym++; - } - - /* second pass: we try symtab symbols (no line number info) */ - incl_index = 0; - { - ElfW(Sym) *sym, *sym_end; - int type; - - sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { - type = ELFW(ST_TYPE)(sym->st_info); - if (type == STT_FUNC) { - if (wanted_pc >= sym->st_value && - wanted_pc < sym->st_value + sym->st_size) { - pstrcpy(last_func_name, sizeof(last_func_name), - strtab_section->data + sym->st_name); - goto found; - } - } - } - } - /* did not find any info: */ - fprintf(stderr, " ???\n"); - return; - found: - if (last_func_name[0] != '\0') { - fprintf(stderr, " %s()", last_func_name); - } - if (incl_index > 0) { - fprintf(stderr, " (%s:%d", - incl_files[incl_index - 1], last_line_num); - for(i = incl_index - 2; i >= 0; i--) - fprintf(stderr, ", included from %s", incl_files[i]); - fprintf(stderr, ")"); - } - fprintf(stderr, "\n"); -} - -#ifdef __i386__ -/* fix for glibc 2.1 */ -#ifndef REG_EIP -#define REG_EIP EIP -#define REG_EBP EBP -#endif - -/* return the PC at frame level 'level'. Return non zero if not found */ -static int rt_get_caller_pc(unsigned long *paddr, - ucontext_t *uc, int level) -{ - unsigned long fp; - int i; - - if (level == 0) { -#if defined(__FreeBSD__) - *paddr = uc->uc_mcontext.mc_eip; -#elif defined(__dietlibc__) - *paddr = uc->uc_mcontext.eip; -#else - *paddr = uc->uc_mcontext.gregs[REG_EIP]; -#endif - return 0; - } else { -#if defined(__FreeBSD__) - fp = uc->uc_mcontext.mc_ebp; -#elif defined(__dietlibc__) - fp = uc->uc_mcontext.ebp; -#else - fp = uc->uc_mcontext.gregs[REG_EBP]; -#endif - for(i=1;i<level;i++) { - /* XXX: check address validity with program info */ - if (fp <= 0x1000 || fp >= 0xc0000000) - return -1; - fp = ((unsigned long *)fp)[0]; - } - *paddr = ((unsigned long *)fp)[1]; - return 0; - } -} -#elif defined(__x86_64__) -/* return the PC at frame level 'level'. Return non zero if not found */ -static int rt_get_caller_pc(unsigned long *paddr, - ucontext_t *uc, int level) -{ - unsigned long fp; - int i; - - if (level == 0) { - /* XXX: only support linux */ - *paddr = uc->uc_mcontext.gregs[REG_RIP]; - return 0; - } else { - fp = uc->uc_mcontext.gregs[REG_RBP]; - for(i=1;i<level;i++) { - /* XXX: check address validity with program info */ - if (fp <= 0x1000) - return -1; - fp = ((unsigned long *)fp)[0]; - } - *paddr = ((unsigned long *)fp)[1]; - return 0; - } -} -#else -#warning add arch specific rt_get_caller_pc() -static int rt_get_caller_pc(unsigned long *paddr, - ucontext_t *uc, int level) -{ - return -1; -} -#endif - -/* emit a run time error at position 'pc' */ -void rt_error(ucontext_t *uc, const char *fmt, ...) -{ - va_list ap; - unsigned long pc; - int i; - - va_start(ap, fmt); - fprintf(stderr, "Runtime error: "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - for(i=0;i<num_callers;i++) { - if (rt_get_caller_pc(&pc, uc, i) < 0) - break; - if (i == 0) - fprintf(stderr, "at "); - else - fprintf(stderr, "by "); - rt_printline(pc); - } - exit(255); - va_end(ap); -} - -/* signal handler for fatal errors */ -static void sig_error(int signum, siginfo_t *siginf, void *puc) -{ - ucontext_t *uc = puc; - - switch(signum) { - case SIGFPE: - switch(siginf->si_code) { - case FPE_INTDIV: - case FPE_FLTDIV: - rt_error(uc, "division by zero"); - break; - default: - rt_error(uc, "floating point exception"); - break; - } - break; - case SIGBUS: - case SIGSEGV: - if (rt_bound_error_msg && *rt_bound_error_msg) - rt_error(uc, *rt_bound_error_msg); - else - rt_error(uc, "dereferencing invalid pointer"); - break; - case SIGILL: - rt_error(uc, "illegal instruction"); - break; - case SIGABRT: - rt_error(uc, "abort() called"); - break; - default: - rt_error(uc, "caught signal %d", signum); - break; - } - exit(255); -} - -#endif - -/* copy code into memory passed in by the caller and do all relocations - (needed before using tcc_get_symbol()). - returns -1 on error and required size if ptr is NULL */ -int tcc_relocate(TCCState *s1, void *ptr) -{ - Section *s; - unsigned long offset, length, mem; - int i; - - if (0 == s1->runtime_added) { - s1->runtime_added = 1; - s1->nb_errors = 0; -#ifdef TCC_TARGET_PE - pe_add_runtime(s1); - relocate_common_syms(); - tcc_add_linker_symbols(s1); -#else - tcc_add_runtime(s1); - relocate_common_syms(); - tcc_add_linker_symbols(s1); - build_got_entries(s1); -#endif - } - - offset = 0, mem = (unsigned long)ptr; - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (0 == (s->sh_flags & SHF_ALLOC)) - continue; - length = s->data_offset; - s->sh_addr = mem ? (mem + offset + 15) & ~15 : 0; - offset = (offset + length + 15) & ~15; - } - - /* relocate symbols */ - relocate_syms(s1, 1); - if (s1->nb_errors) - return -1; - -#ifdef TCC_TARGET_X86_64 - s1->runtime_plt_and_got_offset = 0; - s1->runtime_plt_and_got = (char *)(mem + offset); - /* double the size of the buffer for got and plt entries - XXX: calculate exact size for them? */ - offset *= 2; -#endif - - if (0 == mem) - return offset + 15; - - /* relocate each section */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (s->reloc) - relocate_section(s1, s); - } - - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (0 == (s->sh_flags & SHF_ALLOC)) - continue; - length = s->data_offset; - // printf("%-12s %08x %04x\n", s->name, s->sh_addr, length); - ptr = (void*)s->sh_addr; - if (NULL == s->data || s->sh_type == SHT_NOBITS) - memset(ptr, 0, length); - else - memcpy(ptr, s->data, length); - /* mark executable sections as executable in memory */ - if (s->sh_flags & SHF_EXECINSTR) - set_pages_executable(ptr, length); - } -#ifdef TCC_TARGET_X86_64 - set_pages_executable(s1->runtime_plt_and_got, - s1->runtime_plt_and_got_offset); -#endif - return 0; -} - -/* launch the compiled program with the given arguments */ -int tcc_run(TCCState *s1, int argc, char **argv) -{ - int (*prog_main)(int, char **); - void *ptr; - int ret; - - ret = tcc_relocate(s1, NULL); - if (ret < 0) - return -1; - ptr = tcc_malloc(ret); - tcc_relocate(s1, ptr); - - prog_main = tcc_get_symbol_err(s1, "main"); - - if (s1->do_debug) { -#ifdef CONFIG_TCC_BACKTRACE - struct sigaction sigact; - /* install TCC signal handlers to print debug info on fatal - runtime errors */ - sigact.sa_flags = SA_SIGINFO | SA_RESETHAND; - sigact.sa_sigaction = sig_error; - sigemptyset(&sigact.sa_mask); - sigaction(SIGFPE, &sigact, NULL); - sigaction(SIGILL, &sigact, NULL); - sigaction(SIGSEGV, &sigact, NULL); - sigaction(SIGBUS, &sigact, NULL); - sigaction(SIGABRT, &sigact, NULL); -#else - error("debug mode not available"); -#endif - } - -#ifdef CONFIG_TCC_BCHECK - if (s1->do_bounds_check) { - void (*bound_init)(void); - - /* set error function */ - rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg"); - - /* XXX: use .init section so that it also work in binary ? */ - bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init"); - bound_init(); - } -#endif - ret = (*prog_main)(argc, argv); - tcc_free(ptr); - return ret; -} - -void tcc_memstats(void) -{ -#ifdef MEM_DEBUG - printf("memory in use: %d\n", mem_cur_size); -#endif -} - +/* cleanup all static data used during compilation */ static void tcc_cleanup(void) { - int i, n; - if (NULL == tcc_state) return; + while (file) + tcc_close(); + tccpp_delete(tcc_state); tcc_state = NULL; - - /* free -D defines */ - free_defines(NULL); - - /* free tokens */ - n = tok_ident - TOK_IDENT; - for(i = 0; i < n; i++) - tcc_free(table_ident[i]); - tcc_free(table_ident); - /* free sym_pools */ dynarray_reset(&sym_pools, &nb_sym_pools); - /* string buffer */ - cstr_free(&tokcstr); /* reset symbol stack */ sym_free_first = NULL; - /* cleanup from error/setjmp */ - macro_ptr = NULL; } -TCCState *tcc_new(void) +LIBTCCAPI TCCState *tcc_new(void) { TCCState *s; @@ -1768,10 +729,30 @@ TCCState *tcc_new(void) if (!s) return NULL; tcc_state = s; - s->output_type = TCC_OUTPUT_MEMORY; - s->tcc_lib_path = CONFIG_TCCDIR; + ++nb_states; + + s->alacarte_link = 1; + s->nocommon = 1; + s->warn_implicit_function_declaration = 1; + s->ms_extensions = 1; - preprocess_new(); +#ifdef CHAR_IS_UNSIGNED + s->char_is_unsigned = 1; +#endif +#ifdef TCC_TARGET_I386 + s->seg_size = 32; +#endif + /* enable this if you want symbols with leading underscore on windows: */ +#if 0 /* def TCC_TARGET_PE */ + s->leading_underscore = 1; +#endif +#ifdef _WIN32 + tcc_set_lib_path_w32(s); +#else + tcc_set_lib_path(s, CONFIG_TCCDIR); +#endif + tccelf_new(s); + tccpp_new(s); /* we add dummy defines for some special macros to speed up tests and to have working defined() */ @@ -1779,17 +760,28 @@ TCCState *tcc_new(void) define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL); define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL); define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL); + define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL); + { + /* define __TINYC__ 92X */ + char buffer[32]; int a,b,c; + sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); + sprintf(buffer, "%d", a*10000 + b*100 + c); + tcc_define_symbol(s, "__TINYC__", buffer); + } /* standard defines */ tcc_define_symbol(s, "__STDC__", NULL); tcc_define_symbol(s, "__STDC_VERSION__", "199901L"); + tcc_define_symbol(s, "__STDC_HOSTED__", NULL); + + /* target defines */ #if defined(TCC_TARGET_I386) tcc_define_symbol(s, "__i386__", NULL); -#endif -#if defined(TCC_TARGET_X86_64) + tcc_define_symbol(s, "__i386", NULL); + tcc_define_symbol(s, "i386", NULL); +#elif defined(TCC_TARGET_X86_64) tcc_define_symbol(s, "__x86_64__", NULL); -#endif -#if defined(TCC_TARGET_ARM) +#elif defined(TCC_TARGET_ARM) tcc_define_symbol(s, "__ARM_ARCH_4__", NULL); tcc_define_symbol(s, "__arm_elf__", NULL); tcc_define_symbol(s, "__arm_elf", NULL); @@ -1798,372 +790,403 @@ TCCState *tcc_new(void) tcc_define_symbol(s, "__arm", NULL); tcc_define_symbol(s, "arm", NULL); tcc_define_symbol(s, "__APCS_32__", NULL); + tcc_define_symbol(s, "__ARMEL__", NULL); +#if defined(TCC_ARM_EABI) + tcc_define_symbol(s, "__ARM_EABI__", NULL); +#endif +#if defined(TCC_ARM_HARDFLOAT) + s->float_abi = ARM_HARD_FLOAT; + tcc_define_symbol(s, "__ARM_PCS_VFP", NULL); +#else + s->float_abi = ARM_SOFTFP_FLOAT; #endif +#elif defined(TCC_TARGET_ARM64) + tcc_define_symbol(s, "__aarch64__", NULL); +#elif defined TCC_TARGET_C67 + tcc_define_symbol(s, "__C67__", NULL); +#endif + #ifdef TCC_TARGET_PE tcc_define_symbol(s, "_WIN32", NULL); +# ifdef TCC_TARGET_X86_64 + tcc_define_symbol(s, "_WIN64", NULL); +# endif #else tcc_define_symbol(s, "__unix__", NULL); tcc_define_symbol(s, "__unix", NULL); -#if defined(__linux) + tcc_define_symbol(s, "unix", NULL); +# if defined(__linux__) tcc_define_symbol(s, "__linux__", NULL); tcc_define_symbol(s, "__linux", NULL); +# endif +# if defined(__FreeBSD__) + tcc_define_symbol(s, "__FreeBSD__", "__FreeBSD__"); + /* No 'Thread Storage Local' on FreeBSD with tcc */ + tcc_define_symbol(s, "__NO_TLS", NULL); +# endif +# if defined(__FreeBSD_kernel__) + tcc_define_symbol(s, "__FreeBSD_kernel__", NULL); +# endif +# if defined(__NetBSD__) + tcc_define_symbol(s, "__NetBSD__", "__NetBSD__"); +# endif +# if defined(__OpenBSD__) + tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__"); +# endif #endif -#endif - /* tiny C specific defines */ - tcc_define_symbol(s, "__TINYC__", NULL); - /* tiny C & gcc defines */ + /* TinyCC & gcc defines */ +#if PTR_SIZE == 4 + /* 32bit systems. */ tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int"); tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int"); + tcc_define_symbol(s, "__ILP32__", NULL); +#elif LONG_SIZE == 4 + /* 64bit Windows. */ + tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long"); + tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long"); + tcc_define_symbol(s, "__LLP64__", NULL); +#else + /* Other 64bit systems. */ + tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long"); + tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long"); + tcc_define_symbol(s, "__LP64__", NULL); +#endif + #ifdef TCC_TARGET_PE tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short"); + tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short"); #else tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); -#endif - -#ifndef TCC_TARGET_PE - /* default library paths */ - tcc_add_library_path(s, CONFIG_SYSROOT "/usr/local/lib"); - tcc_add_library_path(s, CONFIG_SYSROOT "/usr/lib"); - tcc_add_library_path(s, CONFIG_SYSROOT "/lib"); -#endif - - /* no section zero */ - dynarray_add((void ***)&s->sections, &s->nb_sections, NULL); - - /* create standard sections */ - text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); - data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); - bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); - - /* symbols are always generated for linking stage */ - symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, - ".strtab", - ".hashtab", SHF_PRIVATE); - strtab_section = symtab_section->link; - - /* private symbol table for dynamic symbols */ - s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, - ".dynstrtab", - ".dynhashtab", SHF_PRIVATE); - s->alacarte_link = 1; - -#ifdef CHAR_IS_UNSIGNED - s->char_is_unsigned = 1; -#endif -#if defined(TCC_TARGET_PE) && 0 - /* XXX: currently the PE linker is not ready to support that */ - s->leading_underscore = 1; -#endif + /* wint_t is unsigned int by default, but (signed) int on BSDs + and unsigned short on windows. Other OSes might have still + other conventions, sigh. */ +# if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) \ + || defined(__NetBSD__) || defined(__OpenBSD__) + tcc_define_symbol(s, "__WINT_TYPE__", "int"); +# ifdef __FreeBSD__ + /* define __GNUC__ to have some useful stuff from sys/cdefs.h + that are unconditionally used in FreeBSDs other system headers :/ */ + tcc_define_symbol(s, "__GNUC__", "2"); + tcc_define_symbol(s, "__GNUC_MINOR__", "7"); + tcc_define_symbol(s, "__builtin_alloca", "alloca"); +# endif +# else + tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int"); + /* glibc defines */ + tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", + "name proto __asm__ (#alias)"); + tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", + "name proto __asm__ (#alias) __THROW"); +# endif +# if defined(TCC_MUSL) + tcc_define_symbol(s, "__DEFINED_va_list", ""); + tcc_define_symbol(s, "__DEFINED___isoc_va_list", ""); + tcc_define_symbol(s, "__isoc_va_list", "void *"); +# endif /* TCC_MUSL */ + /* Some GCC builtins that are simple to express as macros. */ + tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x"); +#endif /* ndef TCC_TARGET_PE */ return s; } -void tcc_delete(TCCState *s1) +LIBTCCAPI void tcc_delete(TCCState *s1) { - int i; - tcc_cleanup(); - /* free all sections */ - for(i = 1; i < s1->nb_sections; i++) - free_section(s1->sections[i]); - dynarray_reset(&s1->sections, &s1->nb_sections); - - for(i = 0; i < s1->nb_priv_sections; i++) - free_section(s1->priv_sections[i]); - dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections); - - /* free any loaded DLLs */ - for ( i = 0; i < s1->nb_loaded_dlls; i++) { - DLLReference *ref = s1->loaded_dlls[i]; - if ( ref->handle ) - dlclose(ref->handle); - } - - /* free loaded dlls array */ - dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); + /* free sections */ + tccelf_delete(s1); /* free library paths */ dynarray_reset(&s1->library_paths, &s1->nb_library_paths); + dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths); /* free include paths */ dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes); dynarray_reset(&s1->include_paths, &s1->nb_include_paths); dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths); + dynarray_reset(&s1->cmd_include_files, &s1->nb_cmd_include_files); + + tcc_free(s1->tcc_lib_path); + tcc_free(s1->soname); + tcc_free(s1->rpath); + tcc_free(s1->init_symbol); + tcc_free(s1->fini_symbol); + tcc_free(s1->outfile); + tcc_free(s1->deps_outfile); + dynarray_reset(&s1->files, &s1->nb_files); + dynarray_reset(&s1->target_deps, &s1->nb_target_deps); + dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs); + dynarray_reset(&s1->argv, &s1->argc); + +#ifdef TCC_IS_NATIVE + /* free runtime memory */ + tcc_run_free(s1); +#endif tcc_free(s1); + if (0 == --nb_states) + tcc_memcheck(); } -int tcc_add_include_path(TCCState *s1, const char *pathname) +LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) { - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1); + s->output_type = output_type; + + /* always elf for objects */ + if (output_type == TCC_OUTPUT_OBJ) + s->output_format = TCC_OUTPUT_FORMAT_ELF; + + if (s->char_is_unsigned) + tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL); + + if (!s->nostdinc) { + /* default include paths */ + /* -isystem paths have already been handled */ + tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS); + } + +#ifdef CONFIG_TCC_BCHECK + if (s->do_bounds_check) { + /* if bound checking, then add corresponding sections */ + tccelf_bounds_new(s); + /* define symbol */ + tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); + } +#endif + if (s->do_debug) { + /* add debug sections */ + tccelf_stab_new(s); + } + + tcc_add_library_path(s, CONFIG_TCC_LIBPATHS); + +#ifdef TCC_TARGET_PE +# ifdef _WIN32 + if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ) + tcc_add_systemdir(s); +# endif +#else + /* paths for crt objects */ + tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX); + /* add libc crt1/crti objects */ + if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && + !s->nostdlib) { + if (output_type != TCC_OUTPUT_DLL) + tcc_add_crt(s, "crt1.o"); + tcc_add_crt(s, "crti.o"); + } +#endif return 0; } -int tcc_add_sysinclude_path(TCCState *s1, const char *pathname) +LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) { - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1); + tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname); return 0; } -static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) +LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) { - const char *ext; - ElfW(Ehdr) ehdr; - int fd, ret; - BufferedFile *saved_file; + tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname); + return 0; +} - /* find source file type with extension */ - ext = tcc_fileextension(filename); - if (ext[0]) - ext++; +ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) +{ + int ret; /* open the file */ - saved_file = file; - file = tcc_open(s1, filename); - if (!file) { - if (flags & AFF_PRINT_ERROR) { - error_noabort("file '%s' not found", filename); - } - ret = -1; - goto fail1; + ret = tcc_open(s1, filename); + if (ret < 0) { + if (flags & AFF_PRINT_ERROR) + tcc_error_noabort("file '%s' not found", filename); + return ret; } - if (flags & AFF_PREPROCESS) { - ret = tcc_preprocess(s1); - } else if (!ext[0] || !PATHCMP(ext, "c")) { - /* C file assumed */ - ret = tcc_compile(s1); - } else -#ifdef CONFIG_TCC_ASM - if (!strcmp(ext, "S")) { - /* preprocessed assembler */ - ret = tcc_assemble(s1, 1); - } else if (!strcmp(ext, "s")) { - /* non preprocessed assembler */ - ret = tcc_assemble(s1, 0); - } else -#endif -#ifdef TCC_TARGET_PE - if (!PATHCMP(ext, "def")) { - ret = pe_load_def_file(s1, file->fd); - } else -#endif - { + /* update target deps */ + dynarray_add(&s1->target_deps, &s1->nb_target_deps, + tcc_strdup(filename)); + + if (flags & AFF_TYPE_BIN) { + ElfW(Ehdr) ehdr; + int fd, obj_type; + fd = file->fd; - /* assume executable format: auto guess file type */ - ret = read(fd, &ehdr, sizeof(ehdr)); + obj_type = tcc_object_type(fd, &ehdr); lseek(fd, 0, SEEK_SET); - if (ret <= 0) { - error_noabort("could not read header"); - goto fail; - } else if (ret != sizeof(ehdr)) { - goto try_load_script; - } - if (ehdr.e_ident[0] == ELFMAG0 && - ehdr.e_ident[1] == ELFMAG1 && - ehdr.e_ident[2] == ELFMAG2 && - ehdr.e_ident[3] == ELFMAG3) { - file->line_num = 0; /* do not display line number if error */ - if (ehdr.e_type == ET_REL) { - ret = tcc_load_object_file(s1, fd, 0); - } else if (ehdr.e_type == ET_DYN) { - if (s1->output_type == TCC_OUTPUT_MEMORY) { -#ifdef TCC_TARGET_PE + /* do not display line number if error */ + file->line_num = 0; + +#ifdef TCC_TARGET_MACHO + if (0 == obj_type && 0 == strcmp(tcc_fileextension(filename), ".dylib")) + obj_type = AFF_BINTYPE_DYN; +#endif + + switch (obj_type) { + case AFF_BINTYPE_REL: + ret = tcc_load_object_file(s1, fd, 0); + break; +#ifndef TCC_TARGET_PE + case AFF_BINTYPE_DYN: + if (s1->output_type == TCC_OUTPUT_MEMORY) { + ret = 0; +#ifdef TCC_IS_NATIVE + if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY)) ret = -1; -#else - void *h; - h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); - if (h) - ret = 0; - else - ret = -1; #endif - } else { - ret = tcc_load_dll(s1, fd, filename, - (flags & AFF_REFERENCED_DLL) != 0); - } } else { - error_noabort("unrecognized ELF file"); - goto fail; + ret = tcc_load_dll(s1, fd, filename, + (flags & AFF_REFERENCED_DLL) != 0); } - } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) { - file->line_num = 0; /* do not display line number if error */ + break; +#endif + case AFF_BINTYPE_AR: ret = tcc_load_archive(s1, fd); - } else + break; #ifdef TCC_TARGET_COFF - if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) { + case AFF_BINTYPE_C67: ret = tcc_load_coff(s1, fd); - } else + break; #endif + default: #ifdef TCC_TARGET_PE - if (pe_test_res_file(&ehdr, ret)) { - ret = pe_load_res_file(s1, fd); - } else -#endif - { + ret = pe_load_file(s1, filename, fd); +#else /* as GNU ld, consider it is an ld script if not recognized */ - try_load_script: ret = tcc_load_ldscript(s1); - if (ret < 0) { - error_noabort("unrecognized file type"); - goto fail; - } +#endif + if (ret < 0) + tcc_error_noabort("unrecognized file type"); + break; } + } else { + ret = tcc_compile(s1); } - the_end: - tcc_close(file); - fail1: - file = saved_file; + tcc_close(); return ret; - fail: - ret = -1; - goto the_end; } -int tcc_add_file(TCCState *s, const char *filename) -{ - if (s->output_type == TCC_OUTPUT_PREPROCESS) - return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS); - else - return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR); +LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) +{ + int filetype = s->filetype; + int flags = AFF_PRINT_ERROR; + if (filetype == 0) { + /* use a file extension to detect a filetype */ + const char *ext = tcc_fileextension(filename); + if (ext[0]) { + ext++; + if (!strcmp(ext, "S")) + filetype = AFF_TYPE_ASMPP; + else if (!strcmp(ext, "s")) + filetype = AFF_TYPE_ASM; + else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i")) + filetype = AFF_TYPE_C; + else + flags |= AFF_TYPE_BIN; + } else { + filetype = AFF_TYPE_C; + } + s->filetype = filetype; + } + return tcc_add_file_internal(s, filename, flags); } -int tcc_add_library_path(TCCState *s, const char *pathname) +LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) { - char *pathname1; - - pathname1 = tcc_strdup(pathname); - dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1); + tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname); return 0; } -/* find and load a dll. Return non zero if not found */ -/* XXX: add '-rpath' option support ? */ -static int tcc_add_dll(TCCState *s, const char *filename, int flags) +static int tcc_add_library_internal(TCCState *s, const char *fmt, + const char *filename, int flags, char **paths, int nb_paths) { char buf[1024]; int i; - for(i = 0; i < s->nb_library_paths; i++) { - snprintf(buf, sizeof(buf), "%s/%s", - s->library_paths[i], filename); - if (tcc_add_file_internal(s, buf, flags) == 0) + for(i = 0; i < nb_paths; i++) { + snprintf(buf, sizeof(buf), fmt, paths[i], filename); + if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0) return 0; } return -1; } -/* the library name is the same as the argument of the '-l' option */ -int tcc_add_library(TCCState *s, const char *libraryname) +/* find and load a dll. Return non zero if not found */ +/* XXX: add '-rpath' option support ? */ +ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) { - char buf[1024]; - int i; - - /* first we look for the dynamic library if not static linking */ - if (!s->static_link) { -#ifdef TCC_TARGET_PE - snprintf(buf, sizeof(buf), "%s.def", libraryname); + return tcc_add_library_internal(s, "%s/%s", filename, flags, + s->library_paths, s->nb_library_paths); +} + +ST_FUNC int tcc_add_crt(TCCState *s, const char *filename) +{ + if (-1 == tcc_add_library_internal(s, "%s/%s", + filename, 0, s->crt_paths, s->nb_crt_paths)) + tcc_error_noabort("file '%s' not found", filename); + return 0; +} + +/* the library name is the same as the argument of the '-l' option */ +LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) +{ +#if defined TCC_TARGET_PE + const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL }; + const char **pp = s->static_link ? libs + 4 : libs; +#elif defined TCC_TARGET_MACHO + const char *libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL }; + const char **pp = s->static_link ? libs + 1 : libs; #else - snprintf(buf, sizeof(buf), "lib%s.so", libraryname); + const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL }; + const char **pp = s->static_link ? libs + 1 : libs; #endif - if (tcc_add_dll(s, buf, 0) == 0) - return 0; - } - - /* then we look for the static library */ - for(i = 0; i < s->nb_library_paths; i++) { - snprintf(buf, sizeof(buf), "%s/lib%s.a", - s->library_paths[i], libraryname); - if (tcc_add_file_internal(s, buf, 0) == 0) + while (*pp) { + if (0 == tcc_add_library_internal(s, *pp, + libraryname, 0, s->library_paths, s->nb_library_paths)) return 0; + ++pp; } return -1; } -int tcc_add_symbol(TCCState *s, const char *name, void *val) +PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname) { - add_elf_sym(symtab_section, (unsigned long)val, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - SHN_ABS, name); - return 0; + int ret = tcc_add_library(s, libname); + if (ret < 0) + tcc_error_noabort("library '%s' not found", libname); + return ret; } -int tcc_set_output_type(TCCState *s, int output_type) +/* handle #pragma comment(lib,) */ +ST_FUNC void tcc_add_pragma_libs(TCCState *s1) { - char buf[1024]; - - s->output_type = output_type; - - if (!s->nostdinc) { - /* default include paths */ - /* XXX: reverse order needed if -isystem support */ -#ifndef TCC_TARGET_PE - tcc_add_sysinclude_path(s, CONFIG_SYSROOT "/usr/local/include"); - tcc_add_sysinclude_path(s, CONFIG_SYSROOT "/usr/include"); -#endif - snprintf(buf, sizeof(buf), "%s/include", s->tcc_lib_path); - tcc_add_sysinclude_path(s, buf); -#ifdef TCC_TARGET_PE - snprintf(buf, sizeof(buf), "%s/include/winapi", s->tcc_lib_path); - tcc_add_sysinclude_path(s, buf); -#endif - } - - /* if bound checking, then add corresponding sections */ -#ifdef CONFIG_TCC_BCHECK - if (s->do_bounds_check) { - /* define symbol */ - tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); - /* create bounds sections */ - bounds_section = new_section(s, ".bounds", - SHT_PROGBITS, SHF_ALLOC); - lbounds_section = new_section(s, ".lbounds", - SHT_PROGBITS, SHF_ALLOC); - } -#endif - - if (s->char_is_unsigned) { - tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL); - } - - /* add debug sections */ - if (s->do_debug) { - /* stab symbols */ - stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); - stab_section->sh_entsize = sizeof(Stab_Sym); - stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); - put_elf_str(stabstr_section, ""); - stab_section->link = stabstr_section; - /* put first entry */ - put_stabs("", 0, 0, 0, 0); - } - - /* add libc crt1/crti objects */ -#ifndef TCC_TARGET_PE - if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && - !s->nostdlib) { - if (output_type != TCC_OUTPUT_DLL) - tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o"); - tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o"); - } -#endif + int i; + for (i = 0; i < s1->nb_pragma_libs; i++) + tcc_add_library_err(s1, s1->pragma_libs[i]); +} +LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) +{ #ifdef TCC_TARGET_PE - snprintf(buf, sizeof(buf), "%s/lib", s->tcc_lib_path); - tcc_add_library_path(s, buf); + /* On x86_64 'val' might not be reachable with a 32bit offset. + So it is handled here as if it were in a DLL. */ + pe_putimport(s, 0, name, (uintptr_t)val); +#else + set_elf_sym(symtab_section, (uintptr_t)val, 0, + ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, + SHN_ABS, name); #endif - return 0; } +LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) +{ + tcc_free(s->tcc_lib_path); + s->tcc_lib_path = tcc_strdup(path); +} + #define WD_ALL 0x0001 /* warning is activated when using -Wall */ #define FD_INVERT 0x0002 /* invert value before storing */ @@ -2173,87 +1196,787 @@ typedef struct FlagDef { const char *name; } FlagDef; -static const FlagDef warning_defs[] = { - { offsetof(TCCState, warn_unsupported), 0, "unsupported" }, - { offsetof(TCCState, warn_write_strings), 0, "write-strings" }, - { offsetof(TCCState, warn_error), 0, "error" }, - { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, - "implicit-function-declaration" }, -}; +static int no_flag(const char **pp) +{ + const char *p = *pp; + if (*p != 'n' || *++p != 'o' || *++p != '-') + return 0; + *pp = p + 1; + return 1; +} -static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, - const char *name, int value) +ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name) { - int i; + int value, ret; const FlagDef *p; const char *r; + value = 1; r = name; - if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') { - r += 3; - value = !value; - } - for(i = 0, p = flags; i < nb_flags; i++, p++) { - if (!strcmp(r, p->name)) - goto found; + if (no_flag(&r)) + value = 0; + + for (ret = -1, p = flags; p->name; ++p) { + if (ret) { + if (strcmp(r, p->name)) + continue; + } else { + if (0 == (p->flags & WD_ALL)) + continue; + } + if (p->offset) { + *(int*)((char *)s + p->offset) = + p->flags & FD_INVERT ? !value : value; + if (ret) + return 0; + } else { + ret = 0; + } } - return -1; - found: - if (p->flags & FD_INVERT) - value = !value; - *(int *)((uint8_t *)s + p->offset) = value; - return 0; + return ret; } +static int strstart(const char *val, const char **str) +{ + const char *p, *q; + p = *str; + q = val; + while (*q) { + if (*p != *q) + return 0; + p++; + q++; + } + *str = p; + return 1; +} -/* set/reset a warning */ -int tcc_set_warning(TCCState *s, const char *warning_name, int value) +/* Like strstart, but automatically takes into account that ld options can + * + * - start with double or single dash (e.g. '--soname' or '-soname') + * - arguments can be given as separate or after '=' (e.g. '-Wl,-soname,x.so' + * or '-Wl,-soname=x.so') + * + * you provide `val` always in 'option[=]' form (no leading -) + */ +static int link_option(const char *str, const char *val, const char **ptr) { - int i; - const FlagDef *p; + const char *p, *q; + int ret; - if (!strcmp(warning_name, "all")) { - for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) { - if (p->flags & WD_ALL) - *(int *)((uint8_t *)s + p->offset) = 1; - } + /* there should be 1 or 2 dashes */ + if (*str++ != '-') return 0; - } else { - return set_flag(s, warning_defs, countof(warning_defs), - warning_name, value); + if (*str == '-') + str++; + + /* then str & val should match (potentially up to '=') */ + p = str; + q = val; + + ret = 1; + if (q[0] == '?') { + ++q; + if (no_flag(&p)) + ret = -1; + } + + while (*q != '\0' && *q != '=') { + if (*p != *q) + return 0; + p++; + q++; + } + + /* '=' near eos means ',' or '=' is ok */ + if (*q == '=') { + if (*p == 0) + *ptr = p; + if (*p != ',' && *p != '=') + return 0; + p++; + } else if (*p) { + return 0; + } + *ptr = p; + return ret; +} + +static const char *skip_linker_arg(const char **str) +{ + const char *s1 = *str; + const char *s2 = strchr(s1, ','); + *str = s2 ? s2++ : (s2 = s1 + strlen(s1)); + return s2; +} + +static void copy_linker_arg(char **pp, const char *s, int sep) +{ + const char *q = s; + char *p = *pp; + int l = 0; + if (p && sep) + p[l = strlen(p)] = sep, ++l; + skip_linker_arg(&q); + pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s); +} + +/* set linker options */ +static int tcc_set_linker(TCCState *s, const char *option) +{ + while (*option) { + + const char *p = NULL; + char *end = NULL; + int ignoring = 0; + int ret; + + if (link_option(option, "Bsymbolic", &p)) { + s->symbolic = 1; + } else if (link_option(option, "nostdlib", &p)) { + s->nostdlib = 1; + } else if (link_option(option, "fini=", &p)) { + copy_linker_arg(&s->fini_symbol, p, 0); + ignoring = 1; + } else if (link_option(option, "image-base=", &p) + || link_option(option, "Ttext=", &p)) { + s->text_addr = strtoull(p, &end, 16); + s->has_text_addr = 1; + } else if (link_option(option, "init=", &p)) { + copy_linker_arg(&s->init_symbol, p, 0); + ignoring = 1; + } else if (link_option(option, "oformat=", &p)) { +#if defined(TCC_TARGET_PE) + if (strstart("pe-", &p)) { +#elif PTR_SIZE == 8 + if (strstart("elf64-", &p)) { +#else + if (strstart("elf32-", &p)) { +#endif + s->output_format = TCC_OUTPUT_FORMAT_ELF; + } else if (!strcmp(p, "binary")) { + s->output_format = TCC_OUTPUT_FORMAT_BINARY; +#ifdef TCC_TARGET_COFF + } else if (!strcmp(p, "coff")) { + s->output_format = TCC_OUTPUT_FORMAT_COFF; +#endif + } else + goto err; + + } else if (link_option(option, "as-needed", &p)) { + ignoring = 1; + } else if (link_option(option, "O", &p)) { + ignoring = 1; + } else if (link_option(option, "export-all-symbols", &p)) { + s->rdynamic = 1; + } else if (link_option(option, "rpath=", &p)) { + copy_linker_arg(&s->rpath, p, ':'); + } else if (link_option(option, "enable-new-dtags", &p)) { + s->enable_new_dtags = 1; + } else if (link_option(option, "section-alignment=", &p)) { + s->section_align = strtoul(p, &end, 16); + } else if (link_option(option, "soname=", &p)) { + copy_linker_arg(&s->soname, p, 0); +#ifdef TCC_TARGET_PE + } else if (link_option(option, "large-address-aware", &p)) { + s->pe_characteristics |= 0x20; + } else if (link_option(option, "file-alignment=", &p)) { + s->pe_file_align = strtoul(p, &end, 16); + } else if (link_option(option, "stack=", &p)) { + s->pe_stack_size = strtoul(p, &end, 10); + } else if (link_option(option, "subsystem=", &p)) { +#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) + if (!strcmp(p, "native")) { + s->pe_subsystem = 1; + } else if (!strcmp(p, "console")) { + s->pe_subsystem = 3; + } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) { + s->pe_subsystem = 2; + } else if (!strcmp(p, "posix")) { + s->pe_subsystem = 7; + } else if (!strcmp(p, "efiapp")) { + s->pe_subsystem = 10; + } else if (!strcmp(p, "efiboot")) { + s->pe_subsystem = 11; + } else if (!strcmp(p, "efiruntime")) { + s->pe_subsystem = 12; + } else if (!strcmp(p, "efirom")) { + s->pe_subsystem = 13; +#elif defined(TCC_TARGET_ARM) + if (!strcmp(p, "wince")) { + s->pe_subsystem = 9; +#endif + } else + goto err; +#endif + } else if (ret = link_option(option, "?whole-archive", &p), ret) { + s->alacarte_link = ret < 0; + } else if (p) { + return 0; + } else { + err: + tcc_error("unsupported linker option '%s'", option); + } + + if (ignoring && s->warn_unsupported) + tcc_warning("unsupported linker option '%s'", option); + + option = skip_linker_arg(&p); } + return 1; } -static const FlagDef flag_defs[] = { +typedef struct TCCOption { + const char *name; + uint16_t index; + uint16_t flags; +} TCCOption; + +enum { + TCC_OPTION_HELP, + TCC_OPTION_HELP2, + TCC_OPTION_v, + TCC_OPTION_I, + TCC_OPTION_D, + TCC_OPTION_U, + TCC_OPTION_P, + TCC_OPTION_L, + TCC_OPTION_B, + TCC_OPTION_l, + TCC_OPTION_bench, + TCC_OPTION_bt, + TCC_OPTION_b, + TCC_OPTION_g, + TCC_OPTION_c, + TCC_OPTION_dumpversion, + TCC_OPTION_d, + TCC_OPTION_static, + TCC_OPTION_std, + TCC_OPTION_shared, + TCC_OPTION_soname, + TCC_OPTION_o, + TCC_OPTION_r, + TCC_OPTION_s, + TCC_OPTION_traditional, + TCC_OPTION_Wl, + TCC_OPTION_Wp, + TCC_OPTION_W, + TCC_OPTION_O, + TCC_OPTION_mfloat_abi, + TCC_OPTION_m, + TCC_OPTION_f, + TCC_OPTION_isystem, + TCC_OPTION_iwithprefix, + TCC_OPTION_include, + TCC_OPTION_nostdinc, + TCC_OPTION_nostdlib, + TCC_OPTION_print_search_dirs, + TCC_OPTION_rdynamic, + TCC_OPTION_param, + TCC_OPTION_pedantic, + TCC_OPTION_pthread, + TCC_OPTION_run, + TCC_OPTION_w, + TCC_OPTION_pipe, + TCC_OPTION_E, + TCC_OPTION_MD, + TCC_OPTION_MF, + TCC_OPTION_x, + TCC_OPTION_ar, + TCC_OPTION_impdef +}; + +#define TCC_OPTION_HAS_ARG 0x0001 +#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ + +static const TCCOption tcc_options[] = { + { "h", TCC_OPTION_HELP, 0 }, + { "-help", TCC_OPTION_HELP, 0 }, + { "?", TCC_OPTION_HELP, 0 }, + { "hh", TCC_OPTION_HELP2, 0 }, + { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, + { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, + { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, + { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, + { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, + { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "bench", TCC_OPTION_bench, 0 }, +#ifdef CONFIG_TCC_BACKTRACE + { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG }, +#endif +#ifdef CONFIG_TCC_BCHECK + { "b", TCC_OPTION_b, 0 }, +#endif + { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "c", TCC_OPTION_c, 0 }, + { "dumpversion", TCC_OPTION_dumpversion, 0}, + { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "static", TCC_OPTION_static, 0 }, + { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "shared", TCC_OPTION_shared, 0 }, + { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG }, + { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG }, + { "-param", TCC_OPTION_param, TCC_OPTION_HAS_ARG }, + { "pedantic", TCC_OPTION_pedantic, 0}, + { "pthread", TCC_OPTION_pthread, 0}, + { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "rdynamic", TCC_OPTION_rdynamic, 0 }, + { "r", TCC_OPTION_r, 0 }, + { "s", TCC_OPTION_s, 0 }, + { "traditional", TCC_OPTION_traditional, 0 }, + { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "Wp,", TCC_OPTION_Wp, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, +#ifdef TCC_TARGET_ARM + { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG }, +#endif + { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG }, + { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG }, + { "nostdinc", TCC_OPTION_nostdinc, 0 }, + { "nostdlib", TCC_OPTION_nostdlib, 0 }, + { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, + { "w", TCC_OPTION_w, 0 }, + { "pipe", TCC_OPTION_pipe, 0}, + { "E", TCC_OPTION_E, 0}, + { "MD", TCC_OPTION_MD, 0}, + { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG }, + { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG }, + { "ar", TCC_OPTION_ar, 0}, +#ifdef TCC_TARGET_PE + { "impdef", TCC_OPTION_impdef, 0}, +#endif + { NULL, 0, 0 }, +}; + +static const FlagDef options_W[] = { + { 0, 0, "all" }, + { offsetof(TCCState, warn_unsupported), 0, "unsupported" }, + { offsetof(TCCState, warn_write_strings), 0, "write-strings" }, + { offsetof(TCCState, warn_error), 0, "error" }, + { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" }, + { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, + "implicit-function-declaration" }, + { 0, 0, NULL } +}; + +static const FlagDef options_f[] = { { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" }, { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" }, { offsetof(TCCState, nocommon), FD_INVERT, "common" }, { offsetof(TCCState, leading_underscore), 0, "leading-underscore" }, + { offsetof(TCCState, ms_extensions), 0, "ms-extensions" }, + { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" }, + { 0, 0, NULL } +}; + +static const FlagDef options_m[] = { + { offsetof(TCCState, ms_bitfields), 0, "ms-bitfields" }, +#ifdef TCC_TARGET_X86_64 + { offsetof(TCCState, nosse), FD_INVERT, "sse" }, +#endif + { 0, 0, NULL } }; -/* set/reset a flag */ -int tcc_set_flag(TCCState *s, const char *flag_name, int value) +static void parse_option_D(TCCState *s1, const char *optarg) { - return set_flag(s, flag_defs, countof(flag_defs), - flag_name, value); + char *sym = tcc_strdup(optarg); + char *value = strchr(sym, '='); + if (value) + *value++ = '\0'; + tcc_define_symbol(s1, sym, value); + tcc_free(sym); } -/* set CONFIG_TCCDIR at runtime */ -void tcc_set_lib_path(TCCState *s, const char *path) +static void args_parser_add_file(TCCState *s, const char* filename, int filetype) { - s->tcc_lib_path = tcc_strdup(path); + struct filespec *f = tcc_malloc(sizeof *f + strlen(filename)); + f->type = filetype; + f->alacarte = s->alacarte_link; + strcpy(f->name, filename); + dynarray_add(&s->files, &s->nb_files, f); +} + +static int args_parser_make_argv(const char *r, int *argc, char ***argv) +{ + int ret = 0, q, c; + CString str; + for(;;) { + while (c = (unsigned char)*r, c && c <= ' ') + ++r; + if (c == 0) + break; + q = 0; + cstr_new(&str); + while (c = (unsigned char)*r, c) { + ++r; + if (c == '\\' && (*r == '"' || *r == '\\')) { + c = *r++; + } else if (c == '"') { + q = !q; + continue; + } else if (q == 0 && c <= ' ') { + break; + } + cstr_ccat(&str, c); + } + cstr_ccat(&str, 0); + //printf("<%s>\n", str.data), fflush(stdout); + dynarray_add(argv, argc, tcc_strdup(str.data)); + cstr_free(&str); + ++ret; + } + return ret; +} + +/* read list file */ +static void args_parser_listfile(TCCState *s, + const char *filename, int optind, int *pargc, char ***pargv) +{ + int fd, i; + size_t len; + char *p; + int argc = 0; + char **argv = NULL; + + fd = open(filename, O_RDONLY | O_BINARY); + if (fd < 0) + tcc_error("listfile '%s' not found", filename); + + len = lseek(fd, 0, SEEK_END); + p = tcc_malloc(len + 1), p[len] = 0; + lseek(fd, 0, SEEK_SET), read(fd, p, len), close(fd); + + for (i = 0; i < *pargc; ++i) + if (i == optind) + args_parser_make_argv(p, &argc, &argv); + else + dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i])); + + tcc_free(p); + dynarray_reset(&s->argv, &s->argc); + *pargc = s->argc = argc, *pargv = s->argv = argv; } -void tcc_print_stats(TCCState *s, int64_t total_time) +PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) { - double tt; - tt = (double)total_time / 1000000.0; - if (tt < 0.001) - tt = 0.001; + const TCCOption *popt; + const char *optarg, *r; + const char *run = NULL; + int last_o = -1; + int x; + CString linker_arg; /* collect -Wl options */ + int tool = 0, arg_start = 0, noaction = optind; + char **argv = *pargv; + int argc = *pargc; + + cstr_new(&linker_arg); + + while (optind < argc) { + r = argv[optind]; + if (r[0] == '@' && r[1] != '\0') { + args_parser_listfile(s, r + 1, optind, &argc, &argv); + continue; + } + optind++; + if (tool) { + if (r[0] == '-' && r[1] == 'v' && r[2] == 0) + ++s->verbose; + continue; + } +reparse: + if (r[0] != '-' || r[1] == '\0') { + if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */ + args_parser_add_file(s, r, s->filetype); + if (run) { + tcc_set_options(s, run); + arg_start = optind - 1; + break; + } + continue; + } + + /* find option in table */ + for(popt = tcc_options; ; ++popt) { + const char *p1 = popt->name; + const char *r1 = r + 1; + if (p1 == NULL) + tcc_error("invalid option -- '%s'", r); + if (!strstart(p1, &r1)) + continue; + optarg = r1; + if (popt->flags & TCC_OPTION_HAS_ARG) { + if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) { + if (optind >= argc) + arg_err: + tcc_error("argument to '%s' is missing", r); + optarg = argv[optind++]; + } + } else if (*r1 != '\0') + continue; + break; + } + + switch(popt->index) { + case TCC_OPTION_HELP: + return OPT_HELP; + case TCC_OPTION_HELP2: + return OPT_HELP2; + case TCC_OPTION_I: + tcc_add_include_path(s, optarg); + break; + case TCC_OPTION_D: + parse_option_D(s, optarg); + break; + case TCC_OPTION_U: + tcc_undefine_symbol(s, optarg); + break; + case TCC_OPTION_L: + tcc_add_library_path(s, optarg); + break; + case TCC_OPTION_B: + /* set tcc utilities path (mainly for tcc development) */ + tcc_set_lib_path(s, optarg); + break; + case TCC_OPTION_l: + args_parser_add_file(s, optarg, AFF_TYPE_LIB); + s->nb_libraries++; + break; + case TCC_OPTION_pthread: + parse_option_D(s, "_REENTRANT"); + s->option_pthread = 1; + break; + case TCC_OPTION_bench: + s->do_bench = 1; + break; +#ifdef CONFIG_TCC_BACKTRACE + case TCC_OPTION_bt: + tcc_set_num_callers(atoi(optarg)); + break; +#endif +#ifdef CONFIG_TCC_BCHECK + case TCC_OPTION_b: + s->do_bounds_check = 1; + s->do_debug = 1; + break; +#endif + case TCC_OPTION_g: + s->do_debug = 1; + break; + case TCC_OPTION_c: + x = TCC_OUTPUT_OBJ; + set_output_type: + if (s->output_type) + tcc_warning("-%s: overriding compiler action already specified", popt->name); + s->output_type = x; + break; + case TCC_OPTION_d: + if (*optarg == 'D') + s->dflag = 3; + else if (*optarg == 'M') + s->dflag = 7; + else if (*optarg == 't') + s->dflag = 16; + else if (isnum(*optarg)) + g_debug = atoi(optarg); + else + goto unsupported_option; + break; + case TCC_OPTION_static: + s->static_link = 1; + break; + case TCC_OPTION_std: + /* silently ignore, a current purpose: + allow to use a tcc as a reference compiler for "make test" */ + break; + case TCC_OPTION_shared: + x = TCC_OUTPUT_DLL; + goto set_output_type; + case TCC_OPTION_soname: + s->soname = tcc_strdup(optarg); + break; + case TCC_OPTION_o: + if (s->outfile) { + tcc_warning("multiple -o option"); + tcc_free(s->outfile); + } + s->outfile = tcc_strdup(optarg); + break; + case TCC_OPTION_r: + /* generate a .o merging several output files */ + s->option_r = 1; + x = TCC_OUTPUT_OBJ; + goto set_output_type; + case TCC_OPTION_isystem: + tcc_add_sysinclude_path(s, optarg); + break; + case TCC_OPTION_include: + dynarray_add(&s->cmd_include_files, + &s->nb_cmd_include_files, tcc_strdup(optarg)); + break; + case TCC_OPTION_nostdinc: + s->nostdinc = 1; + break; + case TCC_OPTION_nostdlib: + s->nostdlib = 1; + break; + case TCC_OPTION_run: +#ifndef TCC_IS_NATIVE + tcc_error("-run is not available in a cross compiler"); +#endif + run = optarg; + x = TCC_OUTPUT_MEMORY; + goto set_output_type; + case TCC_OPTION_v: + do ++s->verbose; while (*optarg++ == 'v'); + ++noaction; + break; + case TCC_OPTION_f: + if (set_flag(s, options_f, optarg) < 0) + goto unsupported_option; + break; +#ifdef TCC_TARGET_ARM + case TCC_OPTION_mfloat_abi: + /* tcc doesn't support soft float yet */ + if (!strcmp(optarg, "softfp")) { + s->float_abi = ARM_SOFTFP_FLOAT; + tcc_undefine_symbol(s, "__ARM_PCS_VFP"); + } else if (!strcmp(optarg, "hard")) + s->float_abi = ARM_HARD_FLOAT; + else + tcc_error("unsupported float abi '%s'", optarg); + break; +#endif + case TCC_OPTION_m: + if (set_flag(s, options_m, optarg) < 0) { + if (x = atoi(optarg), x != 32 && x != 64) + goto unsupported_option; + if (PTR_SIZE != x/8) + return x; + ++noaction; + } + break; + case TCC_OPTION_W: + if (set_flag(s, options_W, optarg) < 0) + goto unsupported_option; + break; + case TCC_OPTION_w: + s->warn_none = 1; + break; + case TCC_OPTION_rdynamic: + s->rdynamic = 1; + break; + case TCC_OPTION_Wl: + if (linker_arg.size) + --linker_arg.size, cstr_ccat(&linker_arg, ','); + cstr_cat(&linker_arg, optarg, 0); + if (tcc_set_linker(s, linker_arg.data)) + cstr_free(&linker_arg); + break; + case TCC_OPTION_Wp: + r = optarg; + goto reparse; + case TCC_OPTION_E: + x = TCC_OUTPUT_PREPROCESS; + goto set_output_type; + case TCC_OPTION_P: + s->Pflag = atoi(optarg) + 1; + break; + case TCC_OPTION_MD: + s->gen_deps = 1; + break; + case TCC_OPTION_MF: + s->deps_outfile = tcc_strdup(optarg); + break; + case TCC_OPTION_dumpversion: + printf ("%s\n", TCC_VERSION); + exit(0); + break; + case TCC_OPTION_x: + if (*optarg == 'c') + s->filetype = AFF_TYPE_C; + else if (*optarg == 'a') + s->filetype = AFF_TYPE_ASMPP; + else if (*optarg == 'n') + s->filetype = AFF_TYPE_NONE; + else + tcc_warning("unsupported language '%s'", optarg); + break; + case TCC_OPTION_O: + last_o = atoi(optarg); + break; + case TCC_OPTION_print_search_dirs: + x = OPT_PRINT_DIRS; + goto extra_action; + case TCC_OPTION_impdef: + x = OPT_IMPDEF; + goto extra_action; + case TCC_OPTION_ar: + x = OPT_AR; + extra_action: + arg_start = optind - 1; + if (arg_start != noaction) + tcc_error("cannot parse %s here", r); + tool = x; + break; + case TCC_OPTION_traditional: + case TCC_OPTION_pedantic: + case TCC_OPTION_pipe: + case TCC_OPTION_s: + /* ignored */ + break; + default: +unsupported_option: + if (s->warn_unsupported) + tcc_warning("unsupported option '%s'", r); + break; + } + } + if (last_o > 0) + tcc_define_symbol(s, "__OPTIMIZE__", NULL); + if (linker_arg.size) { + r = linker_arg.data; + goto arg_err; + } + *pargc = argc - arg_start; + *pargv = argv + arg_start; + if (tool) + return tool; + if (optind != noaction) + return 0; + if (s->verbose == 2) + return OPT_PRINT_DIRS; + if (s->verbose) + return OPT_V; + return OPT_HELP; +} + +LIBTCCAPI void tcc_set_options(TCCState *s, const char *r) +{ + char **argv = NULL; + int argc = 0; + args_parser_make_argv(r, &argc, &argv); + tcc_parse_args(s, &argc, &argv, 0); + dynarray_reset(&argv, &argc); +} + +PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time) +{ + if (total_time < 1) + total_time = 1; if (total_bytes < 1) total_bytes = 1; - printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", + fprintf(stderr, "* %d idents, %d lines, %d bytes\n" + "* %0.3f s, %u lines/s, %0.1f MB/s\n", tok_ident - TOK_IDENT, total_lines, total_bytes, - tt, (int)(total_lines / tt), - total_bytes / tt / 1000000.0); + (double)total_time/1000, + (unsigned)total_lines*1000/total_time, + (double)total_bytes/1000/total_time); +#ifdef MEM_DEBUG + fprintf(stderr, "* %d bytes memory used\n", mem_max_size); +#endif } diff --git a/tinyc/libtcc.h b/tinyc/libtcc.h index 96070e299..a1b31e300 100644 --- a/tinyc/libtcc.h +++ b/tinyc/libtcc.h @@ -1,10 +1,8 @@ #ifndef LIBTCC_H #define LIBTCC_H -#ifdef LIBTCC_AS_DLL -#define LIBTCCAPI __declspec(dllexport) -#else -#define LIBTCCAPI +#ifndef LIBTCCAPI +# define LIBTCCAPI #endif #ifdef __cplusplus @@ -21,15 +19,15 @@ LIBTCCAPI TCCState *tcc_new(void); /* free a TCC compilation context */ LIBTCCAPI void tcc_delete(TCCState *s); -/* add debug information in the generated code */ -LIBTCCAPI void tcc_enable_debug(TCCState *s); +/* set CONFIG_TCCDIR at runtime */ +LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); /* set error/warning display callback */ LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, - void (*error_func)(void *opaque, const char *msg)); + void (*error_func)(void *opaque, const char *msg)); -/* set/reset a warning */ -LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value); +/* set options as from command line (multiple supported) */ +LIBTCCAPI void tcc_set_options(TCCState *s, const char *str); /*****************************/ /* preprocessor */ @@ -49,29 +47,22 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym); /*****************************/ /* compiling */ -/* add a file (either a C file, dll, an object, a library or an ld - script). Return -1 if error. */ +/* add a file (C file, dll, object, library, ld script). Return -1 if error. */ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename); -/* compile a string containing a C source. Return non zero if - error. */ +/* compile a string containing a C source. Return -1 if error. */ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf); /*****************************/ /* linking commands */ /* set output type. MUST BE CALLED before any compilation */ -#define TCC_OUTPUT_MEMORY 0 /* output will be ran in memory (no - output file) (default) */ -#define TCC_OUTPUT_EXE 1 /* executable file */ -#define TCC_OUTPUT_DLL 2 /* dynamic library */ -#define TCC_OUTPUT_OBJ 3 /* object file */ -#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type); - -#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */ -#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */ -#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */ +#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */ +#define TCC_OUTPUT_EXE 2 /* executable file */ +#define TCC_OUTPUT_DLL 3 /* dynamic library */ +#define TCC_OUTPUT_OBJ 4 /* object file */ +#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */ /* equivalent to -Lpath option */ LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname); @@ -80,7 +71,7 @@ LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname); LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname); /* add a symbol to the compiled program */ -LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val); +LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val); /* output an executable, library or object file. DO NOT call tcc_relocate() before. */ @@ -90,17 +81,18 @@ LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename); tcc_relocate() before. */ LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv); -/* copy code into memory passed in by the caller and do all relocations - (needed before using tcc_get_symbol()). - returns -1 on error and required size if ptr is NULL */ +/* do all relocations (needed before using tcc_get_symbol()) */ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr); +/* possible values for 'ptr': + - TCC_RELOCATE_AUTO : Allocate and manage memory internally + - NULL : return required memory size for the step below + - memory address : copy code to memory passed by the caller + returns -1 if error. */ +#define TCC_RELOCATE_AUTO (void*)1 /* return symbol value or NULL if not found */ LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name); -/* set CONFIG_TCCDIR at runtime */ -LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); - #ifdef __cplusplus } #endif diff --git a/tinyc/tcc-doc.html b/tinyc/tcc-doc.html deleted file mode 100644 index bd856d256..000000000 --- a/tinyc/tcc-doc.html +++ /dev/null @@ -1,2241 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd"> -<html> -<!-- Created on May, 18 2009 by texi2html 1.78 --> -<!-- -Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author) - Karl Berry <karl@freefriends.org> - Olaf Bachmann <obachman@mathematik.uni-kl.de> - and many others. -Maintained by: Many creative people. -Send bugs and suggestions to <texi2html-bug@nongnu.org> - ---> -<head> -<title>Tiny C Compiler Reference Documentation</title> - -<meta name="description" content="Tiny C Compiler Reference Documentation"> -<meta name="keywords" content="Tiny C Compiler Reference Documentation"> -<meta name="resource-type" content="document"> -<meta name="distribution" content="global"> -<meta name="Generator" content="texi2html 1.78"> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<style type="text/css"> -<!-- -a.summary-letter {text-decoration: none} -pre.display {font-family: serif} -pre.format {font-family: serif} -pre.menu-comment {font-family: serif} -pre.menu-preformatted {font-family: serif} -pre.smalldisplay {font-family: serif; font-size: smaller} -pre.smallexample {font-size: smaller} -pre.smallformat {font-family: serif; font-size: smaller} -pre.smalllisp {font-size: smaller} -span.roman {font-family:serif; font-weight:normal;} -span.sansserif {font-family:sans-serif; font-weight:normal;} -ul.toc {list-style: none} ---> -</style> - - -</head> - -<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000"> - -<a name="Top"></a> -<a name="SEC_Top"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="settitle">Tiny C Compiler Reference Documentation</h1> - -<p>This manual documents version of the Tiny C Compiler. -</p> -<table class="menu" border="0" cellspacing="0"> -<tr><td align="left" valign="top"><a href="#SEC1">1. Introduction</a></td><td> </td><td align="left" valign="top"> Introduction to tcc. -</td></tr> -<tr><td align="left" valign="top"><a href="#SEC2">2. Command line invocation</a></td><td> </td><td align="left" valign="top"> Invocation of tcc (command line, options). -</td></tr> -<tr><td align="left" valign="top"><a href="#SEC5">3. C language support</a></td><td> </td><td align="left" valign="top"> ANSI C and extensions. -</td></tr> -<tr><td align="left" valign="top"><a href="#SEC10">4. TinyCC Assembler</a></td><td> </td><td align="left" valign="top"> Assembler syntax. -</td></tr> -<tr><td align="left" valign="top"><a href="#SEC16">5. TinyCC Linker</a></td><td> </td><td align="left" valign="top"> Output file generation and supported targets. -</td></tr> -<tr><td align="left" valign="top"><a href="#SEC21">6. TinyCC Memory and Bound checks</a></td><td> </td><td align="left" valign="top"> Automatic bounds-checking of C code. -</td></tr> -<tr><td align="left" valign="top"><a href="#SEC22">7. The <code>libtcc</code> library</a></td><td> </td><td align="left" valign="top"> The libtcc library. -</td></tr> -<tr><td align="left" valign="top"><a href="#SEC23">8. Developer's guide</a></td><td> </td><td align="left" valign="top"> Guide for Developers. -</td></tr> -</table> - - -<hr size="1"> -<a name="Introduction"></a> -<a name="SEC1"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC_Top" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC2" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[ << ]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC2" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="chapter"> 1. Introduction </h1> - -<p>TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C -compilers, it is meant to be self-relying: you do not need an -external assembler or linker because TCC does that for you. -</p> -<p>TCC compiles so <em>fast</em> that even for big projects <code>Makefile</code>s may -not be necessary. -</p> -<p>TCC not only supports ANSI C, but also most of the new ISO C99 -standard and many GNUC extensions including inline assembly. -</p> -<p>TCC can also be used to make <em>C scripts</em>, i.e. pieces of C source -that you run as a Perl or Python script. Compilation is so fast that -your script will be as fast as if it was an executable. -</p> -<p>TCC can also automatically generate memory and bound checks -(see section <a href="#SEC21">TinyCC Memory and Bound checks</a>) while allowing all C pointers operations. TCC can do -these checks even if non patched libraries are used. -</p> -<p>With <code>libtcc</code>, you can use TCC as a backend for dynamic code -generation (see section <a href="#SEC22">The <code>libtcc</code> library</a>). -</p> -<p>TCC mainly supports the i386 target on Linux and Windows. There are alpha -ports for the ARM (<code>arm-tcc</code>) and the TMS320C67xx targets -(<code>c67-tcc</code>). More information about the ARM port is available at -<a href="http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html">http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html</a>. -</p> -<p>For usage on Windows, see also tcc-win32.txt. -</p> -<hr size="6"> -<a name="Invoke"></a> -<a name="SEC2"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC1" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC3" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC1" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC5" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="chapter"> 2. Command line invocation </h1> - -<hr size="6"> -<a name="SEC3"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC2" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC4" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC2" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC2" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC5" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 2.1 Quick start </h2> - -<table><tr><td> </td><td><pre class="example">usage: tcc [options] [<var>infile1</var> <var>infile2</var>…] [‘<samp>-run</samp>’ <var>infile</var> <var>args</var>…] -</pre></td></tr></table> - -<p>TCC options are a very much like gcc options. The main difference is that TCC -can also execute directly the resulting program and give it runtime -arguments. -</p> -<p>Here are some examples to understand the logic: -</p> -<dl compact="compact"> -<dt> <code>‘<samp>tcc -run a.c</samp>’</code></dt> -<dd><p>Compile ‘<tt>a.c</tt>’ and execute it directly -</p> -</dd> -<dt> <code>‘<samp>tcc -run a.c arg1</samp>’</code></dt> -<dd><p>Compile a.c and execute it directly. arg1 is given as first argument to -the <code>main()</code> of a.c. -</p> -</dd> -<dt> <code>‘<samp>tcc a.c -run b.c arg1</samp>’</code></dt> -<dd><p>Compile ‘<tt>a.c</tt>’ and ‘<tt>b.c</tt>’, link them together and execute them. arg1 is given -as first argument to the <code>main()</code> of the resulting program. -</p> -</dd> -<dt> <code>‘<samp>tcc -o myprog a.c b.c</samp>’</code></dt> -<dd><p>Compile ‘<tt>a.c</tt>’ and ‘<tt>b.c</tt>’, link them and generate the executable ‘<tt>myprog</tt>’. -</p> -</dd> -<dt> <code>‘<samp>tcc -o myprog a.o b.o</samp>’</code></dt> -<dd><p>link ‘<tt>a.o</tt>’ and ‘<tt>b.o</tt>’ together and generate the executable ‘<tt>myprog</tt>’. -</p> -</dd> -<dt> <code>‘<samp>tcc -c a.c</samp>’</code></dt> -<dd><p>Compile ‘<tt>a.c</tt>’ and generate object file ‘<tt>a.o</tt>’. -</p> -</dd> -<dt> <code>‘<samp>tcc -c asmfile.S</samp>’</code></dt> -<dd><p>Preprocess with C preprocess and assemble ‘<tt>asmfile.S</tt>’ and generate -object file ‘<tt>asmfile.o</tt>’. -</p> -</dd> -<dt> <code>‘<samp>tcc -c asmfile.s</samp>’</code></dt> -<dd><p>Assemble (but not preprocess) ‘<tt>asmfile.s</tt>’ and generate object file -‘<tt>asmfile.o</tt>’. -</p> -</dd> -<dt> <code>‘<samp>tcc -r -o ab.o a.c b.c</samp>’</code></dt> -<dd><p>Compile ‘<tt>a.c</tt>’ and ‘<tt>b.c</tt>’, link them together and generate the object file ‘<tt>ab.o</tt>’. -</p> -</dd> -</dl> - -<p>Scripting: -</p> -<p>TCC can be invoked from <em>scripts</em>, just as shell scripts. You just -need to add <code>#!/usr/local/bin/tcc -run</code> at the start of your C source: -</p> -<table><tr><td> </td><td><pre class="example">#!/usr/local/bin/tcc -run -#include <stdio.h> - -int main() -{ - printf("Hello World\n"); - return 0; -} -</pre></td></tr></table> - -<p>TCC can read C source code from <em>standard input</em> when ‘<samp>-</samp>’ is used in -place of ‘<samp>infile</samp>’. Example: -</p> -<table><tr><td> </td><td><pre class="example">echo 'main(){puts("hello");}' | tcc -run - -</pre></td></tr></table> - -<hr size="6"> -<a name="SEC4"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC3" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC5" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC2" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC2" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC5" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 2.2 Option summary </h2> - -<p>General Options: -</p> -<dl compact="compact"> -<dt> ‘<samp>-v</samp>’</dt> -<dd><p>Display current TCC version, increase verbosity. -</p> -</dd> -<dt> ‘<samp>-c</samp>’</dt> -<dd><p>Generate an object file (‘<samp>-o</samp>’ option must also be given). -</p> -</dd> -<dt> ‘<samp>-o outfile</samp>’</dt> -<dd><p>Put object file, executable, or dll into output file ‘<tt>outfile</tt>’. -</p> -</dd> -<dt> ‘<samp>-Bdir</samp>’</dt> -<dd><p>Set the path where the tcc internal libraries can be found (default is -‘<tt>PREFIX/lib/tcc</tt>’). -</p> -</dd> -<dt> ‘<samp>-bench</samp>’</dt> -<dd><p>Output compilation statistics. -</p> -</dd> -<dt> ‘<samp>-run source [args...]</samp>’</dt> -<dd><p>Compile file <var>source</var> and run it with the command line arguments -<var>args</var>. In order to be able to give more than one argument to a -script, several TCC options can be given <em>after</em> the -‘<samp>-run</samp>’ option, separated by spaces. Example: -</p> -<table><tr><td> </td><td><pre class="example">tcc "-run -L/usr/X11R6/lib -lX11" ex4.c -</pre></td></tr></table> - -<p>In a script, it gives the following header: -</p> -<table><tr><td> </td><td><pre class="example">#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11 -#include <stdlib.h> -int main(int argc, char **argv) -{ - ... -} -</pre></td></tr></table> - -</dd> -</dl> - -<p>Preprocessor options: -</p> -<dl compact="compact"> -<dt> ‘<samp>-Idir</samp>’</dt> -<dd><p>Specify an additional include path. Include paths are searched in the -order they are specified. -</p> -<p>System include paths are always searched after. The default system -include paths are: ‘<tt>/usr/local/include</tt>’, ‘<tt>/usr/include</tt>’ -and ‘<tt>PREFIX/lib/tcc/include</tt>’. (‘<tt>PREFIX</tt>’ is usually -‘<tt>/usr</tt>’ or ‘<tt>/usr/local</tt>’). -</p> -</dd> -<dt> ‘<samp>-Dsym[=val]</samp>’</dt> -<dd><p>Define preprocessor symbol ‘<samp>sym</samp>’ to -val. If val is not present, its value is ‘<samp>1</samp>’. Function-like macros can -also be defined: ‘<samp>-DF(a)=a+1</samp>’ -</p> -</dd> -<dt> ‘<samp>-Usym</samp>’</dt> -<dd><p>Undefine preprocessor symbol ‘<samp>sym</samp>’. -</p></dd> -</dl> - -<p>Compilation flags: -</p> -<p>Note: each of the following warning options has a negative form beginning with -‘<samp>-fno-</samp>’. -</p> -<dl compact="compact"> -<dt> ‘<samp>-funsigned-char</samp>’</dt> -<dd><p>Let the <code>char</code> type be unsigned. -</p> -</dd> -<dt> ‘<samp>-fsigned-char</samp>’</dt> -<dd><p>Let the <code>char</code> type be signed. -</p> -</dd> -<dt> ‘<samp>-fno-common</samp>’</dt> -<dd><p>Do not generate common symbols for uninitialized data. -</p> -</dd> -<dt> ‘<samp>-fleading-underscore</samp>’</dt> -<dd><p>Add a leading underscore at the beginning of each C symbol. -</p> -</dd> -</dl> - -<p>Warning options: -</p> -<dl compact="compact"> -<dt> ‘<samp>-w</samp>’</dt> -<dd><p>Disable all warnings. -</p> -</dd> -</dl> - -<p>Note: each of the following warning options has a negative form beginning with -‘<samp>-Wno-</samp>’. -</p> -<dl compact="compact"> -<dt> ‘<samp>-Wimplicit-function-declaration</samp>’</dt> -<dd><p>Warn about implicit function declaration. -</p> -</dd> -<dt> ‘<samp>-Wunsupported</samp>’</dt> -<dd><p>Warn about unsupported GCC features that are ignored by TCC. -</p> -</dd> -<dt> ‘<samp>-Wwrite-strings</samp>’</dt> -<dd><p>Make string constants be of type <code>const char *</code> instead of <code>char -*</code>. -</p> -</dd> -<dt> ‘<samp>-Werror</samp>’</dt> -<dd><p>Abort compilation if warnings are issued. -</p> -</dd> -<dt> ‘<samp>-Wall</samp>’ </dt> -<dd><p>Activate all warnings, except ‘<samp>-Werror</samp>’, ‘<samp>-Wunusupported</samp>’ and -‘<samp>-Wwrite-strings</samp>’. -</p> -</dd> -</dl> - -<p>Linker options: -</p> -<dl compact="compact"> -<dt> ‘<samp>-Ldir</samp>’</dt> -<dd><p>Specify an additional static library path for the ‘<samp>-l</samp>’ option. The -default library paths are ‘<tt>/usr/local/lib</tt>’, ‘<tt>/usr/lib</tt>’ and ‘<tt>/lib</tt>’. -</p> -</dd> -<dt> ‘<samp>-lxxx</samp>’</dt> -<dd><p>Link your program with dynamic library libxxx.so or static library -libxxx.a. The library is searched in the paths specified by the -‘<samp>-L</samp>’ option. -</p> -</dd> -<dt> ‘<samp>-shared</samp>’</dt> -<dd><p>Generate a shared library instead of an executable (‘<samp>-o</samp>’ option -must also be given). -</p> -</dd> -<dt> ‘<samp>-static</samp>’</dt> -<dd><p>Generate a statically linked executable (default is a shared linked -executable) (‘<samp>-o</samp>’ option must also be given). -</p> -</dd> -<dt> ‘<samp>-rdynamic</samp>’</dt> -<dd><p>Export global symbols to the dynamic linker. It is useful when a library -opened with <code>dlopen()</code> needs to access executable symbols. -</p> -</dd> -<dt> ‘<samp>-r</samp>’</dt> -<dd><p>Generate an object file combining all input files (‘<samp>-o</samp>’ option must -also be given). -</p> -</dd> -<dt> ‘<samp>-Wl,-Ttext,address</samp>’</dt> -<dd><p>Set the start of the .text section to <var>address</var>. -</p> -</dd> -<dt> ‘<samp>-Wl,--oformat,fmt</samp>’</dt> -<dd><p>Use <var>fmt</var> as output format. The supported output formats are: -</p><dl compact="compact"> -<dt> <code>elf32-i386</code></dt> -<dd><p>ELF output format (default) -</p></dd> -<dt> <code>binary</code></dt> -<dd><p>Binary image (only for executable output) -</p></dd> -<dt> <code>coff</code></dt> -<dd><p>COFF output format (only for executable output for TMS320C67xx target) -</p></dd> -</dl> - -</dd> -</dl> - -<p>Debugger options: -</p> -<dl compact="compact"> -<dt> ‘<samp>-g</samp>’</dt> -<dd><p>Generate run time debug information so that you get clear run time -error messages: <code> test.c:68: in function 'test5()': dereferencing -invalid pointer</code> instead of the laconic <code>Segmentation -fault</code>. -</p> -</dd> -<dt> ‘<samp>-b</samp>’</dt> -<dd><p>Generate additional support code to check -memory allocations and array/pointer bounds. ‘<samp>-g</samp>’ is implied. Note -that the generated code is slower and bigger in this case. -</p> -</dd> -<dt> ‘<samp>-bt N</samp>’</dt> -<dd><p>Display N callers in stack traces. This is useful with ‘<samp>-g</samp>’ or -‘<samp>-b</samp>’. -</p> -</dd> -</dl> - -<p>Note: GCC options ‘<samp>-Ox</samp>’, ‘<samp>-fx</samp>’ and ‘<samp>-mx</samp>’ are -ignored. -</p> - -<hr size="6"> -<a name="Clang"></a> -<a name="SEC5"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC4" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC6" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC2" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="chapter"> 3. C language support </h1> - -<hr size="6"> -<a name="SEC6"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC5" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC7" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC5" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 3.1 ANSI C </h2> - -<p>TCC implements all the ANSI C standard, including structure bit fields -and floating point numbers (<code>long double</code>, <code>double</code>, and -<code>float</code> fully supported). -</p> -<hr size="6"> -<a name="SEC7"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC6" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC8" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC5" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 3.2 ISOC99 extensions </h2> - -<p>TCC implements many features of the new C standard: ISO C99. Currently -missing items are: complex and imaginary numbers and variable length -arrays. -</p> -<p>Currently implemented ISOC99 features: -</p> -<ul class="toc"> -<li> 64 bit <code>long long</code> types are fully supported. - -</li><li> The boolean type <code>_Bool</code> is supported. - -</li><li> <code>__func__</code> is a string variable containing the current -function name. - -</li><li> Variadic macros: <code>__VA_ARGS__</code> can be used for - function-like macros: -<table><tr><td> </td><td><pre class="example"> #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__) -</pre></td></tr></table> - -<p><code>dprintf</code> can then be used with a variable number of parameters. -</p> -</li><li> Declarations can appear anywhere in a block (as in C++). - -</li><li> Array and struct/union elements can be initialized in any order by - using designators: -<table><tr><td> </td><td><pre class="example"> struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 }; - - int tab[10] = { 1, 2, [5] = 5, [9] = 9}; -</pre></td></tr></table> - -</li><li> Compound initializers are supported: -<table><tr><td> </td><td><pre class="example"> int *p = (int []){ 1, 2, 3 }; -</pre></td></tr></table> -<p>to initialize a pointer pointing to an initialized array. The same -works for structures and strings. -</p> -</li><li> Hexadecimal floating point constants are supported: -<table><tr><td> </td><td><pre class="example"> double d = 0x1234p10; -</pre></td></tr></table> - -<p>is the same as writing -</p><table><tr><td> </td><td><pre class="example"> double d = 4771840.0; -</pre></td></tr></table> - -</li><li> <code>inline</code> keyword is ignored. - -</li><li> <code>restrict</code> keyword is ignored. -</li></ul> - -<hr size="6"> -<a name="SEC8"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC7" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC9" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC5" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 3.3 GNU C extensions </h2> - -<p>TCC implements some GNU C extensions: -</p> -<ul class="toc"> -<li> array designators can be used without '=': -<table><tr><td> </td><td><pre class="example"> int a[10] = { [0] 1, [5] 2, 3, 4 }; -</pre></td></tr></table> - -</li><li> Structure field designators can be a label: -<table><tr><td> </td><td><pre class="example"> struct { int x, y; } st = { x: 1, y: 1}; -</pre></td></tr></table> -<p>instead of -</p><table><tr><td> </td><td><pre class="example"> struct { int x, y; } st = { .x = 1, .y = 1}; -</pre></td></tr></table> - -</li><li> <code>\e</code> is ASCII character 27. - -</li><li> case ranges : ranges can be used in <code>case</code>s: -<table><tr><td> </td><td><pre class="example"> switch(a) { - case 1 … 9: - printf("range 1 to 9\n"); - break; - default: - printf("unexpected\n"); - break; - } -</pre></td></tr></table> - -<a name="IDX1"></a> -<a name="IDX2"></a> -<a name="IDX3"></a> -<a name="IDX4"></a> -<a name="IDX5"></a> -<a name="IDX6"></a> -<a name="IDX7"></a> -<a name="IDX8"></a> - -</li><li> The keyword <code>__attribute__</code> is handled to specify variable or -function attributes. The following attributes are supported: - -<ul class="toc"> -<li> <code>aligned(n)</code>: align a variable or a structure field to n bytes -(must be a power of two). - - </li><li> <code>packed</code>: force alignment of a variable or a structure field to - 1. - - </li><li> <code>section(name)</code>: generate function or data in assembly section -name (name is a string containing the section name) instead of the default -section. - - </li><li> <code>unused</code>: specify that the variable or the function is unused. - - </li><li> <code>cdecl</code>: use standard C calling convention (default). - - </li><li> <code>stdcall</code>: use Pascal-like calling convention. - - </li><li> <code>regparm(n)</code>: use fast i386 calling convention. <var>n</var> must be -between 1 and 3. The first <var>n</var> function parameters are respectively put in -registers <code>%eax</code>, <code>%edx</code> and <code>%ecx</code>. - - </li><li> <code>dllexport</code>: export function from dll/executable (win32 only) - -</li></ul> - -<p>Here are some examples: -</p><table><tr><td> </td><td><pre class="example"> int a __attribute__ ((aligned(8), section(".mysection"))); -</pre></td></tr></table> - -<p>align variable <code>a</code> to 8 bytes and put it in section <code>.mysection</code>. -</p> -<table><tr><td> </td><td><pre class="example"> int my_add(int a, int b) __attribute__ ((section(".mycodesection"))) - { - return a + b; - } -</pre></td></tr></table> - -<p>generate function <code>my_add</code> in section <code>.mycodesection</code>. -</p> -</li><li> GNU style variadic macros: -<table><tr><td> </td><td><pre class="example"> #define dprintf(fmt, args…) printf(fmt, ## args) - - dprintf("no arg\n"); - dprintf("one arg %d\n", 1); -</pre></td></tr></table> - -</li><li> <code>__FUNCTION__</code> is interpreted as C99 <code>__func__</code> -(so it has not exactly the same semantics as string literal GNUC -where it is a string literal). - -</li><li> The <code>__alignof__</code> keyword can be used as <code>sizeof</code> -to get the alignment of a type or an expression. - -</li><li> The <code>typeof(x)</code> returns the type of <code>x</code>. -<code>x</code> is an expression or a type. - -</li><li> Computed gotos: <code>&&label</code> returns a pointer of type -<code>void *</code> on the goto label <code>label</code>. <code>goto *expr</code> can be -used to jump on the pointer resulting from <code>expr</code>. - -</li><li> Inline assembly with asm instruction: -<a name="IDX9"></a> -<a name="IDX10"></a> -<a name="IDX11"></a> -<table><tr><td> </td><td><pre class="example">static inline void * my_memcpy(void * to, const void * from, size_t n) -{ -int d0, d1, d2; -__asm__ __volatile__( - "rep ; movsl\n\t" - "testb $2,%b4\n\t" - "je 1f\n\t" - "movsw\n" - "1:\ttestb $1,%b4\n\t" - "je 2f\n\t" - "movsb\n" - "2:" - : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) - : "memory"); -return (to); -} -</pre></td></tr></table> - -<a name="IDX12"></a> -<p>TCC includes its own x86 inline assembler with a <code>gas</code>-like (GNU -assembler) syntax. No intermediate files are generated. GCC 3.x named -operands are supported. -</p> -</li><li> <code>__builtin_types_compatible_p()</code> and <code>__builtin_constant_p()</code> -are supported. - -</li><li> <code>#pragma pack</code> is supported for win32 compatibility. - -</li></ul> - -<hr size="6"> -<a name="SEC9"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC8" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC5" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 3.4 TinyCC extensions </h2> - -<ul class="toc"> -<li> <code>__TINYC__</code> is a predefined macro to <code>1</code> to -indicate that you use TCC. - -</li><li> <code>#!</code> at the start of a line is ignored to allow scripting. - -</li><li> Binary digits can be entered (<code>0b101</code> instead of -<code>5</code>). - -</li><li> <code>__BOUNDS_CHECKING_ON</code> is defined if bound checking is activated. - -</li></ul> - -<hr size="6"> -<a name="asm"></a> -<a name="SEC10"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC9" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC11" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="chapter"> 4. TinyCC Assembler </h1> - -<p>Since version 0.9.16, TinyCC integrates its own assembler. TinyCC -assembler supports a gas-like syntax (GNU assembler). You can -desactivate assembler support if you want a smaller TinyCC executable -(the C compiler does not rely on the assembler). -</p> -<p>TinyCC Assembler is used to handle files with ‘<tt>.S</tt>’ (C -preprocessed assembler) and ‘<tt>.s</tt>’ extensions. It is also used to -handle the GNU inline assembler with the <code>asm</code> keyword. -</p> -<hr size="6"> -<a name="SEC11"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC10" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC12" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 4.1 Syntax </h2> - -<p>TinyCC Assembler supports most of the gas syntax. The tokens are the -same as C. -</p> -<ul class="toc"> -<li> C and C++ comments are supported. - -</li><li> Identifiers are the same as C, so you cannot use '.' or '$'. - -</li><li> Only 32 bit integer numbers are supported. - -</li></ul> - -<hr size="6"> -<a name="SEC12"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC11" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC13" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 4.2 Expressions </h2> - -<ul class="toc"> -<li> Integers in decimal, octal and hexa are supported. - -</li><li> Unary operators: +, -, ~. - -</li><li> Binary operators in decreasing priority order: - -<ol> -<li> *, /, % -</li><li> &, |, ^ -</li><li> +, - -</li></ol> - -</li><li> A value is either an absolute number or a label plus an offset. -All operators accept absolute values except '+' and '-'. '+' or '-' can be -used to add an offset to a label. '-' supports two labels only if they -are the same or if they are both defined and in the same section. - -</li></ul> - -<hr size="6"> -<a name="SEC13"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC12" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC14" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 4.3 Labels </h2> - -<ul class="toc"> -<li> All labels are considered as local, except undefined ones. - -</li><li> Numeric labels can be used as local <code>gas</code>-like labels. -They can be defined several times in the same source. Use 'b' -(backward) or 'f' (forward) as suffix to reference them: - -<table><tr><td> </td><td><pre class="example"> 1: - jmp 1b /* jump to '1' label before */ - jmp 1f /* jump to '1' label after */ - 1: -</pre></td></tr></table> - -</li></ul> - -<hr size="6"> -<a name="SEC14"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC13" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC15" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 4.4 Directives </h2> - -<p>All directives are preceded by a '.'. The following directives are -supported: -</p> -<ul class="toc"> -<li> .align n[,value] -</li><li> .skip n[,value] -</li><li> .space n[,value] -</li><li> .byte value1[,...] -</li><li> .word value1[,...] -</li><li> .short value1[,...] -</li><li> .int value1[,...] -</li><li> .long value1[,...] -</li><li> .quad immediate_value1[,...] -</li><li> .globl symbol -</li><li> .global symbol -</li><li> .section section -</li><li> .text -</li><li> .data -</li><li> .bss -</li><li> .fill repeat[,size[,value]] -</li><li> .org n -</li><li> .previous -</li><li> .string string[,...] -</li><li> .asciz string[,...] -</li><li> .ascii string[,...] -</li></ul> - -<hr size="6"> -<a name="SEC15"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC14" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 4.5 X86 Assembler </h2> - -<p>All X86 opcodes are supported. Only ATT syntax is supported (source -then destination operand order). If no size suffix is given, TinyCC -tries to guess it from the operand sizes. -</p> -<p>Currently, MMX opcodes are supported but not SSE ones. -</p> -<hr size="6"> -<a name="linker"></a> -<a name="SEC16"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC15" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC17" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="chapter"> 5. TinyCC Linker </h1> - -<hr size="6"> -<a name="SEC17"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC16" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC18" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 5.1 ELF file generation </h2> - -<p>TCC can directly output relocatable ELF files (object files), -executable ELF files and dynamic ELF libraries without relying on an -external linker. -</p> -<p>Dynamic ELF libraries can be output but the C compiler does not generate -position independent code (PIC). It means that the dynamic library -code generated by TCC cannot be factorized among processes yet. -</p> -<p>TCC linker eliminates unreferenced object code in libraries. A single pass is -done on the object and library list, so the order in which object files and -libraries are specified is important (same constraint as GNU ld). No grouping -options (‘<samp>--start-group</samp>’ and ‘<samp>--end-group</samp>’) are supported. -</p> -<hr size="6"> -<a name="SEC18"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC17" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC19" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 5.2 ELF file loader </h2> - -<p>TCC can load ELF object files, archives (.a files) and dynamic -libraries (.so). -</p> -<hr size="6"> -<a name="SEC19"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC18" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC20" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 5.3 PE-i386 file generation </h2> - -<p>TCC for Windows supports the native Win32 executable file format (PE-i386). It -generates EXE files (console and gui) and DLL files. -</p> -<p>For usage on Windows, see also tcc-win32.txt. -</p> -<hr size="6"> -<a name="SEC20"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC19" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC21" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC16" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 5.4 GNU Linker Scripts </h2> - -<p>Because on many Linux systems some dynamic libraries (such as -‘<tt>/usr/lib/libc.so</tt>’) are in fact GNU ld link scripts (horrible!), -the TCC linker also supports a subset of GNU ld scripts. -</p> -<p>The <code>GROUP</code> and <code>FILE</code> commands are supported. <code>OUTPUT_FORMAT</code> -and <code>TARGET</code> are ignored. -</p> -<p>Example from ‘<tt>/usr/lib/libc.so</tt>’: -</p><table><tr><td> </td><td><pre class="example">/* GNU ld script - Use the shared library, but some functions are only in - the static library, so try that secondarily. */ -GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a ) -</pre></td></tr></table> - -<hr size="6"> -<a name="Bounds"></a> -<a name="SEC21"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC20" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC22" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC22" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="chapter"> 6. TinyCC Memory and Bound checks </h1> - -<p>This feature is activated with the ‘<samp>-b</samp>’ (see section <a href="#SEC2">Command line invocation</a>). -</p> -<p>Note that pointer size is <em>unchanged</em> and that code generated -with bound checks is <em>fully compatible</em> with unchecked -code. When a pointer comes from unchecked code, it is assumed to be -valid. Even very obscure C code with casts should work correctly. -</p> -<p>For more information about the ideas behind this method, see -<a href="http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html">http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html</a>. -</p> -<p>Here are some examples of caught errors: -</p> -<dl compact="compact"> -<dt> Invalid range with standard string function:</dt> -<dd><table><tr><td> </td><td><pre class="example">{ - char tab[10]; - memset(tab, 0, 11); -} -</pre></td></tr></table> - -</dd> -<dt> Out of bounds-error in global or local arrays:</dt> -<dd><table><tr><td> </td><td><pre class="example">{ - int tab[10]; - for(i=0;i<11;i++) { - sum += tab[i]; - } -} -</pre></td></tr></table> - -</dd> -<dt> Out of bounds-error in malloc'ed data:</dt> -<dd><table><tr><td> </td><td><pre class="example">{ - int *tab; - tab = malloc(20 * sizeof(int)); - for(i=0;i<21;i++) { - sum += tab4[i]; - } - free(tab); -} -</pre></td></tr></table> - -</dd> -<dt> Access of freed memory:</dt> -<dd><table><tr><td> </td><td><pre class="example">{ - int *tab; - tab = malloc(20 * sizeof(int)); - free(tab); - for(i=0;i<20;i++) { - sum += tab4[i]; - } -} -</pre></td></tr></table> - -</dd> -<dt> Double free:</dt> -<dd><table><tr><td> </td><td><pre class="example">{ - int *tab; - tab = malloc(20 * sizeof(int)); - free(tab); - free(tab); -} -</pre></td></tr></table> - -</dd> -</dl> - -<hr size="6"> -<a name="Libtcc"></a> -<a name="SEC22"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC21" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC21" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="chapter"> 7. The <code>libtcc</code> library </h1> - -<p>The <code>libtcc</code> library enables you to use TCC as a backend for -dynamic code generation. -</p> -<p>Read the ‘<tt>libtcc.h</tt>’ to have an overview of the API. Read -‘<tt>libtcc_test.c</tt>’ to have a very simple example. -</p> -<p>The idea consists in giving a C string containing the program you want -to compile directly to <code>libtcc</code>. Then you can access to any global -symbol (function or variable) defined. -</p> -<hr size="6"> -<a name="devel"></a> -<a name="SEC23"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC22" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC24" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC22" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="chapter"> 8. Developer's guide </h1> - -<p>This chapter gives some hints to understand how TCC works. You can skip -it if you do not intend to modify the TCC code. -</p> -<hr size="6"> -<a name="SEC24"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC23" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC25" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 8.1 File reading </h2> - -<p>The <code>BufferedFile</code> structure contains the context needed to read a -file, including the current line number. <code>tcc_open()</code> opens a new -file and <code>tcc_close()</code> closes it. <code>inp()</code> returns the next -character. -</p> -<hr size="6"> -<a name="SEC25"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC24" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC26" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 8.2 Lexer </h2> - -<p><code>next()</code> reads the next token in the current -file. <code>next_nomacro()</code> reads the next token without macro -expansion. -</p> -<p><code>tok</code> contains the current token (see <code>TOK_xxx</code>) -constants. Identifiers and keywords are also keywords. <code>tokc</code> -contains additional infos about the token (for example a constant value -if number or string token). -</p> -<hr size="6"> -<a name="SEC26"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC25" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC27" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 8.3 Parser </h2> - -<p>The parser is hardcoded (yacc is not necessary). It does only one pass, -except: -</p> -<ul class="toc"> -<li> For initialized arrays with unknown size, a first pass -is done to count the number of elements. - -</li><li> For architectures where arguments are evaluated in -reverse order, a first pass is done to reverse the argument order. - -</li></ul> - -<hr size="6"> -<a name="SEC27"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC26" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC28" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 8.4 Types </h2> - -<p>The types are stored in a single 'int' variable. It was chosen in the -first stages of development when tcc was much simpler. Now, it may not -be the best solution. -</p> -<table><tr><td> </td><td><pre class="example">#define VT_INT 0 /* integer type */ -#define VT_BYTE 1 /* signed byte type */ -#define VT_SHORT 2 /* short type */ -#define VT_VOID 3 /* void type */ -#define VT_PTR 4 /* pointer */ -#define VT_ENUM 5 /* enum definition */ -#define VT_FUNC 6 /* function type */ -#define VT_STRUCT 7 /* struct/union definition */ -#define VT_FLOAT 8 /* IEEE float */ -#define VT_DOUBLE 9 /* IEEE double */ -#define VT_LDOUBLE 10 /* IEEE long double */ -#define VT_BOOL 11 /* ISOC99 boolean type */ -#define VT_LLONG 12 /* 64 bit integer */ -#define VT_LONG 13 /* long integer (NEVER USED as type, only - during parsing) */ -#define VT_BTYPE 0x000f /* mask for basic type */ -#define VT_UNSIGNED 0x0010 /* unsigned type */ -#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */ -#define VT_BITFIELD 0x0040 /* bitfield modifier */ - -#define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */ -</pre></td></tr></table> - -<p>When a reference to another type is needed (for pointers, functions and -structures), the <code>32 - VT_STRUCT_SHIFT</code> high order bits are used to -store an identifier reference. -</p> -<p>The <code>VT_UNSIGNED</code> flag can be set for chars, shorts, ints and long -longs. -</p> -<p>Arrays are considered as pointers <code>VT_PTR</code> with the flag -<code>VT_ARRAY</code> set. -</p> -<p>The <code>VT_BITFIELD</code> flag can be set for chars, shorts, ints and long -longs. If it is set, then the bitfield position is stored from bits -VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored -from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11. -</p> -<p><code>VT_LONG</code> is never used except during parsing. -</p> -<p>During parsing, the storage of an object is also stored in the type -integer: -</p> -<table><tr><td> </td><td><pre class="example">#define VT_EXTERN 0x00000080 /* extern definition */ -#define VT_STATIC 0x00000100 /* static variable */ -#define VT_TYPEDEF 0x00000200 /* typedef definition */ -</pre></td></tr></table> - -<hr size="6"> -<a name="SEC28"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC27" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC29" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 8.5 Symbols </h2> - -<p>All symbols are stored in hashed symbol stacks. Each symbol stack -contains <code>Sym</code> structures. -</p> -<p><code>Sym.v</code> contains the symbol name (remember -an idenfier is also a token, so a string is never necessary to store -it). <code>Sym.t</code> gives the type of the symbol. <code>Sym.r</code> is usually -the register in which the corresponding variable is stored. <code>Sym.c</code> is -usually a constant associated to the symbol. -</p> -<p>Four main symbol stacks are defined: -</p> -<dl compact="compact"> -<dt> <code>define_stack</code></dt> -<dd><p>for the macros (<code>#define</code>s). -</p> -</dd> -<dt> <code>global_stack</code></dt> -<dd><p>for the global variables, functions and types. -</p> -</dd> -<dt> <code>local_stack</code></dt> -<dd><p>for the local variables, functions and types. -</p> -</dd> -<dt> <code>global_label_stack</code></dt> -<dd><p>for the local labels (for <code>goto</code>). -</p> -</dd> -<dt> <code>label_stack</code></dt> -<dd><p>for GCC block local labels (see the <code>__label__</code> keyword). -</p> -</dd> -</dl> - -<p><code>sym_push()</code> is used to add a new symbol in the local symbol -stack. If no local symbol stack is active, it is added in the global -symbol stack. -</p> -<p><code>sym_pop(st,b)</code> pops symbols from the symbol stack <var>st</var> until -the symbol <var>b</var> is on the top of stack. If <var>b</var> is NULL, the stack -is emptied. -</p> -<p><code>sym_find(v)</code> return the symbol associated to the identifier -<var>v</var>. The local stack is searched first from top to bottom, then the -global stack. -</p> -<hr size="6"> -<a name="SEC29"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC28" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC30" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 8.6 Sections </h2> - -<p>The generated code and datas are written in sections. The structure -<code>Section</code> contains all the necessary information for a given -section. <code>new_section()</code> creates a new section. ELF file semantics -is assumed for each section. -</p> -<p>The following sections are predefined: -</p> -<dl compact="compact"> -<dt> <code>text_section</code></dt> -<dd><p>is the section containing the generated code. <var>ind</var> contains the -current position in the code section. -</p> -</dd> -<dt> <code>data_section</code></dt> -<dd><p>contains initialized data -</p> -</dd> -<dt> <code>bss_section</code></dt> -<dd><p>contains uninitialized data -</p> -</dd> -<dt> <code>bounds_section</code></dt> -<dt> <code>lbounds_section</code></dt> -<dd><p>are used when bound checking is activated -</p> -</dd> -<dt> <code>stab_section</code></dt> -<dt> <code>stabstr_section</code></dt> -<dd><p>are used when debugging is activated to store debug information -</p> -</dd> -<dt> <code>symtab_section</code></dt> -<dt> <code>strtab_section</code></dt> -<dd><p>contain the exported symbols (currently only used for debugging). -</p> -</dd> -</dl> - -<hr size="6"> -<a name="SEC30"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC29" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC31" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 8.7 Code generation </h2> - -<hr size="6"> -<a name="SEC31"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC30" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC32" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC30" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h3 class="subsection"> 8.7.1 Introduction </h3> - -<p>The TCC code generator directly generates linked binary code in one -pass. It is rather unusual these days (see gcc for example which -generates text assembly), but it can be very fast and surprisingly -little complicated. -</p> -<p>The TCC code generator is register based. Optimization is only done at -the expression level. No intermediate representation of expression is -kept except the current values stored in the <em>value stack</em>. -</p> -<p>On x86, three temporary registers are used. When more registers are -needed, one register is spilled into a new temporary variable on the stack. -</p> -<hr size="6"> -<a name="SEC32"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC31" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC33" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC30" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h3 class="subsection"> 8.7.2 The value stack </h3> - -<p>When an expression is parsed, its value is pushed on the value stack -(<var>vstack</var>). The top of the value stack is <var>vtop</var>. Each value -stack entry is the structure <code>SValue</code>. -</p> -<p><code>SValue.t</code> is the type. <code>SValue.r</code> indicates how the value is -currently stored in the generated code. It is usually a CPU register -index (<code>REG_xxx</code> constants), but additional values and flags are -defined: -</p> -<table><tr><td> </td><td><pre class="example">#define VT_CONST 0x00f0 -#define VT_LLOCAL 0x00f1 -#define VT_LOCAL 0x00f2 -#define VT_CMP 0x00f3 -#define VT_JMP 0x00f4 -#define VT_JMPI 0x00f5 -#define VT_LVAL 0x0100 -#define VT_SYM 0x0200 -#define VT_MUSTCAST 0x0400 -#define VT_MUSTBOUND 0x0800 -#define VT_BOUNDED 0x8000 -#define VT_LVAL_BYTE 0x1000 -#define VT_LVAL_SHORT 0x2000 -#define VT_LVAL_UNSIGNED 0x4000 -#define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED) -</pre></td></tr></table> - -<dl compact="compact"> -<dt> <code>VT_CONST</code></dt> -<dd><p>indicates that the value is a constant. It is stored in the union -<code>SValue.c</code>, depending on its type. -</p> -</dd> -<dt> <code>VT_LOCAL</code></dt> -<dd><p>indicates a local variable pointer at offset <code>SValue.c.i</code> in the -stack. -</p> -</dd> -<dt> <code>VT_CMP</code></dt> -<dd><p>indicates that the value is actually stored in the CPU flags (i.e. the -value is the consequence of a test). The value is either 0 or 1. The -actual CPU flags used is indicated in <code>SValue.c.i</code>. -</p> -<p>If any code is generated which destroys the CPU flags, this value MUST be -put in a normal register. -</p> -</dd> -<dt> <code>VT_JMP</code></dt> -<dt> <code>VT_JMPI</code></dt> -<dd><p>indicates that the value is the consequence of a conditional jump. For VT_JMP, -it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted. -</p> -<p>These values are used to compile the <code>||</code> and <code>&&</code> logical -operators. -</p> -<p>If any code is generated, this value MUST be put in a normal -register. Otherwise, the generated code won't be executed if the jump is -taken. -</p> -</dd> -<dt> <code>VT_LVAL</code></dt> -<dd><p>is a flag indicating that the value is actually an lvalue (left value of -an assignment). It means that the value stored is actually a pointer to -the wanted value. -</p> -<p>Understanding the use <code>VT_LVAL</code> is very important if you want to -understand how TCC works. -</p> -</dd> -<dt> <code>VT_LVAL_BYTE</code></dt> -<dt> <code>VT_LVAL_SHORT</code></dt> -<dt> <code>VT_LVAL_UNSIGNED</code></dt> -<dd><p>if the lvalue has an integer type, then these flags give its real -type. The type alone is not enough in case of cast optimisations. -</p> -</dd> -<dt> <code>VT_LLOCAL</code></dt> -<dd><p>is a saved lvalue on the stack. <code>VT_LLOCAL</code> should be eliminated -ASAP because its semantics are rather complicated. -</p> -</dd> -<dt> <code>VT_MUSTCAST</code></dt> -<dd><p>indicates that a cast to the value type must be performed if the value -is used (lazy casting). -</p> -</dd> -<dt> <code>VT_SYM</code></dt> -<dd><p>indicates that the symbol <code>SValue.sym</code> must be added to the constant. -</p> -</dd> -<dt> <code>VT_MUSTBOUND</code></dt> -<dt> <code>VT_BOUNDED</code></dt> -<dd><p>are only used for optional bound checking. -</p> -</dd> -</dl> - -<hr size="6"> -<a name="SEC33"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC32" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC34" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC30" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h3 class="subsection"> 8.7.3 Manipulating the value stack </h3> - -<p><code>vsetc()</code> and <code>vset()</code> pushes a new value on the value -stack. If the previous <var>vtop</var> was stored in a very unsafe place(for -example in the CPU flags), then some code is generated to put the -previous <var>vtop</var> in a safe storage. -</p> -<p><code>vpop()</code> pops <var>vtop</var>. In some cases, it also generates cleanup -code (for example if stacked floating point registers are used as on -x86). -</p> -<p>The <code>gv(rc)</code> function generates code to evaluate <var>vtop</var> (the -top value of the stack) into registers. <var>rc</var> selects in which -register class the value should be put. <code>gv()</code> is the <em>most -important function</em> of the code generator. -</p> -<p><code>gv2()</code> is the same as <code>gv()</code> but for the top two stack -entries. -</p> -<hr size="6"> -<a name="SEC34"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC33" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC35" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC30" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h3 class="subsection"> 8.7.4 CPU dependent code generation </h3> -<p>See the ‘<tt>i386-gen.c</tt>’ file to have an example. -</p> -<dl compact="compact"> -<dt> <code>load()</code></dt> -<dd><p>must generate the code needed to load a stack value into a register. -</p> -</dd> -<dt> <code>store()</code></dt> -<dd><p>must generate the code needed to store a register into a stack value -lvalue. -</p> -</dd> -<dt> <code>gfunc_start()</code></dt> -<dt> <code>gfunc_param()</code></dt> -<dt> <code>gfunc_call()</code></dt> -<dd><p>should generate a function call -</p> -</dd> -<dt> <code>gfunc_prolog()</code></dt> -<dt> <code>gfunc_epilog()</code></dt> -<dd><p>should generate a function prolog/epilog. -</p> -</dd> -<dt> <code>gen_opi(op)</code></dt> -<dd><p>must generate the binary integer operation <var>op</var> on the two top -entries of the stack which are guaranted to contain integer types. -</p> -<p>The result value should be put on the stack. -</p> -</dd> -<dt> <code>gen_opf(op)</code></dt> -<dd><p>same as <code>gen_opi()</code> for floating point operations. The two top -entries of the stack are guaranted to contain floating point values of -same types. -</p> -</dd> -<dt> <code>gen_cvt_itof()</code></dt> -<dd><p>integer to floating point conversion. -</p> -</dd> -<dt> <code>gen_cvt_ftoi()</code></dt> -<dd><p>floating point to integer conversion. -</p> -</dd> -<dt> <code>gen_cvt_ftof()</code></dt> -<dd><p>floating point to floating point of different size conversion. -</p> -</dd> -<dt> <code>gen_bounded_ptr_add()</code></dt> -<dt> <code>gen_bounded_ptr_deref()</code></dt> -<dd><p>are only used for bounds checking. -</p> -</dd> -</dl> - -<hr size="6"> -<a name="SEC35"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC34" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next section in reading order"> > </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> >> </a>]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h2 class="section"> 8.8 Optimizations done </h2> -<p>Constant propagation is done for all operations. Multiplications and -divisions are optimized to shifts when appropriate. Comparison -operators are optimized by maintaining a special cache for the -processor flags. &&, || and ! are optimized by maintaining a special -'jump target' value. No other jump optimization is currently performed -because it would require to store the code in a more abstract fashion. -</p> -<hr size="6"> -<a name="SEC36"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC35" title="Previous section in reading order"> < </a>]</td> -<td valign="middle" align="left">[ > ]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> << </a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td> -<td valign="middle" align="left">[ >> ]</td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left"> </td> -<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1 class="unnumbered"> Concept Index </h1> -<table><tr><th valign="top">Jump to: </th><td><a href="#SEC36_0" class="summary-letter"><b>_</b></a> - -<br> -<a href="#SEC36_1" class="summary-letter"><b>A</b></a> - -<a href="#SEC36_2" class="summary-letter"><b>B</b></a> - -<a href="#SEC36_3" class="summary-letter"><b>C</b></a> - -<a href="#SEC36_4" class="summary-letter"><b>D</b></a> - -<a href="#SEC36_5" class="summary-letter"><b>E</b></a> - -<a href="#SEC36_6" class="summary-letter"><b>F</b></a> - -<a href="#SEC36_7" class="summary-letter"><b>G</b></a> - -<a href="#SEC36_8" class="summary-letter"><b>I</b></a> - -<a href="#SEC36_9" class="summary-letter"><b>J</b></a> - -<a href="#SEC36_10" class="summary-letter"><b>L</b></a> - -<a href="#SEC36_11" class="summary-letter"><b>M</b></a> - -<a href="#SEC36_12" class="summary-letter"><b>O</b></a> - -<a href="#SEC36_13" class="summary-letter"><b>P</b></a> - -<a href="#SEC36_14" class="summary-letter"><b>Q</b></a> - -<a href="#SEC36_15" class="summary-letter"><b>R</b></a> - -<a href="#SEC36_16" class="summary-letter"><b>S</b></a> - -<a href="#SEC36_17" class="summary-letter"><b>T</b></a> - -<a href="#SEC36_18" class="summary-letter"><b>U</b></a> - -<a href="#SEC36_19" class="summary-letter"><b>V</b></a> - -<a href="#SEC36_20" class="summary-letter"><b>W</b></a> - -</td></tr></table> -<table border="0" class="index-cp"> -<tr><td></td><th align="left">Index Entry</th><th align="left"> Section</th></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_0">_</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#IDX11">__asm__</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_1">A</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">align directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#IDX1">aligned attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">ascii directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">asciz directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC15">assembler</a></td><td valign="top"><a href="#SEC15">4.5 X86 Assembler</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">assembler directives</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#IDX10">assembly, inline</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_2">B</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC21">bound checks</a></td><td valign="top"><a href="#SEC21">6. TinyCC Memory and Bound checks</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">bss directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">byte directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_3">C</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC35">caching processor flags</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr> -<tr><td></td><td valign="top"><a href="#IDX5">cdecl attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC30">code generation</a></td><td valign="top"><a href="#SEC30">8.7 Code generation</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC35">comparison operators</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC35">constant propagation</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC34">CPU dependent</a></td><td valign="top"><a href="#SEC34">8.7.4 CPU dependent code generation</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_4">D</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">data directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">directives, assembler</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#IDX8">dllexport attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_5">E</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC17">ELF</a></td><td valign="top"><a href="#SEC17">5.1 ELF file generation</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_6">F</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC20">FILE, linker command</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">fill directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC35">flags, caching</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_7">G</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#IDX12">gas</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">global directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">globl directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC20">GROUP, linker command</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_8">I</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#IDX9">inline assembly</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">int directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_9">J</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC35">jump optimization</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_10">L</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC16">linker</a></td><td valign="top"><a href="#SEC16">5. TinyCC Linker</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC20">linker scripts</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">long directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_11">M</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC21">memory checks</a></td><td valign="top"><a href="#SEC21">6. TinyCC Memory and Bound checks</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_12">O</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC35">optimizations</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">org directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC20">OUTPUT_FORMAT, linker command</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_13">P</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#IDX2">packed attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC19">PE-i386</a></td><td valign="top"><a href="#SEC19">5.3 PE-i386 file generation</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">previous directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_14">Q</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">quad directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_15">R</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#IDX7">regparm attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_16">S</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC20">scripts, linker</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr> -<tr><td></td><td valign="top"><a href="#IDX3">section attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">section directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">short directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">skip directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">space directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td></td><td valign="top"><a href="#IDX6">stdcall attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC35">strength reduction</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">string directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_17">T</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC20">TARGET, linker command</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">text directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_18">U</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#IDX4">unused attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_19">V</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC33">value stack</a></td><td valign="top"><a href="#SEC33">8.7.3 Manipulating the value stack</a></td></tr> -<tr><td></td><td valign="top"><a href="#SEC32">value stack, introduction</a></td><td valign="top"><a href="#SEC32">8.7.2 The value stack</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -<tr><th><a name="SEC36_20">W</a></th><td></td><td></td></tr> -<tr><td></td><td valign="top"><a href="#SEC14">word directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr> -<tr><td colspan="3"> <hr></td></tr> -</table> -<table><tr><th valign="top">Jump to: </th><td><a href="#SEC36_0" class="summary-letter"><b>_</b></a> - -<br> -<a href="#SEC36_1" class="summary-letter"><b>A</b></a> - -<a href="#SEC36_2" class="summary-letter"><b>B</b></a> - -<a href="#SEC36_3" class="summary-letter"><b>C</b></a> - -<a href="#SEC36_4" class="summary-letter"><b>D</b></a> - -<a href="#SEC36_5" class="summary-letter"><b>E</b></a> - -<a href="#SEC36_6" class="summary-letter"><b>F</b></a> - -<a href="#SEC36_7" class="summary-letter"><b>G</b></a> - -<a href="#SEC36_8" class="summary-letter"><b>I</b></a> - -<a href="#SEC36_9" class="summary-letter"><b>J</b></a> - -<a href="#SEC36_10" class="summary-letter"><b>L</b></a> - -<a href="#SEC36_11" class="summary-letter"><b>M</b></a> - -<a href="#SEC36_12" class="summary-letter"><b>O</b></a> - -<a href="#SEC36_13" class="summary-letter"><b>P</b></a> - -<a href="#SEC36_14" class="summary-letter"><b>Q</b></a> - -<a href="#SEC36_15" class="summary-letter"><b>R</b></a> - -<a href="#SEC36_16" class="summary-letter"><b>S</b></a> - -<a href="#SEC36_17" class="summary-letter"><b>T</b></a> - -<a href="#SEC36_18" class="summary-letter"><b>U</b></a> - -<a href="#SEC36_19" class="summary-letter"><b>V</b></a> - -<a href="#SEC36_20" class="summary-letter"><b>W</b></a> - -</td></tr></table> - -<hr size="6"> -<a name="SEC_Contents"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1>Table of Contents</h1> -<div class="contents"> - -<ul class="toc"> - <li><a name="TOC1" href="#SEC1">1. Introduction</a></li> - <li><a name="TOC2" href="#SEC2">2. Command line invocation</a> - <ul class="toc"> - <li><a name="TOC3" href="#SEC3">2.1 Quick start</a></li> - <li><a name="TOC4" href="#SEC4">2.2 Option summary</a></li> - </ul></li> - <li><a name="TOC5" href="#SEC5">3. C language support</a> - <ul class="toc"> - <li><a name="TOC6" href="#SEC6">3.1 ANSI C</a></li> - <li><a name="TOC7" href="#SEC7">3.2 ISOC99 extensions</a></li> - <li><a name="TOC8" href="#SEC8">3.3 GNU C extensions</a></li> - <li><a name="TOC9" href="#SEC9">3.4 TinyCC extensions</a></li> - </ul></li> - <li><a name="TOC10" href="#SEC10">4. TinyCC Assembler</a> - <ul class="toc"> - <li><a name="TOC11" href="#SEC11">4.1 Syntax</a></li> - <li><a name="TOC12" href="#SEC12">4.2 Expressions</a></li> - <li><a name="TOC13" href="#SEC13">4.3 Labels</a></li> - <li><a name="TOC14" href="#SEC14">4.4 Directives</a></li> - <li><a name="TOC15" href="#SEC15">4.5 X86 Assembler</a></li> - </ul></li> - <li><a name="TOC16" href="#SEC16">5. TinyCC Linker</a> - <ul class="toc"> - <li><a name="TOC17" href="#SEC17">5.1 ELF file generation</a></li> - <li><a name="TOC18" href="#SEC18">5.2 ELF file loader</a></li> - <li><a name="TOC19" href="#SEC19">5.3 PE-i386 file generation</a></li> - <li><a name="TOC20" href="#SEC20">5.4 GNU Linker Scripts</a></li> - </ul></li> - <li><a name="TOC21" href="#SEC21">6. TinyCC Memory and Bound checks</a></li> - <li><a name="TOC22" href="#SEC22">7. The <code>libtcc</code> library</a></li> - <li><a name="TOC23" href="#SEC23">8. Developer's guide</a> - <ul class="toc"> - <li><a name="TOC24" href="#SEC24">8.1 File reading</a></li> - <li><a name="TOC25" href="#SEC25">8.2 Lexer</a></li> - <li><a name="TOC26" href="#SEC26">8.3 Parser</a></li> - <li><a name="TOC27" href="#SEC27">8.4 Types</a></li> - <li><a name="TOC28" href="#SEC28">8.5 Symbols</a></li> - <li><a name="TOC29" href="#SEC29">8.6 Sections</a></li> - <li><a name="TOC30" href="#SEC30">8.7 Code generation</a> - <ul class="toc"> - <li><a name="TOC31" href="#SEC31">8.7.1 Introduction</a></li> - <li><a name="TOC32" href="#SEC32">8.7.2 The value stack</a></li> - <li><a name="TOC33" href="#SEC33">8.7.3 Manipulating the value stack</a></li> - <li><a name="TOC34" href="#SEC34">8.7.4 CPU dependent code generation</a></li> - </ul></li> - <li><a name="TOC35" href="#SEC35">8.8 Optimizations done</a></li> - </ul></li> - <li><a name="TOC36" href="#SEC36">Concept Index</a></li> -</ul> -</div> -<hr size="1"> -<a name="SEC_About"></a> -<table cellpadding="1" cellspacing="1" border="0"> -<tr><td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td> -<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td> -<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td> -</tr></table> -<h1>About This Document</h1> -<p> - This document was generated by <em>gr</em> on <em>May, 18 2009</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.78</em></a>. -</p> -<p> - The buttons in the navigation panels have the following meaning: -</p> -<table border="1"> - <tr> - <th> Button </th> - <th> Name </th> - <th> Go to </th> - <th> From 1.2.3 go to</th> - </tr> - <tr> - <td align="center"> [ < ] </td> - <td align="center">Back</td> - <td>Previous section in reading order</td> - <td>1.2.2</td> - </tr> - <tr> - <td align="center"> [ > ] </td> - <td align="center">Forward</td> - <td>Next section in reading order</td> - <td>1.2.4</td> - </tr> - <tr> - <td align="center"> [ << ] </td> - <td align="center">FastBack</td> - <td>Beginning of this chapter or previous chapter</td> - <td>1</td> - </tr> - <tr> - <td align="center"> [ Up ] </td> - <td align="center">Up</td> - <td>Up section</td> - <td>1.2</td> - </tr> - <tr> - <td align="center"> [ >> ] </td> - <td align="center">FastForward</td> - <td>Next chapter</td> - <td>2</td> - </tr> - <tr> - <td align="center"> [Top] </td> - <td align="center">Top</td> - <td>Cover (top) of document</td> - <td> </td> - </tr> - <tr> - <td align="center"> [Contents] </td> - <td align="center">Contents</td> - <td>Table of contents</td> - <td> </td> - </tr> - <tr> - <td align="center"> [Index] </td> - <td align="center">Index</td> - <td>Index</td> - <td> </td> - </tr> - <tr> - <td align="center"> [ ? ] </td> - <td align="center">About</td> - <td>About (help)</td> - <td> </td> - </tr> -</table> - -<p> - where the <strong> Example </strong> assumes that the current position is at <strong> Subsubsection One-Two-Three </strong> of a document of the following structure: -</p> - -<ul> - <li> 1. Section One - <ul> - <li>1.1 Subsection One-One - <ul> - <li>...</li> - </ul> - </li> - <li>1.2 Subsection One-Two - <ul> - <li>1.2.1 Subsubsection One-Two-One</li> - <li>1.2.2 Subsubsection One-Two-Two</li> - <li>1.2.3 Subsubsection One-Two-Three - <strong><== Current Position </strong></li> - <li>1.2.4 Subsubsection One-Two-Four</li> - </ul> - </li> - <li>1.3 Subsection One-Three - <ul> - <li>...</li> - </ul> - </li> - <li>1.4 Subsection One-Four</li> - </ul> - </li> -</ul> - -<hr size="1"> -<p> - <font size="-1"> - This document was generated by <em>gr</em> on <em>May, 18 2009</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.78</em></a>. - </font> - <br> - -</p> -</body> -</html> diff --git a/tinyc/tcc-doc.texi b/tinyc/tcc-doc.texi index 47a8c8b00..5e718a2c5 100644 --- a/tinyc/tcc-doc.texi +++ b/tinyc/tcc-doc.texi @@ -2,6 +2,10 @@ @c %**start of header @setfilename tcc-doc.info @settitle Tiny C Compiler Reference Documentation +@dircategory Software development +@direntry +* TCC: (tcc-doc). The Tiny C Compiler. +@end direntry @c %**end of header @include config.texi @@ -64,7 +68,7 @@ ports for the ARM (@code{arm-tcc}) and the TMS320C67xx targets (@code{c67-tcc}). More information about the ARM port is available at @url{http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html}. -For usage on Windows, see also tcc-win32.txt. +For usage on Windows, see also @url{tcc-win32.txt}. @node Invoke @chapter Command line invocation @@ -153,43 +157,34 @@ General Options: @c man begin OPTIONS @table @option -@item -v -Display current TCC version, increase verbosity. - @item -c -Generate an object file (@option{-o} option must also be given). +Generate an object file. @item -o outfile Put object file, executable, or dll into output file @file{outfile}. -@item -Bdir -Set the path where the tcc internal libraries can be found (default is -@file{PREFIX/lib/tcc}). - -@item -bench -Output compilation statistics. - @item -run source [args...] Compile file @var{source} and run it with the command line arguments @var{args}. In order to be able to give more than one argument to a script, several TCC options can be given @emph{after} the -@option{-run} option, separated by spaces. Example: - +@option{-run} option, separated by spaces: @example tcc "-run -L/usr/X11R6/lib -lX11" ex4.c @end example - In a script, it gives the following header: - @example #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11 -#include <stdlib.h> -int main(int argc, char **argv) -@{ - ... -@} @end example +@item -v +Display TCC version. + +@item -vv +Show included files. As sole argument, print search dirs. -vvv shows tries too. + +@item -bench +Display compilation statistics. + @end table Preprocessor options: @@ -211,11 +206,15 @@ also be defined: @option{-DF(a)=a+1} @item -Usym Undefine preprocessor symbol @samp{sym}. + +@item -E +Preprocess only, to stdout or file (with -o). + @end table Compilation flags: -Note: each of the following warning options has a negative form beginning with +Note: each of the following options has a negative form beginning with @option{-fno-}. @table @option @@ -231,6 +230,14 @@ Do not generate common symbols for uninitialized data. @item -fleading-underscore Add a leading underscore at the beginning of each C symbol. +@item -fms-extensions +Allow a MS C compiler extensions to the language. Currently this +assumes a nested named structure declaration without an identifier +behaves like an unnamed one. + +@item -fdollars-in-identifiers +Allow dollar signs in identifiers + @end table Warning options: @@ -274,28 +281,37 @@ default library paths are @file{/usr/local/lib}, @file{/usr/lib} and @file{/lib} @item -lxxx Link your program with dynamic library libxxx.so or static library libxxx.a. The library is searched in the paths specified by the -@option{-L} option. +@option{-L} option and @env{LIBRARY_PATH} variable. + +@item -Bdir +Set the path where the tcc internal libraries (and include files) can be +found (default is @file{PREFIX/lib/tcc}). @item -shared -Generate a shared library instead of an executable (@option{-o} option -must also be given). +Generate a shared library instead of an executable. + +@item -soname name +set name for shared library to be used at runtime @item -static Generate a statically linked executable (default is a shared linked -executable) (@option{-o} option must also be given). +executable). @item -rdynamic Export global symbols to the dynamic linker. It is useful when a library opened with @code{dlopen()} needs to access executable symbols. @item -r -Generate an object file combining all input files (@option{-o} option must -also be given). +Generate an object file combining all input files. + +@item -Wl,-rpath=path +Put custom search path for dynamic libraries into executable. -@item -Wl,-Ttext,address -Set the start of the .text section to @var{address}. +@item -Wl,--enable-new-dtags +When putting a custom search path for dynamic libraries into the executable, +create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH. -@item -Wl,--oformat,fmt +@item -Wl,--oformat=fmt Use @var{fmt} as output format. The supported output formats are: @table @code @item elf32-i386 @@ -306,6 +322,18 @@ Binary image (only for executable output) COFF output format (only for executable output for TMS320C67xx target) @end table +@item -Wl,-subsystem=console/gui/wince/... +Set type for PE (Windows) executables. + +@item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#] +Modify executable layout. + +@item -Wl,-Bsymbolic +Set DT_SYMBOLIC tag. + +@item -Wl,-(no-)whole-archive +Turn on/off linking of all objects in archives. + @end table Debugger options: @@ -322,22 +350,79 @@ Generate additional support code to check memory allocations and array/pointer bounds. @option{-g} is implied. Note that the generated code is slower and bigger in this case. +Note: @option{-b} is only available on i386 when using libtcc for the moment. + @item -bt N Display N callers in stack traces. This is useful with @option{-g} or @option{-b}. @end table +Misc options: + +@table @option +@item -MD +Generate makefile fragment with dependencies. + +@item -MF depfile +Use @file{depfile} as output for -MD. + +@item -print-search-dirs +Print the configured installation directory and a list of library +and include directories tcc will search. + +@item -dumpversion +Print version. + +@end table + +Target specific options: + +@table @option +@item -mms-bitfields +Use an algorithm for bitfield alignment consistent with MSVC. Default is +gcc's algorithm. + +@item -mfloat-abi (ARM only) +Select the float ABI. Possible values: @code{softfp} and @code{hard} + +@item -mno-sse +Do not use sse registers on x86_64 + +@item -m32, -m64 +Pass command line to the i386/x86_64 cross compiler. + +@end table + Note: GCC options @option{-Ox}, @option{-fx} and @option{-mx} are ignored. @c man end +@c man begin ENVIRONMENT +Environment variables that affect how tcc operates. + +@table @option + +@item CPATH +@item C_INCLUDE_PATH +A colon-separated list of directories searched for include files, +directories given with @option{-I} are searched first. + +@item LIBRARY_PATH +A colon-separated list of directories searched for libraries for the +@option{-l} option, directories given with @option{-L} are searched first. + +@end table + +@c man end + @ignore @setfilename tcc @settitle Tiny C Compiler @c man begin SEEALSO +cpp(1), gcc(1) @c man end @@ -359,13 +444,14 @@ and floating point numbers (@code{long double}, @code{double}, and @section ISOC99 extensions TCC implements many features of the new C standard: ISO C99. Currently -missing items are: complex and imaginary numbers and variable length -arrays. +missing items are: complex and imaginary numbers. Currently implemented ISOC99 features: @itemize +@item variable length arrays. + @item 64 bit @code{long long} types are fully supported. @item The boolean type @code{_Bool} is supported. @@ -567,8 +653,7 @@ are supported. @itemize -@item @code{__TINYC__} is a predefined macro to @code{1} to -indicate that you use TCC. +@item @code{__TINYC__} is a predefined macro to indicate that you use TCC. @item @code{#!} at the start of a line is ignored to allow scripting. @@ -584,7 +669,7 @@ indicate that you use TCC. Since version 0.9.16, TinyCC integrates its own assembler. TinyCC assembler supports a gas-like syntax (GNU assembler). You can -desactivate assembler support if you want a smaller TinyCC executable +deactivate assembler support if you want a smaller TinyCC executable (the C compiler does not rely on the assembler). TinyCC Assembler is used to handle files with @file{.S} (C @@ -915,9 +1000,13 @@ be the best solution. #define VT_BTYPE 0x000f /* mask for basic type */ #define VT_UNSIGNED 0x0010 /* unsigned type */ #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */ +#define VT_VLA 0x20000 /* VLA type (also has VT_PTR and VT_ARRAY) */ #define VT_BITFIELD 0x0040 /* bitfield modifier */ +#define VT_CONSTANT 0x0800 /* const modifier */ +#define VT_VOLATILE 0x1000 /* volatile modifier */ +#define VT_DEFSIGN 0x2000 /* signed type */ -#define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */ +#define VT_STRUCT_SHIFT 18 /* structure/enum name shift (14 bits left) */ @end example When a reference to another type is needed (for pointers, functions and @@ -928,7 +1017,8 @@ The @code{VT_UNSIGNED} flag can be set for chars, shorts, ints and long longs. Arrays are considered as pointers @code{VT_PTR} with the flag -@code{VT_ARRAY} set. +@code{VT_ARRAY} set. Variable length arrays are considered as special +arrays and have flag @code{VT_VLA} set instead of @code{VT_ARRAY}. The @code{VT_BITFIELD} flag can be set for chars, shorts, ints and long longs. If it is set, then the bitfield position is stored from bits @@ -944,6 +1034,10 @@ integer: #define VT_EXTERN 0x00000080 /* extern definition */ #define VT_STATIC 0x00000100 /* static variable */ #define VT_TYPEDEF 0x00000200 /* typedef definition */ +#define VT_INLINE 0x00000400 /* inline definition */ +#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ +#define VT_EXPORT 0x00008000 /* win32: data exported from dll */ +#define VT_WEAK 0x00010000 /* win32: data exported from dll */ @end example @section Symbols @@ -952,10 +1046,13 @@ All symbols are stored in hashed symbol stacks. Each symbol stack contains @code{Sym} structures. @code{Sym.v} contains the symbol name (remember -an idenfier is also a token, so a string is never necessary to store +an identifier is also a token, so a string is never necessary to store it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually the register in which the corresponding variable is stored. @code{Sym.c} is -usually a constant associated to the symbol. +usually a constant associated to the symbol like its address for normal +symbols, and the number of entries for symbols representing arrays. +Variable length array types use @code{Sym.c} as a location on the stack +which holds the runtime sizeof for the type. Four main symbol stacks are defined: @@ -992,7 +1089,7 @@ global stack. @section Sections -The generated code and datas are written in sections. The structure +The generated code and data are written in sections. The structure @code{Section} contains all the necessary information for a given section. @code{new_section()} creates a new section. ELF file semantics is assumed for each section. @@ -1017,7 +1114,7 @@ are used when bound checking is activated @item stab_section @itemx stabstr_section -are used when debugging is activated to store debug information +are used when debugging is active to store debug information @item symtab_section @itemx strtab_section @@ -1117,8 +1214,10 @@ if the lvalue has an integer type, then these flags give its real type. The type alone is not enough in case of cast optimisations. @item VT_LLOCAL -is a saved lvalue on the stack. @code{VT_LLOCAL} should be eliminated -ASAP because its semantics are rather complicated. +is a saved lvalue on the stack. @code{VT_LVAL} must also be set with +@code{VT_LLOCAL}. @code{VT_LLOCAL} can arise when a @code{VT_LVAL} in +a register has to be saved to the stack, or it can come from an +architecture-specific calling convention. @item VT_MUSTCAST indicates that a cast to the value type must be performed if the value @@ -1177,13 +1276,13 @@ should generate a function prolog/epilog. @item gen_opi(op) must generate the binary integer operation @var{op} on the two top -entries of the stack which are guaranted to contain integer types. +entries of the stack which are guaranteed to contain integer types. The result value should be put on the stack. @item gen_opf(op) same as @code{gen_opi()} for floating point operations. The two top -entries of the stack are guaranted to contain floating point values of +entries of the stack are guaranteed to contain floating point values of same types. @item gen_cvt_itof() diff --git a/tinyc/tcc.c b/tinyc/tcc.c index 3fce60804..c347a06ea 100644 --- a/tinyc/tcc.c +++ b/tinyc/tcc.c @@ -18,536 +18,354 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "libtcc.c" - -void help(void) -{ - printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n" - "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n" - " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-soname name]\n" - " [-static] [infile1 infile2...] [-run infile args...]\n" - "\n" - "General options:\n" - " -v display current version, increase verbosity\n" - " -c compile only - generate an object file\n" - " -o outfile set output filename\n" - " -Bdir set tcc internal library path\n" - " -bench output compilation statistics\n" - " -run run compiled source\n" - " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n" - " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n" - " -w disable all warnings\n" - "Preprocessor options:\n" - " -E preprocess only\n" - " -Idir add include path 'dir'\n" - " -Dsym[=val] define 'sym' with value 'val'\n" - " -Usym undefine 'sym'\n" - "Linker options:\n" - " -Ldir add library path 'dir'\n" - " -llib link with dynamic or static library 'lib'\n" - " -shared generate a shared library\n" - " -soname set name for shared library to be used at runtime\n" - " -static static linking\n" - " -rdynamic export all global symbols to dynamic linker\n" - " -r generate (relocatable) object file\n" - "Debugger options:\n" - " -g generate runtime debug info\n" +#include "tcc.h" +#if ONE_SOURCE +# include "libtcc.c" +#endif +#include "tcctools.c" + +static const char help[] = + "Tiny C Compiler "TCC_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n" + "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n" + " tcc [options...] -run infile [arguments...]\n" + "General options:\n" + " -c compile only - generate an object file\n" + " -o outfile set output filename\n" + " -run run compiled source\n" + " -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n" + " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n" + " -w disable all warnings\n" + " -v -vv show version, show search paths or loaded files\n" + " -h -hh show this, show more help\n" + " -bench show compilation statistics\n" + " - use stdin pipe as infile\n" + " @listfile read arguments from listfile\n" + "Preprocessor options:\n" + " -Idir add include path 'dir'\n" + " -Dsym[=val] define 'sym' with value 'val'\n" + " -Usym undefine 'sym'\n" + " -E preprocess only\n" + "Linker options:\n" + " -Ldir add library path 'dir'\n" + " -llib link with dynamic or static library 'lib'\n" + " -r generate (relocatable) object file\n" + " -shared generate a shared library/dll\n" + " -rdynamic export all global symbols to dynamic linker\n" + " -soname set name for shared library to be used at runtime\n" + " -Wl,-opt[=val] set linker option (see tcc -hh)\n" + "Debugger options:\n" + " -g generate runtime debug info\n" #ifdef CONFIG_TCC_BCHECK - " -b compile with built-in memory and bounds checker (implies -g)\n" + " -b compile with built-in memory and bounds checker (implies -g)\n" #endif #ifdef CONFIG_TCC_BACKTRACE - " -bt N show N callers in stack traces\n" + " -bt N show N callers in stack traces\n" #endif - ); -} - -static char **files; -static int nb_files, nb_libraries; -static int multiple_files; -static int print_search_dirs; -static int output_type; -static int reloc_output; -static const char *outfile; -static int do_bench = 0; - -#define TCC_OPTION_HAS_ARG 0x0001 -#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ - -typedef struct TCCOption { - const char *name; - uint16_t index; - uint16_t flags; -} TCCOption; - -enum { - TCC_OPTION_HELP, - TCC_OPTION_I, - TCC_OPTION_D, - TCC_OPTION_U, - TCC_OPTION_L, - TCC_OPTION_B, - TCC_OPTION_l, - TCC_OPTION_bench, - TCC_OPTION_bt, - TCC_OPTION_b, - TCC_OPTION_g, - TCC_OPTION_c, - TCC_OPTION_static, - TCC_OPTION_shared, - TCC_OPTION_soname, - TCC_OPTION_o, - TCC_OPTION_r, - TCC_OPTION_Wl, - TCC_OPTION_W, - TCC_OPTION_O, - TCC_OPTION_m, - TCC_OPTION_f, - TCC_OPTION_nostdinc, - TCC_OPTION_nostdlib, - TCC_OPTION_print_search_dirs, - TCC_OPTION_rdynamic, - TCC_OPTION_run, - TCC_OPTION_v, - TCC_OPTION_w, - TCC_OPTION_pipe, - TCC_OPTION_E, -}; - -static const TCCOption tcc_options[] = { - { "h", TCC_OPTION_HELP, 0 }, - { "?", TCC_OPTION_HELP, 0 }, - { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, - { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, - { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, - { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, - { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, - { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "bench", TCC_OPTION_bench, 0 }, - { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG }, -#ifdef CONFIG_TCC_BCHECK - { "b", TCC_OPTION_b, 0 }, + "Misc. options:\n" + " -x[c|a|n] specify type of the next infile\n" + " -nostdinc do not use standard system include paths\n" + " -nostdlib do not link with standard crt and libraries\n" + " -Bdir set tcc's private include/library dir\n" + " -MD generate dependency file for make\n" + " -MF file specify dependency file name\n" + " -m32/64 defer to i386/x86_64 cross compiler\n" + "Tools:\n" + " create library : tcc -ar [rcsv] lib.a files\n" +#ifdef TCC_TARGET_PE + " create def file : tcc -impdef lib.dll [-v] [-o lib.def]\n" #endif - { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "c", TCC_OPTION_c, 0 }, - { "static", TCC_OPTION_static, 0 }, - { "shared", TCC_OPTION_shared, 0 }, - { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG }, - { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG }, - { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "rdynamic", TCC_OPTION_rdynamic, 0 }, - { "r", TCC_OPTION_r, 0 }, - { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG }, - { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "nostdinc", TCC_OPTION_nostdinc, 0 }, - { "nostdlib", TCC_OPTION_nostdlib, 0 }, - { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, - { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, - { "w", TCC_OPTION_w, 0 }, - { "pipe", TCC_OPTION_pipe, 0}, - { "E", TCC_OPTION_E, 0}, - { NULL }, -}; - -static int64_t getclock_us(void) -{ -#ifdef _WIN32 - struct _timeb tb; - _ftime(&tb); - return (tb.time * 1000LL + tb.millitm) * 1000LL; + ; + +static const char help2[] = + "Tiny C Compiler "TCC_VERSION" - More Options\n" + "Special options:\n" + " -P -P1 with -E: no/alternative #line output\n" + " -dD -dM with -E: output #define directives\n" + " -pthread same as -D_REENTRANT and -lpthread\n" + " -On same as -D__OPTIMIZE__ for n > 0\n" + " -Wp,-opt same as -opt\n" + " -include file include 'file' above each input file\n" + " -isystem dir add 'dir' to system include path\n" + " -static link to static libraries (not recommended)\n" + " -dumpversion print version\n" + " -print-search-dirs print search paths\n" + " -dt with -run/-E: auto-define 'test_...' macros\n" + "Ignored options:\n" + " --param -pedantic -pipe -s -std -traditional\n" + "-W... warnings:\n" + " all turn on some (*) warnings\n" + " error stop after first warning\n" + " unsupported warn about ignored options, pragmas, etc.\n" + " write-strings strings are const\n" + " implicit-function-declaration warn for missing prototype (*)\n" + "-f[no-]... flags:\n" + " unsigned-char default char is unsigned\n" + " signed-char default char is signed\n" + " common use common section instead of bss\n" + " leading-underscore decorate extern symbols\n" + " ms-extensions allow anonymous struct in struct\n" + " dollars-in-identifiers allow '$' in C symbols\n" + "-m... target specific options:\n" + " ms-bitfields use MSVC bitfield layout\n" +#ifdef TCC_TARGET_ARM + " float-abi hard/softfp on arm\n" +#endif +#ifdef TCC_TARGET_X86_64 + " no-sse disable floats on x86_64\n" +#endif + "-Wl,... linker options:\n" + " -nostdlib do not link with standard crt/libs\n" + " -[no-]whole-archive load lib(s) fully/only as needed\n" + " -export-all-symbols same as -rdynamic\n" + " -image-base= -Ttext= set base address of executable\n" + " -section-alignment= set section alignment in executable\n" +#ifdef TCC_TARGET_PE + " -file-alignment= set PE file alignment\n" + " -stack= set PE stack reserve\n" + " -large-address-aware set related PE option\n" + " -subsystem=[console/windows] set PE subsystem\n" + " -oformat=[pe-* binary] set executable output format\n" + "Predefined macros:\n" + " tcc -E -dM - < nul\n" #else - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec * 1000000LL + tv.tv_usec; + " -rpath= set dynamic library search path\n" + " -enable-new-dtags set DT_RUNPATH instead of DT_RPATH\n" + " -soname= set DT_SONAME elf tag\n" + " -Bsymbolic set DT_SYMBOLIC elf tag\n" + " -oformat=[elf32/64-* binary] set executable output format\n" + " -init= -fini= -as-needed -O (ignored)\n" + "Predefined macros:\n" + " tcc -E -dM - < /dev/null\n" +#endif + "See also the manual for more details.\n" + ; + +static const char version[] = + "tcc version "TCC_VERSION" (" +#ifdef TCC_TARGET_I386 + "i386" +#elif defined TCC_TARGET_X86_64 + "x86_64" +#elif defined TCC_TARGET_C67 + "C67" +#elif defined TCC_TARGET_ARM + "ARM" +#elif defined TCC_TARGET_ARM64 + "AArch64" +#endif +#ifdef TCC_ARM_HARDFLOAT + " Hard Float" +#endif +#ifdef TCC_TARGET_PE + " Windows" +#elif defined(TCC_TARGET_MACHO) + " Darwin" +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + " FreeBSD" +#else + " Linux" #endif + ")\n" + ; + +static void print_dirs(const char *msg, char **paths, int nb_paths) +{ + int i; + printf("%s:\n%s", msg, nb_paths ? "" : " -\n"); + for(i = 0; i < nb_paths; i++) + printf(" %s\n", paths[i]); } -static int strstart(const char *str, const char *val, const char **ptr) +static void print_search_dirs(TCCState *s) { - const char *p, *q; - p = str; - q = val; - while (*q != '\0') { - if (*p != *q) - return 0; - p++; - q++; - } - if (ptr) - *ptr = p; - return 1; + printf("install: %s\n", s->tcc_lib_path); + /* print_dirs("programs", NULL, 0); */ + print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths); + print_dirs("libraries", s->library_paths, s->nb_library_paths); +#ifndef TCC_TARGET_PE + print_dirs("crt", s->crt_paths, s->nb_crt_paths); + printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path); + printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s)); +#endif } -/* convert 'str' into an array of space separated strings */ -static int expand_args(char ***pargv, const char *str) +static void set_environment(TCCState *s) { - const char *s1; - char **argv, *arg; - int argc, len; + char * path; - argc = 0; - argv = NULL; - for(;;) { - while (is_space(*str)) - str++; - if (*str == '\0') - break; - s1 = str; - while (*str != '\0' && !is_space(*str)) - str++; - len = str - s1; - arg = tcc_malloc(len + 1); - memcpy(arg, s1, len); - arg[len] = '\0'; - dynarray_add((void ***)&argv, &argc, arg); + path = getenv("C_INCLUDE_PATH"); + if(path != NULL) { + tcc_add_sysinclude_path(s, path); + } + path = getenv("CPATH"); + if(path != NULL) { + tcc_add_include_path(s, path); + } + path = getenv("LIBRARY_PATH"); + if(path != NULL) { + tcc_add_library_path(s, path); } - *pargv = argv; - return argc; } -int parse_args(TCCState *s, int argc, char **argv) +static char *default_outputfile(TCCState *s, const char *first_file) { - int optind; - const TCCOption *popt; - const char *optarg, *p1, *r1; - char *r; - - optind = 0; - while (optind < argc) { - - r = argv[optind++]; - if (r[0] != '-' || r[1] == '\0') { - /* add a new file */ - dynarray_add((void ***)&files, &nb_files, r); - if (!multiple_files) { - optind--; - /* argv[0] will be this file */ - break; - } - } else { - /* find option in table (match only the first chars */ - popt = tcc_options; - for(;;) { - p1 = popt->name; - if (p1 == NULL) - error("invalid option -- '%s'", r); - r1 = r + 1; - for(;;) { - if (*p1 == '\0') - goto option_found; - if (*r1 != *p1) - break; - p1++; - r1++; - } - popt++; - } - option_found: - if (popt->flags & TCC_OPTION_HAS_ARG) { - if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) { - optarg = r1; - } else { - if (optind >= argc) - error("argument to '%s' is missing", r); - optarg = argv[optind++]; - } - } else { - if (*r1 != '\0') - return 0; - optarg = NULL; - } - - switch(popt->index) { - case TCC_OPTION_HELP: - return 0; - - case TCC_OPTION_I: - if (tcc_add_include_path(s, optarg) < 0) - error("too many include paths"); - break; - case TCC_OPTION_D: - { - char *sym, *value; - sym = (char *)optarg; - value = strchr(sym, '='); - if (value) { - *value = '\0'; - value++; - } - tcc_define_symbol(s, sym, value); - } - break; - case TCC_OPTION_U: - tcc_undefine_symbol(s, optarg); - break; - case TCC_OPTION_L: - tcc_add_library_path(s, optarg); - break; - case TCC_OPTION_B: - /* set tcc utilities path (mainly for tcc development) */ - tcc_set_lib_path(s, optarg); - break; - case TCC_OPTION_l: - dynarray_add((void ***)&files, &nb_files, r); - nb_libraries++; - break; - case TCC_OPTION_bench: - do_bench = 1; - break; -#ifdef CONFIG_TCC_BACKTRACE - case TCC_OPTION_bt: - num_callers = atoi(optarg); - break; -#endif -#ifdef CONFIG_TCC_BCHECK - case TCC_OPTION_b: - s->do_bounds_check = 1; - s->do_debug = 1; - break; + char buf[1024]; + char *ext; + const char *name = "a"; + + if (first_file && strcmp(first_file, "-")) + name = tcc_basename(first_file); + snprintf(buf, sizeof(buf), "%s", name); + ext = tcc_fileextension(buf); +#ifdef TCC_TARGET_PE + if (s->output_type == TCC_OUTPUT_DLL) + strcpy(ext, ".dll"); + else + if (s->output_type == TCC_OUTPUT_EXE) + strcpy(ext, ".exe"); + else #endif - case TCC_OPTION_g: - s->do_debug = 1; - break; - case TCC_OPTION_c: - multiple_files = 1; - output_type = TCC_OUTPUT_OBJ; - break; - case TCC_OPTION_static: - s->static_link = 1; - break; - case TCC_OPTION_shared: - output_type = TCC_OUTPUT_DLL; - break; - case TCC_OPTION_soname: - s->soname = optarg; - break; - case TCC_OPTION_o: - multiple_files = 1; - outfile = optarg; - break; - case TCC_OPTION_r: - /* generate a .o merging several output files */ - reloc_output = 1; - output_type = TCC_OUTPUT_OBJ; - break; - case TCC_OPTION_nostdinc: - s->nostdinc = 1; - break; - case TCC_OPTION_nostdlib: - s->nostdlib = 1; - break; - case TCC_OPTION_print_search_dirs: - print_search_dirs = 1; - break; - case TCC_OPTION_run: - { - int argc1; - char **argv1; - argc1 = expand_args(&argv1, optarg); - if (argc1 > 0) { - parse_args(s, argc1, argv1); - } - multiple_files = 0; - output_type = TCC_OUTPUT_MEMORY; - } - break; - case TCC_OPTION_v: - do { - if (0 == s->verbose++) - printf("tcc version %s\n", TCC_VERSION); - } while (*optarg++ == 'v'); - break; - case TCC_OPTION_f: - if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported) - goto unsupported_option; - break; - case TCC_OPTION_W: - if (tcc_set_warning(s, optarg, 1) < 0 && - s->warn_unsupported) - goto unsupported_option; - break; - case TCC_OPTION_w: - s->warn_none = 1; - break; - case TCC_OPTION_rdynamic: - s->rdynamic = 1; - break; - case TCC_OPTION_Wl: - { - const char *p; - if (strstart(optarg, "-Ttext,", &p)) { - s->text_addr = strtoul(p, NULL, 16); - s->has_text_addr = 1; - } else if (strstart(optarg, "--oformat,", &p)) { - if (strstart(p, "elf32-", NULL)) { - s->output_format = TCC_OUTPUT_FORMAT_ELF; - } else if (!strcmp(p, "binary")) { - s->output_format = TCC_OUTPUT_FORMAT_BINARY; - } else -#ifdef TCC_TARGET_COFF - if (!strcmp(p, "coff")) { - s->output_format = TCC_OUTPUT_FORMAT_COFF; - } else + if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext) + strcpy(ext, ".o"); + else + strcpy(buf, "a.out"); + return tcc_strdup(buf); +} + +static unsigned getclock_ms(void) +{ +#ifdef _WIN32 + return GetTickCount(); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec*1000 + (tv.tv_usec+500)/1000; #endif - { - error("target %s not found", p); - } - } else { - error("unsupported linker option '%s'", optarg); - } - } - break; - case TCC_OPTION_E: - output_type = TCC_OUTPUT_PREPROCESS; - break; - default: - if (s->warn_unsupported) { - unsupported_option: - warning("unsupported option '%s'", r); - } - break; - } - } - } - return optind + 1; } -int main(int argc, char **argv) +int main(int argc0, char **argv0) { - int i; TCCState *s; - int nb_objfiles, ret, optind; - char objfilename[1024]; - int64_t start_time = 0; - + int ret, opt, n = 0, t = 0; + unsigned start_time = 0; + const char *first_file; + int argc; char **argv; + FILE *ppfp = stdout; + +redo: + argc = argc0, argv = argv0; s = tcc_new(); -#ifdef _WIN32 - tcc_set_lib_path_w32(s); + opt = tcc_parse_args(s, &argc, &argv, 1); + + if ((n | t) == 0) { + if (opt == OPT_HELP) + return printf(help), 1; + if (opt == OPT_HELP2) + return printf(help2), 1; + if (opt == OPT_M32 || opt == OPT_M64) + tcc_tool_cross(s, argv, opt); /* never returns */ + if (s->verbose) + printf(version); + if (opt == OPT_AR) + return tcc_tool_ar(s, argc, argv); +#ifdef TCC_TARGET_PE + if (opt == OPT_IMPDEF) + return tcc_tool_impdef(s, argc, argv); #endif - output_type = TCC_OUTPUT_EXE; - outfile = NULL; - multiple_files = 1; - files = NULL; - nb_files = 0; - nb_libraries = 0; - reloc_output = 0; - print_search_dirs = 0; - ret = 0; - - optind = parse_args(s, argc - 1, argv + 1); - if (print_search_dirs) { - /* enough for Linux kernel */ - printf("install: %s/\n", s->tcc_lib_path); - return 0; - } - if (optind == 0 || nb_files == 0) { - if (optind && s->verbose) + if (opt == OPT_V) return 0; - help(); - return 1; - } - - nb_objfiles = nb_files - nb_libraries; - - /* if outfile provided without other options, we output an - executable */ - if (outfile && output_type == TCC_OUTPUT_MEMORY) - output_type = TCC_OUTPUT_EXE; + if (opt == OPT_PRINT_DIRS) { + /* initialize search dirs */ + set_environment(s); + tcc_set_output_type(s, TCC_OUTPUT_MEMORY); + print_search_dirs(s); + return 0; + } - /* check -c consistency : only single file handled. XXX: checks file type */ - if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { - /* accepts only a single input file */ - if (nb_objfiles != 1) - error("cannot specify multiple files with -c"); - if (nb_libraries != 0) - error("cannot specify libraries with -c"); - } - + n = s->nb_files; + if (n == 0) + tcc_error("no input files\n"); - if (output_type == TCC_OUTPUT_PREPROCESS) { - if (!outfile) { - s->outfile = stdout; + if (s->output_type == TCC_OUTPUT_PREPROCESS) { + if (s->outfile) { + ppfp = fopen(s->outfile, "w"); + if (!ppfp) + tcc_error("could not write '%s'", s->outfile); + } + } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { + if (s->nb_libraries) + tcc_error("cannot specify libraries with -c"); + if (n > 1 && s->outfile) + tcc_error("cannot specify output file with -c many files"); } else { - s->outfile = fopen(outfile, "w"); - if (!s->outfile) - error("could not open '%s", outfile); - } - } else if (output_type != TCC_OUTPUT_MEMORY) { - if (!outfile) { - /* compute default outfile name */ - char *ext; - const char *name = - strcmp(files[0], "-") == 0 ? "a" : tcc_basename(files[0]); - pstrcpy(objfilename, sizeof(objfilename), name); - ext = tcc_fileextension(objfilename); -#ifdef TCC_TARGET_PE - if (output_type == TCC_OUTPUT_DLL) - strcpy(ext, ".dll"); - else - if (output_type == TCC_OUTPUT_EXE) - strcpy(ext, ".exe"); - else -#endif - if (output_type == TCC_OUTPUT_OBJ && !reloc_output && *ext) - strcpy(ext, ".o"); - else - pstrcpy(objfilename, sizeof(objfilename), "a.out"); - outfile = objfilename; + if (s->option_pthread) + tcc_set_options(s, "-lpthread"); } - } - if (do_bench) { - start_time = getclock_us(); + if (s->do_bench) + start_time = getclock_ms(); } - tcc_set_output_type(s, output_type); + set_environment(s); + if (s->output_type == 0) + s->output_type = TCC_OUTPUT_EXE; + tcc_set_output_type(s, s->output_type); + s->ppfp = ppfp; - /* compile or add each files or library */ - for(i = 0; i < nb_files && ret == 0; i++) { - const char *filename; + if ((s->output_type == TCC_OUTPUT_MEMORY + || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16)) + s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files; - filename = files[i]; - if (filename[0] == '-' && filename[1]) { - if (tcc_add_library(s, filename + 2) < 0) { - error_noabort("cannot find %s", filename); + /* compile or add each files or library */ + for (first_file = NULL, ret = 0;;) { + struct filespec *f = s->files[s->nb_files - n]; + s->filetype = f->type; + s->alacarte_link = f->alacarte; + if (f->type == AFF_TYPE_LIB) { + if (tcc_add_library_err(s, f->name) < 0) ret = 1; - } } else { if (1 == s->verbose) - printf("-> %s\n", filename); - if (tcc_add_file(s, filename) < 0) + printf("-> %s\n", f->name); + if (!first_file) + first_file = f->name; + if (tcc_add_file(s, f->name) < 0) ret = 1; } + s->filetype = 0; + s->alacarte_link = 1; + if (--n == 0 || ret + || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r)) + break; } - /* free all files */ - tcc_free(files); - - if (ret) - goto the_end; - - if (do_bench) - tcc_print_stats(s, getclock_us() - start_time); - - if (s->output_type == TCC_OUTPUT_PREPROCESS) { - if (outfile) - fclose(s->outfile); - } else if (s->output_type == TCC_OUTPUT_MEMORY) { - ret = tcc_run(s, argc - optind, argv + optind); - } else - ret = tcc_output_file(s, outfile) ? 1 : 0; - the_end: - /* XXX: cannot do it with bound checking because of the malloc hooks */ - if (!s->do_bounds_check) - tcc_delete(s); - -#ifdef MEM_DEBUG - if (do_bench) { - printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size); - } + if (s->run_test) { + t = 0; + } else if (s->output_type == TCC_OUTPUT_PREPROCESS) { + ; + } else if (0 == ret) { + if (s->output_type == TCC_OUTPUT_MEMORY) { +#ifdef TCC_IS_NATIVE + ret = tcc_run(s, argc, argv); #endif + } else { + if (!s->outfile) + s->outfile = default_outputfile(s, first_file); + if (tcc_output_file(s, s->outfile)) + ret = 1; + else if (s->gen_deps) + gen_makedeps(s, s->outfile, s->deps_outfile); + } + } + + if (s->do_bench && (n | t | ret) == 0) + tcc_print_stats(s, getclock_ms() - start_time); + tcc_delete(s); + if (ret == 0 && n) + goto redo; /* compile more files with -c */ + if (t) + goto redo; /* run more tests with -dt -run */ + if (ppfp && ppfp != stdout) + fclose(ppfp); return ret; } - diff --git a/tinyc/tcc.h b/tinyc/tcc.h index be9c4ccb0..da26298fb 100644 --- a/tinyc/tcc.h +++ b/tinyc/tcc.h @@ -1,6 +1,6 @@ /* * TCC - Tiny C Compiler - * + * * Copyright (c) 2001-2004 Fabrice Bellard * * This library is free software; you can redistribute it and/or @@ -18,123 +18,361 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef _TCC_H +#define _TCC_H + #define _GNU_SOURCE #include "config.h" -#ifdef CONFIG_TCCBOOT - -#include "tccboot.h" -#define CONFIG_TCC_STATIC - -#else - #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include <string.h> #include <errno.h> #include <math.h> -#include <signal.h> #include <fcntl.h> #include <setjmp.h> #include <time.h> +#ifndef _WIN32 +# include <unistd.h> +# include <sys/time.h> +# ifndef CONFIG_TCC_STATIC +# include <dlfcn.h> +# endif +/* XXX: need to define this to use them in non ISOC99 context */ +extern float strtof (const char *__nptr, char **__endptr); +extern long double strtold (const char *__nptr, char **__endptr); +#endif + #ifdef _WIN32 -#include <windows.h> -#include <sys/timeb.h> -#include <io.h> /* open, close etc. */ -#include <direct.h> /* getcwd */ -#define inline __inline -#define inp next_inp +# include <windows.h> +# include <io.h> /* open, close etc. */ +# include <direct.h> /* getcwd */ +# ifdef __GNUC__ +# include <stdint.h> +# endif +# define inline __inline +# define snprintf _snprintf +# define vsnprintf _vsnprintf +# ifndef __GNUC__ +# define strtold (long double)strtod +# define strtof (float)strtod +# define strtoll _strtoi64 +# define strtoull _strtoui64 +# endif +# ifdef LIBTCC_AS_DLL +# define LIBTCCAPI __declspec(dllexport) +# define PUB_FUNC LIBTCCAPI +# endif +# define inp next_inp /* inp is an intrinsic on msvc/mingw */ +# ifdef _MSC_VER +# pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data +# pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data +# pragma warning (disable : 4996) // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name +# pragma warning (disable : 4018) // signed/unsigned mismatch +# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned +# define ssize_t intptr_t +# endif +# undef CONFIG_TCC_STATIC #endif -#ifndef _WIN32 -#include <unistd.h> -#include <sys/time.h> -#include <sys/ucontext.h> -#include <sys/mman.h> +#ifndef O_BINARY +# define O_BINARY 0 #endif -#endif /* !CONFIG_TCCBOOT */ +#ifndef offsetof +#define offsetof(type, field) ((size_t) &((type *)0)->field) +#endif -#ifndef PAGESIZE -#define PAGESIZE 4096 +#ifndef countof +#define countof(tab) (sizeof(tab) / sizeof((tab)[0])) #endif -#include "elf.h" -#include "stab.h" +#ifdef _MSC_VER +# define NORETURN __declspec(noreturn) +# define ALIGNED(x) __declspec(align(x)) +#else +# define NORETURN __attribute__((noreturn)) +# define ALIGNED(x) __attribute__((aligned(x))) +#endif -#ifndef O_BINARY -#define O_BINARY 0 +#ifdef _WIN32 +# define IS_DIRSEP(c) (c == '/' || c == '\\') +# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2]))) +# define PATHCMP stricmp +# define PATHSEP ";" +#else +# define IS_DIRSEP(c) (c == '/') +# define IS_ABSPATH(p) IS_DIRSEP(p[0]) +# define PATHCMP strcmp +# define PATHSEP ":" #endif -#include "libtcc.h" +/* -------------------------------------------- */ /* parser debug */ -//#define PARSE_DEBUG +/* #define PARSE_DEBUG */ /* preprocessor debug */ -//#define PP_DEBUG +/* #define PP_DEBUG */ /* include file debug */ -//#define INC_DEBUG - -//#define MEM_DEBUG - +/* #define INC_DEBUG */ +/* memory leak debug */ +/* #define MEM_DEBUG */ /* assembler debug */ -//#define ASM_DEBUG +/* #define ASM_DEBUG */ /* target selection */ -//#define TCC_TARGET_I386 /* i386 code generator */ -//#define TCC_TARGET_ARM /* ARMv4 code generator */ -//#define TCC_TARGET_C67 /* TMS320C67xx code generator */ -//#define TCC_TARGET_X86_64 /* x86-64 code generator */ +/* #define TCC_TARGET_I386 *//* i386 code generator */ +/* #define TCC_TARGET_X86_64 *//* x86-64 code generator */ +/* #define TCC_TARGET_ARM *//* ARMv4 code generator */ +/* #define TCC_TARGET_ARM64 *//* ARMv8 code generator */ +/* #define TCC_TARGET_C67 *//* TMS320C67xx code generator */ /* default target is I386 */ #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ - !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64) -#define TCC_TARGET_I386 + !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ + !defined(TCC_TARGET_X86_64) +# if defined __x86_64__ || defined _AMD64_ +# define TCC_TARGET_X86_64 +# elif defined __arm__ +# define TCC_TARGET_ARM +# define TCC_ARM_EABI +# define TCC_ARM_HARDFLOAT +# elif defined __aarch64__ +# define TCC_TARGET_ARM64 +# else +# define TCC_TARGET_I386 +# endif +# ifdef _WIN32 +# define TCC_TARGET_PE 1 +# endif #endif -#if !defined(_WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \ - !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64) -#define CONFIG_TCC_BCHECK /* enable bound checking code */ +/* only native compiler supports -run */ +#if defined _WIN32 == defined TCC_TARGET_PE +# if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386 +# define TCC_IS_NATIVE +# elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64 +# define TCC_IS_NATIVE +# elif defined __arm__ && defined TCC_TARGET_ARM +# define TCC_IS_NATIVE +# elif defined __aarch64__ && defined TCC_TARGET_ARM64 +# define TCC_IS_NATIVE +# endif #endif -#if defined(_WIN32) && !defined(TCC_TARGET_PE) -#define CONFIG_TCC_STATIC +#if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT +# define CONFIG_TCC_BACKTRACE +# if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) \ + && !defined TCC_UCLIBC && !defined TCC_MUSL +# define CONFIG_TCC_BCHECK /* enable bound checking code */ +# endif #endif -/* define it to include assembler support */ -#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) && \ - !defined(TCC_TARGET_X86_64) -#define CONFIG_TCC_ASM +/* ------------ path configuration ------------ */ + +#ifndef CONFIG_SYSROOT +# define CONFIG_SYSROOT "" +#endif +#ifndef CONFIG_TCCDIR +# define CONFIG_TCCDIR "/usr/local/lib/tcc" +#endif +#ifndef CONFIG_LDDIR +# define CONFIG_LDDIR "lib" +#endif +#ifdef CONFIG_TRIPLET +# define USE_TRIPLET(s) s "/" CONFIG_TRIPLET +# define ALSO_TRIPLET(s) USE_TRIPLET(s) ":" s +#else +# define USE_TRIPLET(s) s +# define ALSO_TRIPLET(s) s +#endif + +/* path to find crt1.o, crti.o and crtn.o */ +#ifndef CONFIG_TCC_CRTPREFIX +# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) +#endif + +/* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */ + +/* system include paths */ +#ifndef CONFIG_TCC_SYSINCLUDEPATHS +# ifdef TCC_TARGET_PE +# define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi" +# else +# define CONFIG_TCC_SYSINCLUDEPATHS \ + "{B}/include" \ + ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \ + ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include") +# endif +#endif + +/* library search paths */ +#ifndef CONFIG_TCC_LIBPATHS +# ifdef TCC_TARGET_PE +# define CONFIG_TCC_LIBPATHS "{B}/lib" +# else +# define CONFIG_TCC_LIBPATHS \ + ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \ + ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \ + ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR) +# endif +#endif + +/* name of ELF interpreter */ +#ifndef CONFIG_TCC_ELFINTERP +# if defined __FreeBSD__ +# define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1" +# elif defined __FreeBSD_kernel__ +# if defined(TCC_TARGET_X86_64) +# define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1" +# else +# define CONFIG_TCC_ELFINTERP "/lib/ld.so.1" +# endif +# elif defined __DragonFly__ +# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2" +# elif defined __NetBSD__ +# define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so" +# elif defined __GNU__ +# define CONFIG_TCC_ELFINTERP "/lib/ld.so" +# elif defined(TCC_TARGET_PE) +# define CONFIG_TCC_ELFINTERP "-" +# elif defined(TCC_UCLIBC) +# define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */ +# elif defined TCC_TARGET_ARM64 +# if defined(TCC_MUSL) +# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1" +# else +# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1" +# endif +# elif defined(TCC_TARGET_X86_64) +# if defined(TCC_MUSL) +# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1" +# else +# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2" +# endif +# elif !defined(TCC_ARM_EABI) +# if defined(TCC_MUSL) +# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1" +# else +# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2" +# endif +# endif +#endif + +/* var elf_interp dans *-gen.c */ +#ifdef CONFIG_TCC_ELFINTERP +# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP +#else +# define DEFAULT_ELFINTERP(s) default_elfinterp(s) #endif -/* object format selection */ -#if defined(TCC_TARGET_C67) -#define TCC_TARGET_COFF +/* (target specific) libtcc1.a */ +#ifndef TCC_LIBTCC1 +# define TCC_LIBTCC1 "libtcc1.a" #endif -#if !defined(_WIN32) && !defined(CONFIG_TCCBOOT) -#define CONFIG_TCC_BACKTRACE +/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */ +#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC +#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1" +#endif + +/* -------------------------------------------- */ + +#include "libtcc.h" +#include "elf.h" +#include "stab.h" + +/* -------------------------------------------- */ + +#ifndef PUB_FUNC /* functions used by tcc.c but not in libtcc.h */ +# define PUB_FUNC +#endif + +#ifndef ONE_SOURCE +# define ONE_SOURCE 1 +#endif + +#if ONE_SOURCE +#define ST_INLN static inline +#define ST_FUNC static +#define ST_DATA static +#else +#define ST_INLN +#define ST_FUNC +#define ST_DATA extern +#endif + +#ifdef TCC_PROFILE /* profile all functions */ +# define static +#endif + +/* -------------------------------------------- */ +/* include the target specific definitions */ + +#define TARGET_DEFS_ONLY +#ifdef TCC_TARGET_I386 +# include "i386-gen.c" +# include "i386-link.c" +#endif +#ifdef TCC_TARGET_X86_64 +# include "x86_64-gen.c" +# include "x86_64-link.c" +#endif +#ifdef TCC_TARGET_ARM +# include "arm-gen.c" +# include "arm-link.c" +# include "arm-asm.c" +#endif +#ifdef TCC_TARGET_ARM64 +# include "arm64-gen.c" +# include "arm64-link.c" +#endif +#ifdef TCC_TARGET_C67 +# define TCC_TARGET_COFF +# include "coff.h" +# include "c67-gen.c" +# include "c67-link.c" +#endif +#undef TARGET_DEFS_ONLY + +/* -------------------------------------------- */ + +#if PTR_SIZE == 8 +# define ELFCLASSW ELFCLASS64 +# define ElfW(type) Elf##64##_##type +# define ELFW(type) ELF##64##_##type +# define ElfW_Rel ElfW(Rela) +# define SHT_RELX SHT_RELA +# define REL_SECTION_FMT ".rela%s" +#else +# define ELFCLASSW ELFCLASS32 +# define ElfW(type) Elf##32##_##type +# define ELFW(type) ELF##32##_##type +# define ElfW_Rel ElfW(Rel) +# define SHT_RELX SHT_REL +# define REL_SECTION_FMT ".rel%s" #endif +/* target address type */ +#define addr_t ElfW(Addr) -#define FALSE 0 -#define false 0 -#define TRUE 1 -#define true 1 -typedef int BOOL; +#if PTR_SIZE == 8 && !defined TCC_TARGET_PE +# define LONG_SIZE 8 +#else +# define LONG_SIZE 4 +#endif -/* path to find crt1.o, crti.o and crtn.o. Only needed when generating - executables or dlls */ -#define CONFIG_TCC_CRT_PREFIX CONFIG_SYSROOT "/usr/lib" +/* -------------------------------------------- */ #define INCLUDE_STACK_SIZE 32 #define IFDEF_STACK_SIZE 64 #define VSTACK_SIZE 256 #define STRING_MAX_SIZE 1024 +#define TOKSTR_MAX_SIZE 256 #define PACK_STACK_SIZE 8 -#define TOK_HASH_SIZE 8192 /* must be a power of two */ +#define TOK_HASH_SIZE 16384 /* must be a power of two */ #define TOK_ALLOC_INCR 512 /* must be a power of two */ #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */ @@ -160,7 +398,6 @@ typedef struct CString { int size; /* size in bytes */ void *data; /* either 'char *' or 'nwchar_t *' */ int size_allocated; - void *data_allocated; /* if non NULL, data has been malloced */ } CString; /* type definition */ @@ -174,14 +411,12 @@ typedef union CValue { long double ld; double d; float f; - int i; - unsigned int ui; - unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */ - long long ll; - unsigned long long ull; - struct CString *cstr; - void *ptr; - int tab[1]; + uint64_t i; + struct { + int size; + const void *data; + } str; + int tab[LDOUBLE_SIZE/4]; } CValue; /* value on stack */ @@ -191,16 +426,64 @@ typedef struct SValue { unsigned short r2; /* second register, used for 'long long' type. If not used, set to VT_CONST */ CValue c; /* constant, if VT_CONST */ - struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */ + struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST), or if + result of unary() for an identifier. */ } SValue; +/* symbol attributes */ +struct SymAttr { + unsigned short + aligned : 5, /* alignment as log2+1 (0 == unspecified) */ + packed : 1, + weak : 1, + visibility : 2, + dllexport : 1, + dllimport : 1, + unused : 5; +}; + +/* function attributes or temporary attributes for parsing */ +struct FuncAttr { + unsigned + func_call : 3, /* calling convention (0..5), see below */ + func_type : 2, /* FUNC_OLD/NEW/ELLIPSIS */ + func_body : 1, /* body was defined */ + func_args : 8; /* PE __stdcall args */ +}; + +/* GNUC attribute definition */ +typedef struct AttributeDef { + struct SymAttr a; + struct FuncAttr f; + struct Section *section; + int alias_target; /* token */ + int asm_label; /* associated asm label */ + char attr_mode; /* __attribute__((__mode__(...))) */ +} AttributeDef; + /* symbol management */ typedef struct Sym { - int v; /* symbol token */ - long r; /* associated register */ - long c; /* associated number */ - CType type; /* associated type */ - struct Sym *next; /* next related symbol */ + int v; /* symbol token */ + unsigned short r; /* associated register or VT_CONST/VT_LOCAL and LVAL type */ + struct SymAttr a; /* symbol attributes */ + union { + struct { + int c; /* associated number or Elf symbol index */ + union { + int sym_scope; /* scope level for locals */ + int jnext; /* next jump label */ + struct FuncAttr f; /* function attributes */ + int auxtype; /* bitfield access type */ + }; + }; + long long enum_val; /* enum constant if IS_ENUM_VAL */ + int *d; /* define token stream */ + }; + CType type; /* associated type */ + union { + struct Sym *next; /* next related symbol (for fields and anoms) */ + int asm_label; /* associated asm label */ + }; struct Sym *prev; /* prev symbol in stack */ struct Sym *prev_tok; /* previous symbol for this token */ } Sym; @@ -226,13 +509,13 @@ typedef struct Section { int sh_addralign; /* elf section alignment */ int sh_entsize; /* elf entry size */ unsigned long sh_size; /* section size (only used during output) */ - unsigned long sh_addr; /* address at which the section is relocated */ - unsigned long sh_offset; /* file offset */ + addr_t sh_addr; /* address at which the section is relocated */ + unsigned long sh_offset; /* file offset */ int nb_hashed_syms; /* used to resize the hash table */ struct Section *link; /* link to another section */ struct Section *reloc; /* corresponding section for relocation, if any */ - struct Section *hash; /* hash table for symbols */ - struct Section *next; + struct Section *hash; /* hash table for symbols */ + struct Section *prev; /* previous section on section stack */ char name[1]; /* section name */ } Section; @@ -242,39 +525,18 @@ typedef struct DLLReference { char name[1]; } DLLReference; -/* GNUC attribute definition */ -typedef struct AttributeDef { - int aligned; - int packed; - Section *section; - int func_attr; /* calling convention, exports, ... */ -} AttributeDef; - -/* -------------------------------------------------- */ -/* gr: wrappers for casting sym->r for other purposes */ -typedef struct { - unsigned - func_call : 8, - func_args : 8, - func_export : 1; -} func_attr_t; - -#define FUNC_CALL(r) (((func_attr_t*)&(r))->func_call) -#define FUNC_EXPORT(r) (((func_attr_t*)&(r))->func_export) -#define FUNC_ARGS(r) (((func_attr_t*)&(r))->func_args) -#define INLINE_DEF(r) (*(int **)&(r)) /* -------------------------------------------------- */ #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */ #define SYM_FIELD 0x20000000 /* struct/union field symbol space */ #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */ -/* stored in 'Sym.c' field */ +/* stored in 'Sym->f.func_type' field */ #define FUNC_NEW 1 /* ansi function prototype */ #define FUNC_OLD 2 /* old function prototype */ #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */ -/* stored in 'Sym.r' field */ +/* stored in 'Sym->f.func_call' field */ #define FUNC_CDECL 0 /* standard c call */ #define FUNC_STDCALL 1 /* pascal c call */ #define FUNC_FASTCALL1 2 /* first param in %eax */ @@ -301,56 +563,64 @@ typedef struct BufferedFile { uint8_t *buf_ptr; uint8_t *buf_end; int fd; + struct BufferedFile *prev; int line_num; /* current line number - here to simplify code */ + int line_ref; /* tcc -E: last printed line */ int ifndef_macro; /* #ifndef macro / #endif search */ int ifndef_macro_saved; /* saved ifndef_macro */ int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */ - char inc_type; /* type of include */ - char inc_filename[512]; /* filename specified by the user */ - char filename[1024]; /* current filename - here to simplify code */ - unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */ + int include_next_index; /* next search path */ + char filename[1024]; /* filename */ + char *true_filename; /* filename not modified by # line directive */ + unsigned char unget[4]; + unsigned char buffer[1]; /* extra size for CH_EOB char */ } BufferedFile; #define CH_EOB '\\' /* end of buffer or '\0' char in file */ #define CH_EOF (-1) /* end of file */ -/* parsing state (used to save parser state to reparse part of the - source several times) */ -typedef struct ParseState { - int *macro_ptr; - int line_num; - int tok; - CValue tokc; -} ParseState; - /* used to record tokens */ typedef struct TokenString { int *str; int len; + int lastlen; int allocated_len; int last_line_num; + int save_line_num; + /* used to chain token-strings with begin/end_macro() */ + struct TokenString *prev; + const int *prev_ptr; + char alloc; } TokenString; +/* inline functions */ +typedef struct InlineFunc { + TokenString *func_str; + Sym *sym; + char filename[1]; +} InlineFunc; + /* include file cache, used to find files faster and also to eliminate inclusion if the include file is protected by #ifndef ... #endif */ typedef struct CachedInclude { int ifndef_macro; + int once; int hash_next; /* -1 if none */ - char type; /* '"' or '>' to give include type */ char filename[1]; /* path specified in #include */ } CachedInclude; -#define CACHED_INCLUDES_HASH_SIZE 512 +#define CACHED_INCLUDES_HASH_SIZE 32 #ifdef CONFIG_TCC_ASM typedef struct ExprValue { - uint32_t v; + uint64_t v; Sym *sym; + int pcrel; } ExprValue; #define MAX_ASM_OPERANDS 30 typedef struct ASMOperand { - int id; /* GCC 3 optionnal identifier (0 if number only supported */ + int id; /* GCC 3 optional identifier (0 if number only supported */ char *constraint; char asm_str[16]; /* computed asm string for operand */ SValue *vt; /* C value of the expression */ @@ -362,93 +632,103 @@ typedef struct ASMOperand { int is_memory; /* true if memory operand */ int is_rw; /* for '+' modifier */ } ASMOperand; +#endif +/* extra symbol attributes (not in symbol table) */ +struct sym_attr { + unsigned got_offset; + unsigned plt_offset; + int plt_sym; + int dyn_index; +#ifdef TCC_TARGET_ARM + unsigned char plt_thumb_stub:1; #endif +}; struct TCCState { - int output_type; - - BufferedFile **include_stack_ptr; - int *ifdef_stack_ptr; - - /* include file handling */ - char **include_paths; - int nb_include_paths; - char **sysinclude_paths; - int nb_sysinclude_paths; - CachedInclude **cached_includes; - int nb_cached_includes; - - char **library_paths; - int nb_library_paths; - - /* array of all loaded dlls (including those referenced by loaded - dlls) */ - DLLReference **loaded_dlls; - int nb_loaded_dlls; - - /* sections */ - Section **sections; - int nb_sections; /* number of sections, including first dummy section */ - - Section **priv_sections; - int nb_priv_sections; /* number of private sections */ - - /* got handling */ - Section *got; - Section *plt; - unsigned long *got_offsets; - int nb_got_offsets; - /* give the correspondance from symtab indexes to dynsym indexes */ - int *symtab_to_dynsym; - - /* temporary dynamic symbol sections (for dll loading) */ - Section *dynsymtab_section; - /* exported dynamic symbol section */ - Section *dynsym; + int verbose; /* if true, display some information during compilation */ int nostdinc; /* if true, no standard headers are added */ int nostdlib; /* if true, no standard libraries are added */ int nocommon; /* if true, do not use common symbols for .bss data */ + int static_link; /* if true, static linking is performed */ + int rdynamic; /* if true, all symbols are exported */ + int symbolic; /* if true, resolve symbols in the current module first */ + int alacarte_link; /* if true, only link in referenced objects from archive */ - /* if true, static linking is performed */ - int static_link; - - /* soname as specified on the command line (-soname) */ - const char *soname; - - /* if true, all symbols are exported */ - int rdynamic; + char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */ + char *soname; /* as specified on the command line (-soname) */ + char *rpath; /* as specified on the command line (-Wl,-rpath=) */ + int enable_new_dtags; /* ditto, (-Wl,--enable-new-dtags) */ - /* if true, only link in referenced objects from archive */ - int alacarte_link; - - /* address of text section */ - unsigned long text_addr; - int has_text_addr; - + /* output type, see TCC_OUTPUT_XXX */ + int output_type; /* output format, see TCC_OUTPUT_FORMAT_xxx */ int output_format; /* C language options */ int char_is_unsigned; int leading_underscore; - + int ms_extensions; /* allow nested named struct w/o identifier behave like unnamed */ + int dollars_in_identifiers; /* allows '$' char in identifiers */ + int ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */ + /* warning switches */ int warn_write_strings; int warn_unsupported; int warn_error; int warn_none; int warn_implicit_function_declaration; + int warn_gcc_compat; - /* display some information during compilation */ - int verbose; /* compile with debug symbol (and use them if error during execution) */ int do_debug; +#ifdef CONFIG_TCC_BCHECK /* compile with built-in memory and bounds checker */ int do_bounds_check; - /* give the path of the tcc libraries */ - const char *tcc_lib_path; +#endif +#ifdef TCC_TARGET_ARM + enum float_abi float_abi; /* float ABI of the generated code*/ +#endif + int run_test; /* nth test to run with -dt -run */ + + addr_t text_addr; /* address of text section */ + int has_text_addr; + + unsigned section_align; /* section alignment */ + + char *init_symbol; /* symbols to call at load-time (not used currently) */ + char *fini_symbol; /* symbols to call at unload-time (not used currently) */ + +#ifdef TCC_TARGET_I386 + int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */ +#endif +#ifdef TCC_TARGET_X86_64 + int nosse; /* For -mno-sse support. */ +#endif + + /* array of all loaded dlls (including those referenced by loaded dlls) */ + DLLReference **loaded_dlls; + int nb_loaded_dlls; + + /* include paths */ + char **include_paths; + int nb_include_paths; + + char **sysinclude_paths; + int nb_sysinclude_paths; + + /* library paths */ + char **library_paths; + int nb_library_paths; + + /* crt?.o object path */ + char **crt_paths; + int nb_crt_paths; + + /* -include files */ + char **cmd_include_files; + int nb_cmd_include_files; /* error handling */ void *error_opaque; @@ -457,44 +737,114 @@ struct TCCState { jmp_buf error_jmp_buf; int nb_errors; - /* tiny assembler state */ - Sym *asm_labels; - - /* see include_stack_ptr */ + /* output file for preprocessing (-E) */ + FILE *ppfp; + enum { + LINE_MACRO_OUTPUT_FORMAT_GCC, + LINE_MACRO_OUTPUT_FORMAT_NONE, + LINE_MACRO_OUTPUT_FORMAT_STD, + LINE_MACRO_OUTPUT_FORMAT_P10 = 11 + } Pflag; /* -P switch */ + char dflag; /* -dX value */ + + /* for -MD/-MF: collected dependencies for this compilation */ + char **target_deps; + int nb_target_deps; + + /* compilation */ BufferedFile *include_stack[INCLUDE_STACK_SIZE]; + BufferedFile **include_stack_ptr; - /* see ifdef_stack_ptr */ int ifdef_stack[IFDEF_STACK_SIZE]; + int *ifdef_stack_ptr; - /* see cached_includes */ + /* included files enclosed with #ifndef MACRO */ int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE]; + CachedInclude **cached_includes; + int nb_cached_includes; - /* pack stack */ + /* #pragma pack stack */ int pack_stack[PACK_STACK_SIZE]; int *pack_stack_ptr; + char **pragma_libs; + int nb_pragma_libs; - /* output file for preprocessing */ - FILE *outfile; + /* inline functions are stored as token lists and compiled last + only if referenced */ + struct InlineFunc **inline_fns; + int nb_inline_fns; - /* for tcc_relocate */ - int runtime_added; + /* sections */ + Section **sections; + int nb_sections; /* number of sections, including first dummy section */ -#ifdef TCC_TARGET_X86_64 - /* write PLT and GOT here */ - char *runtime_plt_and_got; - unsigned int runtime_plt_and_got_offset; + Section **priv_sections; + int nb_priv_sections; /* number of private sections */ + + /* got & plt handling */ + Section *got; + Section *plt; + + /* temporary dynamic symbol sections (for dll loading) */ + Section *dynsymtab_section; + /* exported dynamic symbol section */ + Section *dynsym; + /* copy of the global symtab_section variable */ + Section *symtab; + /* extra attributes (eg. GOT/PLT value) for symtab symbols */ + struct sym_attr *sym_attrs; + int nb_sym_attrs; + /* tiny assembler state */ + Sym *asm_labels; + +#ifdef TCC_TARGET_PE + /* PE info */ + int pe_subsystem; + unsigned pe_characteristics; + unsigned pe_file_align; + unsigned pe_stack_size; +# ifdef TCC_TARGET_X86_64 + Section *uw_pdata; + int uw_sym; + unsigned uw_offs; +# endif +#endif + +#ifdef TCC_IS_NATIVE + const char *runtime_main; + void **runtime_mem; + int nb_runtime_mem; #endif + + /* used by main and tcc_parse_args only */ + struct filespec **files; /* files seen on command line */ + int nb_files; /* number thereof */ + int nb_libraries; /* number of libs thereof */ + int filetype; + char *outfile; /* output filename */ + int option_r; /* option -r */ + int do_bench; /* option -bench */ + int gen_deps; /* option -MD */ + char *deps_outfile; /* option -MF */ + int option_pthread; /* -pthread option */ + int argc; + char **argv; +}; + +struct filespec { + char type; + char alacarte; + char name[1]; }; /* The current value can be: */ -#define VT_VALMASK 0x00ff -#define VT_CONST 0x00f0 /* constant in vc - (must be first non register value) */ -#define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */ -#define VT_LOCAL 0x00f2 /* offset on stack */ -#define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */ -#define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */ -#define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */ +#define VT_VALMASK 0x003f /* mask for value location, register or: */ +#define VT_CONST 0x0030 /* constant in vc (must be first non register value) */ +#define VT_LLOCAL 0x0031 /* lvalue, offset on stack */ +#define VT_LOCAL 0x0032 /* offset on stack */ +#define VT_CMP 0x0033 /* the value is stored in processor flags (in vc) */ +#define VT_JMP 0x0034 /* value is the consequence of jmp true (even) */ +#define VT_JMPI 0x0035 /* value is the consequence of jmp false (odd) */ #define VT_LVAL 0x0100 /* var is an lvalue */ #define VT_SYM 0x0200 /* a symbol value is added */ #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for @@ -509,40 +859,54 @@ struct TCCState { #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED) /* types */ -#define VT_INT 0 /* integer type */ -#define VT_BYTE 1 /* signed byte type */ -#define VT_SHORT 2 /* short type */ -#define VT_VOID 3 /* void type */ -#define VT_PTR 4 /* pointer */ -#define VT_ENUM 5 /* enum definition */ -#define VT_FUNC 6 /* function type */ -#define VT_STRUCT 7 /* struct/union definition */ -#define VT_FLOAT 8 /* IEEE float */ -#define VT_DOUBLE 9 /* IEEE double */ -#define VT_LDOUBLE 10 /* IEEE long double */ -#define VT_BOOL 11 /* ISOC99 boolean type */ -#define VT_LLONG 12 /* 64 bit integer */ -#define VT_LONG 13 /* long integer (NEVER USED as type, only - during parsing) */ -#define VT_BTYPE 0x000f /* mask for basic type */ -#define VT_UNSIGNED 0x0010 /* unsigned type */ -#define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */ -#define VT_BITFIELD 0x0040 /* bitfield modifier */ -#define VT_CONSTANT 0x0800 /* const modifier */ -#define VT_VOLATILE 0x1000 /* volatile modifier */ -#define VT_SIGNED 0x2000 /* signed type */ +#define VT_BTYPE 0x000f /* mask for basic type */ +#define VT_VOID 0 /* void type */ +#define VT_BYTE 1 /* signed byte type */ +#define VT_SHORT 2 /* short type */ +#define VT_INT 3 /* integer type */ +#define VT_LLONG 4 /* 64 bit integer */ +#define VT_PTR 5 /* pointer */ +#define VT_FUNC 6 /* function type */ +#define VT_STRUCT 7 /* struct/union definition */ +#define VT_FLOAT 8 /* IEEE float */ +#define VT_DOUBLE 9 /* IEEE double */ +#define VT_LDOUBLE 10 /* IEEE long double */ +#define VT_BOOL 11 /* ISOC99 boolean type */ +#define VT_QLONG 13 /* 128-bit integer. Only used for x86-64 ABI */ +#define VT_QFLOAT 14 /* 128-bit float. Only used for x86-64 ABI */ + +#define VT_UNSIGNED 0x0010 /* unsigned type */ +#define VT_DEFSIGN 0x0020 /* explicitly signed or unsigned */ +#define VT_ARRAY 0x0040 /* array type (also has VT_PTR) */ +#define VT_BITFIELD 0x0080 /* bitfield modifier */ +#define VT_CONSTANT 0x0100 /* const modifier */ +#define VT_VOLATILE 0x0200 /* volatile modifier */ +#define VT_VLA 0x0400 /* VLA type (also has VT_PTR and VT_ARRAY) */ +#define VT_LONG 0x0800 /* long type (also has VT_INT rsp. VT_LLONG) */ /* storage */ -#define VT_EXTERN 0x00000080 /* extern definition */ -#define VT_STATIC 0x00000100 /* static variable */ -#define VT_TYPEDEF 0x00000200 /* typedef definition */ -#define VT_INLINE 0x00000400 /* inline definition */ +#define VT_EXTERN 0x00001000 /* extern definition */ +#define VT_STATIC 0x00002000 /* static variable */ +#define VT_TYPEDEF 0x00004000 /* typedef definition */ +#define VT_INLINE 0x00008000 /* inline definition */ +/* currently unused: 0x000[1248]0000 */ + +#define VT_STRUCT_SHIFT 20 /* shift for bitfield shift values (32 - 2*6) */ +#define VT_STRUCT_MASK (((1 << (6+6)) - 1) << VT_STRUCT_SHIFT | VT_BITFIELD) +#define BIT_POS(t) (((t) >> VT_STRUCT_SHIFT) & 0x3f) +#define BIT_SIZE(t) (((t) >> (VT_STRUCT_SHIFT + 6)) & 0x3f) -#define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ +#define VT_UNION (1 << VT_STRUCT_SHIFT | VT_STRUCT) +#define VT_ENUM (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */ +#define VT_ENUM_VAL (3 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */ + +#define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM) +#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL) +#define IS_UNION(t) ((t & (VT_STRUCT_MASK|VT_BTYPE)) == VT_UNION) /* type mask (except storage) */ #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE) -#define VT_TYPE (~(VT_STORAGE)) +#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK)) /* token values */ @@ -562,40 +926,50 @@ struct TCCState { #define TOK_LAND 0xa0 #define TOK_LOR 0xa1 - #define TOK_DEC 0xa2 #define TOK_MID 0xa3 /* inc/dec, to void constant */ #define TOK_INC 0xa4 #define TOK_UDIV 0xb0 /* unsigned division */ #define TOK_UMOD 0xb1 /* unsigned modulo */ #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */ -#define TOK_CINT 0xb3 /* number in tokc */ -#define TOK_CCHAR 0xb4 /* char constant in tokc */ -#define TOK_STR 0xb5 /* pointer to string in tokc */ -#define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */ -#define TOK_LCHAR 0xb7 -#define TOK_LSTR 0xb8 -#define TOK_CFLOAT 0xb9 /* float constant */ -#define TOK_LINENUM 0xba /* line number info */ -#define TOK_CDOUBLE 0xc0 /* double constant */ -#define TOK_CLDOUBLE 0xc1 /* long double constant */ + +/* tokens that carry values (in additional token string space / tokc) --> */ +#define TOK_CCHAR 0xb3 /* char constant in tokc */ +#define TOK_LCHAR 0xb4 +#define TOK_CINT 0xb5 /* number in tokc */ +#define TOK_CUINT 0xb6 /* unsigned int constant */ +#define TOK_CLLONG 0xb7 /* long long constant */ +#define TOK_CULLONG 0xb8 /* unsigned long long constant */ +#define TOK_STR 0xb9 /* pointer to string in tokc */ +#define TOK_LSTR 0xba +#define TOK_CFLOAT 0xbb /* float constant */ +#define TOK_CDOUBLE 0xbc /* double constant */ +#define TOK_CLDOUBLE 0xbd /* long double constant */ +#define TOK_PPNUM 0xbe /* preprocessor number */ +#define TOK_PPSTR 0xbf /* preprocessor string */ +#define TOK_LINENUM 0xc0 /* line number info */ +#define TOK_TWODOTS 0xa8 /* C++ token ? */ +/* <-- */ + #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */ #define TOK_ADDC1 0xc3 /* add with carry generation */ #define TOK_ADDC2 0xc4 /* add with carry use */ #define TOK_SUBC1 0xc5 /* add with carry generation */ #define TOK_SUBC2 0xc6 /* add with carry use */ -#define TOK_CUINT 0xc8 /* unsigned int constant */ -#define TOK_CLLONG 0xc9 /* long long constant */ -#define TOK_CULLONG 0xca /* unsigned long long constant */ -#define TOK_ARROW 0xcb -#define TOK_DOTS 0xcc /* three dots */ -#define TOK_SHR 0xcd /* unsigned shift right */ -#define TOK_PPNUM 0xce /* preprocessor number */ +#define TOK_ARROW 0xc7 +#define TOK_DOTS 0xc8 /* three dots */ +#define TOK_SHR 0xc9 /* unsigned shift right */ +#define TOK_TWOSHARPS 0xca /* ## preprocessing token */ +#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */ +#define TOK_NOSUBST 0xcc /* means following token has already been pp'd */ +#define TOK_PPJOIN 0xcd /* A '##' in the right position to mean pasting */ +#define TOK_CLONG 0xce /* long constant */ +#define TOK_CULONG 0xcf /* unsigned long constant */ #define TOK_SHL 0x01 /* shift left */ #define TOK_SAR 0x02 /* signed shift right */ - -/* assignement operators : normal operator or 0x80 */ + +/* assignment operators : normal operator or 0x80 */ #define TOK_A_MOD 0xa5 #define TOK_A_AND 0xa6 #define TOK_A_MUL 0xaa @@ -607,33 +981,51 @@ struct TCCState { #define TOK_A_SHL 0x81 #define TOK_A_SAR 0x82 -#ifndef offsetof -#define offsetof(type, field) ((size_t) &((type *)0)->field) -#endif - -#ifndef countof -#define countof(tab) (sizeof(tab) / sizeof((tab)[0])) -#endif - #define TOK_EOF (-1) /* end of file */ #define TOK_LINEFEED 10 /* line feed */ -/* all identificators and strings have token above that */ +/* all identifiers and strings have token above that */ #define TOK_IDENT 256 -/* only used for i386 asm opcodes definitions */ #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x) +#define TOK_ASM_int TOK_INT +#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x) +#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte +#define TOK_ASMDIR_LAST TOK_ASMDIR_section +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 +/* only used for i386 asm opcodes definitions */ #define DEF_BWL(x) \ DEF(TOK_ASM_ ## x ## b, #x "b") \ DEF(TOK_ASM_ ## x ## w, #x "w") \ DEF(TOK_ASM_ ## x ## l, #x "l") \ DEF(TOK_ASM_ ## x, #x) - #define DEF_WL(x) \ DEF(TOK_ASM_ ## x ## w, #x "w") \ DEF(TOK_ASM_ ## x ## l, #x "l") \ DEF(TOK_ASM_ ## x, #x) +#ifdef TCC_TARGET_X86_64 +# define DEF_BWLQ(x) \ + DEF(TOK_ASM_ ## x ## b, #x "b") \ + DEF(TOK_ASM_ ## x ## w, #x "w") \ + DEF(TOK_ASM_ ## x ## l, #x "l") \ + DEF(TOK_ASM_ ## x ## q, #x "q") \ + DEF(TOK_ASM_ ## x, #x) +# define DEF_WLQ(x) \ + DEF(TOK_ASM_ ## x ## w, #x "w") \ + DEF(TOK_ASM_ ## x ## l, #x "l") \ + DEF(TOK_ASM_ ## x ## q, #x "q") \ + DEF(TOK_ASM_ ## x, #x) +# define DEF_BWLX DEF_BWLQ +# define DEF_WLX DEF_WLQ +/* number of sizes + 1 */ +# define NBWLX 5 +#else +# define DEF_BWLX DEF_BWL +# define DEF_WLX DEF_WL +/* number of sizes + 1 */ +# define NBWLX 4 +#endif #define DEF_FP1(x) \ DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \ @@ -646,121 +1038,620 @@ struct TCCState { DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \ DEF_FP1(x) -#define DEF_ASMTEST(x) \ - DEF_ASM(x ## o) \ - DEF_ASM(x ## no) \ - DEF_ASM(x ## b) \ - DEF_ASM(x ## c) \ - DEF_ASM(x ## nae) \ - DEF_ASM(x ## nb) \ - DEF_ASM(x ## nc) \ - DEF_ASM(x ## ae) \ - DEF_ASM(x ## e) \ - DEF_ASM(x ## z) \ - DEF_ASM(x ## ne) \ - DEF_ASM(x ## nz) \ - DEF_ASM(x ## be) \ - DEF_ASM(x ## na) \ - DEF_ASM(x ## nbe) \ - DEF_ASM(x ## a) \ - DEF_ASM(x ## s) \ - DEF_ASM(x ## ns) \ - DEF_ASM(x ## p) \ - DEF_ASM(x ## pe) \ - DEF_ASM(x ## np) \ - DEF_ASM(x ## po) \ - DEF_ASM(x ## l) \ - DEF_ASM(x ## nge) \ - DEF_ASM(x ## nl) \ - DEF_ASM(x ## ge) \ - DEF_ASM(x ## le) \ - DEF_ASM(x ## ng) \ - DEF_ASM(x ## nle) \ - DEF_ASM(x ## g) - -#define TOK_ASM_int TOK_INT +#define DEF_ASMTEST(x,suffix) \ + DEF_ASM(x ## o ## suffix) \ + DEF_ASM(x ## no ## suffix) \ + DEF_ASM(x ## b ## suffix) \ + DEF_ASM(x ## c ## suffix) \ + DEF_ASM(x ## nae ## suffix) \ + DEF_ASM(x ## nb ## suffix) \ + DEF_ASM(x ## nc ## suffix) \ + DEF_ASM(x ## ae ## suffix) \ + DEF_ASM(x ## e ## suffix) \ + DEF_ASM(x ## z ## suffix) \ + DEF_ASM(x ## ne ## suffix) \ + DEF_ASM(x ## nz ## suffix) \ + DEF_ASM(x ## be ## suffix) \ + DEF_ASM(x ## na ## suffix) \ + DEF_ASM(x ## nbe ## suffix) \ + DEF_ASM(x ## a ## suffix) \ + DEF_ASM(x ## s ## suffix) \ + DEF_ASM(x ## ns ## suffix) \ + DEF_ASM(x ## p ## suffix) \ + DEF_ASM(x ## pe ## suffix) \ + DEF_ASM(x ## np ## suffix) \ + DEF_ASM(x ## po ## suffix) \ + DEF_ASM(x ## l ## suffix) \ + DEF_ASM(x ## nge ## suffix) \ + DEF_ASM(x ## nl ## suffix) \ + DEF_ASM(x ## ge ## suffix) \ + DEF_ASM(x ## le ## suffix) \ + DEF_ASM(x ## ng ## suffix) \ + DEF_ASM(x ## nle ## suffix) \ + DEF_ASM(x ## g ## suffix) + +#endif /* defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 */ enum tcc_token { - TOK_LAST = TOK_IDENT - 1, -#define DEF(id, str) id, + TOK_LAST = TOK_IDENT - 1 +#define DEF(id, str) ,id #include "tcctok.h" #undef DEF }; +/* keywords: tok >= TOK_IDENT && tok < TOK_UIDENT */ #define TOK_UIDENT TOK_DEFINE +/* ------------ libtcc.c ------------ */ + +/* use GNU C extensions */ +ST_DATA int gnu_ext; +/* use Tiny C extensions */ +ST_DATA int tcc_ext; +/* XXX: get rid of this ASAP */ +ST_DATA struct TCCState *tcc_state; + +/* public functions currently used by the tcc main function */ +ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s); +ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s); +ST_FUNC char *pstrncpy(char *out, const char *in, size_t num); +PUB_FUNC char *tcc_basename(const char *name); +PUB_FUNC char *tcc_fileextension (const char *name); + +#ifndef MEM_DEBUG +PUB_FUNC void tcc_free(void *ptr); +PUB_FUNC void *tcc_malloc(unsigned long size); +PUB_FUNC void *tcc_mallocz(unsigned long size); +PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size); +PUB_FUNC char *tcc_strdup(const char *str); +#else +#define tcc_free(ptr) tcc_free_debug(ptr) +#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__) +#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__) +#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__) +#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__) +PUB_FUNC void tcc_free_debug(void *ptr); +PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line); +PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line); +PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line); +PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line); +#endif + +#define free(p) use_tcc_free(p) +#define malloc(s) use_tcc_malloc(s) +#define realloc(p, s) use_tcc_realloc(p, s) +#undef strdup +#define strdup(s) use_tcc_strdup(s) +PUB_FUNC void tcc_memcheck(void); +PUB_FUNC void tcc_error_noabort(const char *fmt, ...); +PUB_FUNC NORETURN void tcc_error(const char *fmt, ...); +PUB_FUNC void tcc_warning(const char *fmt, ...); + +/* other utilities */ +ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data); +ST_FUNC void dynarray_reset(void *pp, int *n); +ST_INLN void cstr_ccat(CString *cstr, int ch); +ST_FUNC void cstr_cat(CString *cstr, const char *str, int len); +ST_FUNC void cstr_wccat(CString *cstr, int ch); +ST_FUNC void cstr_new(CString *cstr); +ST_FUNC void cstr_free(CString *cstr); +ST_FUNC void cstr_reset(CString *cstr); + +ST_INLN void sym_free(Sym *sym); +ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c); +ST_FUNC Sym *sym_find2(Sym *s, int v); +ST_FUNC Sym *sym_push(int v, CType *type, int r, int c); +ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep); +ST_INLN Sym *struct_find(int v); +ST_INLN Sym *sym_find(int v); +ST_FUNC Sym *global_identifier_push(int v, int t, int c); + +ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen); +ST_FUNC int tcc_open(TCCState *s1, const char *filename); +ST_FUNC void tcc_close(void); + +ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags); +/* flags: */ +#define AFF_PRINT_ERROR 0x10 /* print error if file not found */ +#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */ +#define AFF_TYPE_BIN 0x40 /* file to add is binary */ +/* s->filetype: */ +#define AFF_TYPE_NONE 0 +#define AFF_TYPE_C 1 +#define AFF_TYPE_ASM 2 +#define AFF_TYPE_ASMPP 3 +#define AFF_TYPE_LIB 4 +/* values from tcc_object_type(...) */ +#define AFF_BINTYPE_REL 1 +#define AFF_BINTYPE_DYN 2 +#define AFF_BINTYPE_AR 3 +#define AFF_BINTYPE_C67 4 + + +ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); +ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); +ST_FUNC void tcc_add_pragma_libs(TCCState *s1); +PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f); +PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time); +PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind); #ifdef _WIN32 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#ifndef __GNUC__ - #define strtold (long double)strtod - #define strtof (float)strtod - #define strtoll (long long)strtol -#endif -#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \ - || defined(__OpenBSD__) -/* currently incorrect */ -long double strtold(const char *nptr, char **endptr) -{ - return (long double)strtod(nptr, endptr); +ST_FUNC char *normalize_slashes(char *path); +#endif + +/* tcc_parse_args return codes: */ +#define OPT_HELP 1 +#define OPT_HELP2 2 +#define OPT_V 3 +#define OPT_PRINT_DIRS 4 +#define OPT_AR 5 +#define OPT_IMPDEF 6 +#define OPT_M32 32 +#define OPT_M64 64 + +/* ------------ tccpp.c ------------ */ + +ST_DATA struct BufferedFile *file; +ST_DATA int ch, tok; +ST_DATA CValue tokc; +ST_DATA const int *macro_ptr; +ST_DATA int parse_flags; +ST_DATA int tok_flags; +ST_DATA CString tokcstr; /* current parsed string, if any */ + +/* display benchmark infos */ +ST_DATA int total_lines; +ST_DATA int total_bytes; +ST_DATA int tok_ident; +ST_DATA TokenSym **table_ident; + +#define TOK_FLAG_BOL 0x0001 /* beginning of line before */ +#define TOK_FLAG_BOF 0x0002 /* beginning of file before */ +#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ +#define TOK_FLAG_EOF 0x0008 /* end of file */ + +#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */ +#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */ +#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a + token. line feed is also + returned at eof */ +#define PARSE_FLAG_ASM_FILE 0x0008 /* we processing an asm file: '#' can be used for line comment, etc. */ +#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */ +#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */ +#define PARSE_FLAG_TOK_STR 0x0040 /* return parsed strings instead of TOK_PPSTR */ + +/* isidnum_table flags: */ +#define IS_SPC 1 +#define IS_ID 2 +#define IS_NUM 4 + +ST_FUNC TokenSym *tok_alloc(const char *str, int len); +ST_FUNC const char *get_tok_str(int v, CValue *cv); +ST_FUNC void begin_macro(TokenString *str, int alloc); +ST_FUNC void end_macro(void); +ST_FUNC int set_idnum(int c, int val); +ST_INLN void tok_str_new(TokenString *s); +ST_FUNC TokenString *tok_str_alloc(void); +ST_FUNC void tok_str_free(TokenString *s); +ST_FUNC void tok_str_free_str(int *str); +ST_FUNC void tok_str_add(TokenString *s, int t); +ST_FUNC void tok_str_add_tok(TokenString *s); +ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg); +ST_FUNC void define_undef(Sym *s); +ST_INLN Sym *define_find(int v); +ST_FUNC void free_defines(Sym *b); +ST_FUNC Sym *label_find(int v); +ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); +ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep); +ST_FUNC void parse_define(void); +ST_FUNC void preprocess(int is_bof); +ST_FUNC void next_nomacro(void); +ST_FUNC void next(void); +ST_INLN void unget_tok(int last_tok); +ST_FUNC void preprocess_start(TCCState *s1, int is_asm); +ST_FUNC void preprocess_end(TCCState *s1); +ST_FUNC void tccpp_new(TCCState *s); +ST_FUNC void tccpp_delete(TCCState *s); +ST_FUNC int tcc_preprocess(TCCState *s1); +ST_FUNC void skip(int c); +ST_FUNC NORETURN void expect(const char *msg); + +/* space excluding newline */ +static inline int is_space(int ch) { + return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r'; } -float strtof(const char *nptr, char **endptr) -{ - return (float)strtod(nptr, endptr); +static inline int isid(int c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; } -#else -/* XXX: need to define this to use them in non ISOC99 context */ -extern float strtof (const char *__nptr, char **__endptr); -extern long double strtold (const char *__nptr, char **__endptr); +static inline int isnum(int c) { + return c >= '0' && c <= '9'; +} +static inline int isoct(int c) { + return c >= '0' && c <= '7'; +} +static inline int toup(int c) { + return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; +} + +/* ------------ tccgen.c ------------ */ + +#define SYM_POOL_NB (8192 / sizeof(Sym)) +ST_DATA Sym *sym_free_first; +ST_DATA void **sym_pools; +ST_DATA int nb_sym_pools; + +ST_DATA Sym *global_stack; +ST_DATA Sym *local_stack; +ST_DATA Sym *local_label_stack; +ST_DATA Sym *global_label_stack; +ST_DATA Sym *define_stack; +ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; +ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop; +#define vstack (__vstack + 1) +ST_DATA int rsym, anon_sym, ind, loc; + +ST_DATA int const_wanted; /* true if constant wanted */ +ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ +ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ +ST_DATA CType func_vt; /* current function return type (used by return instruction) */ +ST_DATA int func_var; /* true if current function is variadic */ +ST_DATA int func_vc; +ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ +ST_DATA const char *funcname; +ST_DATA int g_debug; + +ST_FUNC void tcc_debug_start(TCCState *s1); +ST_FUNC void tcc_debug_end(TCCState *s1); +ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym); +ST_FUNC void tcc_debug_funcend(TCCState *s1, int size); +ST_FUNC void tcc_debug_line(TCCState *s1); + +ST_FUNC int tccgen_compile(TCCState *s1); +ST_FUNC void free_inline_functions(TCCState *s); +ST_FUNC void check_vstack(void); + +ST_INLN int is_float(int t); +ST_FUNC int ieee_finite(double d); +ST_FUNC void test_lvalue(void); +ST_FUNC void vpushi(int v); +ST_FUNC Sym *external_global_sym(int v, CType *type, int r); +ST_FUNC void vset(CType *type, int r, int v); +ST_FUNC void vswap(void); +ST_FUNC void vpush_global_sym(CType *type, int v); +ST_FUNC void vrote(SValue *e, int n); +ST_FUNC void vrott(int n); +ST_FUNC void vrotb(int n); +#ifdef TCC_TARGET_ARM +ST_FUNC int get_reg_ex(int rc, int rc2); +ST_FUNC void lexpand_nr(void); +#endif +ST_FUNC void vpushv(SValue *v); +ST_FUNC void save_reg(int r); +ST_FUNC void save_reg_upstack(int r, int n); +ST_FUNC int get_reg(int rc); +ST_FUNC void save_regs(int n); +ST_FUNC void gaddrof(void); +ST_FUNC int gv(int rc); +ST_FUNC void gv2(int rc1, int rc2); +ST_FUNC void vpop(void); +ST_FUNC void gen_op(int op); +ST_FUNC int type_size(CType *type, int *a); +ST_FUNC void mk_pointer(CType *type); +ST_FUNC void vstore(void); +ST_FUNC void inc(int post, int c); +ST_FUNC void parse_mult_str (CString *astr, const char *msg); +ST_FUNC void parse_asm_str(CString *astr); +ST_FUNC int lvalue_type(int t); +ST_FUNC void indir(void); +ST_FUNC void unary(void); +ST_FUNC void expr_prod(void); +ST_FUNC void expr_sum(void); +ST_FUNC void gexpr(void); +ST_FUNC int expr_const(void); +#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 +ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size); +#endif +#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE +ST_FUNC int classify_x86_64_va_arg(CType *ty); #endif -#ifdef _WIN32 -#define IS_PATHSEP(c) (c == '/' || c == '\\') -#define IS_ABSPATH(p) (IS_PATHSEP(p[0]) || (p[0] && p[1] == ':' && IS_PATHSEP(p[2]))) -#define PATHCMP stricmp +/* ------------ tccelf.c ------------ */ + +#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */ +#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */ +#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */ + +#define ARMAG "!<arch>\012" /* For COFF and a.out archives */ + +typedef struct { + unsigned int n_strx; /* index into string table of name */ + unsigned char n_type; /* type of symbol */ + unsigned char n_other; /* misc info (usually empty) */ + unsigned short n_desc; /* description field */ + unsigned int n_value; /* value of symbol */ +} Stab_Sym; + +ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ +ST_DATA Section *common_section; +ST_DATA Section *cur_text_section; /* current section where function code is generated */ +#ifdef CONFIG_TCC_ASM +ST_DATA Section *last_text_section; /* to handle .previous asm directive */ +#endif +#ifdef CONFIG_TCC_BCHECK +/* bound check related sections */ +ST_DATA Section *bounds_section; /* contains global data bound description */ +ST_DATA Section *lbounds_section; /* contains local data bound description */ +ST_FUNC void tccelf_bounds_new(TCCState *s); +#endif +/* symbol sections */ +ST_DATA Section *symtab_section, *strtab_section; +/* debug sections */ +ST_DATA Section *stab_section, *stabstr_section; + +ST_FUNC void tccelf_new(TCCState *s); +ST_FUNC void tccelf_delete(TCCState *s); +ST_FUNC void tccelf_stab_new(TCCState *s); + +ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); +ST_FUNC void section_realloc(Section *sec, unsigned long new_size); +ST_FUNC size_t section_add(Section *sec, addr_t size, int align); +ST_FUNC void *section_ptr_add(Section *sec, addr_t size); +ST_FUNC void section_reserve(Section *sec, unsigned long size); +ST_FUNC Section *find_section(TCCState *s1, const char *name); +ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); + +ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore); +ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size); +#if PTR_SIZE == 4 +ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type); +#endif +ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend); + +ST_FUNC int put_elf_str(Section *s, const char *sym); +ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); +ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); +ST_FUNC int find_elf_sym(Section *s, const char *name); +ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol); +ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend); + +ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value); +ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index); +ST_FUNC void put_stabn(int type, int other, int desc, int value); +ST_FUNC void put_stabd(int type, int other, int desc); + +ST_FUNC void relocate_common_syms(void); +ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve); +ST_FUNC void relocate_section(TCCState *s1, Section *s); + +ST_FUNC void tcc_add_linker_symbols(TCCState *s1); +ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h); +ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset); +ST_FUNC int tcc_load_archive(TCCState *s1, int fd); +ST_FUNC void tcc_add_bcheck(TCCState *s1); +ST_FUNC void tcc_add_runtime(TCCState *s1); + +ST_FUNC void build_got_entries(TCCState *s1); +ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc); +ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset); + +ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err); +#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE +ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name); +#endif + +#ifndef TCC_TARGET_PE +ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level); +ST_FUNC int tcc_load_ldscript(TCCState *s1); +ST_FUNC uint8_t *parse_comment(uint8_t *p); +ST_FUNC void minp(void); +ST_INLN void inp(void); +ST_FUNC int handle_eob(void); +#endif + +/* ------------ xxx-link.c ------------ */ + +/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so + that unknown relocation don't create a GOT or PLT entry */ +enum gotplt_entry { + NO_GOTPLT_ENTRY, /* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */ + BUILD_GOT_ONLY, /* only build GOT (eg. TPOFF relocs) */ + AUTO_GOTPLT_ENTRY, /* generate if sym is UNDEF */ + ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */ +}; + +ST_FUNC int code_reloc (int reloc_type); +ST_FUNC int gotplt_entry_type (int reloc_type); +ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr); +ST_FUNC void relocate_init(Section *sr); +ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val); +ST_FUNC void relocate_plt(TCCState *s1); + +/* ------------ xxx-gen.c ------------ */ + +ST_DATA const int reg_classes[NB_REGS]; + +ST_FUNC void gsym_addr(int t, int a); +ST_FUNC void gsym(int t); +ST_FUNC void load(int r, SValue *sv); +ST_FUNC void store(int r, SValue *v); +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize); +ST_FUNC void gfunc_call(int nb_args); +ST_FUNC void gfunc_prolog(CType *func_type); +ST_FUNC void gfunc_epilog(void); +ST_FUNC int gjmp(int t); +ST_FUNC void gjmp_addr(int a); +ST_FUNC int gtst(int inv, int t); +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 +ST_FUNC void gtst_addr(int inv, int a); #else -#define IS_PATHSEP(c) (c == '/') -#define IS_ABSPATH(p) IS_PATHSEP(p[0]) -#define PATHCMP strcmp +#define gtst_addr(inv, a) gsym_addr(gtst(inv, 0), a) +#endif +ST_FUNC void gen_opi(int op); +ST_FUNC void gen_opf(int op); +ST_FUNC void gen_cvt_ftoi(int t); +ST_FUNC void gen_cvt_ftof(int t); +ST_FUNC void ggoto(void); +#ifndef TCC_TARGET_C67 +ST_FUNC void o(unsigned int c); +#endif +#ifndef TCC_TARGET_ARM +ST_FUNC void gen_cvt_itof(int t); +#endif +ST_FUNC void gen_vla_sp_save(int addr); +ST_FUNC void gen_vla_sp_restore(int addr); +ST_FUNC void gen_vla_alloc(CType *type, int align); + +static inline uint16_t read16le(unsigned char *p) { + return p[0] | (uint16_t)p[1] << 8; +} +static inline void write16le(unsigned char *p, uint16_t x) { + p[0] = x & 255; p[1] = x >> 8 & 255; +} +static inline uint32_t read32le(unsigned char *p) { + return read16le(p) | (uint32_t)read16le(p + 2) << 16; +} +static inline void write32le(unsigned char *p, uint32_t x) { + write16le(p, x); write16le(p + 2, x >> 16); +} +static inline void add32le(unsigned char *p, int32_t x) { + write32le(p, read32le(p) + x); +} +static inline uint64_t read64le(unsigned char *p) { + return read32le(p) | (uint64_t)read32le(p + 4) << 32; +} +static inline void write64le(unsigned char *p, uint64_t x) { + write32le(p, x); write32le(p + 4, x >> 32); +} +static inline void add64le(unsigned char *p, int64_t x) { + write64le(p, read64le(p) + x); +} + +/* ------------ i386-gen.c ------------ */ +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 +ST_FUNC void g(int c); +ST_FUNC void gen_le16(int c); +ST_FUNC void gen_le32(int c); +ST_FUNC void gen_addr32(int r, Sym *sym, int c); +ST_FUNC void gen_addrpc32(int r, Sym *sym, int c); #endif -void error(const char *fmt, ...); -void error_noabort(const char *fmt, ...); -void warning(const char *fmt, ...); +#ifdef CONFIG_TCC_BCHECK +ST_FUNC void gen_bounded_ptr_add(void); +ST_FUNC void gen_bounded_ptr_deref(void); +#endif -void tcc_set_lib_path_w32(TCCState *s); -int tcc_set_flag(TCCState *s, const char *flag_name, int value); -void tcc_print_stats(TCCState *s, int64_t total_time); +/* ------------ x86_64-gen.c ------------ */ +#ifdef TCC_TARGET_X86_64 +ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c); +ST_FUNC void gen_opl(int op); +#endif -void tcc_free(void *ptr); -void *tcc_malloc(unsigned long size); -void *tcc_mallocz(unsigned long size); -void *tcc_realloc(void *ptr, unsigned long size); -char *tcc_strdup(const char *str); +/* ------------ arm-gen.c ------------ */ +#ifdef TCC_TARGET_ARM +#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP) +PUB_FUNC const char *default_elfinterp(struct TCCState *s); +#endif +ST_FUNC void arm_init(struct TCCState *s); +ST_FUNC void gen_cvt_itof1(int t); +#endif -char *tcc_basename(const char *name); -char *tcc_fileextension (const char *name); -char *pstrcpy(char *buf, int buf_size, const char *s); -char *pstrcat(char *buf, int buf_size, const char *s); -void dynarray_add(void ***ptab, int *nb_ptr, void *data); -void dynarray_reset(void *pp, int *n); +/* ------------ arm64-gen.c ------------ */ +#ifdef TCC_TARGET_ARM64 +ST_FUNC void gen_cvt_sxtw(void); +ST_FUNC void gen_opl(int op); +ST_FUNC void gfunc_return(CType *func_type); +ST_FUNC void gen_va_start(void); +ST_FUNC void gen_va_arg(CType *t); +ST_FUNC void gen_clear_cache(void); +#endif -#ifdef CONFIG_TCC_BACKTRACE -extern int num_callers; -extern const char **rt_bound_error_msg; +/* ------------ c67-gen.c ------------ */ +#ifdef TCC_TARGET_C67 #endif -/* true if float/double/long double type */ -static inline int is_float(int t) -{ - int bt; - bt = t & VT_BTYPE; - return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT; -} +/* ------------ tcccoff.c ------------ */ -/* space exlcuding newline */ -static inline int is_space(int ch) -{ - return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r'; -} +#ifdef TCC_TARGET_COFF +ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f); +ST_FUNC int tcc_load_coff(TCCState * s1, int fd); +#endif +/* ------------ tccasm.c ------------ */ +ST_FUNC void asm_instr(void); +ST_FUNC void asm_global_instr(void); +#ifdef CONFIG_TCC_ASM +ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp); +ST_FUNC Sym* get_asm_sym(int name, Sym *csym); +ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); +ST_FUNC int asm_int_expr(TCCState *s1); +ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess); +/* ------------ i386-asm.c ------------ */ +ST_FUNC void gen_expr32(ExprValue *pe); +#ifdef TCC_TARGET_X86_64 +ST_FUNC void gen_expr64(ExprValue *pe); +#endif +ST_FUNC void asm_opcode(TCCState *s1, int opcode); +ST_FUNC int asm_parse_regvar(int t); +ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg); +ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier); +ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg); +ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str); +#endif + +/* ------------ tccpe.c -------------- */ +#ifdef TCC_TARGET_PE +ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd); +ST_FUNC int pe_output_file(TCCState * s1, const char *filename); +ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value); +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 +ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2); +#endif +#ifdef TCC_TARGET_X86_64 +ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack); +#endif +PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp); +/* symbol properties stored in Elf32_Sym->st_other */ +# define ST_PE_EXPORT 0x10 +# define ST_PE_IMPORT 0x20 +# define ST_PE_STDCALL 0x40 +#endif +/* ------------ tccrun.c ----------------- */ +#ifdef TCC_IS_NATIVE +#ifdef CONFIG_TCC_STATIC +#define RTLD_LAZY 0x001 +#define RTLD_NOW 0x002 +#define RTLD_GLOBAL 0x100 +#define RTLD_DEFAULT NULL +/* dummy function for profiling */ +ST_FUNC void *dlopen(const char *filename, int flag); +ST_FUNC void dlclose(void *p); +ST_FUNC const char *dlerror(void); +ST_FUNC void *dlsym(void *handle, const char *symbol); +#endif +#ifdef CONFIG_TCC_BACKTRACE +ST_DATA int rt_num_callers; +ST_DATA const char **rt_bound_error_msg; +ST_DATA void *rt_prog_main; +ST_FUNC void tcc_set_num_callers(int n); +#endif +ST_FUNC void tcc_run_free(TCCState *s1); +#endif + +/* ------------ tcctools.c ----------------- */ +#if 0 /* included in tcc.c */ +ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv); +#ifdef TCC_TARGET_PE +ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv); +#endif +ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option); +ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename); +#endif + +/********************************************************/ +#undef ST_DATA +#if ONE_SOURCE +#define ST_DATA static +#else +#define ST_DATA +#endif +/********************************************************/ +#endif /* _TCC_H */ diff --git a/tinyc/tccasm.c b/tinyc/tccasm.c index 9b5289f77..ac1618a52 100644 --- a/tinyc/tccasm.c +++ b/tinyc/tccasm.c @@ -18,7 +18,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -static int asm_get_local_label_name(TCCState *s1, unsigned int n) +#include "tcc.h" +#ifdef CONFIG_TCC_ASM + +ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n) { char buf[64]; TokenSym *ts; @@ -28,7 +31,56 @@ static int asm_get_local_label_name(TCCState *s1, unsigned int n) return ts->tok; } -static void asm_expr(TCCState *s1, ExprValue *pe); +ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); +static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global); +static Sym sym_dot; + +/* Return a symbol we can use inside the assembler, having name NAME. + The assembler symbol table is different from the C symbol table + (and the Sym members are used differently). But we must be able + to look up file-global C symbols from inside the assembler, e.g. + for global asm blocks to be able to refer to defined C symbols. + + This routine gives back either an existing asm-internal + symbol, or a new one. In the latter case the new asm-internal + symbol is initialized with info from the C symbol table. + + If CSYM is non-null we take symbol info from it, otherwise + we look up NAME in the C symbol table and use that. */ +ST_FUNC Sym* get_asm_sym(int name, Sym *csym) +{ + Sym *sym = label_find(name); + if (!sym) { + sym = label_push(&tcc_state->asm_labels, name, 0); + sym->type.t = VT_VOID | VT_EXTERN; + if (!csym) { + csym = sym_find(name); + /* We might be called for an asm block from inside a C routine + and so might have local decls on the identifier stack. Search + for the first global one. */ + while (csym && csym->sym_scope) + csym = csym->prev_tok; + } + /* Now, if we have a defined global symbol copy over + section and offset. */ + if (csym && + ((csym->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST)) && + csym->c) { + ElfW(Sym) *esym; + esym = &((ElfW(Sym) *)symtab_section->data)[csym->c]; + sym->c = csym->c; + sym->r = esym->st_shndx; + sym->jnext = esym->st_value; + /* XXX can't yet store st_size anywhere. */ + sym->type.t &= ~VT_EXTERN; + /* Mark that this asm symbol doesn't need to be fed back. */ + sym->a.dllimport = 1; + } else { + sym->type.t |= VT_STATIC; + } + } + return sym; +} /* We do not use the C expression parser to handle symbols. Maybe the C expression parser could be tweaked to do so. */ @@ -36,13 +88,14 @@ static void asm_expr(TCCState *s1, ExprValue *pe); static void asm_expr_unary(TCCState *s1, ExprValue *pe) { Sym *sym; - int op, n, label; + int op, label; + uint64_t n; const char *p; switch(tok) { case TOK_PPNUM: - p = tokc.cstr->data; - n = strtoul(p, (char **)&p, 0); + p = tokc.str.data; + n = strtoull(p, (char **)&p, 0); if (*p == 'b' || *p == 'f') { /* backward or forward label */ label = asm_get_local_label_name(s1, n); @@ -52,22 +105,24 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) if (sym && sym->r == 0) sym = sym->prev_tok; if (!sym) - error("local label '%d' not found backward", n); + tcc_error("local label '%d' not found backward", n); } else { /* forward */ if (!sym || sym->r) { /* if the last label is defined, then define a new one */ sym = label_push(&s1->asm_labels, label, 0); - sym->type.t = VT_STATIC | VT_VOID; + sym->type.t = VT_STATIC | VT_VOID | VT_EXTERN; } } - pe->v = 0; - pe->sym = sym; + pe->v = 0; + pe->sym = sym; + pe->pcrel = 0; } else if (*p == '\0') { pe->v = n; pe->sym = NULL; + pe->pcrel = 0; } else { - error("invalid number syntax"); + tcc_error("invalid number syntax"); } next(); break; @@ -81,7 +136,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) next(); asm_expr_unary(s1, pe); if (pe->sym) - error("invalid operation with label"); + tcc_error("invalid operation with label"); if (op == '-') pe->v = -pe->v; else @@ -91,6 +146,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) case TOK_LCHAR: pe->v = tokc.i; pe->sym = NULL; + pe->pcrel = 0; next(); break; case '(': @@ -98,26 +154,32 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) asm_expr(s1, pe); skip(')'); break; + case '.': + pe->v = 0; + pe->sym = &sym_dot; + pe->pcrel = 0; + sym_dot.type.t = VT_VOID | VT_STATIC; + sym_dot.r = cur_text_section->sh_num; + sym_dot.jnext = ind; + next(); + break; default: if (tok >= TOK_IDENT) { /* label case : if the label was not found, add one */ - sym = label_find(tok); - if (!sym) { - sym = label_push(&s1->asm_labels, tok, 0); - /* NOTE: by default, the symbol is global */ - sym->type.t = VT_VOID; - } + sym = get_asm_sym(tok, NULL); if (sym->r == SHN_ABS) { /* if absolute symbol, no need to put a symbol value */ - pe->v = (long)sym->next; + pe->v = sym->jnext; pe->sym = NULL; + pe->pcrel = 0; } else { pe->v = 0; pe->sym = sym; + pe->pcrel = 0; } next(); } else { - error("bad expression syntax [%s]", get_tok_str(tok, &tokc)); + tcc_error("bad expression syntax [%s]", get_tok_str(tok, &tokc)); } break; } @@ -137,7 +199,7 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe) next(); asm_expr_unary(s1, &e2); if (pe->sym || e2.sym) - error("invalid operation with label"); + tcc_error("invalid operation with label"); switch(op) { case '*': pe->v *= e2.v; @@ -145,7 +207,7 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe) case '/': if (e2.v == 0) { div_error: - error("division by zero"); + tcc_error("division by zero"); } pe->v /= e2.v; break; @@ -178,7 +240,7 @@ static void asm_expr_logic(TCCState *s1, ExprValue *pe) next(); asm_expr_prod(s1, &e2); if (pe->sym || e2.sym) - error("invalid operation with label"); + tcc_error("invalid operation with label"); switch(op) { case '&': pe->v &= e2.v; @@ -216,34 +278,77 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) pe->v -= e2.v; /* NOTE: we are less powerful than gas in that case because we store only one symbol in the expression */ - if (!pe->sym && !e2.sym) { - /* OK */ - } else if (pe->sym && !e2.sym) { - /* OK */ - } else if (pe->sym && e2.sym) { - if (pe->sym == e2.sym) { - /* OK */ - } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) { - /* we also accept defined symbols in the same section */ - pe->v += (long)pe->sym->next - (long)e2.sym->next; - } else { - goto cannot_relocate; - } - pe->sym = NULL; /* same symbols can be subtracted to NULL */ + if (!e2.sym) { + /* OK */ + } else if (pe->sym == e2.sym) { + /* OK */ + pe->sym = NULL; /* same symbols can be subtracted to NULL */ + } else if (pe->sym && pe->sym->r == e2.sym->r && pe->sym->r != 0) { + /* we also accept defined symbols in the same section */ + pe->v += pe->sym->jnext - e2.sym->jnext; + pe->sym = NULL; + } else if (e2.sym->r == cur_text_section->sh_num) { + /* When subtracting a defined symbol in current section + this actually makes the value PC-relative. */ + pe->v -= e2.sym->jnext - ind - 4; + pe->pcrel = 1; + e2.sym = NULL; } else { cannot_relocate: - error("invalid operation with label"); + tcc_error("invalid operation with label"); } } } } -static void asm_expr(TCCState *s1, ExprValue *pe) +static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe) { + int op; + ExprValue e2; + asm_expr_sum(s1, pe); + for(;;) { + op = tok; + if (op != TOK_EQ && op != TOK_NE + && (op > TOK_GT || op < TOK_ULE)) + break; + next(); + asm_expr_sum(s1, &e2); + if (pe->sym || e2.sym) + tcc_error("invalid operation with label"); + switch(op) { + case TOK_EQ: + pe->v = pe->v == e2.v; + break; + case TOK_NE: + pe->v = pe->v != e2.v; + break; + case TOK_LT: + pe->v = (int64_t)pe->v < (int64_t)e2.v; + break; + case TOK_GE: + pe->v = (int64_t)pe->v >= (int64_t)e2.v; + break; + case TOK_LE: + pe->v = (int64_t)pe->v <= (int64_t)e2.v; + break; + case TOK_GT: + pe->v = (int64_t)pe->v > (int64_t)e2.v; + break; + default: + break; + } + /* GAS compare results are -1/0 not 1/0. */ + pe->v = -(int64_t)pe->v; + } } -static int asm_int_expr(TCCState *s1) +ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe) +{ + asm_expr_cmp(s1, pe); +} + +ST_FUNC int asm_int_expr(TCCState *s1) { ExprValue e; asm_expr(s1, &e); @@ -254,17 +359,20 @@ static int asm_int_expr(TCCState *s1) /* NOTE: the same name space as C labels is used to avoid using too much memory when storing labels in TokenStrings */ -static void asm_new_label1(TCCState *s1, int label, int is_local, +static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value) { Sym *sym; sym = label_find(label); if (sym) { - if (sym->r) { + /* A VT_EXTERN symbol, even if it has a section is considered + overridable. This is how we "define" .set targets. Real + definitions won't have VT_EXTERN set. */ + if (sym->r && !(sym->type.t & VT_EXTERN)) { /* the label is already defined */ if (!is_local) { - error("assembler label '%s' already defined", + tcc_error("assembler label '%s' already defined", get_tok_str(label, NULL)); } else { /* redefinition of local labels is possible */ @@ -274,31 +382,50 @@ static void asm_new_label1(TCCState *s1, int label, int is_local, } else { new_label: sym = label_push(&s1->asm_labels, label, 0); - sym->type.t = VT_STATIC | VT_VOID; + /* If we need a symbol to hold a value, mark it as + tentative only (for .set). If this is for a real label + we'll remove VT_EXTERN. */ + sym->type.t = VT_STATIC | VT_VOID | VT_EXTERN; } sym->r = sh_num; - sym->next = (void *)value; + sym->jnext = value; + return sym; } -static void asm_new_label(TCCState *s1, int label, int is_local) +static Sym* asm_new_label(TCCState *s1, int label, int is_local) { - asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind); + return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind); +} + +/* Set the value of LABEL to that of some expression (possibly + involving other symbols). LABEL can be overwritten later still. */ +static Sym* set_symbol(TCCState *s1, int label) +{ + long n; + ExprValue e; + next(); + asm_expr(s1, &e); + n = e.v; + if (e.sym) + n += e.sym->jnext; + return asm_new_label1(s1, label, 0, e.sym ? e.sym->r : SHN_ABS, n); } static void asm_free_labels(TCCState *st) { Sym *s, *s1; Section *sec; - + for(s = st->asm_labels; s != NULL; s = s1) { s1 = s->prev; /* define symbol value in object file */ - if (s->r) { + s->type.t &= ~VT_EXTERN; + if (s->r && !s->a.dllimport) { if (s->r == SHN_ABS) sec = SECTION_ABS; else sec = st->sections[s->r]; - put_extern_sym2(s, sec, (long)s->next, 0, 0); + put_extern_sym2(s, sec, s->jnext, 0, 0); } /* remove label */ table_ident[s->v - TOK_IDENT]->sym_label = NULL; @@ -321,31 +448,57 @@ static void use_section(TCCState *s1, const char *name) use_section1(s1, sec); } -static void asm_parse_directive(TCCState *s1) +static void push_section(TCCState *s1, const char *name) +{ + Section *sec = find_section(s1, name); + sec->prev = cur_text_section; + use_section1(s1, sec); +} + +static void pop_section(TCCState *s1) +{ + Section *prev = cur_text_section->prev; + if (!prev) + tcc_error(".popsection without .pushsection"); + cur_text_section->prev = NULL; + use_section1(s1, prev); +} + +static void asm_parse_directive(TCCState *s1, int global) { int n, offset, v, size, tok1; Section *sec; uint8_t *ptr; /* assembler directive */ - next(); sec = cur_text_section; switch(tok) { - case TOK_ASM_align: - case TOK_ASM_skip: - case TOK_ASM_space: + case TOK_ASMDIR_align: + case TOK_ASMDIR_balign: + case TOK_ASMDIR_p2align: + case TOK_ASMDIR_skip: + case TOK_ASMDIR_space: tok1 = tok; next(); n = asm_int_expr(s1); - if (tok1 == TOK_ASM_align) { + if (tok1 == TOK_ASMDIR_p2align) + { + if (n < 0 || n > 30) + tcc_error("invalid p2align, must be between 0 and 30"); + n = 1 << n; + tok1 = TOK_ASMDIR_align; + } + if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) { if (n < 0 || (n & (n-1)) != 0) - error("alignment must be a positive power of two"); + tcc_error("alignment must be a positive power of two"); offset = (ind + n - 1) & -n; size = offset - ind; /* the section must have a compatible alignment */ if (sec->sh_addralign < n) sec->sh_addralign = n; } else { + if (n < 0) + n = 0; size = n; } v = 0; @@ -361,16 +514,20 @@ static void asm_parse_directive(TCCState *s1) } ind += size; break; - case TOK_ASM_quad: + case TOK_ASMDIR_quad: +#ifdef TCC_TARGET_X86_64 + size = 8; + goto asm_data; +#else next(); for(;;) { uint64_t vl; const char *p; - p = tokc.cstr->data; + p = tokc.str.data; if (tok != TOK_PPNUM) { error_constant: - error("64 bit constant"); + tcc_error("64 bit constant"); } vl = strtoll(p, (char **)&p, 0); if (*p != '\0') @@ -388,15 +545,16 @@ static void asm_parse_directive(TCCState *s1) next(); } break; - case TOK_ASM_byte: +#endif + case TOK_ASMDIR_byte: size = 1; goto asm_data; - case TOK_ASM_word: - case TOK_SHORT: + case TOK_ASMDIR_word: + case TOK_ASMDIR_short: size = 2; goto asm_data; - case TOK_LONG: - case TOK_INT: + case TOK_ASMDIR_long: + case TOK_ASMDIR_int: size = 4; asm_data: next(); @@ -406,6 +564,10 @@ static void asm_parse_directive(TCCState *s1) if (sec->sh_type != SHT_NOBITS) { if (size == 4) { gen_expr32(&e); +#ifdef TCC_TARGET_X86_64 + } else if (size == 8) { + gen_expr64(&e); +#endif } else { if (e.sym) expect("constant"); @@ -422,14 +584,14 @@ static void asm_parse_directive(TCCState *s1) next(); } break; - case TOK_ASM_fill: + case TOK_ASMDIR_fill: { int repeat, size, val, i, j; uint8_t repeat_buf[8]; next(); repeat = asm_int_expr(s1); if (repeat < 0) { - error("repeat < 0; .fill ignored"); + tcc_error("repeat < 0; .fill ignored"); break; } size = 1; @@ -438,7 +600,7 @@ static void asm_parse_directive(TCCState *s1) next(); size = asm_int_expr(s1); if (size < 0) { - error("size < 0; .fill ignored"); + tcc_error("size < 0; .fill ignored"); break; } if (size > 8) @@ -464,37 +626,80 @@ static void asm_parse_directive(TCCState *s1) } } break; - case TOK_ASM_org: + case TOK_ASMDIR_rept: + { + int repeat; + TokenString *init_str; + next(); + repeat = asm_int_expr(s1); + init_str = tok_str_alloc(); + while (next(), tok != TOK_ASMDIR_endr) { + if (tok == CH_EOF) + tcc_error("we at end of file, .endr not found"); + tok_str_add_tok(init_str); + } + tok_str_add(init_str, -1); + tok_str_add(init_str, 0); + begin_macro(init_str, 1); + while (repeat-- > 0) { + tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS), + global); + macro_ptr = init_str->str; + } + end_macro(); + next(); + break; + } + case TOK_ASMDIR_org: { unsigned long n; + ExprValue e; next(); - /* XXX: handle section symbols too */ - n = asm_int_expr(s1); + asm_expr(s1, &e); + n = e.v; + if (e.sym) { + if (e.sym->r != cur_text_section->sh_num) + expect("constant or same-section symbol"); + n += e.sym->jnext; + } if (n < ind) - error("attempt to .org backwards"); + tcc_error("attempt to .org backwards"); v = 0; size = n - ind; goto zero_pad; } break; - case TOK_ASM_globl: - case TOK_ASM_global: - { + case TOK_ASMDIR_set: + next(); + tok1 = tok; + next(); + /* Also accept '.set stuff', but don't do anything with this. + It's used in GAS to set various features like '.set mips16'. */ + if (tok == ',') + set_symbol(s1, tok1); + break; + case TOK_ASMDIR_globl: + case TOK_ASMDIR_global: + case TOK_ASMDIR_weak: + case TOK_ASMDIR_hidden: + tok1 = tok; + do { Sym *sym; next(); - sym = label_find(tok); - if (!sym) { - sym = label_push(&s1->asm_labels, tok, 0); - sym->type.t = VT_VOID; - } - sym->type.t &= ~VT_STATIC; + sym = get_asm_sym(tok, NULL); + if (tok1 != TOK_ASMDIR_hidden) + sym->type.t &= ~VT_STATIC; + if (tok1 == TOK_ASMDIR_weak) + sym->a.weak = 1; + else if (tok1 == TOK_ASMDIR_hidden) + sym->a.visibility = STV_HIDDEN; next(); - } + } while (tok == ','); break; - case TOK_ASM_string: - case TOK_ASM_ascii: - case TOK_ASM_asciz: + case TOK_ASMDIR_string: + case TOK_ASMDIR_ascii: + case TOK_ASMDIR_asciz: { const uint8_t *p; int i, size, t; @@ -504,9 +709,9 @@ static void asm_parse_directive(TCCState *s1) for(;;) { if (tok != TOK_STR) expect("string constant"); - p = tokc.cstr->data; - size = tokc.cstr->size; - if (t == TOK_ASM_ascii && size > 0) + p = tokc.str.data; + size = tokc.str.size; + if (t == TOK_ASMDIR_ascii && size > 0) size--; for(i = 0; i < size; i++) g(p[i]); @@ -519,9 +724,9 @@ static void asm_parse_directive(TCCState *s1) } } break; - case TOK_ASM_text: - case TOK_ASM_data: - case TOK_ASM_bss: + case TOK_ASMDIR_text: + case TOK_ASMDIR_data: + case TOK_ASMDIR_bss: { char sname[64]; tok1 = tok; @@ -531,20 +736,110 @@ static void asm_parse_directive(TCCState *s1) n = asm_int_expr(s1); next(); } - sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n); + if (n) + sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n); + else + sprintf(sname, "%s", get_tok_str(tok1, NULL)); use_section(s1, sname); } break; - case TOK_SECTION1: + case TOK_ASMDIR_file: + { + char filename[512]; + + filename[0] = '\0'; + next(); + + if (tok == TOK_STR) + pstrcat(filename, sizeof(filename), tokc.str.data); + else + pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL)); + + if (s1->warn_unsupported) + tcc_warning("ignoring .file %s", filename); + + next(); + } + break; + case TOK_ASMDIR_ident: + { + char ident[256]; + + ident[0] = '\0'; + next(); + + if (tok == TOK_STR) + pstrcat(ident, sizeof(ident), tokc.str.data); + else + pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL)); + + if (s1->warn_unsupported) + tcc_warning("ignoring .ident %s", ident); + + next(); + } + break; + case TOK_ASMDIR_size: + { + Sym *sym; + + next(); + sym = label_find(tok); + if (!sym) { + tcc_error("label not found: %s", get_tok_str(tok, NULL)); + } + + /* XXX .size name,label2-label1 */ + if (s1->warn_unsupported) + tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL)); + + next(); + skip(','); + while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) { + next(); + } + } + break; + case TOK_ASMDIR_type: + { + Sym *sym; + const char *newtype; + + next(); + sym = get_asm_sym(tok, NULL); + next(); + skip(','); + if (tok == TOK_STR) { + newtype = tokc.str.data; + } else { + if (tok == '@' || tok == '%') + next(); + newtype = get_tok_str(tok, NULL); + } + + if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) { + sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; + } + else if (s1->warn_unsupported) + tcc_warning("change type of '%s' from 0x%x to '%s' ignored", + get_tok_str(sym->v, NULL), sym->type.t, newtype); + + next(); + } + break; + case TOK_ASMDIR_pushsection: + case TOK_ASMDIR_section: { char sname[256]; + int old_nb_section = s1->nb_sections; + tok1 = tok; /* XXX: support more options */ next(); sname[0] = '\0'; while (tok != ';' && tok != TOK_LINEFEED && tok != ',') { if (tok == TOK_STR) - pstrcat(sname, sizeof(sname), tokc.cstr->data); + pstrcat(sname, sizeof(sname), tokc.str.data); else pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL)); next(); @@ -555,94 +850,104 @@ static void asm_parse_directive(TCCState *s1) if (tok != TOK_STR) expect("string constant"); next(); + if (tok == ',') { + next(); + if (tok == '@' || tok == '%') + next(); + next(); + } } last_text_section = cur_text_section; - use_section(s1, sname); + if (tok1 == TOK_ASMDIR_section) + use_section(s1, sname); + else + push_section(s1, sname); + /* If we just allocated a new section reset its alignment to + 1. new_section normally acts for GCC compatibility and + sets alignment to PTR_SIZE. The assembler behaves different. */ + if (old_nb_section != s1->nb_sections) + cur_text_section->sh_addralign = 1; } break; - case TOK_ASM_previous: + case TOK_ASMDIR_previous: { Section *sec; next(); if (!last_text_section) - error("no previous section referenced"); + tcc_error("no previous section referenced"); sec = cur_text_section; use_section1(s1, last_text_section); last_text_section = sec; } break; + case TOK_ASMDIR_popsection: + next(); + pop_section(s1); + break; +#ifdef TCC_TARGET_I386 + case TOK_ASMDIR_code16: + { + next(); + s1->seg_size = 16; + } + break; + case TOK_ASMDIR_code32: + { + next(); + s1->seg_size = 32; + } + break; +#endif +#ifdef TCC_TARGET_X86_64 + /* added for compatibility with GAS */ + case TOK_ASMDIR_code64: + next(); + break; +#endif default: - error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); + tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); break; } } /* assemble a file */ -static int tcc_assemble_internal(TCCState *s1, int do_preprocess) +static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) { int opcode; - -#if 0 - /* print stats about opcodes */ - { - const ASMInstr *pa; - int freq[4]; - int op_vals[500]; - int nb_op_vals, i, j; - - nb_op_vals = 0; - memset(freq, 0, sizeof(freq)); - for(pa = asm_instrs; pa->sym != 0; pa++) { - freq[pa->nb_ops]++; - for(i=0;i<pa->nb_ops;i++) { - for(j=0;j<nb_op_vals;j++) { - if (pa->op_type[i] == op_vals[j]) - goto found; - } - op_vals[nb_op_vals++] = pa->op_type[i]; - found: ; - } - } - for(i=0;i<nb_op_vals;i++) { - int v = op_vals[i]; - if ((v & (v - 1)) != 0) - printf("%3d: %08x\n", i, v); - } - printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n", - sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr), - freq[0], freq[1], freq[2], freq[3]); - } -#endif + int saved_parse_flags = parse_flags; /* XXX: undefine C labels */ - - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_ASM_COMMENTS; + parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR; if (do_preprocess) parse_flags |= PARSE_FLAG_PREPROCESS; - next(); for(;;) { + next(); if (tok == TOK_EOF) break; + /* generate line number info */ + if (global && s1->do_debug) + tcc_debug_line(s1); parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ redo: if (tok == '#') { /* horrible gas comment */ while (tok != TOK_LINEFEED) next(); - } else if (tok == '.') { - asm_parse_directive(s1); + } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) { + asm_parse_directive(s1, global); } else if (tok == TOK_PPNUM) { + Sym *sym; const char *p; int n; - p = tokc.cstr->data; + p = tokc.str.data; n = strtoul(p, (char **)&p, 10); if (*p != '\0') expect("':'"); /* new local label */ - asm_new_label(s1, asm_get_local_label_name(s1, n), 1); + sym = asm_new_label(s1, asm_get_local_label_name(s1, n), 1); + /* Remove the marker for tentative definitions. */ + sym->type.t &= ~VT_EXTERN; next(); skip(':'); goto redo; @@ -651,53 +956,51 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess) opcode = tok; next(); if (tok == ':') { + /* handle "extern void vide(void); __asm__("vide: ret");" as + "__asm__("globl vide\nvide: ret");" */ + Sym *sym = sym_find(opcode); + if (sym && (sym->type.t & VT_EXTERN) && global) { + sym = label_find(opcode); + if (!sym) { + sym = label_push(&s1->asm_labels, opcode, 0); + sym->type.t = VT_VOID | VT_EXTERN; + } + } /* new label */ - asm_new_label(s1, opcode, 0); + sym = asm_new_label(s1, opcode, 0); + sym->type.t &= ~VT_EXTERN; next(); goto redo; } else if (tok == '=') { - int n; - next(); - n = asm_int_expr(s1); - asm_new_label1(s1, opcode, 0, SHN_ABS, n); + set_symbol(s1, opcode); goto redo; } else { asm_opcode(s1, opcode); } } /* end of line */ - if (tok != ';' && tok != TOK_LINEFEED){ + if (tok != ';' && tok != TOK_LINEFEED) expect("end of line"); - } parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ - next(); } asm_free_labels(s1); - + parse_flags = saved_parse_flags; return 0; } /* Assemble the current file */ -static int tcc_assemble(TCCState *s1, int do_preprocess) +ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) { - Sym *define_start; int ret; - - preprocess_init(s1); - + tcc_debug_start(s1); /* default section is text */ cur_text_section = text_section; ind = cur_text_section->data_offset; - - define_start = define_stack; - - ret = tcc_assemble_internal(s1, do_preprocess); - + nocode_wanted = 0; + ret = tcc_assemble_internal(s1, do_preprocess, 1); cur_text_section->data_offset = ind; - - free_defines(define_start); - + tcc_debug_end(s1); return ret; } @@ -707,39 +1010,25 @@ static int tcc_assemble(TCCState *s1, int do_preprocess) /* assemble the string 'str' in the current C compilation unit without C preprocessing. NOTE: str is modified by modifying the '\0' at the end */ -static void tcc_assemble_inline(TCCState *s1, char *str, int len) +static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global) { - BufferedFile *bf, *saved_file; - int saved_parse_flags, *saved_macro_ptr; - - bf = tcc_malloc(sizeof(BufferedFile)); - memset(bf, 0, sizeof(BufferedFile)); - bf->fd = -1; - bf->buf_ptr = str; - bf->buf_end = str + len; - str[len] = CH_EOB; - /* same name as current file so that errors are correctly - reported */ - pstrcpy(bf->filename, sizeof(bf->filename), file->filename); - bf->line_num = file->line_num; - saved_file = file; - file = bf; - saved_parse_flags = parse_flags; - saved_macro_ptr = macro_ptr; + const int *saved_macro_ptr = macro_ptr; + int dotid = set_idnum('.', IS_ID); + + tcc_open_bf(s1, ":asm:", len); + memcpy(file->buffer, str, len); macro_ptr = NULL; - - tcc_assemble_internal(s1, 0); + tcc_assemble_internal(s1, 0, global); + tcc_close(); - parse_flags = saved_parse_flags; + set_idnum('.', dotid); macro_ptr = saved_macro_ptr; - file = saved_file; - tcc_free(bf); } /* find a constraint by its number or id (gcc 3 extended syntax). return -1 if not found. Return in *pp in char after the constraint */ -static int find_constraint(ASMOperand *operands, int nb_operands, +ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp) { int index; @@ -778,7 +1067,6 @@ static int find_constraint(ASMOperand *operands, int nb_operands, } static void subst_asm_operands(ASMOperand *operands, int nb_operands, - int nb_outputs, CString *out_str, CString *in_str) { int c, index, modifier; @@ -797,11 +1085,15 @@ static void subst_asm_operands(ASMOperand *operands, int nb_operands, } modifier = 0; if (*str == 'c' || *str == 'n' || - *str == 'b' || *str == 'w' || *str == 'h') + *str == 'b' || *str == 'w' || *str == 'h' || *str == 'k' || + *str == 'q' || + /* P in GCC would add "@PLT" to symbol refs in PIC mode, + and make literal operands not be decorated with '$'. */ + *str == 'P') modifier = *str++; index = find_constraint(operands, nb_operands, str, &str); if (index < 0) - error("invalid operand reference after %%"); + tcc_error("invalid operand reference after %%"); op = &operands[index]; sv = *op->vt; if (op->reg >= 0) { @@ -829,8 +1121,9 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, if (tok != ':') { nb_operands = *nb_operands_ptr; for(;;) { + CString astr; if (nb_operands >= MAX_ASM_OPERANDS) - error("too many asm operands"); + tcc_error("too many asm operands"); op = &operands[nb_operands++]; op->id = 0; if (tok == '[') { @@ -841,15 +1134,15 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, next(); skip(']'); } - if (tok != TOK_STR) - expect("string constant"); - op->constraint = tcc_malloc(tokc.cstr->size); - strcpy(op->constraint, tokc.cstr->data); - next(); + parse_mult_str(&astr, "string constant"); + op->constraint = tcc_malloc(astr.size); + strcpy(op->constraint, astr.data); + cstr_free(&astr); skip('('); gexpr(); if (is_output) { - test_lvalue(); + if (!(vtop->type.t & VT_ARRAY)) + test_lvalue(); } else { /* we want to avoid LLOCAL case, except when the 'm' constraint is used. Note that it may come from @@ -874,27 +1167,12 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, } } -static void parse_asm_str(CString *astr) -{ - skip('('); - /* read the string */ - if (tok != TOK_STR) - expect("string constant"); - cstr_new(astr); - while (tok == TOK_STR) { - /* XXX: add \0 handling too ? */ - cstr_cat(astr, tokc.cstr->data); - next(); - } - cstr_ccat(astr, '\0'); -} - /* parse the GCC asm() instruction */ -static void asm_instr(void) +ST_FUNC void asm_instr(void) { CString astr, astr1; ASMOperand operands[MAX_ASM_OPERANDS]; - int nb_inputs, nb_outputs, nb_operands, i, must_subst, out_reg; + int nb_outputs, nb_operands, i, must_subst, out_reg; uint8_t clobber_regs[NB_ASM_REGS]; next(); @@ -926,7 +1204,7 @@ static void asm_instr(void) for(;;) { if (tok != TOK_STR) expect("string constant"); - asm_clobber(clobber_regs, tokc.cstr->data); + asm_clobber(clobber_regs, tokc.str.data); next(); if (tok == ',') { next(); @@ -943,7 +1221,6 @@ static void asm_instr(void) token after the assembler parsing */ if (tok != ';') expect("';'"); - nb_inputs = nb_operands - nb_outputs; /* save all values in the memory */ save_regs(0); @@ -958,7 +1235,7 @@ static void asm_instr(void) printf("asm: \"%s\"\n", (char *)astr.data); #endif if (must_subst) { - subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr); + subst_asm_operands(operands, nb_operands, &astr1, &astr); cstr_free(&astr); } else { astr1 = astr; @@ -972,7 +1249,7 @@ static void asm_instr(void) clobber_regs, out_reg); /* assemble the string with tcc internal assembler */ - tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1); + tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1, 0); /* restore the current C token */ next(); @@ -991,10 +1268,13 @@ static void asm_instr(void) cstr_free(&astr1); } -static void asm_global_instr(void) +ST_FUNC void asm_global_instr(void) { CString astr; + int saved_nocode_wanted = nocode_wanted; + /* Global asm blocks are always emitted. */ + nocode_wanted = 0; next(); parse_asm_str(&astr); skip(')'); @@ -1010,7 +1290,7 @@ static void asm_global_instr(void) ind = cur_text_section->data_offset; /* assemble the string with tcc internal assembler */ - tcc_assemble_inline(tcc_state, astr.data, astr.size - 1); + tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 1); cur_text_section->data_offset = ind; @@ -1018,4 +1298,6 @@ static void asm_global_instr(void) next(); cstr_free(&astr); + nocode_wanted = saved_nocode_wanted; } +#endif /* CONFIG_TCC_ASM */ diff --git a/tinyc/tcccoff.c b/tinyc/tcccoff.c index 0dcbe50f0..1421ca265 100644 --- a/tinyc/tcccoff.c +++ b/tinyc/tcccoff.c @@ -18,7 +18,8 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "coff.h" + +#include "tcc.h" #define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */ #define MAX_STR_TABLE 1000000 @@ -37,7 +38,7 @@ int EndAddress[MAX_FUNCS]; int LastLineNo[MAX_FUNCS]; int FuncEntries[MAX_FUNCS]; -BOOL OutputTheSection(Section * sect); +int OutputTheSection(Section * sect); short int GetCoffFlags(const char *s); void SortSymbolTable(void); Section *FindSection(TCCState * s1, const char *sname); @@ -73,7 +74,7 @@ typedef struct { unsigned short dummy4; } AUXEF; -int tcc_output_coff(TCCState *s1, FILE *f) +ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f) { Section *tcc_sect; SCNHDR *coff_sec; @@ -532,7 +533,7 @@ int tcc_output_coff(TCCState *s1, FILE *f) } else { if (pCoff_str_table - Coff_str_table + strlen(name) > MAX_STR_TABLE - 1) - error("String table too large"); + tcc_error("String table too large"); csym._n._n_n._n_zeroes = 0; csym._n._n_n._n_offset = @@ -562,11 +563,7 @@ int tcc_output_coff(TCCState *s1, FILE *f) } if (k >= nFuncs) { - char s[256]; - - sprintf(s, "debug info can't find function: %s", name); - - error(s); + tcc_error("debug info can't find function: %s", name); } // put a Function Name @@ -733,13 +730,7 @@ void SortSymbolTable(void) } if (k >= nFuncs) { - char s[256]; - - sprintf(s, - "debug (sort) info can't find function: %s", - name2); - - error(s); + tcc_error("debug (sort) info can't find function: %s", name2); } if (strcmp(AssociatedFile[k], name) == 0) { @@ -766,7 +757,7 @@ void SortSymbolTable(void) } if (n != nb_syms) - error("Internal Compiler error, debug info"); + tcc_error("Internal Compiler error, debug info"); // copy it all back @@ -823,14 +814,14 @@ int FindCoffSymbolIndex(const char *func_name) return n; // total number of symbols } -BOOL OutputTheSection(Section * sect) +int OutputTheSection(Section * sect) { const char *s = sect->name; if (!strcmp(s, ".text")) - return true; + return 1; else if (!strcmp(s, ".data")) - return true; + return 1; else return 0; } @@ -863,11 +854,11 @@ Section *FindSection(TCCState * s1, const char *sname) return s; } - error("could not find section %s", sname); + tcc_error("could not find section %s", sname); return 0; } -int tcc_load_coff(TCCState * s1, int fd) +ST_FUNC int tcc_load_coff(TCCState * s1, int fd) { // tktk TokenSym *ts; @@ -881,39 +872,39 @@ int tcc_load_coff(TCCState * s1, int fd) f = fdopen(fd, "rb"); if (!f) { - error("Unable to open .out file for input"); + tcc_error("Unable to open .out file for input"); } if (fread(&file_hdr, FILHSZ, 1, f) != 1) - error("error reading .out file for input"); + tcc_error("error reading .out file for input"); if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1) - error("error reading .out file for input"); + tcc_error("error reading .out file for input"); // first read the string table if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET)) - error("error reading .out file for input"); + tcc_error("error reading .out file for input"); if (fread(&str_size, sizeof(int), 1, f) != 1) - error("error reading .out file for input"); + tcc_error("error reading .out file for input"); Coff_str_table = (char *) tcc_malloc(str_size); if (fread(Coff_str_table, str_size - 4, 1, f) != 1) - error("error reading .out file for input"); + tcc_error("error reading .out file for input"); // read/process all the symbols // seek back to symbols if (fseek(f, file_hdr.f_symptr, SEEK_SET)) - error("error reading .out file for input"); + tcc_error("error reading .out file for input"); for (i = 0; i < file_hdr.f_nsyms; i++) { if (fread(&csym, SYMESZ, 1, f) != 1) - error("error reading .out file for input"); + tcc_error("error reading .out file for input"); if (csym._n._n_n._n_zeroes == 0) { name = Coff_str_table + csym._n._n_n._n_offset - 4; @@ -942,13 +933,13 @@ int tcc_load_coff(TCCState * s1, int fd) if (name[0] == '_' && strcmp(name, "_main") != 0) name++; - tcc_add_symbol(s1, name, (void*)csym.n_value); + tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value); } // skip any aux records if (csym.n_numaux == 1) { if (fread(&csym, SYMESZ, 1, f) != 1) - error("error reading .out file for input"); + tcc_error("error reading .out file for input"); i++; } } diff --git a/tinyc/tccelf.c b/tinyc/tccelf.c index 4020e249c..22ce5df9c 100644 --- a/tinyc/tccelf.c +++ b/tinyc/tccelf.c @@ -1,6 +1,6 @@ /* * ELF file handling for TCC - * + * * Copyright (c) 2001-2004 Fabrice Bellard * * This library is free software; you can redistribute it and/or @@ -18,22 +18,250 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef TCC_TARGET_X86_64 -#define ElfW_Rel ElfW(Rela) -#define SHT_RELX SHT_RELA -#define REL_SECTION_FMT ".rela%s" -/* x86-64 requires PLT for DLLs */ -#define TCC_OUTPUT_DLL_WITH_PLT -#else -#define ElfW_Rel ElfW(Rel) -#define SHT_RELX SHT_REL -#define REL_SECTION_FMT ".rel%s" +#include "tcc.h" + +/* Define this to get some debug output during relocation processing. */ +#undef DEBUG_RELOC + +/********************************************************/ +/* global variables */ + +ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ +ST_DATA Section *common_section; +ST_DATA Section *cur_text_section; /* current section where function code is generated */ +#ifdef CONFIG_TCC_ASM +ST_DATA Section *last_text_section; /* to handle .previous asm directive */ +#endif +#ifdef CONFIG_TCC_BCHECK +/* bound check related sections */ +ST_DATA Section *bounds_section; /* contains global data bound description */ +ST_DATA Section *lbounds_section; /* contains local data bound description */ +#endif +/* symbol sections */ +ST_DATA Section *symtab_section, *strtab_section; +/* debug sections */ +ST_DATA Section *stab_section, *stabstr_section; + +/* XXX: avoid static variable */ +static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */ + +/* ------------------------------------------------------------------------- */ + +ST_FUNC void tccelf_new(TCCState *s) +{ + /* no section zero */ + dynarray_add(&s->sections, &s->nb_sections, NULL); + + /* create standard sections */ + text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); + data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); + bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); + common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE); + common_section->sh_num = SHN_COMMON; + + /* symbols are always generated for linking stage */ + symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, + ".strtab", + ".hashtab", SHF_PRIVATE); + strtab_section = symtab_section->link; + s->symtab = symtab_section; + + /* private symbol table for dynamic symbols */ + s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, + ".dynstrtab", + ".dynhashtab", SHF_PRIVATE); + get_sym_attr(s, 0, 1); +} + +#ifdef CONFIG_TCC_BCHECK +ST_FUNC void tccelf_bounds_new(TCCState *s) +{ + /* create bounds sections */ + bounds_section = new_section(s, ".bounds", + SHT_PROGBITS, SHF_ALLOC); + lbounds_section = new_section(s, ".lbounds", + SHT_PROGBITS, SHF_ALLOC); +} +#endif + +ST_FUNC void tccelf_stab_new(TCCState *s) +{ + stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); + stab_section->sh_entsize = sizeof(Stab_Sym); + stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); + put_elf_str(stabstr_section, ""); + stab_section->link = stabstr_section; + /* put first entry */ + put_stabs("", 0, 0, 0, 0); +} + +static void free_section(Section *s) +{ + tcc_free(s->data); +} + +ST_FUNC void tccelf_delete(TCCState *s1) +{ + int i; + + /* free all sections */ + for(i = 1; i < s1->nb_sections; i++) + free_section(s1->sections[i]); + dynarray_reset(&s1->sections, &s1->nb_sections); + + for(i = 0; i < s1->nb_priv_sections; i++) + free_section(s1->priv_sections[i]); + dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections); + + /* free any loaded DLLs */ +#ifdef TCC_IS_NATIVE + for ( i = 0; i < s1->nb_loaded_dlls; i++) { + DLLReference *ref = s1->loaded_dlls[i]; + if ( ref->handle ) +# ifdef _WIN32 + FreeLibrary((HMODULE)ref->handle); +# else + dlclose(ref->handle); +# endif + } #endif + /* free loaded dlls array */ + dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls); + tcc_free(s1->sym_attrs); +} + +ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) +{ + Section *sec; + + sec = tcc_mallocz(sizeof(Section) + strlen(name)); + strcpy(sec->name, name); + sec->sh_type = sh_type; + sec->sh_flags = sh_flags; + switch(sh_type) { + case SHT_HASH: + case SHT_REL: + case SHT_RELA: + case SHT_DYNSYM: + case SHT_SYMTAB: + case SHT_DYNAMIC: + sec->sh_addralign = 4; + break; + case SHT_STRTAB: + sec->sh_addralign = 1; + break; + default: + sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */ + break; + } + + if (sh_flags & SHF_PRIVATE) { + dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec); + } else { + sec->sh_num = s1->nb_sections; + dynarray_add(&s1->sections, &s1->nb_sections, sec); + } + + return sec; +} + +ST_FUNC Section *new_symtab(TCCState *s1, + const char *symtab_name, int sh_type, int sh_flags, + const char *strtab_name, + const char *hash_name, int hash_sh_flags) +{ + Section *symtab, *strtab, *hash; + int *ptr, nb_buckets; + + symtab = new_section(s1, symtab_name, sh_type, sh_flags); + symtab->sh_entsize = sizeof(ElfW(Sym)); + strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags); + put_elf_str(strtab, ""); + symtab->link = strtab; + put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL); + + nb_buckets = 1; + + hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags); + hash->sh_entsize = sizeof(int); + symtab->hash = hash; + hash->link = symtab; + + ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int)); + ptr[0] = nb_buckets; + ptr[1] = 1; + memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int)); + return symtab; +} + +/* realloc section and set its content to zero */ +ST_FUNC void section_realloc(Section *sec, unsigned long new_size) +{ + unsigned long size; + unsigned char *data; + + size = sec->data_allocated; + if (size == 0) + size = 1; + while (size < new_size) + size = size * 2; + data = tcc_realloc(sec->data, size); + memset(data + sec->data_allocated, 0, size - sec->data_allocated); + sec->data = data; + sec->data_allocated = size; +} + +/* reserve at least 'size' bytes aligned per 'align' in section + 'sec' from current offset, and return the aligned offset */ +ST_FUNC size_t section_add(Section *sec, addr_t size, int align) +{ + size_t offset, offset1; + + offset = (sec->data_offset + align - 1) & -align; + offset1 = offset + size; + if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated) + section_realloc(sec, offset1); + sec->data_offset = offset1; + if (align > sec->sh_addralign) + sec->sh_addralign = align; + return offset; +} -/* XXX: DLL with PLT would only work with x86-64 for now */ -//#define TCC_OUTPUT_DLL_WITH_PLT +/* reserve at least 'size' bytes in section 'sec' from + sec->data_offset. */ +ST_FUNC void *section_ptr_add(Section *sec, addr_t size) +{ + size_t offset = section_add(sec, size, 1); + return sec->data + offset; +} + +/* reserve at least 'size' bytes from section start */ +ST_FUNC void section_reserve(Section *sec, unsigned long size) +{ + if (size > sec->data_allocated) + section_realloc(sec, size); + if (size > sec->data_offset) + sec->data_offset = size; +} -static int put_elf_str(Section *s, const char *sym) +/* return a reference to a section, and create it if it does not + exists */ +ST_FUNC Section *find_section(TCCState *s1, const char *name) +{ + Section *sec; + int i; + for(i = 1; i < s1->nb_sections; i++) { + sec = s1->sections[i]; + if (!strcmp(name, sec->name)) + return sec; + } + /* sections are created as PROGBITS */ + return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC); +} + +/* ------------------------------------------------------------------------- */ + +ST_FUNC int put_elf_str(Section *s, const char *sym) { int offset, len; char *ptr; @@ -49,7 +277,7 @@ static int put_elf_str(Section *s, const char *sym) static unsigned long elf_hash(const unsigned char *name) { unsigned long h = 0, g; - + while (*name) { h = (h << 4) + *name++; g = h & 0xf0000000; @@ -66,7 +294,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets) { ElfW(Sym) *sym; int *ptr, *hash, nb_syms, sym_index, h; - char *strtab; + unsigned char *strtab; strtab = s->link->data; nb_syms = s->data_offset / sizeof(ElfW(Sym)); @@ -95,15 +323,14 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets) } /* return the symbol number */ -static int put_elf_sym(Section *s, - unsigned long value, unsigned long size, - int info, int other, int shndx, const char *name) +ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, + int info, int other, int shndx, const char *name) { int name_offset, sym_index; int nbuckets, h; ElfW(Sym) *sym; Section *hs; - + sym = section_ptr_add(s, sizeof(ElfW(Sym))); if (name) name_offset = put_elf_str(s->link, name); @@ -126,7 +353,7 @@ static int put_elf_sym(Section *s, if (ELFW(ST_BIND)(info) != STB_LOCAL) { /* add another hashing entry */ nbuckets = base[0]; - h = elf_hash(name) % nbuckets; + h = elf_hash((unsigned char *) name) % nbuckets; *ptr = base[2 + h]; base[2 + h] = sym_index; base[1]++; @@ -145,22 +372,22 @@ static int put_elf_sym(Section *s, /* find global ELF symbol 'name' and return its index. Return 0 if not found. */ -static int find_elf_sym(Section *s, const char *name) +ST_FUNC int find_elf_sym(Section *s, const char *name) { ElfW(Sym) *sym; Section *hs; int nbuckets, sym_index, h; const char *name1; - + hs = s->hash; if (!hs) return 0; nbuckets = ((int *)hs->data)[0]; - h = elf_hash(name) % nbuckets; + h = elf_hash((unsigned char *) name) % nbuckets; sym_index = ((int *)hs->data)[2 + h]; while (sym_index != 0) { sym = &((ElfW(Sym) *)s->data)[sym_index]; - name1 = s->link->data + sym->st_name; + name1 = (char *) s->link->data + sym->st_name; if (!strcmp(name, name1)) return sym_index; sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; @@ -168,31 +395,40 @@ static int find_elf_sym(Section *s, const char *name) return 0; } -/* return elf symbol value or error */ -void *tcc_get_symbol(TCCState *s, const char *name) +/* return elf symbol value, signal error if 'err' is nonzero */ +ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err) { int sym_index; ElfW(Sym) *sym; - sym_index = find_elf_sym(symtab_section, name); - if (!sym_index) - return NULL; - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - return (void*)(long)sym->st_value; + + sym_index = find_elf_sym(s->symtab, name); + sym = &((ElfW(Sym) *)s->symtab->data)[sym_index]; + if (!sym_index || sym->st_shndx == SHN_UNDEF) { + if (err) + tcc_error("%s not defined", name); + return 0; + } + return sym->st_value; } -void *tcc_get_symbol_err(TCCState *s, const char *name) +/* return elf symbol value */ +LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) { - void *sym; - sym = tcc_get_symbol(s, name); - if (!sym) - error("%s not defined", name); - return sym; + return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0); } +#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE +/* return elf symbol value or error */ +ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) +{ + return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1); +} +#endif + /* add an elf symbol : check if it is already defined and patch it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */ -static int add_elf_sym(Section *s, unsigned long value, unsigned long size, - int info, int other, int sh_num, const char *name) +ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, + int info, int other, int shndx, const char *name) { ElfW(Sym) *esym; int sym_bind, sym_index, sym_type, esym_bind; @@ -201,13 +437,18 @@ static int add_elf_sym(Section *s, unsigned long value, unsigned long size, sym_bind = ELFW(ST_BIND)(info); sym_type = ELFW(ST_TYPE)(info); sym_vis = ELFW(ST_VISIBILITY)(other); - + + sym_index = find_elf_sym(s, name); + esym = &((ElfW(Sym) *)s->data)[sym_index]; + if (sym_index && esym->st_value == value && esym->st_size == size + && esym->st_info == info && esym->st_other == other + && esym->st_shndx == shndx) + return sym_index; + if (sym_bind != STB_LOCAL) { /* we search global or weak symbols */ - sym_index = find_elf_sym(s, name); if (!sym_index) goto do_def; - esym = &((ElfW(Sym) *)s->data)[sym_index]; if (esym->st_shndx != SHN_UNDEF) { esym_bind = ELFW(ST_BIND)(esym->st_info); /* propagate the most constraining visibility */ @@ -223,7 +464,7 @@ static int add_elf_sym(Section *s, unsigned long value, unsigned long size, esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | new_vis; other = esym->st_other; /* in case we have to patch esym */ - if (sh_num == SHN_UNDEF) { + if (shndx == SHN_UNDEF) { /* ignore adding of undefined symbol if the corresponding symbol is already defined */ } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) { @@ -231,41 +472,48 @@ static int add_elf_sym(Section *s, unsigned long value, unsigned long size, goto do_patch; } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) { /* weak is ignored if already global */ + } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) { + /* keep first-found weak definition, ignore subsequents */ } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) { /* ignore hidden symbols after */ - } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) { - /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01 - No idea if this is the correct solution ... */ + } else if ((esym->st_shndx == SHN_COMMON + || esym->st_shndx == bss_section->sh_num) + && (shndx < SHN_LORESERVE + && shndx != bss_section->sh_num)) { + /* data symbol gets precedence over common/bss */ goto do_patch; + } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) { + /* data symbol keeps precedence over common/bss */ } else if (s == tcc_state->dynsymtab_section) { /* we accept that two DLL define the same symbol */ } else { -#if 1 +#if 0 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", - sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis); + sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis); #endif - error_noabort("'%s' defined twice", name); + tcc_error_noabort("'%s' defined twice", name); } } else { do_patch: esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type); - esym->st_shndx = sh_num; + esym->st_shndx = shndx; + new_undef_sym = 1; esym->st_value = value; esym->st_size = size; esym->st_other = other; } } else { do_def: - sym_index = put_elf_sym(s, value, size, - ELFW(ST_INFO)(sym_bind, sym_type), other, - sh_num, name); + sym_index = put_elf_sym(s, value, size, + ELFW(ST_INFO)(sym_bind, sym_type), other, + shndx, name); } return sym_index; } /* put relocation */ -static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, - int type, int symbol) +ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, + int type, int symbol, addr_t addend) { char buf[256]; Section *sr; @@ -286,22 +534,60 @@ static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, rel = section_ptr_add(sr, sizeof(ElfW_Rel)); rel->r_offset = offset; rel->r_info = ELFW(R_INFO)(symbol, type); -#ifdef TCC_TARGET_X86_64 - rel->r_addend = 0; +#if SHT_RELX == SHT_RELA + rel->r_addend = addend; +#else + if (addend) + tcc_error("non-zero addend on REL architecture"); #endif } -/* put stab debug information */ +ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, + int type, int symbol) +{ + put_elf_reloca(symtab, s, offset, type, symbol, 0); +} -typedef struct { - unsigned int n_strx; /* index into string table of name */ - unsigned char n_type; /* type of symbol */ - unsigned char n_other; /* misc info (usually empty) */ - unsigned short n_desc; /* description field */ - unsigned int n_value; /* value of symbol */ -} Stab_Sym; +/* Remove relocations for section S->reloc starting at oldrelocoffset + that are to the same place, retaining the last of them. As side effect + the relocations are sorted. Possibly reduces the number of relocs. */ +ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset) +{ + Section *sr = s->reloc; + ElfW_Rel *r, *dest; + ssize_t a; + ElfW(Addr) addr; + + if (oldrelocoffset + sizeof(*r) >= sr->data_offset) + return; + /* The relocs we're dealing with are the result of initializer parsing. + So they will be mostly in order and there aren't many of them. + Secondly we need a stable sort (which qsort isn't). We use + a simple insertion sort. */ + for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) { + ssize_t i = a - sizeof(*r); + addr = ((ElfW_Rel*)(sr->data + a))->r_offset; + for (; i >= (ssize_t)oldrelocoffset && + ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) { + ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a); + *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i); + *(ElfW_Rel*)(sr->data + i) = tmp; + } + } -static void put_stabs(const char *str, int type, int other, int desc, + r = (ElfW_Rel*)(sr->data + oldrelocoffset); + dest = r; + for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) { + if (dest->r_offset != r->r_offset) + dest++; + *dest = *r; + } + sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r); +} + +/* put stab debug information */ + +ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value) { Stab_Sym *sym; @@ -318,25 +604,52 @@ static void put_stabs(const char *str, int type, int other, int desc, sym->n_value = value; } -static void put_stabs_r(const char *str, int type, int other, int desc, +ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index) { put_stabs(str, type, other, desc, value); - put_elf_reloc(symtab_section, stab_section, + put_elf_reloc(symtab_section, stab_section, stab_section->data_offset - sizeof(unsigned int), R_DATA_32, sym_index); } -static void put_stabn(int type, int other, int desc, int value) +ST_FUNC void put_stabn(int type, int other, int desc, int value) { put_stabs(NULL, type, other, desc, value); } -static void put_stabd(int type, int other, int desc) +ST_FUNC void put_stabd(int type, int other, int desc) { put_stabs(NULL, type, other, desc, 0); } +ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc) +{ + int n; + struct sym_attr *tab; + + if (index >= s1->nb_sym_attrs) { + if (!alloc) + return s1->sym_attrs; + /* find immediately bigger power of 2 and reallocate array */ + n = 1; + while (index >= n) + n *= 2; + tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs)); + s1->sym_attrs = tab; + memset(s1->sym_attrs + s1->nb_sym_attrs, 0, + (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs)); + s1->nb_sym_attrs = n; + } + return &s1->sym_attrs[index]; +} + +/* Browse each elem of type <type> in section <sec> starting at elem <startoff> + using variable <elem> */ +#define for_each_elem(sec, startoff, elem, type) \ + for (elem = (type *) sec->data + startoff; \ + elem < (type *) (sec->data + sec->data_offset); elem++) + /* In an ELF file symbol table, the local symbols must appear below the global and weak ones. Since TCC cannot sort it while generating the code, we must do it after. All the relocation tables are also @@ -347,7 +660,7 @@ static void sort_syms(TCCState *s1, Section *s) ElfW(Sym) *new_syms; int nb_syms, i; ElfW(Sym) *p, *q; - ElfW_Rel *rel, *rel_end; + ElfW_Rel *rel; Section *sr; int type, sym_index; @@ -366,7 +679,8 @@ static void sort_syms(TCCState *s1, Section *s) p++; } /* save the number of local symbols in section header */ - s->sh_info = q - new_syms; + if( s->sh_size ) /* this 'if' makes IDA happy */ + s->sh_info = q - new_syms; /* then second pass for non local symbols */ p = (ElfW(Sym) *)s->data; @@ -377,7 +691,7 @@ static void sort_syms(TCCState *s1, Section *s) } p++; } - + /* we copy the new symbols to the old */ memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym))); tcc_free(new_syms); @@ -386,10 +700,7 @@ static void sort_syms(TCCState *s1, Section *s) for(i = 1; i < s1->nb_sections; i++) { sr = s1->sections[i]; if (sr->sh_type == SHT_RELX && sr->link == s) { - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - for(rel = (ElfW_Rel *)sr->data; - rel < rel_end; - rel++) { + for_each_elem(sr, 0, rel, ElfW_Rel) { sym_index = ELFW(R_SYM)(rel->r_info); type = ELFW(R_TYPE)(rel->r_info); sym_index = old_to_new_syms[sym_index]; @@ -397,65 +708,52 @@ static void sort_syms(TCCState *s1, Section *s) } } } - + tcc_free(old_to_new_syms); } /* relocate common symbols in the .bss section */ -static void relocate_common_syms(void) -{ - ElfW(Sym) *sym, *sym_end; - unsigned long offset, align; - - sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { +ST_FUNC void relocate_common_syms(void) +{ + ElfW(Sym) *sym; + + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { if (sym->st_shndx == SHN_COMMON) { - /* align symbol */ - align = sym->st_value; - offset = bss_section->data_offset; - offset = (offset + align - 1) & -align; - sym->st_value = offset; + /* symbol alignment is in st_value for SHN_COMMONs */ + sym->st_value = section_add(bss_section, sym->st_size, + sym->st_value); sym->st_shndx = bss_section->sh_num; - offset += sym->st_size; - bss_section->data_offset = offset; } } } /* relocate symbol table, resolve undefined symbols if do_resolve is true and output error if undefined symbol. */ -static void relocate_syms(TCCState *s1, int do_resolve) +ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) { - ElfW(Sym) *sym, *esym, *sym_end; - int sym_bind, sh_num, sym_index; + ElfW(Sym) *sym; + int sym_bind, sh_num; const char *name; - unsigned long addr; - sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { + for_each_elem(symtab, 1, sym, ElfW(Sym)) { sh_num = sym->st_shndx; if (sh_num == SHN_UNDEF) { - name = strtab_section->data + sym->st_name; + name = (char *) strtab_section->data + sym->st_name; + /* Use ld.so to resolve symbol for us (for tcc -run) */ if (do_resolve) { - name = symtab_section->link->data + sym->st_name; - addr = (unsigned long)resolve_sym(s1, name, ELFW(ST_TYPE)(sym->st_info)); +#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE + void *addr = dlsym(RTLD_DEFAULT, name); if (addr) { - sym->st_value = addr; - goto found; - } - } else if (s1->dynsym) { - /* if dynamic symbol exist, then use it */ - sym_index = find_elf_sym(s1->dynsym, name); - if (sym_index) { - esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index]; - sym->st_value = esym->st_value; + sym->st_value = (addr_t) addr; +#ifdef DEBUG_RELOC + printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value); +#endif goto found; } - } +#endif + /* if dynamic symbol exist, it will be used in relocate_section */ + } else if (s1->dynsym && find_elf_sym(s1->dynsym, name)) + goto found; /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */ if (!strcmp(name, "_fp_hw")) @@ -463,11 +761,10 @@ static void relocate_syms(TCCState *s1, int do_resolve) /* only weak symbols are accepted to be undefined. Their value is zero */ sym_bind = ELFW(ST_BIND)(sym->st_info); - if (sym_bind == STB_WEAK) { + if (sym_bind == STB_WEAK) sym->st_value = 0; - } else { - error_noabort("undefined symbol '%s'", name); - } + else + tcc_error_noabort("undefined symbol '%s'", name); } else if (sh_num < SHN_LORESERVE) { /* add section base */ sym->st_value += s1->sections[sym->st_shndx]->sh_addr; @@ -476,258 +773,30 @@ static void relocate_syms(TCCState *s1, int do_resolve) } } -#ifdef TCC_TARGET_X86_64 -#define JMP_TABLE_ENTRY_SIZE 14 -static unsigned long add_jmp_table(TCCState *s1, unsigned long val) -{ - char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset; - s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; - /* jmp *0x0(%rip) */ - p[0] = 0xff; - p[1] = 0x25; - *(int *)(p + 2) = 0; - *(unsigned long *)(p + 6) = val; - return (unsigned long)p; -} - -static unsigned long add_got_table(TCCState *s1, unsigned long val) +/* relocate a given section (CPU dependent) by applying the relocations + in the associated relocation section */ +ST_FUNC void relocate_section(TCCState *s1, Section *s) { - unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got + - s1->runtime_plt_and_got_offset); - s1->runtime_plt_and_got_offset += sizeof(void *); - *p = val; - return (unsigned long)p; -} -#endif - -/* relocate a given section (CPU dependent) */ -static void relocate_section(TCCState *s1, Section *s) -{ - Section *sr; - ElfW_Rel *rel, *rel_end, *qrel; + Section *sr = s->reloc; + ElfW_Rel *rel; ElfW(Sym) *sym; int type, sym_index; unsigned char *ptr; - unsigned long val, addr; -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - int esym_index; -#endif + addr_t tgt, addr; - sr = s->reloc; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - qrel = (ElfW_Rel *)sr->data; - for(rel = qrel; - rel < rel_end; - rel++) { - ptr = s->data + rel->r_offset; + relocate_init(sr); + for_each_elem(sr, 0, rel, ElfW_Rel) { + ptr = s->data + rel->r_offset; sym_index = ELFW(R_SYM)(rel->r_info); sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - val = sym->st_value; -#ifdef TCC_TARGET_X86_64 - /* XXX: not tested */ - val += rel->r_addend; -#endif type = ELFW(R_TYPE)(rel->r_info); - addr = s->sh_addr + rel->r_offset; - - /* CPU specific */ - switch(type) { -#if defined(TCC_TARGET_I386) - case R_386_32: - if (s1->output_type == TCC_OUTPUT_DLL) { - esym_index = s1->symtab_to_dynsym[sym_index]; - qrel->r_offset = rel->r_offset; - if (esym_index) { - qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32); - qrel++; - break; - } else { - qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE); - qrel++; - } - } - *(int *)ptr += val; - break; - case R_386_PC32: - if (s1->output_type == TCC_OUTPUT_DLL) { - /* DLL relocation */ - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_index) { - qrel->r_offset = rel->r_offset; - qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32); - qrel++; - break; - } - } - *(int *)ptr += val - addr; - break; - case R_386_PLT32: - *(int *)ptr += val - addr; - break; - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - *(int *)ptr = val; - break; - case R_386_GOTPC: - *(int *)ptr += s1->got->sh_addr - addr; - break; - case R_386_GOTOFF: - *(int *)ptr += val - s1->got->sh_addr; - break; - case R_386_GOT32: - /* we load the got offset */ - *(int *)ptr += s1->got_offsets[sym_index]; - break; -#elif defined(TCC_TARGET_ARM) - case R_ARM_PC24: - case R_ARM_CALL: - case R_ARM_JUMP24: - case R_ARM_PLT32: - { - int x; - x = (*(int *)ptr)&0xffffff; - (*(int *)ptr) &= 0xff000000; - if (x & 0x800000) - x -= 0x1000000; - x *= 4; - x += val - addr; - if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000) - error("can't relocate value at %x",addr); - x >>= 2; - x &= 0xffffff; - (*(int *)ptr) |= x; - } - break; - case R_ARM_PREL31: - { - int x; - x = (*(int *)ptr) & 0x7fffffff; - (*(int *)ptr) &= 0x80000000; - x = (x * 2) / 2; - x += val - addr; - if((x^(x>>1))&0x40000000) - error("can't relocate value at %x",addr); - (*(int *)ptr) |= x & 0x7fffffff; - } - case R_ARM_ABS32: - *(int *)ptr += val; - break; - case R_ARM_BASE_PREL: - *(int *)ptr += s1->got->sh_addr - addr; - break; - case R_ARM_GOTOFF32: - *(int *)ptr += val - s1->got->sh_addr; - break; - case R_ARM_GOT_BREL: - /* we load the got offset */ - *(int *)ptr += s1->got_offsets[sym_index]; - break; - case R_ARM_COPY: - break; - default: - fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n", - type,addr,(unsigned int )ptr,val); - break; -#elif defined(TCC_TARGET_C67) - case R_C60_32: - *(int *)ptr += val; - break; - case R_C60LO16: - { - uint32_t orig; - - /* put the low 16 bits of the absolute address */ - // add to what is already there - - orig = ((*(int *)(ptr )) >> 7) & 0xffff; - orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16; - - //patch both at once - assumes always in pairs Low - High - - *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7); - *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7); - } - break; - case R_C60HI16: - break; - default: - fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n", - type,addr,(unsigned int )ptr,val); - break; -#elif defined(TCC_TARGET_X86_64) - case R_X86_64_64: - if (s1->output_type == TCC_OUTPUT_DLL) { - qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); - qrel->r_addend = *(long long *)ptr + val; - qrel++; - } - *(long long *)ptr += val; - break; - case R_X86_64_32: - case R_X86_64_32S: - if (s1->output_type == TCC_OUTPUT_DLL) { - /* XXX: this logic may depend on TCC's codegen - now TCC uses R_X86_64_32 even for a 64bit pointer */ - qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); - qrel->r_addend = *(int *)ptr + val; - qrel++; - } - *(int *)ptr += val; - break; - case R_X86_64_PC32: { - if (s1->output_type == TCC_OUTPUT_DLL) { - /* DLL relocation */ - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_index) { - qrel->r_offset = rel->r_offset; - qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32); - qrel->r_addend = *(int *)ptr; - qrel++; - break; - } - } - long diff = val - addr; - if (diff <= -2147483647 || diff > 2147483647) { - /* XXX: naive support for over 32bit jump */ - if (s1->output_type == TCC_OUTPUT_MEMORY) { - val = add_jmp_table(s1, val); - diff = val - addr; - } - if (diff <= -2147483647 || diff > 2147483647) { - error("internal error: relocation failed"); - } - } - *(int *)ptr += diff; - } - break; - case R_X86_64_PLT32: - *(int *)ptr += val - addr; - break; - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - *(int *)ptr = val; - break; - case R_X86_64_GOTPCREL: - if (s1->output_type == TCC_OUTPUT_MEMORY) { - val = add_got_table(s1, val - rel->r_addend) + rel->r_addend; - *(int *)ptr += val - addr; - break; - } - *(int *)ptr += (s1->got->sh_addr - addr + - s1->got_offsets[sym_index] - 4); - break; - case R_X86_64_GOTTPOFF: - *(int *)ptr += val - s1->got->sh_addr; - break; - case R_X86_64_GOT32: - /* we load the got offset */ - *(int *)ptr += s1->got_offsets[sym_index]; - break; -#else -#error unsupported processor + tgt = sym->st_value; +#if SHT_RELX == SHT_RELA + tgt += rel->r_addend; #endif - } + addr = s->sh_addr + rel->r_offset; + relocate(s1, rel, type, ptr, addr, tgt); } /* if the relocation is allocated, we change its symbol table */ if (sr->sh_flags & SHF_ALLOC) @@ -738,32 +807,33 @@ static void relocate_section(TCCState *s1, Section *s) static void relocate_rel(TCCState *s1, Section *sr) { Section *s; - ElfW_Rel *rel, *rel_end; - + ElfW_Rel *rel; + s = s1->sections[sr->sh_info]; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - for(rel = (ElfW_Rel *)sr->data; - rel < rel_end; - rel++) { + for_each_elem(sr, 0, rel, ElfW_Rel) rel->r_offset += s->sh_addr; - } } /* count the number of dynamic relocations so that we can reserve their space */ static int prepare_dynamic_rel(TCCState *s1, Section *sr) { - ElfW_Rel *rel, *rel_end; - int sym_index, esym_index, type, count; + ElfW_Rel *rel; + int sym_index, type, count; count = 0; - rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); - for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) { + for_each_elem(sr, 0, rel, ElfW_Rel) { sym_index = ELFW(R_SYM)(rel->r_info); type = ELFW(R_TYPE)(rel->r_info); switch(type) { #if defined(TCC_TARGET_I386) case R_386_32: + if (!get_sym_attr(s1, sym_index, 0)->dyn_index + && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) { + /* don't fixup unresolved (weak) symbols */ + rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE); + break; + } #elif defined(TCC_TARGET_X86_64) case R_X86_64_32: case R_X86_64_32S: @@ -776,8 +846,7 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) #elif defined(TCC_TARGET_X86_64) case R_X86_64_PC32: #endif - esym_index = s1->symtab_to_dynsym[sym_index]; - if (esym_index) + if (get_sym_attr(s1, sym_index, 0)->dyn_index) count++; break; default: @@ -792,203 +861,120 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) return count; } -static void put_got_offset(TCCState *s1, int index, unsigned long val) -{ - int n; - unsigned long *tab; - - if (index >= s1->nb_got_offsets) { - /* find immediately bigger power of 2 and reallocate array */ - n = 1; - while (index >= n) - n *= 2; - tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long)); - if (!tab) - error("memory full"); - s1->got_offsets = tab; - memset(s1->got_offsets + s1->nb_got_offsets, 0, - (n - s1->nb_got_offsets) * sizeof(unsigned long)); - s1->nb_got_offsets = n; - } - s1->got_offsets[index] = val; -} - -/* XXX: suppress that */ -static void put32(unsigned char *p, uint32_t val) -{ - p[0] = val; - p[1] = val >> 8; - p[2] = val >> 16; - p[3] = val >> 24; -} - -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \ - defined(TCC_TARGET_X86_64) -static uint32_t get32(unsigned char *p) -{ - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -} -#endif - static void build_got(TCCState *s1) { - unsigned char *ptr; - /* if no got, then create it */ s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); s1->got->sh_entsize = 4; - add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), + set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_"); - ptr = section_ptr_add(s1->got, 3 * PTR_SIZE); -#if PTR_SIZE == 4 - /* keep space for _DYNAMIC pointer, if present */ - put32(ptr, 0); - /* two dummy got entries */ - put32(ptr + 4, 0); - put32(ptr + 8, 0); -#else - /* keep space for _DYNAMIC pointer, if present */ - put32(ptr, 0); - put32(ptr + 4, 0); - /* two dummy got entries */ - put32(ptr + 8, 0); - put32(ptr + 12, 0); - put32(ptr + 16, 0); - put32(ptr + 20, 0); -#endif + /* keep space for _DYNAMIC pointer and two dummy got entries */ + section_ptr_add(s1->got, 3 * PTR_SIZE); } -/* put a got entry corresponding to a symbol in symtab_section. 'size' - and 'info' can be modifed if more precise info comes from the DLL */ -static void put_got_entry(TCCState *s1, - int reloc_type, unsigned long size, int info, - int sym_index) +/* Create a GOT and (for function call) a PLT entry corresponding to a symbol + in s1->symtab. When creating the dynamic symbol table entry for the GOT + relocation, use 'size' and 'info' for the corresponding symbol metadata. + Returns the offset of the GOT or (if any) PLT entry. */ +static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type, + unsigned long size, + int info, int sym_index) { - int index; + int need_plt_entry; const char *name; ElfW(Sym) *sym; - unsigned long offset; - int *ptr; - - if (!s1->got) - build_got(s1); - - /* if a got entry already exists for that symbol, no need to add one */ - if (sym_index < s1->nb_got_offsets && - s1->got_offsets[sym_index] != 0) - return; - - put_got_offset(s1, sym_index, s1->got->data_offset); + struct sym_attr *attr; + unsigned got_offset; + char plt_name[100]; + int len; + + need_plt_entry = (dyn_reloc_type == R_JMP_SLOT); + attr = get_sym_attr(s1, sym_index, 1); + + /* In case a function is both called and its address taken 2 GOT entries + are created, one for taking the address (GOT) and the other for the PLT + entry (PLTGOT). */ + if (need_plt_entry ? attr->plt_offset : attr->got_offset) + return attr; + + /* create the GOT entry */ + got_offset = s1->got->data_offset; + section_ptr_add(s1->got, PTR_SIZE); + + /* Create the GOT relocation that will insert the address of the object or + function of interest in the GOT entry. This is a static relocation for + memory output (dlsym will give us the address of symbols) and dynamic + relocation otherwise (executable and DLLs). The relocation should be + done lazily for GOT entry with *_JUMP_SLOT relocation type (the one + associated to a PLT entry) but is currently done at load time for an + unknown reason. */ + + sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; + name = (char *) symtab_section->link->data + sym->st_name; if (s1->dynsym) { - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - name = symtab_section->link->data + sym->st_name; - offset = sym->st_value; -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) - if (reloc_type == -#ifdef TCC_TARGET_X86_64 - R_X86_64_JUMP_SLOT -#else - R_386_JMP_SLOT -#endif - ) { - Section *plt; - uint8_t *p; - int modrm; + if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) { + /* Hack alarm. We don't want to emit dynamic symbols + and symbol based relocs for STB_LOCAL symbols, but rather + want to resolve them directly. At this point the symbol + values aren't final yet, so we must defer this. We will later + have to create a RELATIVE reloc anyway, so we misuse the + relocation slot to smuggle the symbol reference until + fill_local_got_entries. Not that the sym_index is + relative to symtab_section, not s1->dynsym! Nevertheless + we use s1->dyn_sym so that if this is the first call + that got->reloc is correctly created. Also note that + RELATIVE relocs are not normally created for the .got, + so the types serves as a marker for later (and is retained + also for the final output, which is okay because then the + got is just normal data). */ + put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE, + sym_index); + } else { + if (0 == attr->dyn_index) + attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size, + info, 0, sym->st_shndx, name); + put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type, + attr->dyn_index); + } + } else { + put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type, + sym_index); + } -#if defined(TCC_OUTPUT_DLL_WITH_PLT) - modrm = 0x25; -#else - /* if we build a DLL, we add a %ebx offset */ - if (s1->output_type == TCC_OUTPUT_DLL) - modrm = 0xa3; - else - modrm = 0x25; -#endif + if (need_plt_entry) { + if (!s1->plt) { + s1->plt = new_section(s1, ".plt", SHT_PROGBITS, + SHF_ALLOC | SHF_EXECINSTR); + s1->plt->sh_entsize = 4; + } - /* add a PLT entry */ - plt = s1->plt; - if (plt->data_offset == 0) { - /* first plt entry */ - p = section_ptr_add(plt, 16); - p[0] = 0xff; /* pushl got + PTR_SIZE */ - p[1] = modrm + 0x10; - put32(p + 2, PTR_SIZE); - p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */ - p[7] = modrm; - put32(p + 8, PTR_SIZE * 2); - } + attr->plt_offset = create_plt_entry(s1, got_offset, attr); - p = section_ptr_add(plt, 16); - p[0] = 0xff; /* jmp *(got + x) */ - p[1] = modrm; - put32(p + 2, s1->got->data_offset); - p[6] = 0x68; /* push $xxx */ - put32(p + 7, (plt->data_offset - 32) >> 1); - p[11] = 0xe9; /* jmp plt_start */ - put32(p + 12, -(plt->data_offset)); - - /* the symbol is modified so that it will be relocated to - the PLT */ -#if !defined(TCC_OUTPUT_DLL_WITH_PLT) - if (s1->output_type == TCC_OUTPUT_EXE) -#endif - offset = plt->data_offset - 16; - } -#elif defined(TCC_TARGET_ARM) - if (reloc_type == R_ARM_JUMP_SLOT) { - Section *plt; - uint8_t *p; - - /* if we build a DLL, we add a %ebx offset */ - if (s1->output_type == TCC_OUTPUT_DLL) - error("DLLs unimplemented!"); - - /* add a PLT entry */ - plt = s1->plt; - if (plt->data_offset == 0) { - /* first plt entry */ - p = section_ptr_add(plt, 16); - put32(p , 0xe52de004); - put32(p + 4, 0xe59fe010); - put32(p + 8, 0xe08fe00e); - put32(p + 12, 0xe5bef008); - } + /* create a symbol 'sym@plt' for the PLT jump vector */ + len = strlen(name); + if (len > sizeof plt_name - 5) + len = sizeof plt_name - 5; + memcpy(plt_name, name, len); + strcpy(plt_name + len, "@plt"); + attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size, + ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name); - p = section_ptr_add(plt, 16); - put32(p , 0xe59fc004); - put32(p+4, 0xe08fc00c); - put32(p+8, 0xe59cf000); - put32(p+12, s1->got->data_offset); + } else { + attr->got_offset = got_offset; + } - /* the symbol is modified so that it will be relocated to - the PLT */ - if (s1->output_type == TCC_OUTPUT_EXE) - offset = plt->data_offset - 16; - } -#elif defined(TCC_TARGET_C67) - error("C67 got not implemented"); -#else -#error unsupported CPU -#endif - index = put_elf_sym(s1->dynsym, offset, - size, info, 0, sym->st_shndx, name); - /* put a got entry */ - put_elf_reloc(s1->dynsym, s1->got, - s1->got->data_offset, - reloc_type, index); - } - ptr = section_ptr_add(s1->got, PTR_SIZE); - *ptr = 0; + return attr; } /* build GOT and PLT entries */ -static void build_got_entries(TCCState *s1) +ST_FUNC void build_got_entries(TCCState *s1) { - Section *s, *symtab; - ElfW_Rel *rel, *rel_end; + Section *s; + ElfW_Rel *rel; ElfW(Sym) *sym; - int i, type, reloc_type, sym_index; + int i, type, gotplt_entry, reloc_type, sym_index; + struct sym_attr *attr; for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[i]; @@ -997,131 +983,85 @@ static void build_got_entries(TCCState *s1) /* no need to handle got relocations */ if (s->link != symtab_section) continue; - symtab = s->link; - rel_end = (ElfW_Rel *)(s->data + s->data_offset); - for(rel = (ElfW_Rel *)s->data; - rel < rel_end; - rel++) { + for_each_elem(s, 0, rel, ElfW_Rel) { type = ELFW(R_TYPE)(rel->r_info); - switch(type) { -#if defined(TCC_TARGET_I386) - case R_386_GOT32: - case R_386_GOTOFF: - case R_386_GOTPC: - case R_386_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_386_GOT32 || type == R_386_PLT32) { - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_386_GOT32) - reloc_type = R_386_GLOB_DAT; - else - reloc_type = R_386_JMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#elif defined(TCC_TARGET_ARM) - case R_ARM_GOT_BREL: - case R_ARM_GOTOFF32: - case R_ARM_BASE_PREL: - case R_ARM_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) { - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_ARM_GOT_BREL) - reloc_type = R_ARM_GLOB_DAT; - else - reloc_type = R_ARM_JUMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#elif defined(TCC_TARGET_C67) - case R_C60_GOT32: - case R_C60_GOTOFF: - case R_C60_GOTPC: - case R_C60_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_C60_GOT32 || type == R_C60_PLT32) { - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_C60_GOT32) - reloc_type = R_C60_GLOB_DAT; - else - reloc_type = R_C60_JMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#elif defined(TCC_TARGET_X86_64) - case R_X86_64_GOT32: - case R_X86_64_GOTTPOFF: - case R_X86_64_GOTPCREL: - case R_X86_64_PLT32: - if (!s1->got) - build_got(s1); - if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL || - type == R_X86_64_PLT32) { - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - /* look at the symbol got offset. If none, then add one */ - if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL) - reloc_type = R_X86_64_GLOB_DAT; - else - reloc_type = R_X86_64_JUMP_SLOT; - put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, - sym_index); - } - break; -#else -#error unsupported CPU + gotplt_entry = gotplt_entry_type(type); + sym_index = ELFW(R_SYM)(rel->r_info); + sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; + + if (gotplt_entry == NO_GOTPLT_ENTRY) { + continue; + } + + /* Automatically create PLT/GOT [entry] if it is an undefined + reference (resolved at runtime), or the symbol is absolute, + probably created by tcc_add_symbol, and thus on 64-bit + targets might be too far from application code. */ + if (gotplt_entry == AUTO_GOTPLT_ENTRY) { + if (sym->st_shndx == SHN_UNDEF) { + ElfW(Sym) *esym; + int dynindex; + if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT) + continue; + /* Relocations for UNDEF symbols would normally need + to be transferred into the executable or shared object. + If that were done AUTO_GOTPLT_ENTRY wouldn't exist. + But TCC doesn't do that (at least for exes), so we + need to resolve all such relocs locally. And that + means PLT slots for functions in DLLs and COPY relocs for + data symbols. COPY relocs were generated in + bind_exe_dynsyms (and the symbol adjusted to be defined), + and for functions we were generated a dynamic symbol + of function type. */ + if (s1->dynsym) { + /* dynsym isn't set for -run :-/ */ + dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index; + esym = (ElfW(Sym) *)s1->dynsym->data + dynindex; + if (dynindex + && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC + || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE + && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC))) + goto jmp_slot; + } + } else if (!(sym->st_shndx == SHN_ABS +#ifndef TCC_TARGET_ARM + && PTR_SIZE == 8 #endif - default: - break; + )) + continue; } - } - } -} -static Section *new_symtab(TCCState *s1, - const char *symtab_name, int sh_type, int sh_flags, - const char *strtab_name, - const char *hash_name, int hash_sh_flags) -{ - Section *symtab, *strtab, *hash; - int *ptr, nb_buckets; +#ifdef TCC_TARGET_X86_64 + if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) && + (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT || + ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)) { + rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32); + continue; + } +#endif + if (code_reloc(type)) { + jmp_slot: + reloc_type = R_JMP_SLOT; + } else + reloc_type = R_GLOB_DAT; - symtab = new_section(s1, symtab_name, sh_type, sh_flags); - symtab->sh_entsize = sizeof(ElfW(Sym)); - strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags); - put_elf_str(strtab, ""); - symtab->link = strtab; - put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL); - - nb_buckets = 1; + if (!s1->got) + build_got(s1); - hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags); - hash->sh_entsize = sizeof(int); - symtab->hash = hash; - hash->link = symtab; + if (gotplt_entry == BUILD_GOT_ONLY) + continue; - ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int)); - ptr[0] = nb_buckets; - ptr[1] = 1; - memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int)); - return symtab; + attr = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, + sym_index); + + if (reloc_type == R_JMP_SLOT) + rel->r_info = ELFW(R_INFO)(attr->plt_sym, type); + } + } } /* put dynamic tag */ -static void put_dt(Section *dynamic, int dt, unsigned long val) +static void put_dt(Section *dynamic, int dt, addr_t val) { ElfW(Dyn) *dyn; dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn))); @@ -1129,13 +1069,14 @@ static void put_dt(Section *dynamic, int dt, unsigned long val) dyn->d_un.d_val = val; } +#ifndef TCC_TARGET_PE static void add_init_array_defines(TCCState *s1, const char *section_name) { Section *s; long end_offset; char sym_start[1024]; char sym_end[1024]; - + snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1); snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1); @@ -1147,96 +1088,106 @@ static void add_init_array_defines(TCCState *s1, const char *section_name) end_offset = s->data_offset; } - add_elf_sym(symtab_section, + set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, s->sh_num, sym_start); - add_elf_sym(symtab_section, + set_elf_sym(symtab_section, end_offset, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, s->sh_num, sym_end); } +#endif -/* add tcc runtime libraries */ -static void tcc_add_runtime(TCCState *s1) +static int tcc_add_support(TCCState *s1, const char *filename) { -#if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC) char buf[1024]; -#endif + snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename); + return tcc_add_file(s1, buf); +} +ST_FUNC void tcc_add_bcheck(TCCState *s1) +{ #ifdef CONFIG_TCC_BCHECK - if (s1->do_bounds_check) { - unsigned long *ptr; - Section *init_section; - unsigned char *pinit; - int sym_index; - - /* XXX: add an object file to do that */ - ptr = section_ptr_add(bounds_section, sizeof(unsigned long)); - *ptr = 0; - add_elf_sym(symtab_section, 0, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - bounds_section->sh_num, "__bounds_start"); - /* add bound check code */ - snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "bcheck.o"); - tcc_add_file(s1, buf); -#ifdef TCC_TARGET_I386 - if (s1->output_type != TCC_OUTPUT_MEMORY) { - /* add 'call __bound_init()' in .init section */ - init_section = find_section(s1, ".init"); - pinit = section_ptr_add(init_section, 5); - pinit[0] = 0xe8; - put32(pinit + 1, -4); - sym_index = find_elf_sym(symtab_section, "__bound_init"); - put_elf_reloc(symtab_section, init_section, - init_section->data_offset - 4, R_386_PC32, sym_index); - } -#endif + addr_t *ptr; + int sym_index; + + if (0 == s1->do_bounds_check) + return; + /* XXX: add an object file to do that */ + ptr = section_ptr_add(bounds_section, sizeof(*ptr)); + *ptr = 0; + set_elf_sym(symtab_section, 0, 0, + ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, + bounds_section->sh_num, "__bounds_start"); + /* pull bcheck.o from libtcc1.a */ + sym_index = set_elf_sym(symtab_section, 0, 0, + ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, + SHN_UNDEF, "__bound_init"); + if (s1->output_type != TCC_OUTPUT_MEMORY) { + /* add 'call __bound_init()' in .init section */ + Section *init_section = find_section(s1, ".init"); + unsigned char *pinit = section_ptr_add(init_section, 5); + pinit[0] = 0xe8; + write32le(pinit + 1, -4); + put_elf_reloc(symtab_section, init_section, + init_section->data_offset - 4, R_386_PC32, sym_index); + /* R_386_PC32 = R_X86_64_PC32 = 2 */ } #endif +} + +/* add tcc runtime libraries */ +ST_FUNC void tcc_add_runtime(TCCState *s1) +{ + tcc_add_bcheck(s1); + tcc_add_pragma_libs(s1); /* add libc */ if (!s1->nostdlib) { - tcc_add_library(s1, "c"); - -#ifdef CONFIG_USE_LIBGCC - tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1"); -#else - snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "libtcc1.a"); - tcc_add_file(s1, buf); + tcc_add_library_err(s1, "c"); +#ifdef TCC_LIBGCC + if (!s1->static_link) { + if (TCC_LIBGCC[0] == '/') + tcc_add_file(s1, TCC_LIBGCC); + else + tcc_add_dll(s1, TCC_LIBGCC, 0); + } #endif - } - /* add crt end if not memory output */ - if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) { - tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o"); + tcc_add_support(s1, TCC_LIBTCC1); + /* add crt end if not memory output */ + if (s1->output_type != TCC_OUTPUT_MEMORY) + tcc_add_crt(s1, "crtn.o"); } } /* add various standard linker symbols (must be done after the sections are filled (for example after allocating common symbols)) */ -static void tcc_add_linker_symbols(TCCState *s1) +ST_FUNC void tcc_add_linker_symbols(TCCState *s1) { char buf[1024]; int i; Section *s; - add_elf_sym(symtab_section, + set_elf_sym(symtab_section, text_section->data_offset, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, text_section->sh_num, "_etext"); - add_elf_sym(symtab_section, + set_elf_sym(symtab_section, data_section->data_offset, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, data_section->sh_num, "_edata"); - add_elf_sym(symtab_section, + set_elf_sym(symtab_section, bss_section->data_offset, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, bss_section->sh_num, "_end"); +#ifndef TCC_TARGET_PE /* horrible new standard ldscript defines */ add_init_array_defines(s1, ".preinit_array"); add_init_array_defines(s1, ".init_array"); add_init_array_defines(s1, ".fini_array"); - +#endif + /* add start and stop symbols for sections whose name can be expressed in C */ for(i = 1; i < s1->nb_sections; i++) { @@ -1257,12 +1208,12 @@ static void tcc_add_linker_symbols(TCCState *s1) p++; } snprintf(buf, sizeof(buf), "__start_%s", s->name); - add_elf_sym(symtab_section, + set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, s->sh_num, buf); snprintf(buf, sizeof(buf), "__stop_%s", s->name); - add_elf_sym(symtab_section, + set_elf_sym(symtab_section, s->data_offset, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, s->sh_num, buf); @@ -1271,28 +1222,15 @@ static void tcc_add_linker_symbols(TCCState *s1) } } -/* name of ELF interpreter */ -#if defined __FreeBSD__ -static char elf_interp[] = "/usr/libexec/ld-elf.so.1"; -#elif defined TCC_ARM_EABI -static char elf_interp[] = "/lib/ld-linux.so.3"; -#elif defined(TCC_TARGET_X86_64) -static char elf_interp[] = "/lib/ld-linux-x86-64.so.2"; -#elif defined(TCC_UCLIBC) -static char elf_interp[] = "/lib/ld-uClibc.so.0"; -#else -static char elf_interp[] = "/lib/ld-linux.so.2"; -#endif - static void tcc_output_binary(TCCState *s1, FILE *f, - const int *section_order) + const int *sec_order) { Section *s; int i, offset, size; offset = 0; for(i=1;i<s1->nb_sections;i++) { - s = s1->sections[section_order[i]]; + s = s1->sections[sec_order[i]]; if (s->sh_type != SHT_NOBITS && (s->sh_flags & SHF_ALLOC)) { while (offset < s->sh_offset) { @@ -1306,306 +1244,287 @@ static void tcc_output_binary(TCCState *s1, FILE *f, } } -/* output an ELF file */ -/* XXX: suppress unneeded sections */ -int elf_output_file(TCCState *s1, const char *filename) +ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) { - ElfW(Ehdr) ehdr; - FILE *f; - int fd, mode, ret; - int *section_order; - int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k; - unsigned long addr; - Section *strsec, *s; - ElfW(Shdr) shdr, *sh; - ElfW(Phdr) *phdr, *ph; - Section *interp, *dynamic, *dynstr; - unsigned long saved_dynamic_data_offset; - ElfW(Sym) *sym; - int type, file_type; - unsigned long rel_addr, rel_size; - - file_type = s1->output_type; - s1->nb_errors = 0; + int sym_index = ELFW(R_SYM) (rel->r_info); + ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; + struct sym_attr *attr = get_sym_attr(s1, sym_index, 0); + unsigned offset = attr->got_offset; - if (file_type != TCC_OUTPUT_OBJ) { - tcc_add_runtime(s1); - } - - phdr = NULL; - section_order = NULL; - interp = NULL; - dynamic = NULL; - dynstr = NULL; /* avoid warning */ - saved_dynamic_data_offset = 0; /* avoid warning */ - - if (file_type != TCC_OUTPUT_OBJ) { - relocate_common_syms(); + if (0 == offset) + return; + section_reserve(s1->got, offset + PTR_SIZE); +#ifdef TCC_TARGET_X86_64 + write64le(s1->got->data + offset, sym->st_value); +#else + write32le(s1->got->data + offset, sym->st_value); +#endif +} - tcc_add_linker_symbols(s1); +/* Perform relocation to GOT or PLT entries */ +ST_FUNC void fill_got(TCCState *s1) +{ + Section *s; + ElfW_Rel *rel; + int i; - if (!s1->static_link) { - const char *name; - int sym_index, index; - ElfW(Sym) *esym, *sym_end; - - if (file_type == TCC_OUTPUT_EXE) { - char *ptr; - /* add interpreter section only if executable */ - interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); - interp->sh_addralign = 1; - ptr = section_ptr_add(interp, sizeof(elf_interp)); - strcpy(ptr, elf_interp); + for(i = 1; i < s1->nb_sections; i++) { + s = s1->sections[i]; + if (s->sh_type != SHT_RELX) + continue; + /* no need to handle got relocations */ + if (s->link != symtab_section) + continue; + for_each_elem(s, 0, rel, ElfW_Rel) { + switch (ELFW(R_TYPE) (rel->r_info)) { + case R_X86_64_GOT32: + case R_X86_64_GOTPCREL: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: + case R_X86_64_PLT32: + fill_got_entry(s1, rel); + break; } - - /* add dynamic symbol table */ - s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC, - ".dynstr", - ".hash", SHF_ALLOC); - dynstr = s1->dynsym->link; - - /* add dynamic section */ - dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, - SHF_ALLOC | SHF_WRITE); - dynamic->link = dynstr; - dynamic->sh_entsize = sizeof(ElfW(Dyn)); - - /* add PLT */ - s1->plt = new_section(s1, ".plt", SHT_PROGBITS, - SHF_ALLOC | SHF_EXECINSTR); - s1->plt->sh_entsize = 4; + } + } +} - build_got(s1); +/* See put_got_entry for a description. This is the second stage + where GOT references to local defined symbols are rewritten. */ +static void fill_local_got_entries(TCCState *s1) +{ + ElfW_Rel *rel; + for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) { + if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) { + int sym_index = ELFW(R_SYM) (rel->r_info); + ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; + struct sym_attr *attr = get_sym_attr(s1, sym_index, 0); + unsigned offset = attr->got_offset; + if (offset != rel->r_offset - s1->got->sh_addr) + tcc_error_noabort("huh"); + rel->r_info = ELFW(R_INFO)(0, R_RELATIVE); +#if SHT_RELX == SHT_RELA + rel->r_addend = sym->st_value; +#else + /* All our REL architectures also happen to be 32bit LE. */ + write32le(s1->got->data + offset, sym->st_value); +#endif + } + } +} - /* scan for undefined symbols and see if they are in the - dynamic symbols. If a symbol STT_FUNC is found, then we - add it in the PLT. If a symbol STT_OBJECT is found, we - add it in the .bss section with a suitable relocation */ - sym_end = (ElfW(Sym) *)(symtab_section->data + - symtab_section->data_offset); - if (file_type == TCC_OUTPUT_EXE) { - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { - if (sym->st_shndx == SHN_UNDEF) { - name = symtab_section->link->data + sym->st_name; - sym_index = find_elf_sym(s1->dynsymtab_section, name); - if (sym_index) { - esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; - type = ELFW(ST_TYPE)(esym->st_info); - if (type == STT_FUNC) { - put_got_entry(s1, R_JMP_SLOT, esym->st_size, - esym->st_info, - sym - (ElfW(Sym) *)symtab_section->data); - } else if (type == STT_OBJECT) { - unsigned long offset; - offset = bss_section->data_offset; - /* XXX: which alignment ? */ - offset = (offset + 16 - 1) & -16; - index = put_elf_sym(s1->dynsym, offset, esym->st_size, - esym->st_info, 0, - bss_section->sh_num, name); - put_elf_reloc(s1->dynsym, bss_section, - offset, R_COPY, index); - offset += esym->st_size; - bss_section->data_offset = offset; - } - } else { - /* STB_WEAK undefined symbols are accepted */ - /* XXX: _fp_hw seems to be part of the ABI, so we ignore - it */ - if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK || - !strcmp(name, "_fp_hw")) { - } else { - error_noabort("undefined symbol '%s'", name); +/* Bind symbols of executable: resolve undefined symbols from exported symbols + in shared libraries and export non local defined symbols to shared libraries + if -rdynamic switch was given on command line */ +static void bind_exe_dynsyms(TCCState *s1) +{ + const char *name; + int sym_index, index; + ElfW(Sym) *sym, *esym; + int type; + + /* Resolve undefined symbols from dynamic symbols. When there is a match: + - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT + - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */ + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + if (sym->st_shndx == SHN_UNDEF) { + name = (char *) symtab_section->link->data + sym->st_name; + sym_index = find_elf_sym(s1->dynsymtab_section, name); + if (sym_index) { + esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; + type = ELFW(ST_TYPE)(esym->st_info); + if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { + /* Indirect functions shall have STT_FUNC type in executable + * dynsym section. Indeed, a dlsym call following a lazy + * resolution would pick the symbol value from the + * executable dynsym entry which would contain the address + * of the function wanted by the caller of dlsym instead of + * the address of the function that would return that + * address */ + int dynindex + = put_elf_sym(s1->dynsym, 0, esym->st_size, + ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0, + name); + int index = sym - (ElfW(Sym) *) symtab_section->data; + get_sym_attr(s1, index, 1)->dyn_index = dynindex; + } else if (type == STT_OBJECT) { + unsigned long offset; + ElfW(Sym) *dynsym; + offset = bss_section->data_offset; + /* XXX: which alignment ? */ + offset = (offset + 16 - 1) & -16; + set_elf_sym (s1->symtab, offset, esym->st_size, + esym->st_info, 0, bss_section->sh_num, name); + index = put_elf_sym(s1->dynsym, offset, esym->st_size, + esym->st_info, 0, bss_section->sh_num, + name); + + /* Ensure R_COPY works for weak symbol aliases */ + if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) { + for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) { + if ((dynsym->st_value == esym->st_value) + && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) { + char *dynname = (char *) s1->dynsymtab_section->link->data + + dynsym->st_name; + put_elf_sym(s1->dynsym, offset, dynsym->st_size, + dynsym->st_info, 0, + bss_section->sh_num, dynname); + break; } } - } else if (s1->rdynamic && - ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - /* if -rdynamic option, then export all non - local symbols */ - name = symtab_section->link->data + sym->st_name; - put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); } - } - - if (s1->nb_errors) - goto fail; - /* now look at unresolved dynamic symbols and export - corresponding symbol */ - sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data + - s1->dynsymtab_section->data_offset); - for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; - esym < sym_end; - esym++) { - if (esym->st_shndx == SHN_UNDEF) { - name = s1->dynsymtab_section->link->data + esym->st_name; - sym_index = find_elf_sym(symtab_section, name); - if (sym_index) { - /* XXX: avoid adding a symbol if already - present because of -rdynamic ? */ - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); - } else { - if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) { - /* weak symbols can stay undefined */ - } else { - warning("undefined dynamic symbol '%s'", name); - } - } - } + put_elf_reloc(s1->dynsym, bss_section, + offset, R_COPY, index); + offset += esym->st_size; + bss_section->data_offset = offset; } } else { - int nb_syms; - /* shared library case : we simply export all the global symbols */ - nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym)); - s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); - for(sym = (ElfW(Sym) *)symtab_section->data + 1; - sym < sym_end; - sym++) { - if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { -#if defined(TCC_OUTPUT_DLL_WITH_PLT) - if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC && - sym->st_shndx == SHN_UNDEF) { - put_got_entry(s1, R_JMP_SLOT, sym->st_size, - sym->st_info, - sym - (ElfW(Sym) *)symtab_section->data); - } - else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) { - put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size, - sym->st_info, - sym - (ElfW(Sym) *)symtab_section->data); - } - else -#endif - { - name = symtab_section->link->data + sym->st_name; - index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, - sym->st_info, 0, - sym->st_shndx, name); - s1->symtab_to_dynsym[sym - - (ElfW(Sym) *)symtab_section->data] = - index; - } - } + /* STB_WEAK undefined symbols are accepted */ + /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */ + if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK || + !strcmp(name, "_fp_hw")) { + } else { + tcc_error_noabort("undefined symbol '%s'", name); } } + } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { + /* if -rdynamic option, then export all non local symbols */ + name = (char *) symtab_section->link->data + sym->st_name; + set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, + 0, sym->st_shndx, name); + } + } +} - build_got_entries(s1); - - /* add a list of needed dlls */ - for(i = 0; i < s1->nb_loaded_dlls; i++) { - DLLReference *dllref = s1->loaded_dlls[i]; - if (dllref->level == 0) - put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); - } - /* XXX: currently, since we do not handle PIC code, we - must relocate the readonly segments */ - if (file_type == TCC_OUTPUT_DLL) { - if (s1->soname) - put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); - put_dt(dynamic, DT_TEXTREL, 0); - } +/* Bind symbols of libraries: export all non local symbols of executable that + are referenced by shared libraries. The reason is that the dynamic loader + search symbol first in executable and then in libraries. Therefore a + reference to a symbol already defined by a library can still be resolved by + a symbol in the executable. */ +static void bind_libs_dynsyms(TCCState *s1) +{ + const char *name; + int sym_index; + ElfW(Sym) *sym, *esym; - /* add necessary space for other entries */ - saved_dynamic_data_offset = dynamic->data_offset; - dynamic->data_offset += sizeof(ElfW(Dyn)) * 9; - } else { - /* still need to build got entries in case of static link */ - build_got_entries(s1); + for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { + name = (char *) s1->dynsymtab_section->link->data + esym->st_name; + sym_index = find_elf_sym(symtab_section, name); + sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; + if (sym_index && sym->st_shndx != SHN_UNDEF + && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { + set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, + sym->st_info, 0, sym->st_shndx, name); + } else if (esym->st_shndx == SHN_UNDEF) { + /* weak symbols can stay undefined */ + if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) + tcc_warning("undefined dynamic symbol '%s'", name); } } +} - memset(&ehdr, 0, sizeof(ehdr)); - - /* we add a section for symbols */ - strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); - put_elf_str(strsec, ""); - - /* compute number of sections */ - shnum = s1->nb_sections; +/* Export all non local symbols. This is used by shared libraries so that the + non local symbols they define can resolve a reference in another shared + library or in the executable. Correspondingly, it allows undefined local + symbols to be resolved by other shared libraries or by the executable. */ +static void export_global_syms(TCCState *s1) +{ + int dynindex, index; + const char *name; + ElfW(Sym) *sym; - /* this array is used to reorder sections in the output file */ - section_order = tcc_malloc(sizeof(int) * shnum); - section_order[0] = 0; - sh_order_index = 1; - - /* compute number of program headers */ - switch(file_type) { - default: - case TCC_OUTPUT_OBJ: - phnum = 0; - break; - case TCC_OUTPUT_EXE: - if (!s1->static_link) - phnum = 4; - else - phnum = 2; - break; - case TCC_OUTPUT_DLL: - phnum = 3; - break; + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { + if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { + name = (char *) symtab_section->link->data + sym->st_name; + dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, + sym->st_info, 0, sym->st_shndx, name); + index = sym - (ElfW(Sym) *) symtab_section->data; + get_sym_attr(s1, index, 1)->dyn_index = dynindex; + } } +} + +/* Allocate strings for section names and decide if an unallocated section + should be output. + NOTE: the strsec section comes last, so its size is also correct ! */ +static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec) +{ + int i; + Section *s; + int textrel = 0; - /* allocate strings for section names and decide if an unallocated - section should be output */ - /* NOTE: the strsec section comes last, so its size is also - correct ! */ + /* Allocate strings for section names */ for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[i]; - s->sh_name = put_elf_str(strsec, s->name); -#if 0 //gr - printf("section: f=%08x t=%08x i=%08x %s %s\n", - s->sh_flags, - s->sh_type, - s->sh_info, - s->name, - s->reloc ? s->reloc->name : "n" - ); -#endif /* when generating a DLL, we include relocations but we may patch them */ - if (file_type == TCC_OUTPUT_DLL && - s->sh_type == SHT_RELX && - !(s->sh_flags & SHF_ALLOC)) { - /* //gr: avoid bogus relocs for empty (debug) sections */ - if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) - prepare_dynamic_rel(s1, s); - else if (s1->do_debug) - s->sh_size = s->data_offset; + if (file_type == TCC_OUTPUT_DLL && + s->sh_type == SHT_RELX && + !(s->sh_flags & SHF_ALLOC) && + (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) && + prepare_dynamic_rel(s1, s)) { + if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR) + textrel = 1; } else if (s1->do_debug || - file_type == TCC_OUTPUT_OBJ || + file_type == TCC_OUTPUT_OBJ || (s->sh_flags & SHF_ALLOC) || - i == (s1->nb_sections - 1)) { + i == (s1->nb_sections - 1)) { /* we output all sections if debug or object file */ s->sh_size = s->data_offset; } + if (s->sh_size || (s->sh_flags & SHF_ALLOC)) + s->sh_name = put_elf_str(strsec, s->name); } + strsec->sh_size = strsec->data_offset; + return textrel; +} - /* allocate program segment headers */ - phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); - - if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { +/* Info to be copied in dynamic section */ +struct dyn_inf { + Section *dynamic; + Section *dynstr; + unsigned long data_offset; + addr_t rel_addr; + addr_t rel_size; +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + addr_t bss_addr; + addr_t bss_size; +#endif +}; + +/* Assign sections to segments and decide how are sections laid out when loaded + in memory. This function also fills corresponding program headers. */ +static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, + Section *interp, Section* strsec, + struct dyn_inf *dyninf, int *sec_order) +{ + int i, j, k, file_type, sh_order_index, file_offset; + unsigned long s_align; + long long tmp; + addr_t addr; + ElfW(Phdr) *ph; + Section *s; + + file_type = s1->output_type; + sh_order_index = 1; + file_offset = 0; + if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); - } else { - file_offset = 0; - } + s_align = ELF_PAGE_SIZE; + if (s1->section_align) + s_align = s1->section_align; + if (phnum > 0) { - /* compute section to program header mapping */ - if (s1->has_text_addr) { + if (s1->has_text_addr) { int a_offset, p_offset; addr = s1->text_addr; /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset % ELF_PAGE_SIZE */ - a_offset = addr & (ELF_PAGE_SIZE - 1); - p_offset = file_offset & (ELF_PAGE_SIZE - 1); - if (a_offset < p_offset) - a_offset += ELF_PAGE_SIZE; + a_offset = (int) (addr & (s_align - 1)); + p_offset = file_offset & (s_align - 1); + if (a_offset < p_offset) + a_offset += s_align; file_offset += (a_offset - p_offset); } else { if (file_type == TCC_OUTPUT_DLL) @@ -1613,17 +1532,21 @@ int elf_output_file(TCCState *s1, const char *filename) else addr = ELF_START_ADDR; /* compute address after headers */ - addr += (file_offset & (ELF_PAGE_SIZE - 1)); + addr += (file_offset & (s_align - 1)); } - - /* dynamic relocation table information, for .dynamic section */ - rel_size = 0; - rel_addr = 0; - /* leave one program header for the program interpreter */ ph = &phdr[0]; + /* Leave one program headers for the program interpreter and one for + the program header table itself if needed. These are done later as + they require section layout to be done first. */ if (interp) - ph++; + ph += 2; + + /* dynamic relocation table information, for .dynamic section */ + dyninf->rel_addr = dyninf->rel_size = 0; +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + dyninf->bss_addr = dyninf->bss_size = 0; +#endif for(j = 0; j < 2; j++) { ph->p_type = PT_LOAD; @@ -1631,21 +1554,23 @@ int elf_output_file(TCCState *s1, const char *filename) ph->p_flags = PF_R | PF_X; else ph->p_flags = PF_R | PF_W; - ph->p_align = ELF_PAGE_SIZE; - - /* we do the following ordering: interp, symbol tables, - relocations, progbits, nobits */ + ph->p_align = s_align; + + /* Decide the layout of sections loaded in memory. This must + be done before program headers are filled since they contain + info about the layout. We do the following ordering: interp, + symbol tables, relocations, progbits, nobits */ /* XXX: do faster and simpler sorting */ for(k = 0; k < 5; k++) { for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[i]; /* compute if section should be included */ if (j == 0) { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != + if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != SHF_ALLOC) continue; } else { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != + if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != (SHF_ALLOC | SHF_WRITE)) continue; } @@ -1667,16 +1592,16 @@ int elf_output_file(TCCState *s1, const char *filename) if (k != 3) continue; } - section_order[sh_order_index++] = i; + sec_order[sh_order_index++] = i; /* section matches: we align it and add its size */ tmp = addr; - addr = (addr + s->sh_addralign - 1) & + addr = (addr + s->sh_addralign - 1) & ~(s->sh_addralign - 1); - file_offset += addr - tmp; + file_offset += (int) ( addr - tmp ); s->sh_offset = file_offset; s->sh_addr = addr; - + /* update program header infos */ if (ph->p_offset == 0) { ph->p_offset = file_offset; @@ -1685,15 +1610,35 @@ int elf_output_file(TCCState *s1, const char *filename) } /* update dynamic relocation infos */ if (s->sh_type == SHT_RELX) { - if (rel_size == 0) - rel_addr = addr; - rel_size += s->sh_size; +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { + dyninf->rel_addr = addr; + dyninf->rel_size += s->sh_size; /* XXX only first rel. */ + } + if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) { + dyninf->bss_addr = addr; + dyninf->bss_size = s->sh_size; /* XXX only first rel. */ + } +#else + if (dyninf->rel_size == 0) + dyninf->rel_addr = addr; + dyninf->rel_size += s->sh_size; +#endif } addr += s->sh_size; if (s->sh_type != SHT_NOBITS) file_offset += s->sh_size; } } + if (j == 0) { + /* Make the first PT_LOAD segment include the program + headers itself (and the ELF header as well), it'll + come out with same memory use but will make various + tools like binutils strip work better. */ + ph->p_offset &= ~(ph->p_align - 1); + ph->p_vaddr &= ~(ph->p_align - 1); + ph->p_paddr &= ~(ph->p_align - 1); + } ph->p_filesz = file_offset - ph->p_offset; ph->p_memsz = addr - ph->p_vaddr; ph++; @@ -1701,305 +1646,527 @@ int elf_output_file(TCCState *s1, const char *filename) if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { /* if in the middle of a page, we duplicate the page in memory so that one copy is RX and the other is RW */ - if ((addr & (ELF_PAGE_SIZE - 1)) != 0) - addr += ELF_PAGE_SIZE; + if ((addr & (s_align - 1)) != 0) + addr += s_align; } else { - addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1); - file_offset = (file_offset + ELF_PAGE_SIZE - 1) & - ~(ELF_PAGE_SIZE - 1); + addr = (addr + s_align - 1) & ~(s_align - 1); + file_offset = (file_offset + s_align - 1) & ~(s_align - 1); } } } + } - /* if interpreter, then add corresponing program header */ - if (interp) { - ph = &phdr[0]; - - ph->p_type = PT_INTERP; - ph->p_offset = interp->sh_offset; - ph->p_vaddr = interp->sh_addr; - ph->p_paddr = ph->p_vaddr; - ph->p_filesz = interp->sh_size; - ph->p_memsz = interp->sh_size; - ph->p_flags = PF_R; - ph->p_align = interp->sh_addralign; - } - - /* if dynamic section, then add corresponing program header */ - if (dynamic) { - ElfW(Sym) *sym_end; - - ph = &phdr[phnum - 1]; - - ph->p_type = PT_DYNAMIC; - ph->p_offset = dynamic->sh_offset; - ph->p_vaddr = dynamic->sh_addr; - ph->p_paddr = ph->p_vaddr; - ph->p_filesz = dynamic->sh_size; - ph->p_memsz = dynamic->sh_size; - ph->p_flags = PF_R | PF_W; - ph->p_align = dynamic->sh_addralign; - - /* put GOT dynamic section address */ - put32(s1->got->data, dynamic->sh_addr); - - /* relocate the PLT */ - if (file_type == TCC_OUTPUT_EXE -#if defined(TCC_OUTPUT_DLL_WITH_PLT) - || file_type == TCC_OUTPUT_DLL -#endif - ) { - uint8_t *p, *p_end; + /* all other sections come after */ + for(i = 1; i < s1->nb_sections; i++) { + s = s1->sections[i]; + if (phnum > 0 && (s->sh_flags & SHF_ALLOC)) + continue; + sec_order[sh_order_index++] = i; - p = s1->plt->data; - p_end = p + s1->plt->data_offset; - if (p < p_end) { -#if defined(TCC_TARGET_I386) - put32(p + 2, get32(p + 2) + s1->got->sh_addr); - put32(p + 8, get32(p + 8) + s1->got->sh_addr); - p += 16; - while (p < p_end) { - put32(p + 2, get32(p + 2) + s1->got->sh_addr); - p += 16; - } -#elif defined(TCC_TARGET_X86_64) - int x = s1->got->sh_addr - s1->plt->sh_addr - 6; - put32(p + 2, get32(p + 2) + x); - put32(p + 8, get32(p + 8) + x - 6); - p += 16; - while (p < p_end) { - put32(p + 2, get32(p + 2) + x + s1->plt->data - p); - p += 16; - } -#elif defined(TCC_TARGET_ARM) - int x; - x=s1->got->sh_addr - s1->plt->sh_addr - 12; - p +=16; - while (p < p_end) { - put32(p + 12, x + get32(p + 12) + s1->plt->data - p); - p += 16; - } -#elif defined(TCC_TARGET_C67) - /* XXX: TODO */ + file_offset = (file_offset + s->sh_addralign - 1) & + ~(s->sh_addralign - 1); + s->sh_offset = file_offset; + if (s->sh_type != SHT_NOBITS) + file_offset += s->sh_size; + } + + return file_offset; +} + +static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp, + Section *dynamic) +{ + ElfW(Phdr) *ph; + + /* if interpreter, then add corresponding program header */ + if (interp) { + ph = &phdr[0]; + + ph->p_type = PT_PHDR; + ph->p_offset = sizeof(ElfW(Ehdr)); + ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr)); + ph->p_vaddr = interp->sh_addr - ph->p_filesz; + ph->p_paddr = ph->p_vaddr; + ph->p_flags = PF_R | PF_X; + ph->p_align = 4; /* interp->sh_addralign; */ + ph++; + + ph->p_type = PT_INTERP; + ph->p_offset = interp->sh_offset; + ph->p_vaddr = interp->sh_addr; + ph->p_paddr = ph->p_vaddr; + ph->p_filesz = interp->sh_size; + ph->p_memsz = interp->sh_size; + ph->p_flags = PF_R; + ph->p_align = interp->sh_addralign; + } + + /* if dynamic section, then add corresponding program header */ + if (dynamic) { + ph = &phdr[phnum - 1]; + + ph->p_type = PT_DYNAMIC; + ph->p_offset = dynamic->sh_offset; + ph->p_vaddr = dynamic->sh_addr; + ph->p_paddr = ph->p_vaddr; + ph->p_filesz = dynamic->sh_size; + ph->p_memsz = dynamic->sh_size; + ph->p_flags = PF_R | PF_W; + ph->p_align = dynamic->sh_addralign; + } +} + +/* Fill the dynamic section with tags describing the address and size of + sections */ +static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) +{ + Section *dynamic = dyninf->dynamic; + + /* put dynamic section entries */ + put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); + put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr); + put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); + put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset); + put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym))); +#if PTR_SIZE == 8 + put_dt(dynamic, DT_RELA, dyninf->rel_addr); + put_dt(dynamic, DT_RELASZ, dyninf->rel_size); + put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel)); #else -#error unsupported CPU +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr); + put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size); + put_dt(dynamic, DT_JMPREL, dyninf->rel_addr); + put_dt(dynamic, DT_PLTREL, DT_REL); + put_dt(dynamic, DT_REL, dyninf->bss_addr); + put_dt(dynamic, DT_RELSZ, dyninf->bss_size); +#else + put_dt(dynamic, DT_REL, dyninf->rel_addr); + put_dt(dynamic, DT_RELSZ, dyninf->rel_size); + put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel)); #endif - } - } +#endif + if (s1->do_debug) + put_dt(dynamic, DT_DEBUG, 0); + put_dt(dynamic, DT_NULL, 0); +} - /* relocate symbols in .dynsym */ - sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset); - for(sym = (ElfW(Sym) *)s1->dynsym->data + 1; - sym < sym_end; - sym++) { - if (sym->st_shndx == SHN_UNDEF) { - /* relocate to the PLT if the symbol corresponds - to a PLT entry */ - if (sym->st_value) - sym->st_value += s1->plt->sh_addr; - } else if (sym->st_shndx < SHN_LORESERVE) { - /* do symbol relocation */ - sym->st_value += s1->sections[sym->st_shndx]->sh_addr; - } - } +/* Relocate remaining sections and symbols (that is those not related to + dynamic linking) */ +static int final_sections_reloc(TCCState *s1) +{ + int i; + Section *s; - /* put dynamic section entries */ - dynamic->data_offset = saved_dynamic_data_offset; - put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); - put_dt(dynamic, DT_STRTAB, dynstr->sh_addr); - put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); - put_dt(dynamic, DT_STRSZ, dynstr->data_offset); - put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym))); -#ifdef TCC_TARGET_X86_64 - put_dt(dynamic, DT_RELA, rel_addr); - put_dt(dynamic, DT_RELASZ, rel_size); - put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel)); + relocate_syms(s1, s1->symtab, 0); + + if (s1->nb_errors != 0) + return -1; + + /* relocate sections */ + /* XXX: ignore sections with allocated relocations ? */ + for(i = 1; i < s1->nb_sections; i++) { + s = s1->sections[i]; +#if defined(TCC_TARGET_I386) || defined(TCC_MUSL) + if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr + /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC + checking is removed */ #else - put_dt(dynamic, DT_REL, rel_addr); - put_dt(dynamic, DT_RELSZ, rel_size); - put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel)); + if (s->reloc && s != s1->got) + /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */ #endif - if (s1->do_debug) - put_dt(dynamic, DT_DEBUG, 0); - put_dt(dynamic, DT_NULL, 0); + relocate_section(s1, s); + } + + /* relocate relocation entries if the relocation tables are + allocated in the executable */ + for(i = 1; i < s1->nb_sections; i++) { + s = s1->sections[i]; + if ((s->sh_flags & SHF_ALLOC) && + s->sh_type == SHT_RELX) { + relocate_rel(s1, s); } + } + return 0; +} + +/* Create an ELF file on disk. + This function handle ELF specific layout requirements */ +static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, + int file_offset, int *sec_order) +{ + int i, shnum, offset, size, file_type; + Section *s; + ElfW(Ehdr) ehdr; + ElfW(Shdr) shdr, *sh; + file_type = s1->output_type; + shnum = s1->nb_sections; + + memset(&ehdr, 0, sizeof(ehdr)); + + if (phnum > 0) { ehdr.e_phentsize = sizeof(ElfW(Phdr)); ehdr.e_phnum = phnum; ehdr.e_phoff = sizeof(ElfW(Ehdr)); } - /* all other sections come after */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (phnum > 0 && (s->sh_flags & SHF_ALLOC)) - continue; - section_order[sh_order_index++] = i; - - file_offset = (file_offset + s->sh_addralign - 1) & - ~(s->sh_addralign - 1); - s->sh_offset = file_offset; - if (s->sh_type != SHT_NOBITS) - file_offset += s->sh_size; + /* align to 4 */ + file_offset = (file_offset + 3) & -4; + + /* fill header */ + ehdr.e_ident[0] = ELFMAG0; + ehdr.e_ident[1] = ELFMAG1; + ehdr.e_ident[2] = ELFMAG2; + ehdr.e_ident[3] = ELFMAG3; + ehdr.e_ident[4] = ELFCLASSW; + ehdr.e_ident[5] = ELFDATA2LSB; + ehdr.e_ident[6] = EV_CURRENT; +#if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) + /* FIXME: should set only for freebsd _target_, but we exclude only PE target */ + ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; +#endif +#ifdef TCC_TARGET_ARM +#ifdef TCC_ARM_EABI + ehdr.e_ident[EI_OSABI] = 0; + ehdr.e_flags = EF_ARM_EABI_VER4; + if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL) + ehdr.e_flags |= EF_ARM_HASENTRY; + if (s1->float_abi == ARM_HARD_FLOAT) + ehdr.e_flags |= EF_ARM_VFP_FLOAT; + else + ehdr.e_flags |= EF_ARM_SOFT_FLOAT; +#else + ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; +#endif +#endif + switch(file_type) { + default: + case TCC_OUTPUT_EXE: + ehdr.e_type = ET_EXEC; + ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1); + break; + case TCC_OUTPUT_DLL: + ehdr.e_type = ET_DYN; + ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ + break; + case TCC_OUTPUT_OBJ: + ehdr.e_type = ET_REL; + break; } - - /* if building executable or DLL, then relocate each section - except the GOT which is already relocated */ - if (file_type != TCC_OUTPUT_OBJ) { - relocate_syms(s1, 0); - - if (s1->nb_errors != 0) { - fail: - ret = -1; - goto the_end; + ehdr.e_machine = EM_TCC_TARGET; + ehdr.e_version = EV_CURRENT; + ehdr.e_shoff = file_offset; + ehdr.e_ehsize = sizeof(ElfW(Ehdr)); + ehdr.e_shentsize = sizeof(ElfW(Shdr)); + ehdr.e_shnum = shnum; + ehdr.e_shstrndx = shnum - 1; + + fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f); + fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); + offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); + + sort_syms(s1, symtab_section); + for(i = 1; i < s1->nb_sections; i++) { + s = s1->sections[sec_order[i]]; + if (s->sh_type != SHT_NOBITS) { + while (offset < s->sh_offset) { + fputc(0, f); + offset++; + } + size = s->sh_size; + if (size) + fwrite(s->data, 1, size, f); + offset += size; } + } - /* relocate sections */ - /* XXX: ignore sections with allocated relocations ? */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr - relocate_section(s1, s); - } + /* output section headers */ + while (offset < ehdr.e_shoff) { + fputc(0, f); + offset++; + } - /* relocate relocation entries if the relocation tables are - allocated in the executable */ - for(i = 1; i < s1->nb_sections; i++) { - s = s1->sections[i]; - if ((s->sh_flags & SHF_ALLOC) && - s->sh_type == SHT_RELX) { - relocate_rel(s1, s); - } + for(i = 0; i < s1->nb_sections; i++) { + sh = &shdr; + memset(sh, 0, sizeof(ElfW(Shdr))); + s = s1->sections[i]; + if (s) { + sh->sh_name = s->sh_name; + sh->sh_type = s->sh_type; + sh->sh_flags = s->sh_flags; + sh->sh_entsize = s->sh_entsize; + sh->sh_info = s->sh_info; + if (s->link) + sh->sh_link = s->link->sh_num; + sh->sh_addralign = s->sh_addralign; + sh->sh_addr = s->sh_addr; + sh->sh_offset = s->sh_offset; + sh->sh_size = s->sh_size; } - - /* get entry point address */ - if (file_type == TCC_OUTPUT_EXE) - ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start"); - else - ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ + fwrite(sh, 1, sizeof(ElfW(Shdr)), f); } +} - /* write elf file */ +/* Write an elf, coff or "binary" file */ +static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, + ElfW(Phdr) *phdr, int file_offset, int *sec_order) +{ + int fd, mode, file_type; + FILE *f; + + file_type = s1->output_type; if (file_type == TCC_OUTPUT_OBJ) mode = 0666; else mode = 0777; - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); + unlink(filename); + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); if (fd < 0) { - error_noabort("could not write '%s'", filename); - goto fail; + tcc_error_noabort("could not write '%s'", filename); + return -1; } f = fdopen(fd, "wb"); if (s1->verbose) printf("<- %s\n", filename); #ifdef TCC_TARGET_COFF - if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) { + if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) tcc_output_coff(s1, f); - } else -#endif - if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { - sort_syms(s1, symtab_section); - - /* align to 4 */ - file_offset = (file_offset + 3) & -4; - - /* fill header */ - ehdr.e_ident[0] = ELFMAG0; - ehdr.e_ident[1] = ELFMAG1; - ehdr.e_ident[2] = ELFMAG2; - ehdr.e_ident[3] = ELFMAG3; - ehdr.e_ident[4] = TCC_ELFCLASS; - ehdr.e_ident[5] = ELFDATA2LSB; - ehdr.e_ident[6] = EV_CURRENT; -#ifdef __FreeBSD__ - ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; -#endif -#ifdef TCC_TARGET_ARM -#ifdef TCC_ARM_EABI - ehdr.e_ident[EI_OSABI] = 0; - ehdr.e_flags = 4 << 24; -#else - ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; -#endif + else #endif - switch(file_type) { - default: - case TCC_OUTPUT_EXE: - ehdr.e_type = ET_EXEC; - break; - case TCC_OUTPUT_DLL: - ehdr.e_type = ET_DYN; - break; - case TCC_OUTPUT_OBJ: - ehdr.e_type = ET_REL; - break; - } - ehdr.e_machine = EM_TCC_TARGET; - ehdr.e_version = EV_CURRENT; - ehdr.e_shoff = file_offset; - ehdr.e_ehsize = sizeof(ElfW(Ehdr)); - ehdr.e_shentsize = sizeof(ElfW(Shdr)); - ehdr.e_shnum = shnum; - ehdr.e_shstrndx = shnum - 1; - - fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f); - fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f); - offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); - - for(i=1;i<s1->nb_sections;i++) { - s = s1->sections[section_order[i]]; - if (s->sh_type != SHT_NOBITS) { - while (offset < s->sh_offset) { - fputc(0, f); - offset++; - } - size = s->sh_size; - fwrite(s->data, 1, size, f); - offset += size; + if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) + tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order); + else + tcc_output_binary(s1, f, sec_order); + fclose(f); + + return 0; +} + +/* Sort section headers by assigned sh_addr, remove sections + that we aren't going to output. */ +static void tidy_section_headers(TCCState *s1, int *sec_order) +{ + int i, nnew, l, *backmap; + Section **snew, *s; + ElfW(Sym) *sym; + + snew = tcc_malloc(s1->nb_sections * sizeof(snew[0])); + backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0])); + for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) { + s = s1->sections[sec_order[i]]; + if (!i || s->sh_name) { + backmap[sec_order[i]] = nnew; + snew[nnew] = s; + ++nnew; + } else { + backmap[sec_order[i]] = 0; + snew[--l] = s; + } + } + for (i = 0; i < nnew; i++) { + s = snew[i]; + if (s) { + s->sh_num = i; + if (s->sh_type == SHT_RELX) + s->sh_info = backmap[s->sh_info]; + } + } + + for_each_elem(symtab_section, 1, sym, ElfW(Sym)) + if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) + sym->st_shndx = backmap[sym->st_shndx]; + if( !s1->static_link ) { + for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) + if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) + sym->st_shndx = backmap[sym->st_shndx]; + } + for (i = 0; i < s1->nb_sections; i++) + sec_order[i] = i; + tcc_free(s1->sections); + s1->sections = snew; + s1->nb_sections = nnew; + tcc_free(backmap); +} + +/* Output an elf, coff or binary file */ +/* XXX: suppress unneeded sections */ +static int elf_output_file(TCCState *s1, const char *filename) +{ + int i, ret, phnum, shnum, file_type, file_offset, *sec_order; + struct dyn_inf dyninf = {0}; + ElfW(Phdr) *phdr; + ElfW(Sym) *sym; + Section *strsec, *interp, *dynamic, *dynstr; + int textrel; + + file_type = s1->output_type; + s1->nb_errors = 0; + ret = -1; + phdr = NULL; + sec_order = NULL; + interp = dynamic = dynstr = NULL; /* avoid warning */ + textrel = 0; + + if (file_type != TCC_OUTPUT_OBJ) { + /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ + tcc_add_runtime(s1); + relocate_common_syms(); + tcc_add_linker_symbols(s1); + + if (!s1->static_link) { + if (file_type == TCC_OUTPUT_EXE) { + char *ptr; + /* allow override the dynamic loader */ + const char *elfint = getenv("LD_SO"); + if (elfint == NULL) + elfint = DEFAULT_ELFINTERP(s1); + /* add interpreter section only if executable */ + interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); + interp->sh_addralign = 1; + ptr = section_ptr_add(interp, 1 + strlen(elfint)); + strcpy(ptr, elfint); + } + + /* add dynamic symbol table */ + s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC, + ".dynstr", + ".hash", SHF_ALLOC); + dynstr = s1->dynsym->link; + + /* add dynamic section */ + dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, + SHF_ALLOC | SHF_WRITE); + dynamic->link = dynstr; + dynamic->sh_entsize = sizeof(ElfW(Dyn)); + + build_got(s1); + + if (file_type == TCC_OUTPUT_EXE) { + bind_exe_dynsyms(s1); + if (s1->nb_errors) + goto the_end; + bind_libs_dynsyms(s1); + } else { + /* shared library case: simply export all global symbols */ + export_global_syms(s1); } } + build_got_entries(s1); + } - /* output section headers */ - while (offset < ehdr.e_shoff) { - fputc(0, f); - offset++; + /* we add a section for symbols */ + strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); + put_elf_str(strsec, ""); + + /* Allocate strings for section names */ + textrel = alloc_sec_names(s1, file_type, strsec); + + if (dynamic) { + /* add a list of needed dlls */ + for(i = 0; i < s1->nb_loaded_dlls; i++) { + DLLReference *dllref = s1->loaded_dlls[i]; + if (dllref->level == 0) + put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); + } + + if (s1->rpath) + put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH, + put_elf_str(dynstr, s1->rpath)); + + if (file_type == TCC_OUTPUT_DLL) { + if (s1->soname) + put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname)); + /* XXX: currently, since we do not handle PIC code, we + must relocate the readonly segments */ + if (textrel) + put_dt(dynamic, DT_TEXTREL, 0); } - - for(i=0;i<s1->nb_sections;i++) { - sh = &shdr; - memset(sh, 0, sizeof(ElfW(Shdr))); - s = s1->sections[i]; - if (s) { - sh->sh_name = s->sh_name; - sh->sh_type = s->sh_type; - sh->sh_flags = s->sh_flags; - sh->sh_entsize = s->sh_entsize; - sh->sh_info = s->sh_info; - if (s->link) - sh->sh_link = s->link->sh_num; - sh->sh_addralign = s->sh_addralign; - sh->sh_addr = s->sh_addr; - sh->sh_offset = s->sh_offset; - sh->sh_size = s->sh_size; + + if (s1->symbolic) + put_dt(dynamic, DT_SYMBOLIC, 0); + + dyninf.dynamic = dynamic; + dyninf.dynstr = dynstr; + /* remember offset and reserve space for 2nd call below */ + dyninf.data_offset = dynamic->data_offset; + fill_dynamic(s1, &dyninf); + dynamic->sh_size = dynamic->data_offset; + dynstr->sh_size = dynstr->data_offset; + } + + /* compute number of program headers */ + if (file_type == TCC_OUTPUT_OBJ) + phnum = 0; + else if (file_type == TCC_OUTPUT_DLL) + phnum = 3; + else if (s1->static_link) + phnum = 2; + else + phnum = 5; + + /* allocate program segment headers */ + phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr))); + + /* compute number of sections */ + shnum = s1->nb_sections; + + /* this array is used to reorder sections in the output file */ + sec_order = tcc_malloc(sizeof(int) * shnum); + sec_order[0] = 0; + + /* compute section to program header mapping */ + file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf, + sec_order); + + /* Fill remaining program header and finalize relocation related to dynamic + linking. */ + if (file_type != TCC_OUTPUT_OBJ) { + fill_unloadable_phdr(phdr, phnum, interp, dynamic); + if (dynamic) { + dynamic->data_offset = dyninf.data_offset; + fill_dynamic(s1, &dyninf); + + /* put in GOT the dynamic section address and relocate PLT */ + write32le(s1->got->data, dynamic->sh_addr); + if (file_type == TCC_OUTPUT_EXE + || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL)) + relocate_plt(s1); + + /* relocate symbols in .dynsym now that final addresses are known */ + for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) { + if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) { + /* do symbol relocation */ + sym->st_value += s1->sections[sym->st_shndx]->sh_addr; + } } - fwrite(sh, 1, sizeof(ElfW(Shdr)), f); } - } else { - tcc_output_binary(s1, f, section_order); + + /* if building executable or DLL, then relocate each section + except the GOT which is already relocated */ + ret = final_sections_reloc(s1); + if (ret) + goto the_end; + tidy_section_headers(s1, sec_order); + + /* Perform relocation to GOT or PLT entries */ + if (file_type == TCC_OUTPUT_EXE && s1->static_link) + fill_got(s1); + else if (s1->got) + fill_local_got_entries(s1); } - fclose(f); - ret = 0; + /* Create the ELF file with name 'filename' */ + ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); + s1->nb_sections = shnum; the_end: - tcc_free(s1->symtab_to_dynsym); - tcc_free(section_order); + tcc_free(sec_order); tcc_free(phdr); - tcc_free(s1->got_offsets); return ret; } -int tcc_output_file(TCCState *s, const char *filename) +LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename) { int ret; #ifdef TCC_TARGET_PE @@ -2007,9 +2174,7 @@ int tcc_output_file(TCCState *s, const char *filename) ret = pe_output_file(s, filename); } else #endif - { ret = elf_output_file(s, filename); - } return ret; } @@ -2030,20 +2195,39 @@ typedef struct SectionMergeInfo { uint8_t link_once; /* true if link once section */ } SectionMergeInfo; +ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h) +{ + int size = read(fd, h, sizeof *h); + if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) { + if (h->e_type == ET_REL) + return AFF_BINTYPE_REL; + if (h->e_type == ET_DYN) + return AFF_BINTYPE_DYN; + } else if (size >= 8) { + if (0 == memcmp(h, ARMAG, 8)) + return AFF_BINTYPE_AR; +#ifdef TCC_TARGET_COFF + if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC) + return AFF_BINTYPE_C67; +#endif + } + return 0; +} + /* load an object file and merge it with current files */ /* XXX: handle correctly stab (debug) info */ -static int tcc_load_object_file(TCCState *s1, +ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset) -{ +{ ElfW(Ehdr) ehdr; ElfW(Shdr) *shdr, *sh; - int size, i, j, offset, offseti, nb_syms, sym_index, ret; + int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed; unsigned char *strsec, *strtab; int *old_to_new_syms; char *sh_name, *name; SectionMergeInfo *sm_table, *sm; ElfW(Sym) *sym, *symtab; - ElfW_Rel *rel, *rel_end; + ElfW_Rel *rel; Section *s; int stab_index; @@ -2051,28 +2235,21 @@ static int tcc_load_object_file(TCCState *s1, stab_index = stabstr_index = 0; - if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) - goto fail1; - if (ehdr.e_ident[0] != ELFMAG0 || - ehdr.e_ident[1] != ELFMAG1 || - ehdr.e_ident[2] != ELFMAG2 || - ehdr.e_ident[3] != ELFMAG3) - goto fail1; - /* test if object file */ - if (ehdr.e_type != ET_REL) + lseek(fd, file_offset, SEEK_SET); + if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL) goto fail1; /* test CPU specific stuff */ if (ehdr.e_ident[5] != ELFDATA2LSB || ehdr.e_machine != EM_TCC_TARGET) { fail1: - error_noabort("invalid object file"); + tcc_error_noabort("invalid object file"); return -1; } /* read sections */ - shdr = load_data(fd, file_offset + ehdr.e_shoff, + shdr = load_data(fd, file_offset + ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum); sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum); - + /* load section names */ sh = &shdr[ehdr.e_shstrndx]; strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); @@ -2082,11 +2259,12 @@ static int tcc_load_object_file(TCCState *s1, symtab = NULL; strtab = NULL; nb_syms = 0; + seencompressed = 0; for(i = 1; i < ehdr.e_shnum; i++) { sh = &shdr[i]; if (sh->sh_type == SHT_SYMTAB) { if (symtab) { - error_noabort("object must contain only one symtab"); + tcc_error_noabort("object must contain only one symtab"); fail: ret = -1; goto the_end; @@ -2099,8 +2277,10 @@ static int tcc_load_object_file(TCCState *s1, sh = &shdr[sh->sh_link]; strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); } + if (sh->sh_flags & SHF_COMPRESSED) + seencompressed = 1; } - + /* now examine each section and try to merge its content with the ones in memory */ for(i = 1; i < ehdr.e_shnum; i++) { @@ -2108,24 +2288,33 @@ static int tcc_load_object_file(TCCState *s1, if (i == ehdr.e_shstrndx) continue; sh = &shdr[i]; - sh_name = strsec + sh->sh_name; + sh_name = (char *) strsec + sh->sh_name; /* ignore sections types we do not handle */ if (sh->sh_type != SHT_PROGBITS && - sh->sh_type != SHT_RELX && + sh->sh_type != SHT_RELX && #ifdef TCC_ARM_EABI sh->sh_type != SHT_ARM_EXIDX && #endif - sh->sh_type != SHT_NOBITS && + sh->sh_type != SHT_NOBITS && + sh->sh_type != SHT_PREINIT_ARRAY && + sh->sh_type != SHT_INIT_ARRAY && + sh->sh_type != SHT_FINI_ARRAY && strcmp(sh_name, ".stabstr") ) continue; + if (seencompressed + && (!strncmp(sh_name, ".debug_", sizeof(".debug_")-1) + || (sh->sh_type == SHT_RELX + && !strncmp((char*)strsec + shdr[sh->sh_info].sh_name, + ".debug_", sizeof(".debug_")-1)))) + continue; if (sh->sh_addralign < 1) sh->sh_addralign = 1; /* find corresponding section, if any */ for(j = 1; j < s1->nb_sections;j++) { s = s1->sections[j]; if (!strcmp(s->name, sh_name)) { - if (!strncmp(sh_name, ".gnu.linkonce", + if (!strncmp(sh_name, ".gnu.linkonce", sizeof(".gnu.linkonce") - 1)) { /* if a 'linkonce' section is already present, we do not add it again. It is a little tricky as @@ -2139,7 +2328,7 @@ static int tcc_load_object_file(TCCState *s1, } } /* not found: create new section */ - s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags); + s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP); /* take as much info as possible from the section. sh_link and sh_info will be updated later */ s->sh_addralign = sh->sh_addralign; @@ -2147,7 +2336,7 @@ static int tcc_load_object_file(TCCState *s1, sm_table[i].new_section = 1; found: if (sh->sh_type != s->sh_type) { - error_noabort("invalid section type"); + tcc_error_noabort("invalid section type"); goto fail; } @@ -2184,7 +2373,7 @@ static int tcc_load_object_file(TCCState *s1, next: ; } - /* //gr relocate stab strings */ + /* gr relocate stab strings */ if (stab_index && stabstr_index) { Stab_Sym *a, *b; unsigned o; @@ -2192,7 +2381,7 @@ static int tcc_load_object_file(TCCState *s1, a = (Stab_Sym *)(s->data + sm_table[stab_index].offset); b = (Stab_Sym *)(s->data + s->data_offset); o = sm_table[stabstr_index].offset; - while (a < b) + while (a < b) a->n_strx += o, a++; } @@ -2226,7 +2415,7 @@ static int tcc_load_object_file(TCCState *s1, already defined symbol. It is very important to get correct relocations */ if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - name = strtab + sym->st_name; + name = (char *) strtab + sym->st_name; sym_index = find_elf_sym(symtab_section, name); if (sym_index) old_to_new_syms[i] = sym_index; @@ -2242,9 +2431,9 @@ static int tcc_load_object_file(TCCState *s1, sym->st_value += sm->offset; } /* add symbol */ - name = strtab + sym->st_name; - sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, - sym->st_info, sym->st_other, + name = (char *) strtab + sym->st_name; + sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size, + sym->st_info, sym->st_other, sym->st_shndx, name); old_to_new_syms[i] = sym_index; } @@ -2260,10 +2449,7 @@ static int tcc_load_object_file(TCCState *s1, case SHT_RELX: /* take relocation offset information */ offseti = sm_table[sh->sh_info].offset; - rel_end = (ElfW_Rel *)(s->data + s->data_offset); - for(rel = (ElfW_Rel *)(s->data + offset); - rel < rel_end; - rel++) { + for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) { int type; unsigned sym_index; /* convert symbol index */ @@ -2274,22 +2460,38 @@ static int tcc_load_object_file(TCCState *s1, goto invalid_reloc; sym_index = old_to_new_syms[sym_index]; /* ignore link_once in rel section. */ - if (!sym_index && !sm->link_once) { + if (!sym_index && !sm->link_once +#ifdef TCC_TARGET_ARM + && type != R_ARM_V4BX +#endif + ) { invalid_reloc: - error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x", + tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x", i, strsec + sh->sh_name, rel->r_offset); goto fail; } rel->r_info = ELFW(R_INFO)(sym_index, type); /* offset the relocation offset */ rel->r_offset += offseti; +#ifdef TCC_TARGET_ARM + /* Jumps and branches from a Thumb code to a PLT entry need + special handling since PLT entries are ARM code. + Unconditional bl instructions referencing PLT entries are + handled by converting these instructions into blx + instructions. Other case of instructions referencing a PLT + entry require to add a Thumb stub before the PLT entry to + switch to ARM mode. We set bit plt_thumb_stub of the + attribute of a symbol to indicate such a case. */ + if (type == R_ARM_THM_JUMP24) + get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1; +#endif } break; default: break; } } - + ret = 0; the_end: tcc_free(symtab); @@ -2301,8 +2503,6 @@ static int tcc_load_object_file(TCCState *s1, return ret; } -#define ARMAG "!<arch>\012" /* For COFF and a.out archives */ - typedef struct ArchiveHeader { char ar_name[16]; /* name of this member */ char ar_date[12]; /* file mtime */ @@ -2318,10 +2518,17 @@ static int get_be32(const uint8_t *b) return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24); } +static long get_be64(const uint8_t *b) +{ + long long ret = get_be32(b); + ret = (ret << 32) | (unsigned)get_be32(b+4); + return (long)ret; +} + /* load only the objects which resolve undefined symbols */ -static int tcc_load_alacarte(TCCState *s1, int fd, int size) +static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) { - int i, bound, nsyms, sym_index, off, ret; + long i, bound, nsyms, sym_index, off, ret; uint8_t *data; const char *ar_names, *p; const uint8_t *ar_index; @@ -2330,9 +2537,9 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) data = tcc_malloc(size); if (read(fd, data, size) != size) goto fail; - nsyms = get_be32(data); - ar_index = data + 4; - ar_names = ar_index + nsyms * 4; + nsyms = entrysize == 4 ? get_be32(data) : get_be64(data); + ar_index = data + entrysize; + ar_names = (char *) ar_index + nsyms * entrysize; do { bound = 0; @@ -2341,12 +2548,11 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) if(sym_index) { sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; if(sym->st_shndx == SHN_UNDEF) { - off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader); -#if 0 - printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx); -#endif + off = (entrysize == 4 + ? get_be32(ar_index + i * 4) + : get_be64(ar_index + i * 8)) + + sizeof(ArchiveHeader); ++bound; - lseek(fd, off, SEEK_SET); if(tcc_load_object_file(s1, fd, off) < 0) { fail: ret = -1; @@ -2363,7 +2569,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) } /* load a '.a' file */ -static int tcc_load_archive(TCCState *s1, int fd) +ST_FUNC int tcc_load_archive(TCCState *s1, int fd) { ArchiveHeader hdr; char ar_size[11]; @@ -2374,13 +2580,13 @@ static int tcc_load_archive(TCCState *s1, int fd) /* skip magic which was already checked */ read(fd, magic, sizeof(magic)); - + for(;;) { len = read(fd, &hdr, sizeof(hdr)); if (len == 0) break; if (len != sizeof(hdr)) { - error_noabort("invalid archive"); + tcc_error_noabort("invalid archive"); return -1; } memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size)); @@ -2392,33 +2598,34 @@ static int tcc_load_archive(TCCState *s1, int fd) break; } ar_name[i + 1] = '\0'; - // printf("name='%s' size=%d %s\n", ar_name, size, ar_size); file_offset = lseek(fd, 0, SEEK_CUR); /* align to even */ size = (size + 1) & ~1; if (!strcmp(ar_name, "/")) { /* coff symbol table : we handle it */ if(s1->alacarte_link) - return tcc_load_alacarte(s1, fd, size); - } else if (!strcmp(ar_name, "//") || - !strcmp(ar_name, "__.SYMDEF") || - !strcmp(ar_name, "__.SYMDEF/") || - !strcmp(ar_name, "ARFILENAMES/")) { - /* skip symbol table or archive names */ + return tcc_load_alacarte(s1, fd, size, 4); + } else if (!strcmp(ar_name, "/SYM64/")) { + if(s1->alacarte_link) + return tcc_load_alacarte(s1, fd, size, 8); } else { - if (tcc_load_object_file(s1, fd, file_offset) < 0) - return -1; + ElfW(Ehdr) ehdr; + if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) { + if (tcc_load_object_file(s1, fd, file_offset) < 0) + return -1; + } } lseek(fd, file_offset + size, SEEK_SET); } return 0; } +#ifndef TCC_TARGET_PE /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL is referenced by the user (so it should be added as DT_NEEDED in the generated ELF file) */ -static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) -{ +ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) +{ ElfW(Ehdr) ehdr; ElfW(Shdr) *shdr, *sh, *sh1; int i, j, nb_syms, nb_dts, sym_bind, ret; @@ -2427,13 +2634,13 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) unsigned char *dynstr; const char *name, *soname; DLLReference *dllref; - + read(fd, &ehdr, sizeof(ehdr)); /* test CPU specific stuff */ if (ehdr.e_ident[5] != ELFDATA2LSB || ehdr.e_machine != EM_TCC_TARGET) { - error_noabort("bad architecture"); + tcc_error_noabort("bad architecture"); return -1; } @@ -2462,13 +2669,13 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) break; } } - + /* compute the real library name */ soname = tcc_basename(filename); - + for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { if (dt->d_tag == DT_SONAME) { - soname = dynstr + dt->d_un.d_val; + soname = (char *) dynstr + dt->d_un.d_val; } } @@ -2483,22 +2690,20 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) goto the_end; } } - - // printf("loading dll '%s'\n", soname); /* add the dll and its level */ dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname)); dllref->level = level; strcpy(dllref->name, soname); - dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); + dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); /* add dynamic symbols in dynsym_section */ for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) { sym_bind = ELFW(ST_BIND)(sym->st_info); if (sym_bind == STB_LOCAL) continue; - name = dynstr + sym->st_name; - add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, + name = (char *) dynstr + sym->st_name; + set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, sym->st_info, sym->st_other, sym->st_shndx, name); } @@ -2506,14 +2711,14 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { switch(dt->d_tag) { case DT_NEEDED: - name = dynstr + dt->d_un.d_val; + name = (char *) dynstr + dt->d_un.d_val; for(j = 0; j < s1->nb_loaded_dlls; j++) { dllref = s1->loaded_dlls[j]; if (!strcmp(name, dllref->name)) goto already_loaded; } if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) { - error_noabort("referenced dll '%s' not found", name); + tcc_error_noabort("referenced dll '%s' not found", name); ret = -1; goto the_end; } @@ -2561,6 +2766,11 @@ static int ld_next(TCCState *s1, char *name, int name_size) goto parse_name; } break; + case '\\': + ch = handle_eob(); + if (ch != '\\') + goto redo; + /* fall through */ /* case 'a' ... 'z': */ case 'a': case 'b': @@ -2616,7 +2826,6 @@ static int ld_next(TCCState *s1, char *name, int name_size) case 'Y': case 'Z': case '_': - case '\\': case '.': case '$': case '~': @@ -2644,59 +2853,111 @@ static int ld_next(TCCState *s1, char *name, int name_size) inp(); break; } -#if 0 - printf("tok=%c %d\n", c, c); - if (c == LD_TOK_NAME) - printf(" name=%s\n", name); -#endif return c; } -static int ld_add_file_list(TCCState *s1, int as_needed) +static int ld_add_file(TCCState *s1, const char filename[]) { - char filename[1024]; - int t, ret; + if (filename[0] == '/') { + if (CONFIG_SYSROOT[0] == '\0' + && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0) + return 0; + filename = tcc_basename(filename); + } + return tcc_add_dll(s1, filename, 0); +} +static inline int new_undef_syms(void) +{ + int ret = 0; + ret = new_undef_sym; + new_undef_sym = 0; + return ret; +} + +static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed) +{ + char filename[1024], libname[1024]; + int t, group, nblibs = 0, ret = 0; + char **libs = NULL; + + group = !strcmp(cmd, "GROUP"); + if (!as_needed) + new_undef_syms(); t = ld_next(s1, filename, sizeof(filename)); if (t != '(') expect("("); t = ld_next(s1, filename, sizeof(filename)); for(;;) { + libname[0] = '\0'; if (t == LD_TOK_EOF) { - error_noabort("unexpected end of file"); - return -1; + tcc_error_noabort("unexpected end of file"); + ret = -1; + goto lib_parse_error; } else if (t == ')') { break; + } else if (t == '-') { + t = ld_next(s1, filename, sizeof(filename)); + if ((t != LD_TOK_NAME) || (filename[0] != 'l')) { + tcc_error_noabort("library name expected"); + ret = -1; + goto lib_parse_error; + } + pstrcpy(libname, sizeof libname, &filename[1]); + if (s1->static_link) { + snprintf(filename, sizeof filename, "lib%s.a", libname); + } else { + snprintf(filename, sizeof filename, "lib%s.so", libname); + } } else if (t != LD_TOK_NAME) { - error_noabort("filename expected"); - return -1; - } + tcc_error_noabort("filename expected"); + ret = -1; + goto lib_parse_error; + } if (!strcmp(filename, "AS_NEEDED")) { - ret = ld_add_file_list(s1, 1); + ret = ld_add_file_list(s1, cmd, 1); if (ret) - return ret; + goto lib_parse_error; } else { /* TODO: Implement AS_NEEDED support. Ignore it for now */ - if (!as_needed) - tcc_add_file(s1, filename); + if (!as_needed) { + ret = ld_add_file(s1, filename); + if (ret) + goto lib_parse_error; + if (group) { + /* Add the filename *and* the libname to avoid future conversions */ + dynarray_add(&libs, &nblibs, tcc_strdup(filename)); + if (libname[0] != '\0') + dynarray_add(&libs, &nblibs, tcc_strdup(libname)); + } + } } t = ld_next(s1, filename, sizeof(filename)); if (t == ',') { t = ld_next(s1, filename, sizeof(filename)); } } - return 0; + if (group && !as_needed) { + while (new_undef_syms()) { + int i; + + for (i = 0; i < nblibs; i ++) + ld_add_file(s1, libs[i]); + } + } +lib_parse_error: + dynarray_reset(&libs, &nblibs); + return ret; } /* interpret a subset of GNU ldscripts to handle the dummy libc.so files */ -static int tcc_load_ldscript(TCCState *s1) +ST_FUNC int tcc_load_ldscript(TCCState *s1) { char cmd[64]; char filename[1024]; int t, ret; - - ch = file->buf_ptr[0]; + ch = handle_eob(); for(;;) { t = ld_next(s1, cmd, sizeof(cmd)); @@ -2706,7 +2967,7 @@ static int tcc_load_ldscript(TCCState *s1) return -1; if (!strcmp(cmd, "INPUT") || !strcmp(cmd, "GROUP")) { - ret = ld_add_file_list(s1, 0); + ret = ld_add_file_list(s1, cmd, 0); if (ret) return ret; } else if (!strcmp(cmd, "OUTPUT_FORMAT") || @@ -2718,7 +2979,7 @@ static int tcc_load_ldscript(TCCState *s1) for(;;) { t = ld_next(s1, filename, sizeof(filename)); if (t == LD_TOK_EOF) { - error_noabort("unexpected end of file"); + tcc_error_noabort("unexpected end of file"); return -1; } else if (t == ')') { break; @@ -2730,3 +2991,4 @@ static int tcc_load_ldscript(TCCState *s1) } return 0; } +#endif /* !TCC_TARGET_PE */ diff --git a/tinyc/tccgen.c b/tinyc/tccgen.c index a88f32819..7d554b5b1 100644 --- a/tinyc/tccgen.c +++ b/tinyc/tccgen.c @@ -18,56 +18,781 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -void swap(int *p, int *q) +#include "tcc.h" + +/********************************************************/ +/* global variables */ + +/* loc : local variable index + ind : output code index + rsym: return symbol + anon_sym: anonymous symbol index +*/ +ST_DATA int rsym, anon_sym, ind, loc; + +ST_DATA Sym *sym_free_first; +ST_DATA void **sym_pools; +ST_DATA int nb_sym_pools; + +ST_DATA Sym *global_stack; +ST_DATA Sym *local_stack; +ST_DATA Sym *define_stack; +ST_DATA Sym *global_label_stack; +ST_DATA Sym *local_label_stack; +static int local_scope; +static int in_sizeof; +static int section_sym; + +ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */ +ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */ +ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */ + +ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop; + +ST_DATA int const_wanted; /* true if constant wanted */ +ST_DATA int nocode_wanted; /* no code generation wanted */ +#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */ +#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */ +ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ +ST_DATA CType func_vt; /* current function return type (used by return instruction) */ +ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */ +ST_DATA int func_vc; +ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ +ST_DATA const char *funcname; +ST_DATA int g_debug; + +ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type; + +ST_DATA struct switch_t { + struct case_t { + int64_t v1, v2; + int sym; + } **p; int n; /* list of case ranges */ + int def_sym; /* default symbol */ +} *cur_switch; /* current switch */ + +/* ------------------------------------------------------------------------- */ + +static void gen_cast(CType *type); +static void gen_cast_s(int t); +static inline CType *pointed_type(CType *type); +static int is_compatible_types(CType *type1, CType *type2); +static int parse_btype(CType *type, AttributeDef *ad); +static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td); +static void parse_expr_type(CType *type); +static void init_putv(CType *type, Section *sec, unsigned long c); +static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only); +static void block(int *bsym, int *csym, int is_expr); +static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); +static void decl(int l); +static int decl0(int l, int is_for_loop_init, Sym *); +static void expr_eq(void); +static void vla_runtime_type_size(CType *type, int *a); +static void vla_sp_restore(void); +static void vla_sp_restore_root(void); +static int is_compatible_unqualified_types(CType *type1, CType *type2); +static inline int64_t expr_const64(void); +static void vpush64(int ty, unsigned long long v); +static void vpush(CType *type); +static int gvtst(int inv, int t); +static void gen_inline_functions(TCCState *s); +static void skip_or_save_block(TokenString **str); +static void gv_dup(void); + +ST_INLN int is_float(int t) { - int t; - t = *p; - *p = *q; - *q = t; + int bt; + bt = t & VT_BTYPE; + return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT; +} + +/* we use our own 'finite' function to avoid potential problems with + non standard math libs */ +/* XXX: endianness dependent */ +ST_FUNC int ieee_finite(double d) +{ + int p[4]; + memcpy(p, &d, sizeof(double)); + return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; +} + +/* compiling intel long double natively */ +#if (defined __i386__ || defined __x86_64__) \ + && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) +# define TCC_IS_NATIVE_387 +#endif + +ST_FUNC void test_lvalue(void) +{ + if (!(vtop->r & VT_LVAL)) + expect("lvalue"); +} + +ST_FUNC void check_vstack(void) +{ + if (pvtop != vtop) + tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop); +} + +/* ------------------------------------------------------------------------- */ +/* vstack debugging aid */ + +#if 0 +void pv (const char *lbl, int a, int b) +{ + int i; + for (i = a; i < a + b; ++i) { + SValue *p = &vtop[-i]; + printf("%s vtop[-%d] : type.t:%04x r:%04x r2:%04x c.i:%d\n", + lbl, i, p->type.t, p->r, p->r2, (int)p->c.i); + } +} +#endif + +/* ------------------------------------------------------------------------- */ +/* start of translation unit info */ +ST_FUNC void tcc_debug_start(TCCState *s1) +{ + if (s1->do_debug) { + char buf[512]; + + /* file info: full path + filename */ + section_sym = put_elf_sym(symtab_section, 0, 0, + ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, + text_section->sh_num, NULL); + getcwd(buf, sizeof(buf)); +#ifdef _WIN32 + normalize_slashes(buf); +#endif + pstrcat(buf, sizeof(buf), "/"); + put_stabs_r(buf, N_SO, 0, 0, + text_section->data_offset, text_section, section_sym); + put_stabs_r(file->filename, N_SO, 0, 0, + text_section->data_offset, text_section, section_sym); + last_ind = 0; + last_line_num = 0; + } + + /* an elf symbol of type STT_FILE must be put so that STB_LOCAL + symbols can be safely used */ + put_elf_sym(symtab_section, 0, 0, + ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, + SHN_ABS, file->filename); +} + +/* put end of translation unit info */ +ST_FUNC void tcc_debug_end(TCCState *s1) +{ + if (!s1->do_debug) + return; + put_stabs_r(NULL, N_SO, 0, 0, + text_section->data_offset, text_section, section_sym); + +} + +/* generate line number info */ +ST_FUNC void tcc_debug_line(TCCState *s1) +{ + if (!s1->do_debug) + return; + if ((last_line_num != file->line_num || last_ind != ind)) { + put_stabn(N_SLINE, 0, file->line_num, ind - func_ind); + last_ind = ind; + last_line_num = file->line_num; + } +} + +/* put function symbol */ +ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym) +{ + char buf[512]; + + if (!s1->do_debug) + return; + + /* stabs info */ + /* XXX: we put here a dummy type */ + snprintf(buf, sizeof(buf), "%s:%c1", + funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); + put_stabs_r(buf, N_FUN, 0, file->line_num, 0, + cur_text_section, sym->c); + /* //gr gdb wants a line at the function */ + put_stabn(N_SLINE, 0, file->line_num, 0); + + last_ind = 0; + last_line_num = 0; +} + +/* put function size */ +ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) +{ + if (!s1->do_debug) + return; + put_stabn(N_FUN, 0, 0, size); +} + +/* ------------------------------------------------------------------------- */ +ST_FUNC int tccgen_compile(TCCState *s1) +{ + cur_text_section = NULL; + funcname = ""; + anon_sym = SYM_FIRST_ANOM; + section_sym = 0; + const_wanted = 0; + nocode_wanted = 0x80000000; + + /* define some often used types */ + int_type.t = VT_INT; + char_pointer_type.t = VT_BYTE; + mk_pointer(&char_pointer_type); +#if PTR_SIZE == 4 + size_type.t = VT_INT | VT_UNSIGNED; + ptrdiff_type.t = VT_INT; +#elif LONG_SIZE == 4 + size_type.t = VT_LLONG | VT_UNSIGNED; + ptrdiff_type.t = VT_LLONG; +#else + size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED; + ptrdiff_type.t = VT_LONG | VT_LLONG; +#endif + func_old_type.t = VT_FUNC; + func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0); + func_old_type.ref->f.func_call = FUNC_CDECL; + func_old_type.ref->f.func_type = FUNC_OLD; + + tcc_debug_start(s1); + +#ifdef TCC_TARGET_ARM + arm_init(s1); +#endif + +#ifdef INC_DEBUG + printf("%s: **** new file\n", file->filename); +#endif + + parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR; + next(); + decl(VT_CONST); + gen_inline_functions(s1); + check_vstack(); + /* end of translation unit info */ + tcc_debug_end(s1); + return 0; +} + +/* ------------------------------------------------------------------------- */ +/* apply storage attributes to Elf symbol */ + +static void update_storage(Sym *sym) +{ + ElfW(Sym) *esym; + if (0 == sym->c) + return; + esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; + if (sym->a.visibility) + esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) + | sym->a.visibility; + if (sym->a.weak) + esym->st_info = ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(esym->st_info)); +#ifdef TCC_TARGET_PE + if (sym->a.dllimport) + esym->st_other |= ST_PE_IMPORT; + if (sym->a.dllexport) + esym->st_other |= ST_PE_EXPORT; +#endif +#if 0 + printf("storage %s: vis=%d weak=%d exp=%d imp=%d\n", + get_tok_str(sym->v, NULL), + sym->a.visibility, + sym->a.weak, + sym->a.dllexport, + sym->a.dllimport + ); +#endif +} + +/* ------------------------------------------------------------------------- */ +/* update sym->c so that it points to an external symbol in section + 'section' with value 'value' */ + +ST_FUNC void put_extern_sym2(Sym *sym, Section *section, + addr_t value, unsigned long size, + int can_add_underscore) +{ + int sym_type, sym_bind, sh_num, info, other, t; + ElfW(Sym) *esym; + const char *name; + char buf1[256]; +#ifdef CONFIG_TCC_BCHECK + char buf[32]; +#endif + + if (section == NULL) + sh_num = SHN_UNDEF; + else if (section == SECTION_ABS) + sh_num = SHN_ABS; + else + sh_num = section->sh_num; + + if (!sym->c) { + name = get_tok_str(sym->v, NULL); +#ifdef CONFIG_TCC_BCHECK + if (tcc_state->do_bounds_check) { + /* XXX: avoid doing that for statics ? */ + /* if bound checking is activated, we change some function + names by adding the "__bound" prefix */ + switch(sym->v) { +#ifdef TCC_TARGET_PE + /* XXX: we rely only on malloc hooks */ + case TOK_malloc: + case TOK_free: + case TOK_realloc: + case TOK_memalign: + case TOK_calloc: +#endif + case TOK_memcpy: + case TOK_memmove: + case TOK_memset: + case TOK_strlen: + case TOK_strcpy: + case TOK_alloca: + strcpy(buf, "__bound_"); + strcat(buf, name); + name = buf; + break; + } + } +#endif + t = sym->type.t; + if ((t & VT_BTYPE) == VT_FUNC) { + sym_type = STT_FUNC; + } else if ((t & VT_BTYPE) == VT_VOID) { + sym_type = STT_NOTYPE; + } else { + sym_type = STT_OBJECT; + } + if (t & VT_STATIC) + sym_bind = STB_LOCAL; + else + sym_bind = STB_GLOBAL; + other = 0; +#ifdef TCC_TARGET_PE + if (sym_type == STT_FUNC && sym->type.ref) { + Sym *ref = sym->type.ref; + if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) { + sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE); + name = buf1; + other |= ST_PE_STDCALL; + can_add_underscore = 0; + } + } +#endif + if (tcc_state->leading_underscore && can_add_underscore) { + buf1[0] = '_'; + pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); + name = buf1; + } + if (sym->asm_label) + name = get_tok_str(sym->asm_label, NULL); + info = ELFW(ST_INFO)(sym_bind, sym_type); + sym->c = set_elf_sym(symtab_section, value, size, info, other, sh_num, name); + } else { + esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; + esym->st_value = value; + esym->st_size = size; + esym->st_shndx = sh_num; + } + update_storage(sym); +} + +ST_FUNC void put_extern_sym(Sym *sym, Section *section, + addr_t value, unsigned long size) +{ + put_extern_sym2(sym, section, value, size, 1); +} + +/* add a new relocation entry to symbol 'sym' in section 's' */ +ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, + addr_t addend) +{ + int c = 0; + + if (nocode_wanted && s == cur_text_section) + return; + + if (sym) { + if (0 == sym->c) + put_extern_sym(sym, NULL, 0, 0); + c = sym->c; + } + + /* now we can add ELF relocation info */ + put_elf_reloca(symtab_section, s, offset, type, c, addend); +} + +#if PTR_SIZE == 4 +ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type) +{ + greloca(s, sym, offset, type, 0); +} +#endif + +/* ------------------------------------------------------------------------- */ +/* symbol allocator */ +static Sym *__sym_malloc(void) +{ + Sym *sym_pool, *sym, *last_sym; + int i; + + sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym)); + dynarray_add(&sym_pools, &nb_sym_pools, sym_pool); + + last_sym = sym_free_first; + sym = sym_pool; + for(i = 0; i < SYM_POOL_NB; i++) { + sym->next = last_sym; + last_sym = sym; + sym++; + } + sym_free_first = last_sym; + return last_sym; } -void vsetc(CType *type, int r, CValue *vc) +static inline Sym *sym_malloc(void) +{ + Sym *sym; +#ifndef SYM_DEBUG + sym = sym_free_first; + if (!sym) + sym = __sym_malloc(); + sym_free_first = sym->next; + return sym; +#else + sym = tcc_malloc(sizeof(Sym)); + return sym; +#endif +} + +ST_INLN void sym_free(Sym *sym) +{ +#ifndef SYM_DEBUG + sym->next = sym_free_first; + sym_free_first = sym; +#else + tcc_free(sym); +#endif +} + +/* push, without hashing */ +ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c) +{ + Sym *s; + + s = sym_malloc(); + memset(s, 0, sizeof *s); + s->v = v; + s->type.t = t; + s->c = c; + /* add in stack */ + s->prev = *ps; + *ps = s; + return s; +} + +/* find a symbol and return its associated structure. 's' is the top + of the symbol stack */ +ST_FUNC Sym *sym_find2(Sym *s, int v) +{ + while (s) { + if (s->v == v) + return s; + else if (s->v == -1) + return NULL; + s = s->prev; + } + return NULL; +} + +/* structure lookup */ +ST_INLN Sym *struct_find(int v) +{ + v -= TOK_IDENT; + if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) + return NULL; + return table_ident[v]->sym_struct; +} + +/* find an identifier */ +ST_INLN Sym *sym_find(int v) +{ + v -= TOK_IDENT; + if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) + return NULL; + return table_ident[v]->sym_identifier; +} + +/* push a given symbol on the symbol stack */ +ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) +{ + Sym *s, **ps; + TokenSym *ts; + + if (local_stack) + ps = &local_stack; + else + ps = &global_stack; + s = sym_push2(ps, v, type->t, c); + s->type.ref = type->ref; + s->r = r; + /* don't record fields or anonymous symbols */ + /* XXX: simplify */ + if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { + /* record symbol in token array */ + ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; + if (v & SYM_STRUCT) + ps = &ts->sym_struct; + else + ps = &ts->sym_identifier; + s->prev_tok = *ps; + *ps = s; + s->sym_scope = local_scope; + if (s->prev_tok && s->prev_tok->sym_scope == s->sym_scope) + tcc_error("redeclaration of '%s'", + get_tok_str(v & ~SYM_STRUCT, NULL)); + } + return s; +} + +/* push a global identifier */ +ST_FUNC Sym *global_identifier_push(int v, int t, int c) +{ + Sym *s, **ps; + s = sym_push2(&global_stack, v, t, c); + /* don't record anonymous symbol */ + if (v < SYM_FIRST_ANOM) { + ps = &table_ident[v - TOK_IDENT]->sym_identifier; + /* modify the top most local identifier, so that + sym_identifier will point to 's' when popped */ + while (*ps != NULL) + ps = &(*ps)->prev_tok; + s->prev_tok = NULL; + *ps = s; + } + return s; +} + +/* pop symbols until top reaches 'b'. If KEEP is non-zero don't really + pop them yet from the list, but do remove them from the token array. */ +ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep) +{ + Sym *s, *ss, **ps; + TokenSym *ts; + int v; + + s = *ptop; + while(s != b) { + ss = s->prev; + v = s->v; + /* remove symbol in token array */ + /* XXX: simplify */ + if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { + ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; + if (v & SYM_STRUCT) + ps = &ts->sym_struct; + else + ps = &ts->sym_identifier; + *ps = s->prev_tok; + } + if (!keep) + sym_free(s); + s = ss; + } + if (!keep) + *ptop = b; +} + +/* ------------------------------------------------------------------------- */ + +static void vsetc(CType *type, int r, CValue *vc) { int v; if (vtop >= vstack + (VSTACK_SIZE - 1)) - error("memory full"); + tcc_error("memory full (vstack)"); /* cannot let cpu flags if other instruction are generated. Also avoid leaving VT_JMP anywhere except on the top of the stack - because it would complicate the code generator. */ - if (vtop >= vstack) { + because it would complicate the code generator. + + Don't do this when nocode_wanted. vtop might come from + !nocode_wanted regions (see 88_codeopt.c) and transforming + it to a register without actually generating code is wrong + as their value might still be used for real. All values + we push under nocode_wanted will eventually be popped + again, so that the VT_CMP/VT_JMP value will be in vtop + when code is unsuppressed again. + + Same logic below in vswap(); */ + if (vtop >= vstack && !nocode_wanted) { v = vtop->r & VT_VALMASK; if (v == VT_CMP || (v & ~1) == VT_JMP) gv(RC_INT); } + vtop++; vtop->type = *type; vtop->r = r; vtop->r2 = VT_CONST; vtop->c = *vc; + vtop->sym = NULL; +} + +ST_FUNC void vswap(void) +{ + SValue tmp; + /* cannot vswap cpu flags. See comment at vsetc() above */ + if (vtop >= vstack && !nocode_wanted) { + int v = vtop->r & VT_VALMASK; + if (v == VT_CMP || (v & ~1) == VT_JMP) + gv(RC_INT); + } + tmp = vtop[0]; + vtop[0] = vtop[-1]; + vtop[-1] = tmp; +} + +/* pop stack value */ +ST_FUNC void vpop(void) +{ + int v; + v = vtop->r & VT_VALMASK; +#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) + /* for x86, we need to pop the FP stack */ + if (v == TREG_ST0) { + o(0xd8dd); /* fstp %st(0) */ + } else +#endif + if (v == VT_JMP || v == VT_JMPI) { + /* need to put correct jump if && or || without test */ + gsym(vtop->c.i); + } + vtop--; +} + +/* push constant of type "type" with useless value */ +ST_FUNC void vpush(CType *type) +{ + vset(type, VT_CONST, 0); } /* push integer constant */ -void vpushi(int v) +ST_FUNC void vpushi(int v) { CValue cval; cval.i = v; vsetc(&int_type, VT_CONST, &cval); } -/* push long long constant */ -void vpushll(long long v) +/* push a pointer sized constant */ +static void vpushs(addr_t v) +{ + CValue cval; + cval.i = v; + vsetc(&size_type, VT_CONST, &cval); +} + +/* push arbitrary 64bit constant */ +ST_FUNC void vpush64(int ty, unsigned long long v) { CValue cval; CType ctype; - ctype.t = VT_LLONG; - cval.ull = v; + ctype.t = ty; + ctype.ref = NULL; + cval.i = v; vsetc(&ctype, VT_CONST, &cval); } +/* push long long constant */ +static inline void vpushll(long long v) +{ + vpush64(VT_LLONG, v); +} + +ST_FUNC void vset(CType *type, int r, int v) +{ + CValue cval; + + cval.i = v; + vsetc(type, r, &cval); +} + +static void vseti(int r, int v) +{ + CType type; + type.t = VT_INT; + type.ref = NULL; + vset(&type, r, v); +} + +ST_FUNC void vpushv(SValue *v) +{ + if (vtop >= vstack + (VSTACK_SIZE - 1)) + tcc_error("memory full (vstack)"); + vtop++; + *vtop = *v; +} + +static void vdup(void) +{ + vpushv(vtop); +} + +/* rotate n first stack elements to the bottom + I1 ... In -> I2 ... In I1 [top is right] +*/ +ST_FUNC void vrotb(int n) +{ + int i; + SValue tmp; + + tmp = vtop[-n + 1]; + for(i=-n+1;i!=0;i++) + vtop[i] = vtop[i+1]; + vtop[0] = tmp; +} + +/* rotate the n elements before entry e towards the top + I1 ... In ... -> In I1 ... I(n-1) ... [top is right] + */ +ST_FUNC void vrote(SValue *e, int n) +{ + int i; + SValue tmp; + + tmp = *e; + for(i = 0;i < n - 1; i++) + e[-i] = e[-i - 1]; + e[-n + 1] = tmp; +} + +/* rotate n first stack elements to the top + I1 ... In -> In I1 ... I(n-1) [top is right] + */ +ST_FUNC void vrott(int n) +{ + vrote(vtop, n); +} + +/* push a symbol value of TYPE */ +static inline void vpushsym(CType *type, Sym *sym) +{ + CValue cval; + cval.i = 0; + vsetc(type, VT_CONST | VT_SYM, &cval); + vtop->sym = sym; +} + /* Return a static symbol pointing to a section */ -static Sym *get_sym_ref(CType *type, Section *sec, - unsigned long offset, unsigned long size) +ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size) { int v; Sym *sym; @@ -83,15 +808,11 @@ static Sym *get_sym_ref(CType *type, Section *sec, /* push a reference to a section offset by adding a dummy symbol */ static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size) { - CValue cval; - - cval.ul = 0; - vsetc(type, VT_CONST | VT_SYM, &cval); - vtop->sym = get_sym_ref(type, sec, offset, size); + vpushsym(type, get_sym_ref(type, sec, offset, size)); } /* define a new external reference to a symbol 'v' of type 'u' */ -static Sym *external_global_sym(int v, CType *type, int r) +ST_FUNC Sym *external_global_sym(int v, CType *type, int r) { Sym *s; @@ -105,84 +826,94 @@ static Sym *external_global_sym(int v, CType *type, int r) return s; } -/* define a new external reference to a symbol 'v' of type 'u' */ -static Sym *external_sym(int v, CType *type, int r) +/* Merge some storage attributes. */ +static void patch_storage(Sym *sym, AttributeDef *ad, CType *type) { - Sym *s; + if (type && !is_compatible_types(&sym->type, type)) + tcc_error("incompatible types for redefinition of '%s'", + get_tok_str(sym->v, NULL)); +#ifdef TCC_TARGET_PE + if (sym->a.dllimport != ad->a.dllimport) + tcc_error("incompatible dll linkage for redefinition of '%s'", + get_tok_str(sym->v, NULL)); +#endif + sym->a.dllexport |= ad->a.dllexport; + sym->a.weak |= ad->a.weak; + if (ad->a.visibility) { + int vis = sym->a.visibility; + int vis2 = ad->a.visibility; + if (vis == STV_DEFAULT) + vis = vis2; + else if (vis2 != STV_DEFAULT) + vis = (vis < vis2) ? vis : vis2; + sym->a.visibility = vis; + } + if (ad->a.aligned) + sym->a.aligned = ad->a.aligned; + if (ad->asm_label) + sym->asm_label = ad->asm_label; + update_storage(sym); +} +/* define a new external reference to a symbol 'v' */ +static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad) +{ + Sym *s; s = sym_find(v); if (!s) { /* push forward reference */ s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); s->type.t |= VT_EXTERN; + s->a = ad->a; + s->sym_scope = 0; } else { - if (!is_compatible_types(&s->type, type)) - error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); + if (s->type.ref == func_old_type.ref) { + s->type.ref = type->ref; + s->r = r | VT_CONST | VT_SYM; + s->type.t |= VT_EXTERN; + } + patch_storage(s, ad, type); } return s; } /* push a reference to global symbol v */ -static void vpush_global_sym(CType *type, int v) +ST_FUNC void vpush_global_sym(CType *type, int v) { - Sym *sym; - CValue cval; - - sym = external_global_sym(v, type, 0); - cval.ul = 0; - vsetc(type, VT_CONST | VT_SYM, &cval); - vtop->sym = sym; + vpushsym(type, external_global_sym(v, type, 0)); } -void vset(CType *type, int r, int v) -{ - CValue cval; - - cval.i = v; - vsetc(type, r, &cval); -} - -void vseti(int r, int v) -{ - CType type; - type.t = VT_INT; - vset(&type, r, v); -} - -void vswap(void) -{ - SValue tmp; - - tmp = vtop[0]; - vtop[0] = vtop[-1]; - vtop[-1] = tmp; -} - -void vpushv(SValue *v) +/* save registers up to (vtop - n) stack entry */ +ST_FUNC void save_regs(int n) { - if (vtop >= vstack + (VSTACK_SIZE - 1)) - error("memory full"); - vtop++; - *vtop = *v; + SValue *p, *p1; + for(p = vstack, p1 = vtop - n; p <= p1; p++) + save_reg(p->r); } -void vdup(void) +/* save r to the memory stack, and mark it as being free */ +ST_FUNC void save_reg(int r) { - vpushv(vtop); + save_reg_upstack(r, 0); } -/* save r to the memory stack, and mark it as being free */ -void save_reg(int r) +/* save r to the memory stack, and mark it as being free, + if seen up to (vtop - n) stack entry */ +ST_FUNC void save_reg_upstack(int r, int n) { int l, saved, size, align; - SValue *p, sv; + SValue *p, *p1, sv; CType *type; + if ((r &= VT_VALMASK) >= VT_CONST) + return; + if (nocode_wanted) + return; + /* modify all stack values */ saved = 0; l = 0; - for(p=vstack;p<=vtop;p++) { + for(p = vstack, p1 = vtop - n; p <= p1; p++) { if ((p->r & VT_VALMASK) == r || ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) { /* must save value on stack if not already done */ @@ -193,7 +924,7 @@ void save_reg(int r) type = &p->type; if ((p->r & VT_LVAL) || (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG)) -#ifdef TCC_TARGET_X86_64 +#if PTR_SIZE == 8 type = &char_pointer_type; #else type = &int_type; @@ -202,18 +933,18 @@ void save_reg(int r) loc = (loc - size) & -align; sv.type.t = type->t; sv.r = VT_LOCAL | VT_LVAL; - sv.c.ul = loc; + sv.c.i = loc; store(r, &sv); #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) /* x86 specific: need to pop fp register ST0 if saved */ if (r == TREG_ST0) { - o(0xd9dd); /* fstp %st(1) */ + o(0xd8dd); /* fstp %st(0) */ } #endif -#ifndef TCC_TARGET_X86_64 +#if PTR_SIZE == 4 /* special long long case */ if ((type->t & VT_BTYPE) == VT_LLONG) { - sv.c.ul += 4; + sv.c.i += 4; store(p->r2, &sv); } #endif @@ -224,20 +955,21 @@ void save_reg(int r) if (p->r & VT_LVAL) { /* also clear the bounded flag because the relocation address of the function was stored in - p->c.ul */ + p->c.i */ p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL; } else { p->r = lvalue_type(p->type.t) | VT_LOCAL; } p->r2 = VT_CONST; - p->c.ul = l; + p->c.i = l; } } } +#ifdef TCC_TARGET_ARM /* find a register of class 'rc2' with at most one reference on stack. * If none, call get_reg(rc) */ -int get_reg_ex(int rc, int rc2) +ST_FUNC int get_reg_ex(int rc, int rc2) { int r; SValue *p; @@ -257,9 +989,10 @@ int get_reg_ex(int rc, int rc2) } return get_reg(rc); } +#endif /* find a free register of class 'rc'. If none, save one register */ -int get_reg(int rc) +ST_FUNC int get_reg(int rc) { int r; SValue *p; @@ -267,6 +1000,8 @@ int get_reg(int rc) /* find a free register */ for(r=0;r<NB_REGS;r++) { if (reg_classes[r] & rc) { + if (nocode_wanted) + return r; for(p=vstack;p<=vtop;p++) { if ((p->r & VT_VALMASK) == r || (p->r2 & VT_VALMASK) == r) @@ -281,11 +1016,11 @@ int get_reg(int rc) IMPORTANT to start from the bottom to ensure that we don't spill registers used in gen_opi()) */ for(p=vstack;p<=vtop;p++) { - r = p->r & VT_VALMASK; + /* look at second register (if long long) */ + r = p->r2 & VT_VALMASK; if (r < VT_CONST && (reg_classes[r] & rc)) goto save_found; - /* also look at second register (if long long) */ - r = p->r2 & VT_VALMASK; + r = p->r & VT_VALMASK; if (r < VT_CONST && (reg_classes[r] & rc)) { save_found: save_reg(r); @@ -296,47 +1031,36 @@ int get_reg(int rc) return -1; } -/* save registers up to (vtop - n) stack entry */ -void save_regs(int n) -{ - int r; - SValue *p, *p1; - p1 = vtop - n; - for(p = vstack;p <= p1; p++) { - r = p->r & VT_VALMASK; - if (r < VT_CONST) { - save_reg(r); - } - } -} - -/* move register 's' to 'r', and flush previous value of r to memory +/* move register 's' (of type 't') to 'r', and flush previous value of r to memory if needed */ -void move_reg(int r, int s) +static void move_reg(int r, int s, int t) { SValue sv; if (r != s) { save_reg(r); - sv.type.t = VT_INT; + sv.type.t = t; + sv.type.ref = NULL; sv.r = s; - sv.c.ul = 0; + sv.c.i = 0; load(r, &sv); } } /* get address of vtop (vtop MUST BE an lvalue) */ -void gaddrof(void) +ST_FUNC void gaddrof(void) { vtop->r &= ~VT_LVAL; /* tricky: if saved lvalue, then we can go back to lvalue */ if ((vtop->r & VT_VALMASK) == VT_LLOCAL) vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL; + + } #ifdef CONFIG_TCC_BCHECK /* generate lvalue bound code */ -void gbound(void) +static void gbound(void) { int lval_type; CType type1; @@ -349,7 +1073,7 @@ void gbound(void) lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL); /* must save type because we must set it to int to get pointer */ type1 = vtop->type; - vtop->type.t = VT_INT; + vtop->type.t = VT_PTR; gaddrof(); vpushi(0); gen_bounded_ptr_add(); @@ -362,75 +1086,156 @@ void gbound(void) } #endif +static void incr_bf_adr(int o) +{ + vtop->type = char_pointer_type; + gaddrof(); + vpushi(o); + gen_op('+'); + vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN)) + | (VT_BYTE|VT_UNSIGNED); + vtop->r = (vtop->r & ~VT_LVAL_TYPE) + | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL); +} + +/* single-byte load mode for packed or otherwise unaligned bitfields */ +static void load_packed_bf(CType *type, int bit_pos, int bit_size) +{ + int n, o, bits; + save_reg_upstack(vtop->r, 1); + vpush64(type->t & VT_BTYPE, 0); // B X + bits = 0, o = bit_pos >> 3, bit_pos &= 7; + do { + vswap(); // X B + incr_bf_adr(o); + vdup(); // X B B + n = 8 - bit_pos; + if (n > bit_size) + n = bit_size; + if (bit_pos) + vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y + if (n < 8) + vpushi((1 << n) - 1), gen_op('&'); + gen_cast(type); + if (bits) + vpushi(bits), gen_op(TOK_SHL); + vrotb(3); // B Y X + gen_op('|'); // B X + bits += n, bit_size -= n, o = 1; + } while (bit_size); + vswap(), vpop(); + if (!(type->t & VT_UNSIGNED)) { + n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits; + vpushi(n), gen_op(TOK_SHL); + vpushi(n), gen_op(TOK_SAR); + } +} + +/* single-byte store mode for packed or otherwise unaligned bitfields */ +static void store_packed_bf(int bit_pos, int bit_size) +{ + int bits, n, o, m, c; + + c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; + vswap(); // X B + save_reg_upstack(vtop->r, 1); + bits = 0, o = bit_pos >> 3, bit_pos &= 7; + do { + incr_bf_adr(o); // X B + vswap(); //B X + c ? vdup() : gv_dup(); // B V X + vrott(3); // X B V + if (bits) + vpushi(bits), gen_op(TOK_SHR); + if (bit_pos) + vpushi(bit_pos), gen_op(TOK_SHL); + n = 8 - bit_pos; + if (n > bit_size) + n = bit_size; + if (n < 8) { + m = ((1 << n) - 1) << bit_pos; + vpushi(m), gen_op('&'); // X B V1 + vpushv(vtop-1); // X B V1 B + vpushi(m & 0x80 ? ~m & 0x7f : ~m); + gen_op('&'); // X B V1 B1 + gen_op('|'); // X B V2 + } + vdup(), vtop[-1] = vtop[-2]; // X B B V2 + vstore(), vpop(); // X B + bits += n, bit_size -= n, bit_pos = 0, o = 1; + } while (bit_size); + vpop(), vpop(); +} + +static int adjust_bf(SValue *sv, int bit_pos, int bit_size) +{ + int t; + if (0 == sv->type.ref) + return 0; + t = sv->type.ref->auxtype; + if (t != -1 && t != VT_STRUCT) { + sv->type.t = (sv->type.t & ~VT_BTYPE) | t; + sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t); + } + return t; +} + /* store vtop a register belonging to class 'rc'. lvalues are converted to values. Cannot be used if cannot be converted to register value (such as structures). */ -int gv(int rc) +ST_FUNC int gv(int rc) { - int r, rc2, bit_pos, bit_size, size, align, i; + int r, bit_pos, bit_size, size, align, rc2; /* NOTE: get_reg can modify vstack[] */ if (vtop->type.t & VT_BITFIELD) { CType type; - int bits = 32; - bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; + + bit_pos = BIT_POS(vtop->type.t); + bit_size = BIT_SIZE(vtop->type.t); /* remove bit field info to avoid loops */ - vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); - /* cast to int to propagate signedness in following ops */ - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - type.t = VT_LLONG; - bits = 64; - } else - type.t = VT_INT; - if((vtop->type.t & VT_UNSIGNED) || - (vtop->type.t & VT_BTYPE) == VT_BOOL) + vtop->type.t &= ~VT_STRUCT_MASK; + + type.ref = NULL; + type.t = vtop->type.t & VT_UNSIGNED; + if ((vtop->type.t & VT_BTYPE) == VT_BOOL) type.t |= VT_UNSIGNED; - gen_cast(&type); - /* generate shifts */ - vpushi(bits - (bit_pos + bit_size)); - gen_op(TOK_SHL); - vpushi(bits - bit_size); - /* NOTE: transformed to SHR if unsigned */ - gen_op(TOK_SAR); + + r = adjust_bf(vtop, bit_pos, bit_size); + + if ((vtop->type.t & VT_BTYPE) == VT_LLONG) + type.t |= VT_LLONG; + else + type.t |= VT_INT; + + if (r == VT_STRUCT) { + load_packed_bf(&type, bit_pos, bit_size); + } else { + int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32; + /* cast to int to propagate signedness in following ops */ + gen_cast(&type); + /* generate shifts */ + vpushi(bits - (bit_pos + bit_size)); + gen_op(TOK_SHL); + vpushi(bits - bit_size); + /* NOTE: transformed to SHR if unsigned */ + gen_op(TOK_SAR); + } r = gv(rc); } else { if (is_float(vtop->type.t) && (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - Sym *sym; - int *ptr; unsigned long offset; -#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) - CValue check; -#endif - - /* XXX: unify with initializers handling ? */ /* CPUs usually cannot use float constants, so we store them generically in data segment */ size = type_size(&vtop->type, &align); - offset = (data_section->data_offset + align - 1) & -align; - data_section->data_offset = offset; - /* XXX: not portable yet */ -#if defined(__i386__) || defined(__x86_64__) - /* Zero pad x87 tenbyte long doubles */ - if (size == LDOUBLE_SIZE) - vtop->c.tab[2] &= 0xffff; -#endif - ptr = section_ptr_add(data_section, size); - size = size >> 2; -#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) - check.d = 1; - if(check.tab[0]) - for(i=0;i<size;i++) - ptr[i] = vtop->c.tab[size-1-i]; - else -#endif - for(i=0;i<size;i++) - ptr[i] = vtop->c.tab[i]; - sym = get_sym_ref(&vtop->type, data_section, offset, size << 2); - vtop->r |= VT_LVAL | VT_SYM; - vtop->sym = sym; - vtop->c.ul = 0; + if (NODATA_WANTED) + size = 0, align = 1; + offset = section_add(data_section, size, align); + vpush_ref(&vtop->type, data_section, offset, size); + vswap(); + init_putv(&vtop->type, data_section, offset); + vtop->r |= VT_LVAL; } #ifdef CONFIG_TCC_BCHECK if (vtop->r & VT_MUSTBOUND) @@ -438,49 +1243,76 @@ int gv(int rc) #endif r = vtop->r & VT_VALMASK; - rc2 = RC_INT; + rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT; +#ifndef TCC_TARGET_ARM64 if (rc == RC_IRET) rc2 = RC_LRET; +#ifdef TCC_TARGET_X86_64 + else if (rc == RC_FRET) + rc2 = RC_QRET; +#endif +#endif /* need to reload if: - constant - lvalue (need to dereference pointer) - already a register, but not in the right class */ - if (r >= VT_CONST || - (vtop->r & VT_LVAL) || - !(reg_classes[r] & rc) || - ((vtop->type.t & VT_BTYPE) == VT_LLONG && - !(reg_classes[vtop->r2] & rc2))) { + if (r >= VT_CONST + || (vtop->r & VT_LVAL) + || !(reg_classes[r] & rc) +#if PTR_SIZE == 8 + || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2)) + || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2)) +#else + || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2)) +#endif + ) + { r = get_reg(rc); -#ifndef TCC_TARGET_X86_64 +#if PTR_SIZE == 8 + if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) { + int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE; +#else if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - int r2; + int addr_type = VT_INT, load_size = 4, load_type = VT_INT; unsigned long long ll; +#endif + int r2, original_type; + original_type = vtop->type.t; /* two register type load : expand to two words temporarily */ +#if PTR_SIZE == 4 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { /* load constant */ - ll = vtop->c.ull; - vtop->c.ui = ll; /* first word */ + ll = vtop->c.i; + vtop->c.i = ll; /* first word */ load(r, vtop); vtop->r = r; /* save register value */ vpushi(ll >> 32); /* second word */ - } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ - (vtop->r & VT_LVAL)) { + } else +#endif + if (vtop->r & VT_LVAL) { /* We do not want to modifier the long long pointer here, so the safest (and less efficient) is to save all the other registers in the stack. XXX: totally inefficient. */ + #if 0 save_regs(1); + #else + /* lvalue_save: save only if used further down the stack */ + save_reg_upstack(vtop->r, 1); + #endif /* load from memory */ + vtop->type.t = load_type; load(r, vtop); vdup(); vtop[-1].r = r; /* save register value */ /* increment pointer to get second word */ - vtop->type.t = VT_INT; + vtop->type.t = addr_type; gaddrof(); - vpushi(4); + vpushi(load_size); gen_op('+'); vtop->r |= VT_LVAL; + vtop->type.t = load_type; } else { /* move registers */ load(r, vtop); @@ -488,15 +1320,15 @@ int gv(int rc) vtop[-1].r = r; /* save register value */ vtop->r = vtop[-1].r2; } - /* allocate second register */ + /* Allocate second register. Here we rely on the fact that + get_reg() tries first to free r2 of an SValue. */ r2 = get_reg(rc2); load(r2, vtop); vpop(); /* write second register */ vtop->r2 = r2; - } else -#endif - if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { + vtop->type.t = original_type; + } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { int t1, t; /* lvalue of scalar type : need to use lvalue type because of possible cast */ @@ -529,7 +1361,7 @@ int gv(int rc) } /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */ -void gv2(int rc1, int rc2) +ST_FUNC void gv2(int rc1, int rc2) { int v; @@ -560,8 +1392,9 @@ void gv2(int rc1, int rc2) } } +#ifndef TCC_TARGET_ARM64 /* wrapper around RC_FRET to return a register by type */ -int rc_fret(int t) +static int rc_fret(int t) { #ifdef TCC_TARGET_X86_64 if (t == VT_LDOUBLE) { @@ -570,9 +1403,10 @@ int rc_fret(int t) #endif return RC_FRET; } +#endif /* wrapper around REG_FRET to return a register by type */ -int reg_fret(int t) +static int reg_fret(int t) { #ifdef TCC_TARGET_X86_64 if (t == VT_LDOUBLE) { @@ -582,38 +1416,46 @@ int reg_fret(int t) return REG_FRET; } -/* expand long long on stack in two int registers */ -void lexpand(void) +#if PTR_SIZE == 4 +/* expand 64bit on stack in two ints */ +static void lexpand(void) { - int u; - - u = vtop->type.t & VT_UNSIGNED; - gv(RC_INT); - vdup(); - vtop[0].r = vtop[-1].r2; - vtop[0].r2 = VT_CONST; - vtop[-1].r2 = VT_CONST; - vtop[0].type.t = VT_INT | u; - vtop[-1].type.t = VT_INT | u; + int u, v; + u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); + v = vtop->r & (VT_VALMASK | VT_LVAL); + if (v == VT_CONST) { + vdup(); + vtop[0].c.i >>= 32; + } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) { + vdup(); + vtop[0].c.i += 4; + } else { + gv(RC_INT); + vdup(); + vtop[0].r = vtop[-1].r2; + vtop[0].r2 = vtop[-1].r2 = VT_CONST; + } + vtop[0].type.t = vtop[-1].type.t = VT_INT | u; } +#endif #ifdef TCC_TARGET_ARM /* expand long long on stack */ -void lexpand_nr(void) +ST_FUNC void lexpand_nr(void) { int u,v; - u = vtop->type.t & VT_UNSIGNED; + u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); vdup(); vtop->r2 = VT_CONST; vtop->type.t = VT_INT | u; v=vtop[-1].r & (VT_VALMASK | VT_LVAL); if (v == VT_CONST) { - vtop[-1].c.ui = vtop->c.ull; - vtop->c.ui = vtop->c.ull >> 32; + vtop[-1].c.i = vtop->c.i; + vtop->c.i = vtop->c.i >> 32; vtop->r = VT_CONST; } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) { - vtop->c.ui += 4; + vtop->c.i += 4; vtop->r = vtop[-1].r; } else if (v > VT_CONST) { vtop--; @@ -625,86 +1467,31 @@ void lexpand_nr(void) } #endif +#if PTR_SIZE == 4 /* build a long long from two ints */ -void lbuild(int t) +static void lbuild(int t) { gv2(RC_INT, RC_INT); vtop[-1].r2 = vtop[0].r; vtop[-1].type.t = t; vpop(); } - -/* rotate n first stack elements to the bottom - I1 ... In -> I2 ... In I1 [top is right] -*/ -void vrotb(int n) -{ - int i; - SValue tmp; - - tmp = vtop[-n + 1]; - for(i=-n+1;i!=0;i++) - vtop[i] = vtop[i+1]; - vtop[0] = tmp; -} - -/* rotate n first stack elements to the top - I1 ... In -> In I1 ... I(n-1) [top is right] - */ -void vrott(int n) -{ - int i; - SValue tmp; - - tmp = vtop[0]; - for(i = 0;i < n - 1; i++) - vtop[-i] = vtop[-i - 1]; - vtop[-n + 1] = tmp; -} - -#ifdef TCC_TARGET_ARM -/* like vrott but in other direction - In ... I1 -> I(n-1) ... I1 In [top is right] - */ -void vnrott(int n) -{ - int i; - SValue tmp; - - tmp = vtop[-n + 1]; - for(i = n - 1; i > 0; i--) - vtop[-i] = vtop[-i + 1]; - vtop[0] = tmp; -} -#endif - -/* pop stack value */ -void vpop(void) -{ - int v; - v = vtop->r & VT_VALMASK; -#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) - /* for x86, we need to pop the FP stack */ - if (v == TREG_ST0 && !nocode_wanted) { - o(0xd9dd); /* fstp %st(1) */ - } else #endif - if (v == VT_JMP || v == VT_JMPI) { - /* need to put correct jump if && or || without test */ - gsym(vtop->c.ul); - } - vtop--; -} /* convert stack entry to register and duplicate its value in another register */ -void gv_dup(void) +static void gv_dup(void) { int rc, t, r, r1; SValue sv; t = vtop->type.t; +#if PTR_SIZE == 4 if ((t & VT_BTYPE) == VT_LLONG) { + if (t & VT_BITFIELD) { + gv(RC_INT); + t = vtop->type.t; + } lexpand(); gv_dup(); vswap(); @@ -718,7 +1505,9 @@ void gv_dup(void) vswap(); lbuild(t); vswap(); - } else { + } else +#endif + { /* duplicate value */ rc = RC_INT; sv.type.t = VT_INT; @@ -734,17 +1523,38 @@ void gv_dup(void) r = gv(rc); r1 = get_reg(rc); sv.r = r; - sv.c.ul = 0; + sv.c.i = 0; load(r1, &sv); /* move r to r1 */ vdup(); /* duplicates value */ - vtop->r = r1; + if (r != r1) + vtop->r = r1; } } -#ifndef TCC_TARGET_X86_64 +/* Generate value test + * + * Generate a test for any value (jump, comparison and integers) */ +ST_FUNC int gvtst(int inv, int t) +{ + int v = vtop->r & VT_VALMASK; + if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) { + vpushi(0); + gen_op(TOK_NE); + } + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + /* constant jmp optimization */ + if ((vtop->c.i != 0) != inv) + t = gjmp(t); + vtop--; + return t; + } + return gtst(inv, t); +} + +#if PTR_SIZE == 4 /* generate CPU independent (unsigned) long long operations */ -void gen_opl(int op) +static void gen_opl(int op) { int t, a, b, op1, c, i; int func; @@ -785,6 +1595,7 @@ void gen_opl(int op) case '*': case '+': case '-': + //pv("gen_opl A",0,2); t = vtop->type.t; vswap(); lexpand(); @@ -799,6 +1610,7 @@ void gen_opl(int op) vtop[-3] = tmp; vswap(); /* stack: H1 H2 L1 L2 */ + //pv("gen_opl B",0,4); if (op == '*') { vpushv(vtop - 1); vpushv(vtop - 1); @@ -854,7 +1666,7 @@ void gen_opl(int op) c = (int)vtop->c.i; /* constant: simpler */ /* NOTE: all comments are for SHL. the other cases are - done by swaping words */ + done by swapping words */ vpop(); if (op != TOK_SHL) vswap(); @@ -939,25 +1751,15 @@ void gen_opl(int op) a = 0; b = 0; gen_op(op1); - if (op1 != TOK_NE) { - a = gtst(1, 0); - } - if (op != TOK_EQ) { - /* generate non equal test */ - /* XXX: NOT PORTABLE yet */ - if (a == 0) { - b = gtst(0, 0); - } else { -#if defined(TCC_TARGET_I386) - b = psym(0x850f, 0); -#elif defined(TCC_TARGET_ARM) - b = ind; - o(0x1A000000 | encbranch(ind, 0, 1)); -#elif defined(TCC_TARGET_C67) - error("not implemented"); -#else -#error not supported -#endif + if (op == TOK_NE) { + b = gvtst(0, 0); + } else { + a = gvtst(1, 0); + if (op != TOK_EQ) { + /* generate non equal test */ + vpushi(TOK_NE); + vtop->r = VT_CMP; + b = gvtst(0, 0); } } /* compare low. Always unsigned */ @@ -971,7 +1773,7 @@ void gen_opl(int op) else if (op1 == TOK_GE) op1 = TOK_UGE; gen_op(op1); - a = gtst(1, a); + a = gvtst(1, a); gsym(b); vseti(VT_JMPI, a); break; @@ -979,37 +1781,38 @@ void gen_opl(int op) } #endif -/* handle integer constant optimizations and various machine - independent opt */ -void gen_opic(int op) +static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b) { - int c1, c2, t1, t2, n; - SValue *v1, *v2; - long long l1, l2; - typedef unsigned long long U; - - v1 = vtop - 1; - v2 = vtop; - t1 = v1->type.t & VT_BTYPE; - t2 = v2->type.t & VT_BTYPE; + uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b); + return (a ^ b) >> 63 ? -x : x; +} - if (t1 == VT_LLONG) - l1 = v1->c.ll; - else if (v1->type.t & VT_UNSIGNED) - l1 = v1->c.ui; - else - l1 = v1->c.i; +static int gen_opic_lt(uint64_t a, uint64_t b) +{ + return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63); +} - if (t2 == VT_LLONG) - l2 = v2->c.ll; - else if (v2->type.t & VT_UNSIGNED) - l2 = v2->c.ui; - else - l2 = v2->c.i; +/* handle integer constant optimizations and various machine + independent opt */ +static void gen_opic(int op) +{ + SValue *v1 = vtop - 1; + SValue *v2 = vtop; + int t1 = v1->type.t & VT_BTYPE; + int t2 = v2->type.t & VT_BTYPE; + int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; + int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; + uint64_t l1 = c1 ? v1->c.i : 0; + uint64_t l2 = c2 ? v2->c.i : 0; + int shm = (t1 == VT_LLONG) ? 63 : 31; + + if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR)) + l1 = ((uint32_t)l1 | + (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000))); + if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR)) + l2 = ((uint32_t)l2 | + (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000))); - /* currently, we cannot do computations with forward symbols */ - c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; if (c1 && c2) { switch(op) { case '+': l1 += l2; break; @@ -1027,37 +1830,42 @@ void gen_opic(int op) /* if division by zero, generate explicit division */ if (l2 == 0) { if (const_wanted) - error("division by zero in constant"); + tcc_error("division by zero in constant"); goto general_case; } switch(op) { - default: l1 /= l2; break; - case '%': l1 %= l2; break; - case TOK_UDIV: l1 = (U)l1 / l2; break; - case TOK_UMOD: l1 = (U)l1 % l2; break; + default: l1 = gen_opic_sdiv(l1, l2); break; + case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break; + case TOK_UDIV: l1 = l1 / l2; break; + case TOK_UMOD: l1 = l1 % l2; break; } break; - case TOK_SHL: l1 <<= l2; break; - case TOK_SHR: l1 = (U)l1 >> l2; break; - case TOK_SAR: l1 >>= l2; break; + case TOK_SHL: l1 <<= (l2 & shm); break; + case TOK_SHR: l1 >>= (l2 & shm); break; + case TOK_SAR: + l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm); + break; /* tests */ - case TOK_ULT: l1 = (U)l1 < (U)l2; break; - case TOK_UGE: l1 = (U)l1 >= (U)l2; break; + case TOK_ULT: l1 = l1 < l2; break; + case TOK_UGE: l1 = l1 >= l2; break; case TOK_EQ: l1 = l1 == l2; break; case TOK_NE: l1 = l1 != l2; break; - case TOK_ULE: l1 = (U)l1 <= (U)l2; break; - case TOK_UGT: l1 = (U)l1 > (U)l2; break; - case TOK_LT: l1 = l1 < l2; break; - case TOK_GE: l1 = l1 >= l2; break; - case TOK_LE: l1 = l1 <= l2; break; - case TOK_GT: l1 = l1 > l2; break; + case TOK_ULE: l1 = l1 <= l2; break; + case TOK_UGT: l1 = l1 > l2; break; + case TOK_LT: l1 = gen_opic_lt(l1, l2); break; + case TOK_GE: l1 = !gen_opic_lt(l1, l2); break; + case TOK_LE: l1 = !gen_opic_lt(l2, l1); break; + case TOK_GT: l1 = gen_opic_lt(l2, l1); break; /* logical */ case TOK_LAND: l1 = l1 && l2; break; case TOK_LOR: l1 = l1 || l2; break; default: goto general_case; } - v1->c.ll = l1; + if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR)) + l1 = ((uint32_t)l1 | + (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000))); + v1->c.i = l1; vtop--; } else { /* if commutative ops, put c2 as constant */ @@ -1067,26 +1875,41 @@ void gen_opic(int op) c2 = c1; //c = c1, c1 = c2, c2 = c; l2 = l1; //l = l1, l1 = l2, l2 = l; } - /* Filter out NOP operations like x*1, x-0, x&-1... */ - if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || - op == TOK_PDIV) && - l2 == 1) || - ((op == '+' || op == '-' || op == '|' || op == '^' || - op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && - l2 == 0) || - (op == '&' && - l2 == -1))) { - /* nothing to do */ + if (!const_wanted && + c1 && ((l1 == 0 && + (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) || + (l1 == -1 && op == TOK_SAR))) { + /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */ + vtop--; + } else if (!const_wanted && + c2 && ((l2 == 0 && (op == '&' || op == '*')) || + (op == '|' && + (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) || + (l2 == 1 && (op == '%' || op == TOK_UMOD)))) { + /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */ + if (l2 == 1) + vtop->c.i = 0; + vswap(); + vtop--; + } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || + op == TOK_PDIV) && + l2 == 1) || + ((op == '+' || op == '-' || op == '|' || op == '^' || + op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && + l2 == 0) || + (op == '&' && + (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) { + /* filter out NOP operations like x*1, x-0, x&-1... */ vtop--; } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { /* try to use shifts instead of muls or divs */ if (l2 > 0 && (l2 & (l2 - 1)) == 0) { - n = -1; + int n = -1; while (l2) { l2 >>= 1; n++; } - vtop->c.ll = n; + vtop->c.i = n; if (op == '*') op = TOK_SHL; else if (op == TOK_PDIV) @@ -1096,34 +1919,39 @@ void gen_opic(int op) } goto general_case; } else if (c2 && (op == '+' || op == '-') && - ((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == - (VT_CONST | VT_SYM) || - (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) { + (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM)) + || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) { /* symbol + constant case */ if (op == '-') l2 = -l2; + l2 += vtop[-1].c.i; + /* The backends can't always deal with addends to symbols + larger than +-1<<31. Don't construct such. */ + if ((int)l2 != l2) + goto general_case; vtop--; - vtop->c.ll += l2; + vtop->c.i = l2; } else { general_case: - if (!nocode_wanted) { /* call low level op generator */ - if (t1 == VT_LLONG || t2 == VT_LLONG) + if (t1 == VT_LLONG || t2 == VT_LLONG || + (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR))) gen_opl(op); else gen_opi(op); - } else { - vtop--; - } } } } /* generate a floating point operation with constant propagation */ -void gen_opif(int op) +static void gen_opif(int op) { int c1, c2; SValue *v1, *v2; +#if defined _MSC_VER && defined _AMD64_ + /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */ + volatile +#endif long double f1, f2; v1 = vtop - 1; @@ -1155,7 +1983,7 @@ void gen_opif(int op) case '/': if (f2 == 0.0) { if (const_wanted) - error("division by zero in constant"); + tcc_error("division by zero in constant"); goto general_case; } f1 /= f2; @@ -1175,11 +2003,7 @@ void gen_opif(int op) vtop--; } else { general_case: - if (!nocode_wanted) { - gen_opf(op); - } else { - vtop--; - } + gen_opf(op); } } @@ -1189,12 +2013,20 @@ static int pointed_size(CType *type) return type_size(pointed_type(type), &align); } +static void vla_runtime_pointed_size(CType *type) +{ + int align; + vla_runtime_type_size(pointed_type(type), &align); +} + static inline int is_null_pointer(SValue *p) { if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) return 0; - return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) || - ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0); + return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) || + ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) || + ((p->type.t & VT_BTYPE) == VT_PTR && + (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0)); } static inline int is_integer_btype(int bt) @@ -1219,7 +2051,7 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) /* accept comparison between pointer and integer with a warning */ if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') { if (op != TOK_LOR && op != TOK_LAND ) - warning("comparison between pointer and integer"); + tcc_warning("comparison between pointer and integer"); return; } @@ -1233,42 +2065,57 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) type2 = pointed_type(type2); } else if (bt2 != VT_FUNC) { invalid_operands: - error("invalid operands to binary %s", get_tok_str(op, NULL)); + tcc_error("invalid operands to binary %s", get_tok_str(op, NULL)); } if ((type1->t & VT_BTYPE) == VT_VOID || (type2->t & VT_BTYPE) == VT_VOID) return; tmp_type1 = *type1; tmp_type2 = *type2; - tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); + tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); + tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); if (!is_compatible_types(&tmp_type1, &tmp_type2)) { /* gcc-like error if '-' is used */ if (op == '-') goto invalid_operands; else - warning("comparison of distinct pointer types lacks a cast"); + tcc_warning("comparison of distinct pointer types lacks a cast"); } } /* generic gen_op: handles types problems */ -void gen_op(int op) +ST_FUNC void gen_op(int op) { int u, t1, t2, bt1, bt2, t; CType type1; +redo: t1 = vtop[-1].type.t; t2 = vtop[0].type.t; bt1 = t1 & VT_BTYPE; bt2 = t2 & VT_BTYPE; - if (bt1 == VT_PTR || bt2 == VT_PTR) { + if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { + tcc_error("operation on a struct"); + } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { + if (bt2 == VT_FUNC) { + mk_pointer(&vtop->type); + gaddrof(); + } + if (bt1 == VT_FUNC) { + vswap(); + mk_pointer(&vtop->type); + gaddrof(); + vswap(); + } + goto redo; + } else if (bt1 == VT_PTR || bt2 == VT_PTR) { /* at least one operand is a pointer */ - /* relationnal op: must be both pointers */ + /* relational op: must be both pointers */ if (op >= TOK_ULT && op <= TOK_LOR) { check_comparison_pointer_types(vtop - 1, vtop, op); /* pointers are handled are unsigned */ -#ifdef TCC_TARGET_X86_64 +#if PTR_SIZE == 8 t = VT_LLONG | VT_UNSIGNED; #else t = VT_INT | VT_UNSIGNED; @@ -1278,37 +2125,65 @@ void gen_op(int op) /* if both pointers, then it must be the '-' op */ if (bt1 == VT_PTR && bt2 == VT_PTR) { if (op != '-') - error("cannot use pointers here"); + tcc_error("cannot use pointers here"); check_comparison_pointer_types(vtop - 1, vtop, op); /* XXX: check that types are compatible */ - u = pointed_size(&vtop[-1].type); + if (vtop[-1].type.t & VT_VLA) { + vla_runtime_pointed_size(&vtop[-1].type); + } else { + vpushi(pointed_size(&vtop[-1].type)); + } + vrott(3); gen_opic(op); - /* set to integer type */ -#ifdef TCC_TARGET_X86_64 - vtop->type.t = VT_LLONG; -#else - vtop->type.t = VT_INT; -#endif - vpushi(u); + vtop->type.t = ptrdiff_type.t; + vswap(); gen_op(TOK_PDIV); } else { /* exactly one pointer : must be '+' or '-'. */ if (op != '-' && op != '+') - error("cannot use pointers here"); + tcc_error("cannot use pointers here"); /* Put pointer as first operand */ if (bt2 == VT_PTR) { vswap(); - swap(&t1, &t2); + t = t1, t1 = t2, t2 = t; } +#if PTR_SIZE == 4 + if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG) + /* XXX: truncate here because gen_opl can't handle ptr + long long */ + gen_cast_s(VT_INT); +#endif type1 = vtop[-1].type; -#ifdef TCC_TARGET_X86_64 - vpushll(pointed_size(&vtop[-1].type)); + type1.t &= ~VT_ARRAY; + if (vtop[-1].type.t & VT_VLA) + vla_runtime_pointed_size(&vtop[-1].type); + else { + u = pointed_size(&vtop[-1].type); + if (u < 0) + tcc_error("unknown array element size"); +#if PTR_SIZE == 8 + vpushll(u); #else - /* XXX: cast to int ? (long long case) */ - vpushi(pointed_size(&vtop[-1].type)); + /* XXX: cast to int ? (long long case) */ + vpushi(u); #endif + } gen_op('*'); -#ifdef CONFIG_TCC_BCHECK +#if 0 +/* #ifdef CONFIG_TCC_BCHECK + The main reason to removing this code: + #include <stdio.h> + int main () + { + int v[10]; + int i = 10; + int j = 9; + fprintf(stderr, "v+i-j = %p\n", v+i-j); + fprintf(stderr, "v+(i-j) = %p\n", v+(i-j)); + } + When this code is on. then the output looks like + v+i-j = 0xfffffffe + v+(i-j) = 0xbff84000 + */ /* if evaluating constant expression, no code should be generated, so no bound check */ if (tcc_state->do_bounds_check && !const_wanted) { @@ -1340,22 +2215,32 @@ void gen_op(int op) /* floats can only be used for a few operations */ if (op != '+' && op != '-' && op != '*' && op != '/' && (op < TOK_ULT || op > TOK_GT)) - error("invalid operands for binary operation"); + tcc_error("invalid operands for binary operation"); + goto std_op; + } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) { + t = bt1 == VT_LLONG ? VT_LLONG : VT_INT; + if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED)) + t |= VT_UNSIGNED; + t |= (VT_LONG & t1); goto std_op; } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { /* cast to biggest op */ - t = VT_LLONG; + t = VT_LLONG | VT_LONG; + if (bt1 == VT_LLONG) + t &= t1; + if (bt2 == VT_LLONG) + t &= t2; /* convert to unsigned if it does not fit in a long long */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) + if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) || + (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED)) t |= VT_UNSIGNED; goto std_op; } else { /* integer operations */ - t = VT_INT; + t = VT_INT | (VT_LONG & (t1 | t2)); /* convert to unsigned if it does not fit in an integer */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) + if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) || + (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED)) t |= VT_UNSIGNED; std_op: /* XXX: currently, some unsigned operations are explicit, so @@ -1378,6 +2263,7 @@ void gen_op(int op) } vswap(); type1.t = t; + type1.ref = NULL; gen_cast(&type1); vswap(); /* special case for shifts and long long: we keep the shift as @@ -1390,18 +2276,24 @@ void gen_op(int op) else gen_opic(op); if (op >= TOK_ULT && op <= TOK_GT) { - /* relationnal op: the result is an int */ + /* relational op: the result is an int */ vtop->type.t = VT_INT; } else { vtop->type.t = t; } } + // Make sure that we have converted to an rvalue: + if (vtop->r & VT_LVAL) + gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT); } #ifndef TCC_TARGET_ARM /* generic itof for unsigned long long case */ -void gen_cvt_itof1(int t) +static void gen_cvt_itof1(int t) { +#ifdef TCC_TARGET_ARM64 + gen_cvt_itof(t); +#else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) { @@ -1420,12 +2312,16 @@ void gen_cvt_itof1(int t) } else { gen_cvt_itof(t); } +#endif } #endif /* generic ftoi for unsigned long long case */ -void gen_cvt_ftoi1(int t) +static void gen_cvt_ftoi1(int t) { +#ifdef TCC_TARGET_ARM64 + gen_cvt_ftoi(t); +#else int st; if (t == (VT_LLONG | VT_UNSIGNED)) { @@ -1447,12 +2343,18 @@ void gen_cvt_ftoi1(int t) } else { gen_cvt_ftoi(t); } +#endif } /* force char or short cast */ -void force_charshort_cast(int t) +static void force_charshort_cast(int t) { int bits, dbt; + + /* cannot cast static initializers */ + if (STATIC_DATA_WANTED) + return; + dbt = t & VT_BTYPE; /* XXX: add optimization if lvalue : just change type and offset */ if (dbt == VT_BYTE) @@ -1463,7 +2365,10 @@ void force_charshort_cast(int t) vpushi((1 << bits) - 1); gen_op('&'); } else { - bits = 32 - bits; + if ((vtop->type.t & VT_BTYPE) == VT_LLONG) + bits = 64 - bits; + else + bits = 32 - bits; vpushi(bits); gen_op(TOK_SHL); /* result must be signed or the SAR is converted to an SHL @@ -1476,6 +2381,14 @@ void force_charshort_cast(int t) } /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */ +static void gen_cast_s(int t) +{ + CType type; + type.t = t; + type.ref = NULL; + gen_cast(&type); +} + static void gen_cast(CType *type) { int sbt, dbt, sf, df, c, p; @@ -1501,6 +2414,9 @@ static void gen_cast(CType *type) df = is_float(dbt); c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM); +#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387 + c &= dbt != VT_LDOUBLE; +#endif if (c) { /* constant case: we can do it now */ /* XXX: in ISOC, cannot do it if error in convert */ @@ -1511,15 +2427,15 @@ static void gen_cast(CType *type) if (df) { if ((sbt & VT_BTYPE) == VT_LLONG) { - if (sbt & VT_UNSIGNED) - vtop->c.ld = vtop->c.ull; + if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63)) + vtop->c.ld = vtop->c.i; else - vtop->c.ld = vtop->c.ll; + vtop->c.ld = -(long double)-vtop->c.i; } else if(!sf) { - if (sbt & VT_UNSIGNED) - vtop->c.ld = vtop->c.ui; + if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31)) + vtop->c.ld = (uint32_t)vtop->c.i; else - vtop->c.ld = vtop->c.i; + vtop->c.ld = -(long double)-(uint32_t)vtop->c.i; } if (dbt == VT_FLOAT) @@ -1527,40 +2443,45 @@ static void gen_cast(CType *type) else if (dbt == VT_DOUBLE) vtop->c.d = (double)vtop->c.ld; } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) { - vtop->c.ull = (unsigned long long)vtop->c.ld; + vtop->c.i = vtop->c.ld; } else if (sf && dbt == VT_BOOL) { vtop->c.i = (vtop->c.ld != 0); } else { if(sf) - vtop->c.ll = (long long)vtop->c.ld; + vtop->c.i = vtop->c.ld; else if (sbt == (VT_LLONG|VT_UNSIGNED)) - vtop->c.ll = vtop->c.ull; + ; else if (sbt & VT_UNSIGNED) - vtop->c.ll = vtop->c.ui; + vtop->c.i = (uint32_t)vtop->c.i; +#if PTR_SIZE == 8 + else if (sbt == VT_PTR) + ; +#endif else if (sbt != VT_LLONG) - vtop->c.ll = vtop->c.i; + vtop->c.i = ((uint32_t)vtop->c.i | + -(vtop->c.i & 0x80000000)); if (dbt == (VT_LLONG|VT_UNSIGNED)) - vtop->c.ull = vtop->c.ll; + ; else if (dbt == VT_BOOL) - vtop->c.i = (vtop->c.ll != 0); + vtop->c.i = (vtop->c.i != 0); +#if PTR_SIZE == 8 + else if (dbt == VT_PTR) + ; +#endif else if (dbt != VT_LLONG) { - int s = 0; - if ((dbt & VT_BTYPE) == VT_BYTE) - s = 24; - else if ((dbt & VT_BTYPE) == VT_SHORT) - s = 16; - - if(dbt & VT_UNSIGNED) - vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s; - else - vtop->c.i = ((int)vtop->c.ll << s) >> s; + uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff : + (dbt & VT_BTYPE) == VT_SHORT ? 0xffff : + 0xffffffff); + vtop->c.i &= m; + if (!(dbt & VT_UNSIGNED)) + vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1)); } } } else if (p && dbt == VT_BOOL) { vtop->r = VT_CONST; vtop->c.i = 1; - } else if (!nocode_wanted) { + } else { /* non constant case: generate code */ if (sf && df) { /* convert from fp to fp */ @@ -1586,7 +2507,7 @@ static void gen_cast(CType *type) gen_cast(type); } } -#ifndef TCC_TARGET_X86_64 +#if PTR_SIZE == 4 } else if ((dbt & VT_BTYPE) == VT_LLONG) { if ((sbt & VT_BTYPE) != VT_LLONG) { /* scalar to long long */ @@ -1600,7 +2521,7 @@ static void gen_cast(CType *type) if (sbt == VT_PTR) { /* cast from pointer to int before we apply shift operation, which pointers don't support*/ - gen_cast(&int_type); + gen_cast_s(VT_INT); } gv_dup(); vpushi(31); @@ -1612,15 +2533,24 @@ static void gen_cast(CType *type) } #else } else if ((dbt & VT_BTYPE) == VT_LLONG || - (dbt & VT_BTYPE) == VT_PTR) { - /* XXX: not sure if this is perfect... need more tests */ - if ((sbt & VT_BTYPE) != VT_LLONG) { - int r = gv(RC_INT); - if (sbt != (VT_INT | VT_UNSIGNED) && - sbt != VT_PTR && sbt != VT_FUNC) { + (dbt & VT_BTYPE) == VT_PTR || + (dbt & VT_BTYPE) == VT_FUNC) { + if ((sbt & VT_BTYPE) != VT_LLONG && + (sbt & VT_BTYPE) != VT_PTR && + (sbt & VT_BTYPE) != VT_FUNC) { + /* need to convert from 32bit to 64bit */ + gv(RC_INT); + if (sbt != (VT_INT | VT_UNSIGNED)) { +#if defined(TCC_TARGET_ARM64) + gen_cvt_sxtw(); +#elif defined(TCC_TARGET_X86_64) + int r = gv(RC_INT); /* x86_64 specific: movslq */ o(0x6348); o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r)); +#else +#error +#endif } } #endif @@ -1632,12 +2562,13 @@ static void gen_cast(CType *type) (dbt & VT_BTYPE) == VT_SHORT) { if (sbt == VT_PTR) { vtop->type.t = VT_INT; - warning("nonportable conversion from pointer to char/short"); + tcc_warning("nonportable conversion from pointer to char/short"); } force_charshort_cast(dbt); +#if PTR_SIZE == 4 } else if ((dbt & VT_BTYPE) == VT_INT) { /* scalar to int */ - if (sbt == VT_LLONG) { + if ((sbt & VT_BTYPE) == VT_LLONG) { /* from long long: just take low order word */ lexpand(); vpop(); @@ -1645,6 +2576,7 @@ static void gen_cast(CType *type) /* if lvalue and single word type, nothing to do because the lvalue already contains the real type size (see VT_LVAL_xxx constants) */ +#endif } } } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) { @@ -1656,8 +2588,8 @@ static void gen_cast(CType *type) vtop->type = *type; } -/* return type size. Put alignment at 'a' */ -static int type_size(CType *type, int *a) +/* return type size as known at compile time. Put alignment at 'a' */ +ST_FUNC int type_size(CType *type, int *a) { Sym *s; int bt; @@ -1683,6 +2615,8 @@ static int type_size(CType *type, int *a) *a = PTR_SIZE; return PTR_SIZE; } + } else if (IS_ENUM(type->t) && type->ref->c == -1) { + return -1; /* incomplete enum */ } else if (bt == VT_LDOUBLE) { *a = LDOUBLE_ALIGN; return LDOUBLE_SIZE; @@ -1703,12 +2637,15 @@ static int type_size(CType *type, int *a) *a = 8; #endif return 8; - } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) { + } else if (bt == VT_INT || bt == VT_FLOAT) { *a = 4; return 4; } else if (bt == VT_SHORT) { *a = 2; return 2; + } else if (bt == VT_QLONG || bt == VT_QFLOAT) { + *a = 8; + return 16; } else { /* char, void, function, _Bool */ *a = 1; @@ -1716,6 +2653,30 @@ static int type_size(CType *type, int *a) } } +/* push type size as known at runtime time on top of value stack. Put + alignment at 'a' */ +ST_FUNC void vla_runtime_type_size(CType *type, int *a) +{ + if (type->t & VT_VLA) { + type_size(&type->ref->type, a); + vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c); + } else { + vpushi(type_size(type, a)); + } +} + +static void vla_sp_restore(void) { + if (vlas_in_scope) { + gen_vla_sp_restore(vla_sp_loc); + } +} + +static void vla_sp_restore_root(void) { + if (vlas_in_scope) { + gen_vla_sp_restore(vla_sp_root_loc); + } +} + /* return the pointed type of t */ static inline CType *pointed_type(CType *type) { @@ -1723,11 +2684,11 @@ static inline CType *pointed_type(CType *type) } /* modify type so that its it is a pointer to type. */ -static void mk_pointer(CType *type) +ST_FUNC void mk_pointer(CType *type) { Sym *s; s = sym_push(SYM_FIELD, type, 0, -1); - type->t = VT_PTR | (type->t & ~VT_TYPE); + type->t = VT_PTR | (type->t & VT_STORAGE); type->ref = s; } @@ -1741,17 +2702,17 @@ static int is_compatible_func(CType *type1, CType *type2) if (!is_compatible_types(&s1->type, &s2->type)) return 0; /* check func_call */ - if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r)) + if (s1->f.func_call != s2->f.func_call) return 0; /* XXX: not complete */ - if (s1->c == FUNC_OLD || s2->c == FUNC_OLD) + if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD) return 1; - if (s1->c != s2->c) + if (s1->f.func_type != s2->f.func_type) return 0; while (s1 != NULL) { if (s2 == NULL) return 0; - if (!is_compatible_parameter_types(&s1->type, &s2->type)) + if (!is_compatible_unqualified_types(&s1->type, &s2->type)) return 0; s1 = s1->next; s2 = s2->next; @@ -1777,6 +2738,12 @@ static int compare_types(CType *type1, CType *type2, int unqualified) t1 &= ~(VT_CONSTANT | VT_VOLATILE); t2 &= ~(VT_CONSTANT | VT_VOLATILE); } + + /* Default Vs explicit signedness only matters for char */ + if ((t1 & VT_BTYPE) != VT_BYTE) { + t1 &= ~VT_DEFSIGN; + t2 &= ~VT_DEFSIGN; + } /* XXX: bitfields ? */ if (t1 != t2) return 0; @@ -1805,7 +2772,7 @@ static int is_compatible_types(CType *type1, CType *type2) /* return true if type1 and type2 are the same (ignoring qualifiers). */ -static int is_compatible_parameter_types(CType *type1, CType *type2) +static int is_compatible_unqualified_types(CType *type1, CType *type2) { return compare_types(type1,type2,1); } @@ -1814,7 +2781,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2) printed in the type */ /* XXX: union */ /* XXX: add array and function pointers */ -void type_to_str(char *buf, int buf_size, +static void type_to_str(char *buf, int buf_size, CType *type, const char *varstr) { int bt, v, t; @@ -1822,15 +2789,33 @@ void type_to_str(char *buf, int buf_size, char buf1[256]; const char *tstr; - t = type->t & VT_TYPE; + t = type->t; bt = t & VT_BTYPE; buf[0] = '\0'; - if (t & VT_CONSTANT) - pstrcat(buf, buf_size, "const "); + + if (t & VT_EXTERN) + pstrcat(buf, buf_size, "extern "); + if (t & VT_STATIC) + pstrcat(buf, buf_size, "static "); + if (t & VT_TYPEDEF) + pstrcat(buf, buf_size, "typedef "); + if (t & VT_INLINE) + pstrcat(buf, buf_size, "inline "); if (t & VT_VOLATILE) pstrcat(buf, buf_size, "volatile "); - if (t & VT_UNSIGNED) - pstrcat(buf, buf_size, "unsigned "); + if (t & VT_CONSTANT) + pstrcat(buf, buf_size, "const "); + + if (((t & VT_DEFSIGN) && bt == VT_BYTE) + || ((t & VT_UNSIGNED) + && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG) + && !IS_ENUM(t) + )) + pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed "); + + buf_size -= strlen(buf); + buf += strlen(buf); + switch(bt) { case VT_VOID: tstr = "void"; @@ -1846,13 +2831,16 @@ void type_to_str(char *buf, int buf_size, goto add_tstr; case VT_INT: tstr = "int"; - goto add_tstr; - case VT_LONG: - tstr = "long"; - goto add_tstr; + goto maybe_long; case VT_LLONG: tstr = "long long"; - goto add_tstr; + maybe_long: + if (t & VT_LONG) + tstr = "long"; + if (!IS_ENUM(t)) + goto add_tstr; + tstr = "enum "; + goto tstruct; case VT_FLOAT: tstr = "float"; goto add_tstr; @@ -1864,12 +2852,11 @@ void type_to_str(char *buf, int buf_size, add_tstr: pstrcat(buf, buf_size, tstr); break; - case VT_ENUM: case VT_STRUCT: - if (bt == VT_STRUCT) - tstr = "struct "; - else - tstr = "enum "; + tstr = "struct "; + if (IS_UNION(t)) + tstr = "union "; + tstruct: pstrcat(buf, buf_size, tstr); v = type->ref->v & ~SYM_STRUCT; if (v >= SYM_FIRST_ANOM) @@ -1893,7 +2880,16 @@ void type_to_str(char *buf, int buf_size, goto no_var; case VT_PTR: s = type->ref; + if (t & VT_ARRAY) { + snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c); + type_to_str(buf, buf_size, &s->type, buf1); + goto no_var; + } pstrcpy(buf1, sizeof(buf1), "*"); + if (t & VT_CONSTANT) + pstrcat(buf1, buf_size, "const "); + if (t & VT_VOLATILE) + pstrcat(buf1, buf_size, "volatile "); if (varstr) pstrcat(buf1, sizeof(buf1), varstr); type_to_str(buf, buf_size, &s->type, buf1); @@ -1910,15 +2906,29 @@ void type_to_str(char *buf, int buf_size, casts if needed. */ static void gen_assign_cast(CType *dt) { - CType *st, *type1, *type2, tmp_type1, tmp_type2; + CType *st, *type1, *type2; char buf1[256], buf2[256]; int dbt, sbt; st = &vtop->type; /* source type */ dbt = dt->t & VT_BTYPE; sbt = st->t & VT_BTYPE; + if (sbt == VT_VOID || dbt == VT_VOID) { + if (sbt == VT_VOID && dbt == VT_VOID) + ; /* + It is Ok if both are void + A test program: + void func1() {} + void func2() { + return func1(); + } + gcc accepts this program + */ + else + tcc_error("cannot cast from/to void"); + } if (dt->t & VT_CONSTANT) - warning("assignment of read-only location"); + tcc_warning("assignment of read-only location"); switch(dbt) { case VT_PTR: /* special cases for pointers */ @@ -1927,7 +2937,7 @@ static void gen_assign_cast(CType *dt) goto type_ok; /* accept implicit pointer to integer cast with warning */ if (is_integer_btype(sbt)) { - warning("assignment makes pointer from integer without a cast"); + tcc_warning("assignment makes pointer from integer without a cast"); goto type_ok; } type1 = pointed_type(dt); @@ -1935,9 +2945,8 @@ static void gen_assign_cast(CType *dt) if (sbt == VT_FUNC) { if ((type1->t & VT_BTYPE) != VT_VOID && !is_compatible_types(pointed_type(dt), st)) - goto error; - else - goto type_ok; + tcc_warning("assignment from incompatible pointer type"); + goto type_ok; } if (sbt != VT_PTR) goto error; @@ -1946,38 +2955,42 @@ static void gen_assign_cast(CType *dt) (type2->t & VT_BTYPE) == VT_VOID) { /* void * can match anything */ } else { - /* exact type match, except for unsigned */ - tmp_type1 = *type1; - tmp_type2 = *type2; - tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); - if (!is_compatible_types(&tmp_type1, &tmp_type2)) - warning("assignment from incompatible pointer type"); + //printf("types %08x %08x\n", type1->t, type2->t); + /* exact type match, except for qualifiers */ + if (!is_compatible_unqualified_types(type1, type2)) { + /* Like GCC don't warn by default for merely changes + in pointer target signedness. Do warn for different + base types, though, in particular for unsigned enums + and signed int targets. */ + if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG)) + || IS_ENUM(type1->t) || IS_ENUM(type2->t) + ) + tcc_warning("assignment from incompatible pointer type"); + } } /* check const and volatile */ if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) || (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE))) - warning("assignment discards qualifiers from pointer target type"); + tcc_warning("assignment discards qualifiers from pointer target type"); break; case VT_BYTE: case VT_SHORT: case VT_INT: case VT_LLONG: if (sbt == VT_PTR || sbt == VT_FUNC) { - warning("assignment makes integer from pointer without a cast"); + tcc_warning("assignment makes integer from pointer without a cast"); + } else if (sbt == VT_STRUCT) { + goto case_VT_STRUCT; } /* XXX: more tests */ break; case VT_STRUCT: - tmp_type1 = *dt; - tmp_type2 = *st; - tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE); - tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE); - if (!is_compatible_types(&tmp_type1, &tmp_type2)) { + case_VT_STRUCT: + if (!is_compatible_unqualified_types(dt, st)) { error: type_to_str(buf1, sizeof(buf1), st, NULL); type_to_str(buf2, sizeof(buf2), dt, NULL); - error("cannot cast '%s' to '%s'", buf1, buf2); + tcc_error("cannot cast '%s' to '%s'", buf1, buf2); } break; } @@ -1986,21 +2999,22 @@ static void gen_assign_cast(CType *dt) } /* store vtop in lvalue pushed on stack */ -void vstore(void) +ST_FUNC void vstore(void) { int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast; ft = vtop[-1].type.t; sbt = vtop->type.t & VT_BTYPE; dbt = ft & VT_BTYPE; - if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) || - (sbt == VT_INT && dbt == VT_SHORT)) { + if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) || + (sbt == VT_INT && dbt == VT_SHORT)) + && !(vtop->type.t & VT_BITFIELD)) { /* optimize char/short casts */ delayed_cast = VT_MUSTCAST; - vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT))); + vtop->type.t = ft & VT_TYPE; /* XXX: factorize */ if (ft & VT_CONSTANT) - warning("assignment of read-only location"); + tcc_warning("assignment of read-only location"); } else { delayed_cast = 0; if (!(ft & VT_BITFIELD)) @@ -2011,9 +3025,14 @@ void vstore(void) /* if structure, only generate pointer */ /* structure assignment : generate memcpy */ /* XXX: optimize if small size */ - if (!nocode_wanted) { size = type_size(&vtop->type, &align); + /* destination */ + vswap(); + vtop->type.t = VT_PTR; + gaddrof(); + + /* address of memcpy() */ #ifdef TCC_ARM_EABI if(!(align & 7)) vpush_global_sym(&func_old_type, TOK_memcpy8); @@ -2021,12 +3040,10 @@ void vstore(void) vpush_global_sym(&func_old_type, TOK_memcpy4); else #endif - vpush_global_sym(&func_old_type, TOK_memcpy); + /* Use memmove, rather than memcpy, as dest and src may be same: */ + vpush_global_sym(&func_old_type, TOK_memmove); - /* destination */ - vpushv(vtop - 2); - vtop->type.t = VT_PTR; - gaddrof(); + vswap(); /* source */ vpushv(vtop - 2); vtop->type.t = VT_PTR; @@ -2034,77 +3051,76 @@ void vstore(void) /* type size */ vpushi(size); gfunc_call(3); - - vswap(); - vpop(); - } else { - vswap(); - vpop(); - } + /* leave source on stack */ } else if (ft & VT_BITFIELD) { /* bitfield store handling */ - bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f; - /* remove bit field info to avoid loops */ - vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); - /* duplicate source into other register */ - gv_dup(); - vswap(); - vrott(3); + /* save lvalue as expression result (example: s.b = s.a = n;) */ + vdup(), vtop[-1] = vtop[-2]; - if((ft & VT_BTYPE) == VT_BOOL) { + bit_pos = BIT_POS(ft); + bit_size = BIT_SIZE(ft); + /* remove bit field info to avoid loops */ + vtop[-1].type.t = ft & ~VT_STRUCT_MASK; + + if ((ft & VT_BTYPE) == VT_BOOL) { gen_cast(&vtop[-1].type); vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED); } - /* duplicate destination */ - vdup(); - vtop[-1] = vtop[-2]; - - /* mask and shift source */ - if((ft & VT_BTYPE) != VT_BOOL) { - if((ft & VT_BTYPE) == VT_LLONG) { - vpushll((1ULL << bit_size) - 1ULL); - } else { - vpushi((1 << bit_size) - 1); + r = adjust_bf(vtop - 1, bit_pos, bit_size); + if (r == VT_STRUCT) { + gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT); + store_packed_bf(bit_pos, bit_size); + } else { + unsigned long long mask = (1ULL << bit_size) - 1; + if ((ft & VT_BTYPE) != VT_BOOL) { + /* mask source */ + if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG) + vpushll(mask); + else + vpushi((unsigned)mask); + gen_op('&'); } + /* shift source */ + vpushi(bit_pos); + gen_op(TOK_SHL); + vswap(); + /* duplicate destination */ + vdup(); + vrott(3); + /* load destination, mask and or with source */ + if ((vtop->type.t & VT_BTYPE) == VT_LLONG) + vpushll(~(mask << bit_pos)); + else + vpushi(~((unsigned)mask << bit_pos)); gen_op('&'); + gen_op('|'); + /* store result */ + vstore(); + /* ... and discard */ + vpop(); } - vpushi(bit_pos); - gen_op(TOK_SHL); - /* load destination, mask and or with source */ - vswap(); - if((ft & VT_BTYPE) == VT_LLONG) { - vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos)); - } else { - vpushi(~(((1 << bit_size) - 1) << bit_pos)); - } - gen_op('&'); - gen_op('|'); - /* store result */ - vstore(); - - /* pop off shifted source from "duplicate source..." above */ - vpop(); - + } else if (dbt == VT_VOID) { + --vtop; } else { #ifdef CONFIG_TCC_BCHECK - /* bound check case */ - if (vtop[-1].r & VT_MUSTBOUND) { - vswap(); - gbound(); - vswap(); - } + /* bound check case */ + if (vtop[-1].r & VT_MUSTBOUND) { + vswap(); + gbound(); + vswap(); + } #endif - if (!nocode_wanted) { rc = RC_INT; if (is_float(ft)) { rc = RC_FLOAT; #ifdef TCC_TARGET_X86_64 if ((ft & VT_BTYPE) == VT_LDOUBLE) { rc = RC_ST0; + } else if ((ft & VT_BTYPE) == VT_QFLOAT) { + rc = RC_FRET; } #endif } @@ -2113,33 +3129,41 @@ void vstore(void) if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) { SValue sv; t = get_reg(RC_INT); -#ifdef TCC_TARGET_X86_64 +#if PTR_SIZE == 8 sv.type.t = VT_PTR; #else sv.type.t = VT_INT; #endif sv.r = VT_LOCAL | VT_LVAL; - sv.c.ul = vtop[-1].c.ul; + sv.c.i = vtop[-1].c.i; load(t, &sv); vtop[-1].r = t | VT_LVAL; } - store(r, vtop - 1); -#ifndef TCC_TARGET_X86_64 - /* two word case handling : store second register at word + 4 */ + /* two word case handling : store second register at word + 4 (or +8 for x86-64) */ +#if PTR_SIZE == 8 + if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) { + int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE; +#else if ((ft & VT_BTYPE) == VT_LLONG) { + int addr_type = VT_INT, load_size = 4, load_type = VT_INT; +#endif + vtop[-1].type.t = load_type; + store(r, vtop - 1); vswap(); /* convert to int to increment easily */ - vtop->type.t = VT_INT; + vtop->type.t = addr_type; gaddrof(); - vpushi(4); + vpushi(load_size); gen_op('+'); vtop->r |= VT_LVAL; vswap(); + vtop[-1].type.t = load_type; /* XXX: it works because r2 is spilled last ! */ store(vtop->r2, vtop - 1); + } else { + store(r, vtop - 1); } -#endif - } + vswap(); vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ vtop->r |= delayed_cast; @@ -2147,7 +3171,7 @@ void vstore(void) } /* post defines POST/PRE add. c is the token ++ or -- */ -void inc(int post, int c) +ST_FUNC void inc(int post, int c) { test_lvalue(); vdup(); /* save lvalue */ @@ -2164,19 +3188,47 @@ void inc(int post, int c) vpop(); /* if post op, return saved value */ } -/* Parse GNUC __attribute__ extension. Currently, the following - extensions are recognized: - - aligned(n) : set data/function alignment. - - packed : force data alignment to 1 - - section(x) : generate data/code in this section. - - unused : currently ignored, but may be used someday. - - regparm(n) : pass function parameters in registers (i386 only) - */ +ST_FUNC void parse_mult_str (CString *astr, const char *msg) +{ + /* read the string */ + if (tok != TOK_STR) + expect(msg); + cstr_new(astr); + while (tok == TOK_STR) { + /* XXX: add \0 handling too ? */ + cstr_cat(astr, tokc.str.data, -1); + next(); + } + cstr_ccat(astr, '\0'); +} + +/* If I is >= 1 and a power of two, returns log2(i)+1. + If I is 0 returns 0. */ +static int exact_log2p1(int i) +{ + int ret; + if (!i) + return 0; + for (ret = 1; i >= 1 << 8; ret += 8) + i >>= 8; + if (i >= 1 << 4) + ret += 4, i >>= 4; + if (i >= 1 << 2) + ret += 2, i >>= 2; + if (i >= 1 << 1) + ret++; + return ret; +} + +/* Parse __attribute__((...)) GNUC extension. */ static void parse_attribute(AttributeDef *ad) { int t, n; + CString astr; - while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { +redo: + if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2) + return; next(); skip('('); skip('('); @@ -2189,11 +3241,37 @@ static void parse_attribute(AttributeDef *ad) case TOK_SECTION1: case TOK_SECTION2: skip('('); - if (tok != TOK_STR) - expect("section name"); - ad->section = find_section(tcc_state, (char *)tokc.cstr->data); - next(); + parse_mult_str(&astr, "section name"); + ad->section = find_section(tcc_state, (char *)astr.data); + skip(')'); + cstr_free(&astr); + break; + case TOK_ALIAS1: + case TOK_ALIAS2: + skip('('); + parse_mult_str(&astr, "alias(\"target\")"); + ad->alias_target = /* save string as token, for later */ + tok_alloc((char*)astr.data, astr.size-1)->tok; skip(')'); + cstr_free(&astr); + break; + case TOK_VISIBILITY1: + case TOK_VISIBILITY2: + skip('('); + parse_mult_str(&astr, + "visibility(\"default|hidden|internal|protected\")"); + if (!strcmp (astr.data, "default")) + ad->a.visibility = STV_DEFAULT; + else if (!strcmp (astr.data, "hidden")) + ad->a.visibility = STV_HIDDEN; + else if (!strcmp (astr.data, "internal")) + ad->a.visibility = STV_INTERNAL; + else if (!strcmp (astr.data, "protected")) + ad->a.visibility = STV_PROTECTED; + else + expect("visibility(\"default|hidden|internal|protected\")"); + skip(')'); + cstr_free(&astr); break; case TOK_ALIGNED1: case TOK_ALIGNED2: @@ -2201,16 +3279,22 @@ static void parse_attribute(AttributeDef *ad) next(); n = expr_const(); if (n <= 0 || (n & (n - 1)) != 0) - error("alignment must be a positive power of two"); + tcc_error("alignment must be a positive power of two"); skip(')'); } else { n = MAX_ALIGN; } - ad->aligned = n; + ad->a.aligned = exact_log2p1(n); + if (n != 1 << (ad->a.aligned - 1)) + tcc_error("alignment of %d is larger than implemented", n); break; case TOK_PACKED1: case TOK_PACKED2: - ad->packed = 1; + ad->a.packed = 1; + break; + case TOK_WEAK1: + case TOK_WEAK2: + ad->a.weak = 1; break; case TOK_UNUSED1: case TOK_UNUSED2: @@ -2225,12 +3309,12 @@ static void parse_attribute(AttributeDef *ad) case TOK_CDECL1: case TOK_CDECL2: case TOK_CDECL3: - FUNC_CALL(ad->func_attr) = FUNC_CDECL; + ad->f.func_call = FUNC_CDECL; break; case TOK_STDCALL1: case TOK_STDCALL2: case TOK_STDCALL3: - FUNC_CALL(ad->func_attr) = FUNC_STDCALL; + ad->f.func_call = FUNC_STDCALL; break; #ifdef TCC_TARGET_I386 case TOK_REGPARM1: @@ -2242,21 +3326,47 @@ static void parse_attribute(AttributeDef *ad) else if (n < 0) n = 0; if (n > 0) - FUNC_CALL(ad->func_attr) = FUNC_FASTCALL1 + n - 1; + ad->f.func_call = FUNC_FASTCALL1 + n - 1; skip(')'); break; case TOK_FASTCALL1: case TOK_FASTCALL2: case TOK_FASTCALL3: - FUNC_CALL(ad->func_attr) = FUNC_FASTCALLW; + ad->f.func_call = FUNC_FASTCALLW; break; #endif + case TOK_MODE: + skip('('); + switch(tok) { + case TOK_MODE_DI: + ad->attr_mode = VT_LLONG + 1; + break; + case TOK_MODE_QI: + ad->attr_mode = VT_BYTE + 1; + break; + case TOK_MODE_HI: + ad->attr_mode = VT_SHORT + 1; + break; + case TOK_MODE_SI: + case TOK_MODE_word: + ad->attr_mode = VT_INT + 1; + break; + default: + tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL)); + break; + } + next(); + skip(')'); + break; case TOK_DLLEXPORT: - FUNC_EXPORT(ad->func_attr) = 1; + ad->a.dllexport = 1; + break; + case TOK_DLLIMPORT: + ad->a.dllimport = 1; break; default: if (tcc_state->warn_unsupported) - warning("'%s' attribute ignored", get_tok_str(t, NULL)); + tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL)); /* skip parameters */ if (tok == '(') { int parenthesis = 0; @@ -2276,20 +3386,324 @@ static void parse_attribute(AttributeDef *ad) } skip(')'); skip(')'); + goto redo; +} + +static Sym * find_field (CType *type, int v) +{ + Sym *s = type->ref; + v |= SYM_FIELD; + while ((s = s->next) != NULL) { + if ((s->v & SYM_FIELD) && + (s->type.t & VT_BTYPE) == VT_STRUCT && + (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) { + Sym *ret = find_field (&s->type, v); + if (ret) + return ret; + } + if (s->v == v) + break; + } + return s; +} + +static void struct_add_offset (Sym *s, int offset) +{ + while ((s = s->next) != NULL) { + if ((s->v & SYM_FIELD) && + (s->type.t & VT_BTYPE) == VT_STRUCT && + (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) { + struct_add_offset(s->type.ref, offset); + } else + s->c += offset; + } +} + +static void struct_layout(CType *type, AttributeDef *ad) +{ + int size, align, maxalign, offset, c, bit_pos, bit_size; + int packed, a, bt, prevbt, prev_bit_size; + int pcc = !tcc_state->ms_bitfields; + int pragma_pack = *tcc_state->pack_stack_ptr; + Sym *f; + + maxalign = 1; + offset = 0; + c = 0; + bit_pos = 0; + prevbt = VT_STRUCT; /* make it never match */ + prev_bit_size = 0; + +//#define BF_DEBUG + + for (f = type->ref->next; f; f = f->next) { + if (f->type.t & VT_BITFIELD) + bit_size = BIT_SIZE(f->type.t); + else + bit_size = -1; + size = type_size(&f->type, &align); + a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0; + packed = 0; + + if (pcc && bit_size == 0) { + /* in pcc mode, packing does not affect zero-width bitfields */ + + } else { + /* in pcc mode, attribute packed overrides if set. */ + if (pcc && (f->a.packed || ad->a.packed)) + align = packed = 1; + + /* pragma pack overrides align if lesser and packs bitfields always */ + if (pragma_pack) { + packed = 1; + if (pragma_pack < align) + align = pragma_pack; + /* in pcc mode pragma pack also overrides individual align */ + if (pcc && pragma_pack < a) + a = 0; + } + } + /* some individual align was specified */ + if (a) + align = a; + + if (type->ref->type.t == VT_UNION) { + if (pcc && bit_size >= 0) + size = (bit_size + 7) >> 3; + offset = 0; + if (size > c) + c = size; + + } else if (bit_size < 0) { + if (pcc) + c += (bit_pos + 7) >> 3; + c = (c + align - 1) & -align; + offset = c; + if (size > 0) + c += size; + bit_pos = 0; + prevbt = VT_STRUCT; + prev_bit_size = 0; + + } else { + /* A bit-field. Layout is more complicated. There are two + options: PCC (GCC) compatible and MS compatible */ + if (pcc) { + /* In PCC layout a bit-field is placed adjacent to the + preceding bit-fields, except if: + - it has zero-width + - an individual alignment was given + - it would overflow its base type container and + there is no packing */ + if (bit_size == 0) { + new_field: + c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align; + bit_pos = 0; + } else if (f->a.aligned) { + goto new_field; + } else if (!packed) { + int a8 = align * 8; + int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8; + if (ofs > size / align) + goto new_field; + } + + /* in pcc mode, long long bitfields have type int if they fit */ + if (size == 8 && bit_size <= 32) + f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4; + + while (bit_pos >= align * 8) + c += align, bit_pos -= align * 8; + offset = c; + + /* In PCC layout named bit-fields influence the alignment + of the containing struct using the base types alignment, + except for packed fields (which here have correct align). */ + if (f->v & SYM_FIRST_ANOM + // && bit_size // ??? gcc on ARM/rpi does that + ) + align = 1; + + } else { + bt = f->type.t & VT_BTYPE; + if ((bit_pos + bit_size > size * 8) + || (bit_size > 0) == (bt != prevbt) + ) { + c = (c + align - 1) & -align; + offset = c; + bit_pos = 0; + /* In MS bitfield mode a bit-field run always uses + at least as many bits as the underlying type. + To start a new run it's also required that this + or the last bit-field had non-zero width. */ + if (bit_size || prev_bit_size) + c += size; + } + /* In MS layout the records alignment is normally + influenced by the field, except for a zero-width + field at the start of a run (but by further zero-width + fields it is again). */ + if (bit_size == 0 && prevbt != bt) + align = 1; + prevbt = bt; + prev_bit_size = bit_size; + } + + f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT)) + | (bit_pos << VT_STRUCT_SHIFT); + bit_pos += bit_size; + } + if (align > maxalign) + maxalign = align; + +#ifdef BF_DEBUG + printf("set field %s offset %-2d size %-2d align %-2d", + get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align); + if (f->type.t & VT_BITFIELD) { + printf(" pos %-2d bits %-2d", + BIT_POS(f->type.t), + BIT_SIZE(f->type.t) + ); + } + printf("\n"); +#endif + + if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) { + Sym *ass; + /* An anonymous struct/union. Adjust member offsets + to reflect the real offset of our containing struct. + Also set the offset of this anon member inside + the outer struct to be zero. Via this it + works when accessing the field offset directly + (from base object), as well as when recursing + members in initializer handling. */ + int v2 = f->type.ref->v; + if (!(v2 & SYM_FIELD) && + (v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) { + Sym **pps; + /* This happens only with MS extensions. The + anon member has a named struct type, so it + potentially is shared with other references. + We need to unshare members so we can modify + them. */ + ass = f->type.ref; + f->type.ref = sym_push(anon_sym++ | SYM_FIELD, + &f->type.ref->type, 0, + f->type.ref->c); + pps = &f->type.ref->next; + while ((ass = ass->next) != NULL) { + *pps = sym_push(ass->v, &ass->type, 0, ass->c); + pps = &((*pps)->next); + } + *pps = NULL; + } + struct_add_offset(f->type.ref, offset); + f->c = 0; + } else { + f->c = offset; + } + + f->r = 0; + } + + if (pcc) + c += (bit_pos + 7) >> 3; + + /* store size and alignment */ + a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1; + if (a < maxalign) + a = maxalign; + type->ref->r = a; + if (pragma_pack && pragma_pack < maxalign && 0 == pcc) { + /* can happen if individual align for some member was given. In + this case MSVC ignores maxalign when aligning the size */ + a = pragma_pack; + if (a < bt) + a = bt; + } + c = (c + a - 1) & -a; + type->ref->c = c; + +#ifdef BF_DEBUG + printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout); +#endif + + /* check whether we can access bitfields by their type */ + for (f = type->ref->next; f; f = f->next) { + int s, px, cx, c0; + CType t; + + if (0 == (f->type.t & VT_BITFIELD)) + continue; + f->type.ref = f; + f->auxtype = -1; + bit_size = BIT_SIZE(f->type.t); + if (bit_size == 0) + continue; + bit_pos = BIT_POS(f->type.t); + size = type_size(&f->type, &align); + if (bit_pos + bit_size <= size * 8 && f->c + size <= c) + continue; + + /* try to access the field using a different type */ + c0 = -1, s = align = 1; + for (;;) { + px = f->c * 8 + bit_pos; + cx = (px >> 3) & -align; + px = px - (cx << 3); + if (c0 == cx) + break; + s = (px + bit_size + 7) >> 3; + if (s > 4) { + t.t = VT_LLONG; + } else if (s > 2) { + t.t = VT_INT; + } else if (s > 1) { + t.t = VT_SHORT; + } else { + t.t = VT_BYTE; + } + s = type_size(&t, &align); + c0 = cx; + } + + if (px + bit_size <= s * 8 && cx + s <= c) { + /* update offset and bit position */ + f->c = cx; + bit_pos = px; + f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT)) + | (bit_pos << VT_STRUCT_SHIFT); + if (s != size) + f->auxtype = t.t; +#ifdef BF_DEBUG + printf("FIX field %s offset %-2d size %-2d align %-2d " + "pos %-2d bits %-2d\n", + get_tok_str(f->v & ~SYM_FIELD, NULL), + cx, s, align, px, bit_size); +#endif + } else { + /* fall back to load/store single-byte wise */ + f->auxtype = VT_STRUCT; +#ifdef BF_DEBUG + printf("FIX field %s : load byte-wise\n", + get_tok_str(f->v & ~SYM_FIELD, NULL)); +#endif + } } } -/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ +/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */ static void struct_decl(CType *type, int u) { - int a, v, size, align, maxalign, c, offset; - int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; - Sym *s, *ss, *ass, **ps; - AttributeDef ad; + int v, c, size, align, flexible; + int bit_size, bsize, bt; + Sym *s, *ss, **ps; + AttributeDef ad, ad1; CType type1, btype; - a = tok; /* save decl type */ + memset(&ad, 0, sizeof ad); next(); + parse_attribute(&ad); if (tok != '{') { v = tok; next(); @@ -2297,71 +3711,130 @@ static void struct_decl(CType *type, int u) if (v < TOK_IDENT) expect("struct/union/enum name"); s = struct_find(v); - if (s) { - if (s->type.t != a) - error("invalid type"); - goto do_decl; + if (s && (s->sym_scope == local_scope || tok != '{')) { + if (u == s->type.t) + goto do_decl; + if (u == VT_ENUM && IS_ENUM(s->type.t)) + goto do_decl; + tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); } } else { v = anon_sym++; } - type1.t = a; + /* Record the original enum/struct/union token. */ + type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u; + type1.ref = NULL; /* we put an undefined size for struct/union */ s = sym_push(v | SYM_STRUCT, &type1, 0, -1); s->r = 0; /* default alignment is zero as gcc */ - /* put struct/union/enum name in type */ - do_decl: - type->t = u; +do_decl: + type->t = s->type.t; type->ref = s; - + if (tok == '{') { next(); if (s->c != -1) - error("struct/union/enum already defined"); + tcc_error("struct/union/enum already defined"); /* cannot be empty */ - c = 0; /* non empty enums are not allowed */ - if (a == TOK_ENUM) { + ps = &s->next; + if (u == VT_ENUM) { + long long ll = 0, pl = 0, nl = 0; + CType t; + t.ref = s; + /* enum symbols have static storage */ + t.t = VT_INT|VT_STATIC|VT_ENUM_VAL; for(;;) { v = tok; if (v < TOK_UIDENT) expect("identifier"); + ss = sym_find(v); + if (ss && !local_stack) + tcc_error("redefinition of enumerator '%s'", + get_tok_str(v, NULL)); next(); if (tok == '=') { next(); - c = expr_const(); + ll = expr_const64(); } - /* enum symbols have static storage */ - ss = sym_push(v, &int_type, VT_CONST, c); - ss->type.t |= VT_STATIC; + ss = sym_push(v, &t, VT_CONST, 0); + ss->enum_val = ll; + *ps = ss, ps = &ss->next; + if (ll < nl) + nl = ll; + if (ll > pl) + pl = ll; if (tok != ',') break; next(); - c++; + ll++; /* NOTE: we accept a trailing comma */ if (tok == '}') break; } skip('}'); + /* set integral type of the enum */ + t.t = VT_INT; + if (nl >= 0) { + if (pl != (unsigned)pl) + t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG); + t.t |= VT_UNSIGNED; + } else if (pl != (int)pl || nl != (int)nl) + t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG); + s->type.t = type->t = t.t | VT_ENUM; + s->c = 0; + /* set type for enum members */ + for (ss = s->next; ss; ss = ss->next) { + ll = ss->enum_val; + if (ll == (int)ll) /* default is int if it fits */ + continue; + if (t.t & VT_UNSIGNED) { + ss->type.t |= VT_UNSIGNED; + if (ll == (unsigned)ll) + continue; + } + ss->type.t = (ss->type.t & ~VT_BTYPE) + | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG); + } } else { - maxalign = 1; - ps = &s->next; - prevbt = VT_INT; - bit_pos = 0; - offset = 0; + c = 0; + flexible = 0; while (tok != '}') { - parse_btype(&btype, &ad); + if (!parse_btype(&btype, &ad1)) { + skip(';'); + continue; + } while (1) { + if (flexible) + tcc_error("flexible array member '%s' not at the end of struct", + get_tok_str(v, NULL)); bit_size = -1; v = 0; type1 = btype; if (tok != ':') { - type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); - if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) - expect("identifier"); + if (tok != ';') + type_decl(&type1, &ad1, &v, TYPE_DIRECT); + if (v == 0) { + if ((type1.t & VT_BTYPE) != VT_STRUCT) + expect("identifier"); + else { + int v = btype.ref->v; + if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { + if (tcc_state->ms_extensions == 0) + expect("identifier"); + } + } + } + if (type_size(&type1, &align) < 0) { + if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c) + flexible = 1; + else + tcc_error("field '%s' has incomplete type", + get_tok_str(v, NULL)); + } if ((type1.t & VT_BTYPE) == VT_FUNC || - (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) - error("invalid type for '%s'", + (type1.t & VT_STORAGE)) + tcc_error("invalid type for '%s'", get_tok_str(v, NULL)); } if (tok == ':') { @@ -2369,99 +3842,53 @@ static void struct_decl(CType *type, int u) bit_size = expr_const(); /* XXX: handle v = 0 case for messages */ if (bit_size < 0) - error("negative width in bit-field '%s'", + tcc_error("negative width in bit-field '%s'", get_tok_str(v, NULL)); if (v && bit_size == 0) - error("zero width for bit-field '%s'", + tcc_error("zero width for bit-field '%s'", get_tok_str(v, NULL)); + parse_attribute(&ad1); } size = type_size(&type1, &align); - if (ad.aligned) { - if (align < ad.aligned) - align = ad.aligned; - } else if (ad.packed) { - align = 1; - } else if (*tcc_state->pack_stack_ptr) { - if (align > *tcc_state->pack_stack_ptr) - align = *tcc_state->pack_stack_ptr; - } - lbit_pos = 0; if (bit_size >= 0) { bt = type1.t & VT_BTYPE; if (bt != VT_INT && bt != VT_BYTE && bt != VT_SHORT && bt != VT_BOOL && - bt != VT_ENUM && bt != VT_LLONG) - error("bitfields must have scalar type"); + tcc_error("bitfields must have scalar type"); bsize = size * 8; if (bit_size > bsize) { - error("width of '%s' exceeds its type", + tcc_error("width of '%s' exceeds its type", get_tok_str(v, NULL)); - } else if (bit_size == bsize) { + } else if (bit_size == bsize + && !ad.a.packed && !ad1.a.packed) { /* no need for bit fields */ - bit_pos = 0; - } else if (bit_size == 0) { - /* XXX: what to do if only padding in a - structure ? */ - /* zero size: means to pad */ - bit_pos = 0; + ; + } else if (bit_size == 64) { + tcc_error("field width 64 not implemented"); } else { - /* we do not have enough room ? - did the type change? - is it a union? */ - if ((bit_pos + bit_size) > bsize || - bt != prevbt || a == TOK_UNION) - bit_pos = 0; - lbit_pos = bit_pos; - /* XXX: handle LSB first */ - type1.t |= VT_BITFIELD | - (bit_pos << VT_STRUCT_SHIFT) | - (bit_size << (VT_STRUCT_SHIFT + 6)); - bit_pos += bit_size; + type1.t = (type1.t & ~VT_STRUCT_MASK) + | VT_BITFIELD + | (bit_size << (VT_STRUCT_SHIFT + 6)); } - prevbt = bt; - } else { - bit_pos = 0; } if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) { - /* add new memory data only if starting - bit field */ - if (lbit_pos == 0) { - if (a == TOK_STRUCT) { - c = (c + align - 1) & -align; - offset = c; - if (size > 0) - c += size; - } else { - offset = 0; - if (size > c) - c = size; - } - if (align > maxalign) - maxalign = align; - } -#if 0 - printf("add field %s offset=%d", - get_tok_str(v, NULL), offset); - if (type1.t & VT_BITFIELD) { - printf(" pos=%d size=%d", - (type1.t >> VT_STRUCT_SHIFT) & 0x3f, - (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f); - } - printf("\n"); -#endif + /* Remember we've seen a real field to check + for placement of flexible array member. */ + c = 1; } - if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) { - ass = type1.ref; - while ((ass = ass->next) != NULL) { - ss = sym_push(ass->v, &ass->type, 0, offset + ass->c); - *ps = ss; - ps = &ss->next; - } - } else if (v) { - ss = sym_push(v | SYM_FIELD, &type1, 0, offset); + /* If member is a struct or bit-field, enforce + placing into the struct (as anonymous). */ + if (v == 0 && + ((type1.t & VT_BTYPE) == VT_STRUCT || + bit_size >= 0)) { + v = anon_sym++; + } + if (v) { + ss = sym_push(v | SYM_FIELD, &type1, 0, 0); + ss->a = ad1.a; *ps = ss; ps = &ss->next; } @@ -2472,27 +3899,51 @@ static void struct_decl(CType *type, int u) skip(';'); } skip('}'); - /* store size and alignment */ - s->c = (c + maxalign - 1) & -maxalign; - s->r = maxalign; + parse_attribute(&ad); + struct_layout(type, &ad); } } } +static void sym_to_attr(AttributeDef *ad, Sym *s) +{ + if (s->a.aligned && 0 == ad->a.aligned) + ad->a.aligned = s->a.aligned; + if (s->f.func_call && 0 == ad->f.func_call) + ad->f.func_call = s->f.func_call; + if (s->f.func_type && 0 == ad->f.func_type) + ad->f.func_type = s->f.func_type; + if (s->a.packed) + ad->a.packed = 1; +} + +/* Add type qualifiers to a type. If the type is an array then the qualifiers + are added to the element type, copied because it could be a typedef. */ +static void parse_btype_qualify(CType *type, int qualifiers) +{ + while (type->t & VT_ARRAY) { + type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); + type = &type->ref->type; + } + type->t |= qualifiers; +} + /* return 0 if no type declaration. otherwise, return the basic type and skip it. */ static int parse_btype(CType *type, AttributeDef *ad) { - int t, u, type_found, typespec_found, typedef_found; + int t, u, bt, st, type_found, typespec_found, g; Sym *s; CType type1; memset(ad, 0, sizeof(AttributeDef)); type_found = 0; typespec_found = 0; - typedef_found = 0; - t = 0; + t = VT_INT; + bt = st = -1; + type->ref = NULL; + while(1) { switch(tok) { case TOK_EXTENSION: @@ -2506,9 +3957,17 @@ static int parse_btype(CType *type, AttributeDef *ad) basic_type: next(); basic_type1: - if ((t & VT_BTYPE) != 0) - error("too many basic types"); - t |= u; + if (u == VT_SHORT || u == VT_LONG) { + if (st != -1 || (bt != -1 && bt != VT_INT)) + tmbt: tcc_error("too many basic types"); + st = u; + } else { + if (bt != -1 || (st != -1 && u != VT_INT)) + goto tmbt; + bt = u; + } + if (u != VT_INT) + t = (t & ~(VT_BTYPE|VT_LONG)) | u; typespec_found = 1; break; case TOK_VOID: @@ -2518,20 +3977,26 @@ static int parse_btype(CType *type, AttributeDef *ad) u = VT_SHORT; goto basic_type; case TOK_INT: - next(); - typespec_found = 1; - break; + u = VT_INT; + goto basic_type; case TOK_LONG: - next(); if ((t & VT_BTYPE) == VT_DOUBLE) { - t = (t & ~VT_BTYPE) | VT_LDOUBLE; - } else if ((t & VT_BTYPE) == VT_LONG) { - t = (t & ~VT_BTYPE) | VT_LLONG; + t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE; + } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) { + t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG; } else { u = VT_LONG; - goto basic_type1; + goto basic_type; } + next(); break; +#ifdef TCC_TARGET_ARM64 + case TOK_UINT128: + /* GCC's __uint128_t appears in some Linux header files. Make it a + synonym for long double to get the size and alignment right. */ + u = VT_LDOUBLE; + goto basic_type; +#endif case TOK_BOOL: u = VT_BOOL; goto basic_type; @@ -2539,13 +4004,13 @@ static int parse_btype(CType *type, AttributeDef *ad) u = VT_FLOAT; goto basic_type; case TOK_DOUBLE: - next(); - if ((t & VT_BTYPE) == VT_LONG) { - t = (t & ~VT_BTYPE) | VT_LDOUBLE; + if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) { + t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE; } else { u = VT_DOUBLE; - goto basic_type1; + goto basic_type; } + next(); break; case TOK_ENUM: struct_decl(&type1, VT_ENUM); @@ -2554,29 +4019,37 @@ static int parse_btype(CType *type, AttributeDef *ad) type->ref = type1.ref; goto basic_type1; case TOK_STRUCT: - case TOK_UNION: struct_decl(&type1, VT_STRUCT); goto basic_type2; + case TOK_UNION: + struct_decl(&type1, VT_UNION); + goto basic_type2; /* type modifiers */ case TOK_CONST1: case TOK_CONST2: case TOK_CONST3: - t |= VT_CONSTANT; + type->t = t; + parse_btype_qualify(type, VT_CONSTANT); + t = type->t; next(); break; case TOK_VOLATILE1: case TOK_VOLATILE2: case TOK_VOLATILE3: - t |= VT_VOLATILE; + type->t = t; + parse_btype_qualify(type, VT_VOLATILE); + t = type->t; next(); break; case TOK_SIGNED1: case TOK_SIGNED2: case TOK_SIGNED3: - typespec_found = 1; - t |= VT_SIGNED; + if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED)) + tcc_error("signed and unsigned modifier"); + t |= VT_DEFSIGN; next(); + typespec_found = 1; break; case TOK_REGISTER: case TOK_AUTO: @@ -2586,22 +4059,27 @@ static int parse_btype(CType *type, AttributeDef *ad) next(); break; case TOK_UNSIGNED: - t |= VT_UNSIGNED; + if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN) + tcc_error("signed and unsigned modifier"); + t |= VT_DEFSIGN | VT_UNSIGNED; next(); typespec_found = 1; break; /* storage */ case TOK_EXTERN: - t |= VT_EXTERN; - next(); - break; + g = VT_EXTERN; + goto storage; case TOK_STATIC: - t |= VT_STATIC; - next(); - break; + g = VT_STATIC; + goto storage; case TOK_TYPEDEF: - t |= VT_TYPEDEF; + g = VT_TYPEDEF; + goto storage; + storage: + if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g) + tcc_error("multiple storage classes"); + t |= g; next(); break; case TOK_INLINE1: @@ -2615,6 +4093,10 @@ static int parse_btype(CType *type, AttributeDef *ad) case TOK_ATTRIBUTE1: case TOK_ATTRIBUTE2: parse_attribute(ad); + if (ad->attr_mode) { + u = ad->attr_mode -1; + t = (t & ~(VT_BTYPE|VT_LONG)) | u; + } break; /* GNUC typeof */ case TOK_TYPEOF1: @@ -2622,37 +4104,45 @@ static int parse_btype(CType *type, AttributeDef *ad) case TOK_TYPEOF3: next(); parse_expr_type(&type1); + /* remove all storage modifiers except typedef */ + type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); + if (type1.ref) + sym_to_attr(ad, type1.ref); goto basic_type2; default: - if (typespec_found || typedef_found) + if (typespec_found) goto the_end; s = sym_find(tok); if (!s || !(s->type.t & VT_TYPEDEF)) goto the_end; - typedef_found = 1; - t |= (s->type.t & ~VT_TYPEDEF); + t &= ~(VT_BTYPE|VT_LONG); + u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u; + type->t = (s->type.t & ~VT_TYPEDEF) | u; type->ref = s->type.ref; + if (t) + parse_btype_qualify(type, t); + t = type->t; + /* get attributes from typedef */ + sym_to_attr(ad, s); next(); typespec_found = 1; + st = bt = -2; break; } type_found = 1; } the_end: - if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED)) - error("signed and unsigned modifier"); if (tcc_state->char_is_unsigned) { - if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE) + if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE) t |= VT_UNSIGNED; } - t &= ~VT_SIGNED; - - /* long is never used as type */ - if ((t & VT_BTYPE) == VT_LONG) -#ifndef TCC_TARGET_X86_64 - t = (t & ~VT_BTYPE) | VT_INT; -#else - t = (t & ~VT_BTYPE) | VT_LLONG; + /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */ + bt = t & (VT_BTYPE|VT_LONG); + if (bt == VT_LONG) + t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT; +#ifdef TCC_TARGET_PE + if (bt == VT_LDOUBLE) + t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE; #endif type->t = t; return type_found; @@ -2672,7 +4162,30 @@ static inline void convert_parameter_type(CType *pt) } } -static void post_type(CType *type, AttributeDef *ad) +ST_FUNC void parse_asm_str(CString *astr) +{ + skip('('); + parse_mult_str(astr, "string constant"); +} + +/* Parse an asm label and return the token */ +static int asm_label_instr(void) +{ + int v; + CString astr; + + next(); + parse_asm_str(&astr); + skip(')'); +#ifdef ASM_DEBUG + printf("asm_alias: \"%s\"\n", (char *)astr.data); +#endif + v = tok_alloc(astr.data, astr.size - 1)->tok; + cstr_free(&astr); + return v; +} + +static int post_type(CType *type, AttributeDef *ad, int storage, int td) { int n, l, t1, arg_size, align; Sym **plast, *s, *first; @@ -2680,37 +4193,36 @@ static void post_type(CType *type, AttributeDef *ad) CType pt; if (tok == '(') { - /* function declaration */ + /* function type, or recursive declarator (return if so) */ next(); - l = 0; + if (td && !(td & TYPE_ABSTRACT)) + return 0; + if (tok == ')') + l = 0; + else if (parse_btype(&pt, &ad1)) + l = FUNC_NEW; + else if (td) + return 0; + else + l = FUNC_OLD; first = NULL; plast = &first; arg_size = 0; - if (tok != ')') { + if (l) { for(;;) { /* read param name and compute offset */ if (l != FUNC_OLD) { - if (!parse_btype(&pt, &ad1)) { - if (l) { - error("invalid type"); - } else { - l = FUNC_OLD; - goto old_proto; - } - } - l = FUNC_NEW; if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')') break; type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT); if ((pt.t & VT_BTYPE) == VT_VOID) - error("parameter declared as void"); - arg_size += (type_size(&pt, &align) + 3) & ~3; + tcc_error("parameter declared as void"); + arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; } else { - old_proto: n = tok; if (n < TOK_UIDENT) expect("identifier"); - pt.t = VT_INT; + pt.t = VT_VOID; /* invalid type */ next(); } convert_parameter_type(&pt); @@ -2725,60 +4237,110 @@ static void post_type(CType *type, AttributeDef *ad) next(); break; } + if (l == FUNC_NEW && !parse_btype(&pt, &ad1)) + tcc_error("invalid type"); } - } - /* if no parameters, then old type prototype */ - if (l == 0) + } else + /* if no parameters, then old type prototype */ l = FUNC_OLD; skip(')'); - t1 = type->t & VT_STORAGE; /* NOTE: const is ignored in returned type as it has a special meaning in gcc / C++ */ - type->t &= ~(VT_STORAGE | VT_CONSTANT); - post_type(type, ad); + type->t &= ~VT_CONSTANT; + /* some ancient pre-K&R C allows a function to return an array + and the array brackets to be put after the arguments, such + that "int c()[]" means something like "int[] c()" */ + if (tok == '[') { + next(); + skip(']'); /* only handle simple "[]" */ + mk_pointer(type); + } /* we push a anonymous symbol which will contain the function prototype */ - FUNC_ARGS(ad->func_attr) = arg_size; - s = sym_push(SYM_FIELD, type, ad->func_attr, l); + ad->f.func_args = arg_size; + ad->f.func_type = l; + s = sym_push(SYM_FIELD, type, 0, 0); + s->a = ad->a; + s->f = ad->f; s->next = first; - type->t = t1 | VT_FUNC; + type->t = VT_FUNC; type->ref = s; } else if (tok == '[') { + int saved_nocode_wanted = nocode_wanted; /* array definition */ next(); if (tok == TOK_RESTRICT1) next(); n = -1; + t1 = 0; if (tok != ']') { - n = expr_const(); - if (n < 0) - error("invalid array size"); + if (!local_stack || (storage & VT_STATIC)) + vpushi(expr_const()); + else { + /* VLAs (which can only happen with local_stack && !VT_STATIC) + length must always be evaluated, even under nocode_wanted, + so that its size slot is initialized (e.g. under sizeof + or typeof). */ + nocode_wanted = 0; + gexpr(); + } + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + n = vtop->c.i; + if (n < 0) + tcc_error("invalid array size"); + } else { + if (!is_integer_btype(vtop->type.t & VT_BTYPE)) + tcc_error("size of variable length array should be an integer"); + t1 = VT_VLA; + } } skip(']'); /* parse next post type */ - t1 = type->t & VT_STORAGE; - type->t &= ~VT_STORAGE; - post_type(type, ad); + post_type(type, ad, storage, 0); + if (type->t == VT_FUNC) + tcc_error("declaration of an array of functions"); + t1 |= type->t & VT_VLA; - /* we push a anonymous symbol which will contain the array + if (t1 & VT_VLA) { + loc -= type_size(&int_type, &align); + loc &= -align; + n = loc; + + vla_runtime_type_size(type, &align); + gen_op('*'); + vset(&int_type, VT_LOCAL|VT_LVAL, n); + vswap(); + vstore(); + } + if (n != -1) + vpop(); + nocode_wanted = saved_nocode_wanted; + + /* we push an anonymous symbol which will contain the array element type */ s = sym_push(SYM_FIELD, type, 0, n); - type->t = t1 | VT_ARRAY | VT_PTR; + type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR; type->ref = s; } + return 1; } -/* Parse a type declaration (except basic type), and return the type +/* Parse a type declarator (except basic type), and return the type in 'type'. 'td' is a bitmask indicating which kind of type decl is expected. 'type' should contain the basic type. 'ad' is the attribute definition of the basic type. It can be modified by - type_decl(). - */ -static void type_decl(CType *type, AttributeDef *ad, int *v, int td) + type_decl(). If this (possibly abstract) declarator is a pointer chain + it returns the innermost pointed to type (equals *type, but is a different + pointer), otherwise returns type itself, that's used for recursive calls. */ +static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) { - Sym *s; - CType type1, *type2; - int qualifiers; - + CType *post, *ret; + int qualifiers, storage; + + /* recursive type, remove storage bits first, apply them later again */ + storage = type->t & VT_STORAGE; + type->t &= ~VT_STORAGE; + post = ret = type; + while (tok == '*') { qualifiers = 0; redo: @@ -2798,57 +4360,48 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td) case TOK_RESTRICT2: case TOK_RESTRICT3: goto redo; + /* XXX: clarify attribute handling */ + case TOK_ATTRIBUTE1: + case TOK_ATTRIBUTE2: + parse_attribute(ad); + break; } mk_pointer(type); type->t |= qualifiers; + if (ret == type) + /* innermost pointed to type is the one for the first derivation */ + ret = pointed_type(type); } - - /* XXX: clarify attribute handling */ - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - /* recursive type */ - /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ - type1.t = 0; /* XXX: same as int */ if (tok == '(') { - next(); - /* XXX: this is not correct to modify 'ad' at this point, but - the syntax is not clear */ - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - type_decl(&type1, ad, v, td); - skip(')'); + /* This is possibly a parameter type list for abstract declarators + ('int ()'), use post_type for testing this. */ + if (!post_type(type, ad, 0, td)) { + /* It's not, so it's a nested declarator, and the post operations + apply to the innermost pointed to type (if any). */ + /* XXX: this is not correct to modify 'ad' at this point, but + the syntax is not clear */ + parse_attribute(ad); + post = type_decl(type, ad, v, td); + skip(')'); + } + } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { + /* type identifier */ + *v = tok; + next(); } else { - /* type identifier */ - if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { - *v = tok; - next(); - } else { - if (!(td & TYPE_ABSTRACT)) - expect("identifier"); - *v = 0; - } - } - post_type(type, ad); - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute(ad); - if (!type1.t) - return; - /* append type at the end of type1 */ - type2 = &type1; - for(;;) { - s = type2->ref; - type2 = &s->type; - if (!type2->t) { - *type2 = *type; - break; - } + if (!(td & TYPE_ABSTRACT)) + expect("identifier"); + *v = 0; } - *type = type1; + post_type(post, ad, storage, 0); + parse_attribute(ad); + type->t |= storage; + return ret; } /* compute the lvalue VT_LVAL_xxx needed to match type t. */ -static int lvalue_type(int t) +ST_FUNC int lvalue_type(int t) { int bt, r; r = VT_LVAL; @@ -2865,23 +4418,25 @@ static int lvalue_type(int t) } /* indirection with full error checking and bound check */ -static void indir(void) +ST_FUNC void indir(void) { if ((vtop->type.t & VT_BTYPE) != VT_PTR) { if ((vtop->type.t & VT_BTYPE) == VT_FUNC) return; expect("pointer"); } - if ((vtop->r & VT_LVAL) && !nocode_wanted) + if (vtop->r & VT_LVAL) gv(RC_INT); vtop->type = *pointed_type(&vtop->type); /* Arrays and functions are never lvalues */ - if (!(vtop->type.t & VT_ARRAY) + if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA) && (vtop->type.t & VT_BTYPE) != VT_FUNC) { vtop->r |= lvalue_type(vtop->type.t); /* if bound checking, the referenced pointer must be checked */ +#ifdef CONFIG_TCC_BCHECK if (tcc_state->do_bounds_check) vtop->r |= VT_MUSTBOUND; +#endif } } @@ -2891,16 +4446,19 @@ static void gfunc_param_typed(Sym *func, Sym *arg) int func_type; CType type; - func_type = func->c; + func_type = func->f.func_type; if (func_type == FUNC_OLD || (func_type == FUNC_ELLIPSIS && arg == NULL)) { /* default casting : only need to convert float to double */ if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) { - type.t = VT_DOUBLE; + gen_cast_s(VT_DOUBLE); + } else if (vtop->type.t & VT_BITFIELD) { + type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED); + type.ref = vtop->type.ref; gen_cast(&type); } } else if (arg == NULL) { - error("too many arguments to function"); + tcc_error("too many arguments to function"); } else { type = arg->type; type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ @@ -2908,6 +4466,16 @@ static void gfunc_param_typed(Sym *func, Sym *arg) } } +/* parse an expression and return its type without any side effect. */ +static void expr_type(CType *type, void (*expr_fn)(void)) +{ + nocode_wanted++; + expr_fn(); + *type = vtop->type; + vpop(); + nocode_wanted--; +} + /* parse an expression of the form '(type)' or '(expr)' and return its type */ static void parse_expr_type(CType *type) @@ -2919,7 +4487,7 @@ static void parse_expr_type(CType *type) if (parse_btype(type, &ad)) { type_decl(type, &ad, &n, TYPE_ABSTRACT); } else { - expr_type(type); + expr_type(type, gexpr); } skip(')'); } @@ -2935,20 +4503,37 @@ static void parse_type(CType *type) type_decl(type, &ad, &n, TYPE_ABSTRACT); } -static void vpush_tokc(int t) +static void parse_builtin_params(int nc, const char *args) { - CType type; - type.t = t; - vsetc(&type, VT_CONST, &tokc); + char c, sep = '('; + CType t; + if (nc) + nocode_wanted++; + next(); + while ((c = *args++)) { + skip(sep); + sep = ','; + switch (c) { + case 'e': expr_eq(); continue; + case 't': parse_type(&t); vpush(&t); continue; + default: tcc_error("internal error"); break; + } + } + skip(')'); + if (nc) + nocode_wanted--; } -static void unary(void) +ST_FUNC void unary(void) { - int n, t, align, size, r; + int n, t, align, size, r, sizeof_caller; CType type; Sym *s; AttributeDef ad; + sizeof_caller = in_sizeof; + in_sizeof = 0; + type.ref = NULL; /* XXX: GCC 2.95.3 does not generate a table although it should be better here */ tok_next: @@ -2956,36 +4541,43 @@ static void unary(void) case TOK_EXTENSION: next(); goto tok_next; + case TOK_LCHAR: +#ifdef TCC_TARGET_PE + t = VT_SHORT|VT_UNSIGNED; + goto push_tokc; +#endif case TOK_CINT: case TOK_CCHAR: - case TOK_LCHAR: - vpushi(tokc.i); + t = VT_INT; + push_tokc: + type.t = t; + vsetc(&type, VT_CONST, &tokc); next(); break; case TOK_CUINT: - vpush_tokc(VT_INT | VT_UNSIGNED); - next(); - break; + t = VT_INT | VT_UNSIGNED; + goto push_tokc; case TOK_CLLONG: - vpush_tokc(VT_LLONG); - next(); - break; + t = VT_LLONG; + goto push_tokc; case TOK_CULLONG: - vpush_tokc(VT_LLONG | VT_UNSIGNED); - next(); - break; + t = VT_LLONG | VT_UNSIGNED; + goto push_tokc; case TOK_CFLOAT: - vpush_tokc(VT_FLOAT); - next(); - break; + t = VT_FLOAT; + goto push_tokc; case TOK_CDOUBLE: - vpush_tokc(VT_DOUBLE); - next(); - break; + t = VT_DOUBLE; + goto push_tokc; case TOK_CLDOUBLE: - vpush_tokc(VT_LDOUBLE); - next(); - break; + t = VT_LDOUBLE; + goto push_tokc; + case TOK_CLONG: + t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG; + goto push_tokc; + case TOK_CULONG: + t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED; + goto push_tokc; case TOK___FUNCTION__: if (!gnu_ext) goto tok_identifier; @@ -3002,8 +4594,10 @@ static void unary(void) type.t |= VT_ARRAY; type.ref->c = len; vpush_ref(&type, data_section, data_section->data_offset, len); - ptr = section_ptr_add(data_section, len); - memcpy(ptr, funcname, len); + if (!NODATA_WANTED) { + ptr = section_ptr_add(data_section, len); + memcpy(ptr, funcname, len); + } next(); } break; @@ -3017,6 +4611,8 @@ static void unary(void) case TOK_STR: /* string parsing */ t = VT_BYTE; + if (tcc_state->char_is_unsigned) + t = VT_BYTE | VT_UNSIGNED; str_init: if (tcc_state->warn_write_strings) t |= VT_CONSTANT; @@ -3045,15 +4641,26 @@ static void unary(void) memset(&ad, 0, sizeof(AttributeDef)); decl_initializer_alloc(&type, &ad, r, 1, 0, 0); } else { + if (sizeof_caller) { + vpush(&type); + return; + } unary(); gen_cast(&type); } } else if (tok == '{') { + int saved_nocode_wanted = nocode_wanted; + if (const_wanted) + tcc_error("expected constant"); /* save all registers */ - save_regs(0); + save_regs(0); /* statement expression : we do not accept break/continue - inside as GCC does */ - block(NULL, NULL, NULL, NULL, 0, 1); + inside as GCC does. We do retain the nocode_wanted state, + as statement expressions can't ever be entered from the + outside, so any reactivation of code emission (from labels + or loop heads) can be disabled again after the end of it. */ + block(NULL, NULL, 1); + nocode_wanted = saved_nocode_wanted; skip(')'); } else { gexpr(); @@ -3074,7 +4681,7 @@ static void unary(void) there and in function calls. */ /* arrays can also be used although they are not lvalues */ if ((vtop->type.t & VT_BTYPE) != VT_FUNC && - !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL)) + !(vtop->type.t & VT_ARRAY)) test_lvalue(); mk_pointer(&vtop->type); gaddrof(); @@ -3083,15 +4690,13 @@ static void unary(void) next(); unary(); if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - CType boolean; - boolean.t = VT_BOOL; - gen_cast(&boolean); + gen_cast_s(VT_BOOL); vtop->c.i = !vtop->c.i; } else if ((vtop->r & VT_VALMASK) == VT_CMP) - vtop->c.i = vtop->c.i ^ 1; + vtop->c.i ^= 1; else { save_regs(1); - vseti(VT_JMP, gtst(1, 0)); + vseti(VT_JMP, gvtst(1, 0)); } break; case '~': @@ -3102,89 +4707,171 @@ static void unary(void) break; case '+': next(); - /* in order to force cast, we add zero */ unary(); if ((vtop->type.t & VT_BTYPE) == VT_PTR) - error("pointer not accepted for unary plus"); - vpushi(0); - gen_op('+'); + tcc_error("pointer not accepted for unary plus"); + /* In order to force cast, we add zero, except for floating point + where we really need an noop (otherwise -0.0 will be transformed + into +0.0). */ + if (!is_float(vtop->type.t)) { + vpushi(0); + gen_op('+'); + } break; case TOK_SIZEOF: case TOK_ALIGNOF1: case TOK_ALIGNOF2: t = tok; next(); - if (tok == '(') { - parse_expr_type(&type); - } else { - unary_type(&type); - } + in_sizeof++; + expr_type(&type, unary); /* Perform a in_sizeof = 0; */ + s = vtop[1].sym; /* hack: accessing previous vtop */ size = type_size(&type, &align); + if (s && s->a.aligned) + align = 1 << (s->a.aligned - 1); if (t == TOK_SIZEOF) { - if (size < 0) - error("sizeof applied to an incomplete type"); - vpushi(size); + if (!(type.t & VT_VLA)) { + if (size < 0) + tcc_error("sizeof applied to an incomplete type"); + vpushs(size); + } else { + vla_runtime_type_size(&type, &align); + } } else { - vpushi(align); + vpushs(align); } vtop->type.t |= VT_UNSIGNED; break; + case TOK_builtin_expect: + /* __builtin_expect is a no-op for now */ + parse_builtin_params(0, "ee"); + vpop(); + break; case TOK_builtin_types_compatible_p: - { - CType type1, type2; - next(); - skip('('); - parse_type(&type1); - skip(','); - parse_type(&type2); - skip(')'); - type1.t &= ~(VT_CONSTANT | VT_VOLATILE); - type2.t &= ~(VT_CONSTANT | VT_VOLATILE); - vpushi(is_compatible_types(&type1, &type2)); - } + parse_builtin_params(0, "tt"); + vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE); + vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE); + n = is_compatible_types(&vtop[-1].type, &vtop[0].type); + vtop -= 2; + vpushi(n); + break; + case TOK_builtin_choose_expr: + { + int64_t c; + next(); + skip('('); + c = expr_const64(); + skip(','); + if (!c) { + nocode_wanted++; + } + expr_eq(); + if (!c) { + vpop(); + nocode_wanted--; + } + skip(','); + if (c) { + nocode_wanted++; + } + expr_eq(); + if (c) { + vpop(); + nocode_wanted--; + } + skip(')'); + } break; case TOK_builtin_constant_p: - { - int saved_nocode_wanted, res; - next(); - skip('('); - saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - gexpr(); - res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - vpop(); - nocode_wanted = saved_nocode_wanted; - skip(')'); - vpushi(res); - } + parse_builtin_params(1, "e"); + n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; + vtop--; + vpushi(n); break; case TOK_builtin_frame_address: + case TOK_builtin_return_address: { - CType type; + int tok1 = tok; + int level; next(); skip('('); if (tok != TOK_CINT) { - error("__builtin_frame_address only takes integers"); - } - if (tokc.i != 0) { - error("TCC only supports __builtin_frame_address(0)"); + tcc_error("%s only takes positive integers", + tok1 == TOK_builtin_return_address ? + "__builtin_return_address" : + "__builtin_frame_address"); } + level = (uint32_t)tokc.i; next(); skip(')'); type.t = VT_VOID; mk_pointer(&type); - vset(&type, VT_LOCAL, 0); + vset(&type, VT_LOCAL, 0); /* local frame */ + while (level--) { + mk_pointer(&vtop->type); + indir(); /* -> parent frame */ + } + if (tok1 == TOK_builtin_return_address) { + // assume return address is just above frame pointer on stack + vpushi(PTR_SIZE); + gen_op('+'); + mk_pointer(&vtop->type); + indir(); + } } break; #ifdef TCC_TARGET_X86_64 - case TOK_builtin_malloc: - tok = TOK_malloc; - goto tok_identifier; - case TOK_builtin_free: - tok = TOK_free; - goto tok_identifier; +#ifdef TCC_TARGET_PE + case TOK_builtin_va_start: + parse_builtin_params(0, "ee"); + r = vtop->r & VT_VALMASK; + if (r == VT_LLOCAL) + r = VT_LOCAL; + if (r != VT_LOCAL) + tcc_error("__builtin_va_start expects a local variable"); + vtop->r = r; + vtop->type = char_pointer_type; + vtop->c.i += 8; + vstore(); + break; +#else + case TOK_builtin_va_arg_types: + parse_builtin_params(0, "t"); + vpushi(classify_x86_64_va_arg(&vtop->type)); + vswap(); + vpop(); + break; +#endif #endif + +#ifdef TCC_TARGET_ARM64 + case TOK___va_start: { + parse_builtin_params(0, "ee"); + //xx check types + gen_va_start(); + vpushi(0); + vtop->type.t = VT_VOID; + break; + } + case TOK___va_arg: { + parse_builtin_params(0, "et"); + type = vtop->type; + vpop(); + //xx check types + gen_va_arg(&type); + vtop->type = type; + break; + } + case TOK___arm64_clear_cache: { + parse_builtin_params(0, "ee"); + gen_clear_cache(); + vpushi(0); + vtop->type.t = VT_VOID; + break; + } +#endif + /* pre operations */ case TOK_INC: case TOK_DEC: t = tok; @@ -3194,9 +4881,22 @@ static void unary(void) break; case '-': next(); - vpushi(0); unary(); - gen_op('-'); + t = vtop->type.t & VT_BTYPE; + if (is_float(t)) { + /* In IEEE negate(x) isn't subtract(0,x), but rather + subtract(-0, x). */ + vpush(&vtop->type); + if (t == VT_FLOAT) + vtop->c.f = -1.0 * 0.0; + else if (t == VT_DOUBLE) + vtop->c.d = -1.0 * 0.0; + else + vtop->c.ld = -1.0 * 0.0; + } else + vpushi(0); + vswap(); + gen_op('-'); break; case TOK_LAND: if (!gnu_ext) @@ -3217,10 +4917,85 @@ static void unary(void) mk_pointer(&s->type); s->type.t |= VT_STATIC; } - vset(&s->type, VT_CONST | VT_SYM, 0); - vtop->sym = s; + vpushsym(&s->type, s); next(); break; + + case TOK_GENERIC: + { + CType controlling_type; + int has_default = 0; + int has_match = 0; + int learn = 0; + TokenString *str = NULL; + + next(); + skip('('); + expr_type(&controlling_type, expr_eq); + controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY); + for (;;) { + learn = 0; + skip(','); + if (tok == TOK_DEFAULT) { + if (has_default) + tcc_error("too many 'default'"); + has_default = 1; + if (!has_match) + learn = 1; + next(); + } else { + AttributeDef ad_tmp; + int itmp; + CType cur_type; + parse_btype(&cur_type, &ad_tmp); + type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); + if (compare_types(&controlling_type, &cur_type, 0)) { + if (has_match) { + tcc_error("type match twice"); + } + has_match = 1; + learn = 1; + } + } + skip(':'); + if (learn) { + if (str) + tok_str_free(str); + skip_or_save_block(&str); + } else { + skip_or_save_block(NULL); + } + if (tok == ')') + break; + } + if (!str) { + char buf[60]; + type_to_str(buf, sizeof buf, &controlling_type, NULL); + tcc_error("type '%s' does not match any association", buf); + } + begin_macro(str, 1); + next(); + expr_eq(); + if (tok != TOK_EOF) + expect(","); + end_macro(); + next(); + break; + } + // special qnan , snan and infinity values + case TOK___NAN__: + vpush64(VT_DOUBLE, 0x7ff8000000000000ULL); + next(); + break; + case TOK___SNAN__: + vpush64(VT_DOUBLE, 0x7ff0000000000001ULL); + next(); + break; + case TOK___INF__: + vpush64(VT_DOUBLE, 0x7ff0000000000000ULL); + next(); + break; + default: tok_identifier: t = tok; @@ -3229,33 +5004,38 @@ static void unary(void) expect("identifier"); s = sym_find(t); if (!s) { + const char *name = get_tok_str(t, NULL); if (tok != '(') - error("'%s' undeclared", get_tok_str(t, NULL)); + tcc_error("'%s' undeclared", name); /* for simple function calls, we tolerate undeclared external reference to int() function */ - if (tcc_state->warn_implicit_function_declaration) - warning("implicit declaration of function '%s'", - get_tok_str(t, NULL)); + if (tcc_state->warn_implicit_function_declaration +#ifdef TCC_TARGET_PE + /* people must be warned about using undeclared WINAPI functions + (which usually start with uppercase letter) */ + || (name[0] >= 'A' && name[0] <= 'Z') +#endif + ) + tcc_warning("implicit declaration of function '%s'", name); s = external_global_sym(t, &func_old_type, 0); } - if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) == - (VT_STATIC | VT_INLINE | VT_FUNC)) { - /* if referencing an inline function, then we generate a - symbol to it if not already done. It will have the - effect to generate code for it at the end of the - compilation unit. Inline function as always - generated in the text section. */ - if (!s->c) - put_extern_sym(s, text_section, 0, 0); - r = VT_SYM | VT_CONST; - } else { - r = s->r; - } + + r = s->r; + /* A symbol that has a register is a local register variable, + which starts out as VT_LOCAL value. */ + if ((r & VT_VALMASK) < VT_CONST) + r = (r & ~VT_VALMASK) | VT_LOCAL; + vset(&s->type, r, s->c); - /* if forward reference, we must point to s */ - if (vtop->r & VT_SYM) { - vtop->sym = s; - vtop->c.ul = 0; + /* Point to s as backpointer (even without r&VT_SYM). + Will be used by at least the x86 inline asm parser for + regvars. */ + vtop->sym = s; + + if (r & VT_SYM) { + vtop->c.i = 0; + } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) { + vtop->c.i = s->enum_val; } break; } @@ -3265,37 +5045,40 @@ static void unary(void) if (tok == TOK_INC || tok == TOK_DEC) { inc(1, tok); next(); - } else if (tok == '.' || tok == TOK_ARROW) { + } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) { + int qualifiers; /* field */ if (tok == TOK_ARROW) indir(); + qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE); test_lvalue(); gaddrof(); - next(); /* expect pointer on structure */ if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) expect("struct or union"); - s = vtop->type.ref; - /* find field */ - tok |= SYM_FIELD; - while ((s = s->next) != NULL) { - if (s->v == tok) - break; - } + if (tok == TOK_CDOUBLE) + expect("field name"); + next(); + if (tok == TOK_CINT || tok == TOK_CUINT) + expect("field name"); + s = find_field(&vtop->type, tok); if (!s) - error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL)); + tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc)); /* add field offset to pointer */ vtop->type = char_pointer_type; /* change type to 'char *' */ vpushi(s->c); gen_op('+'); /* change type to field type, and set to lvalue */ vtop->type = s->type; + vtop->type.t |= qualifiers; /* an array is never an lvalue */ if (!(vtop->type.t & VT_ARRAY)) { vtop->r |= lvalue_type(vtop->type.t); +#ifdef CONFIG_TCC_BCHECK /* if bound checking, the referenced pointer must be checked */ - if (tcc_state->do_bounds_check) + if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL) vtop->r |= VT_MUSTBOUND; +#endif } next(); } else if (tok == '[') { @@ -3307,7 +5090,7 @@ static void unary(void) } else if (tok == '(') { SValue ret; Sym *sa; - int nb_args; + int nb_args, ret_nregs, ret_align, regsize, variadic; /* function call */ if ((vtop->type.t & VT_BTYPE) != VT_FUNC) { @@ -3327,28 +5110,56 @@ static void unary(void) s = vtop->type.ref; next(); sa = s->next; /* first parameter */ - nb_args = 0; + nb_args = regsize = 0; ret.r2 = VT_CONST; /* compute first implicit argument if a structure is returned */ if ((s->type.t & VT_BTYPE) == VT_STRUCT) { - /* get some space for the returned structure */ - size = type_size(&s->type, &align); - loc = (loc - size) & -align; - ret.type = s->type; - ret.r = VT_LOCAL | VT_LVAL; - /* pass it as 'int' to avoid structure arg passing - problems */ - vseti(VT_LOCAL, loc); - ret.c = vtop->c; - nb_args++; + variadic = (s->f.func_type == FUNC_ELLIPSIS); + ret_nregs = gfunc_sret(&s->type, variadic, &ret.type, + &ret_align, ®size); + if (!ret_nregs) { + /* get some space for the returned structure */ + size = type_size(&s->type, &align); +#ifdef TCC_TARGET_ARM64 + /* On arm64, a small struct is return in registers. + It is much easier to write it to memory if we know + that we are allowed to write some extra bytes, so + round the allocated space up to a power of 2: */ + if (size < 16) + while (size & (size - 1)) + size = (size | (size - 1)) + 1; +#endif + loc = (loc - size) & -align; + ret.type = s->type; + ret.r = VT_LOCAL | VT_LVAL; + /* pass it as 'int' to avoid structure arg passing + problems */ + vseti(VT_LOCAL, loc); + ret.c = vtop->c; + nb_args++; + } } else { - ret.type = s->type; + ret_nregs = 1; + ret.type = s->type; + } + + if (ret_nregs) { /* return in register */ if (is_float(ret.type.t)) { ret.r = reg_fret(ret.type.t); +#ifdef TCC_TARGET_X86_64 + if ((ret.type.t & VT_BTYPE) == VT_QFLOAT) + ret.r2 = REG_QRET; +#endif } else { +#ifndef TCC_TARGET_ARM64 +#ifdef TCC_TARGET_X86_64 + if ((ret.type.t & VT_BTYPE) == VT_QLONG) +#else if ((ret.type.t & VT_BTYPE) == VT_LLONG) +#endif ret.r2 = REG_LRET; +#endif ret.r = REG_IRET; } ret.c.i = 0; @@ -3366,59 +5177,59 @@ static void unary(void) } } if (sa) - error("too few arguments to function"); + tcc_error("too few arguments to function"); skip(')'); - if (!nocode_wanted) { - gfunc_call(nb_args); - } else { - vtop -= (nb_args + 1); - } + gfunc_call(nb_args); + /* return value */ - vsetc(&ret.type, ret.r, &ret.c); - vtop->r2 = ret.r2; - } else { - break; - } - } -} + for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) { + vsetc(&ret.type, r, &ret.c); + vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */ + } -static void uneq(void) -{ - int t; - - unary(); - if (tok == '=' || - (tok >= TOK_A_MOD && tok <= TOK_A_DIV) || - tok == TOK_A_XOR || tok == TOK_A_OR || - tok == TOK_A_SHL || tok == TOK_A_SAR) { - test_lvalue(); - t = tok; - next(); - if (t == '=') { - expr_eq(); + /* handle packed struct return */ + if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) { + int addr, offset; + + size = type_size(&s->type, &align); + /* We're writing whole regs often, make sure there's enough + space. Assume register size is power of 2. */ + if (regsize > align) + align = regsize; + loc = (loc - size) & -align; + addr = loc; + offset = 0; + for (;;) { + vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset); + vswap(); + vstore(); + vtop--; + if (--ret_nregs == 0) + break; + offset += regsize; + } + vset(&s->type, VT_LOCAL | VT_LVAL, addr); + } } else { - vdup(); - expr_eq(); - gen_op(t & 0x7f); + break; } - vstore(); } } -static void expr_prod(void) +ST_FUNC void expr_prod(void) { int t; - uneq(); + unary(); while (tok == '*' || tok == '/' || tok == '%') { t = tok; next(); - uneq(); + unary(); gen_op(t); } } -static void expr_sum(void) +ST_FUNC void expr_sum(void) { int t; @@ -3501,142 +5312,175 @@ static void expr_or(void) } } -/* XXX: fix this mess */ -static void expr_land_const(void) -{ - expr_or(); - while (tok == TOK_LAND) { - next(); - expr_or(); - gen_op(TOK_LAND); - } -} - -/* XXX: fix this mess */ -static void expr_lor_const(void) -{ - expr_land_const(); - while (tok == TOK_LOR) { - next(); - expr_land_const(); - gen_op(TOK_LOR); - } -} - -/* only used if non constant */ static void expr_land(void) { - int t; - expr_or(); if (tok == TOK_LAND) { - t = 0; - save_regs(1); - for(;;) { - t = gtst(1, t); - if (tok != TOK_LAND) { - vseti(VT_JMPI, t); - break; - } - next(); - expr_or(); - } + int t = 0; + for(;;) { + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + gen_cast_s(VT_BOOL); + if (vtop->c.i) { + vpop(); + } else { + nocode_wanted++; + while (tok == TOK_LAND) { + next(); + expr_or(); + vpop(); + } + nocode_wanted--; + if (t) + gsym(t); + gen_cast_s(VT_INT); + break; + } + } else { + if (!t) + save_regs(1); + t = gvtst(1, t); + } + if (tok != TOK_LAND) { + if (t) + vseti(VT_JMPI, t); + else + vpushi(1); + break; + } + next(); + expr_or(); + } } } static void expr_lor(void) { - int t; - expr_land(); if (tok == TOK_LOR) { - t = 0; - save_regs(1); - for(;;) { - t = gtst(0, t); - if (tok != TOK_LOR) { - vseti(VT_JMP, t); - break; - } - next(); - expr_land(); - } + int t = 0; + for(;;) { + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + gen_cast_s(VT_BOOL); + if (!vtop->c.i) { + vpop(); + } else { + nocode_wanted++; + while (tok == TOK_LOR) { + next(); + expr_land(); + vpop(); + } + nocode_wanted--; + if (t) + gsym(t); + gen_cast_s(VT_INT); + break; + } + } else { + if (!t) + save_regs(1); + t = gvtst(0, t); + } + if (tok != TOK_LOR) { + if (t) + vseti(VT_JMP, t); + else + vpushi(0); + break; + } + next(); + expr_land(); + } } } -/* XXX: better constant handling */ -static void expr_eq(void) +/* Assuming vtop is a value used in a conditional context + (i.e. compared with zero) return 0 if it's false, 1 if + true and -1 if it can't be statically determined. */ +static int condition_3way(void) { - int tt, u, r1, r2, rc, t1, t2, bt1, bt2; + int c = -1; + if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && + (!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) { + vdup(); + gen_cast_s(VT_BOOL); + c = vtop->c.i; + vpop(); + } + return c; +} + +static void expr_cond(void) +{ + int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g; SValue sv; CType type, type1, type2; - if (const_wanted) { - expr_lor_const(); - if (tok == '?') { - CType boolean; - int c; - boolean.t = VT_BOOL; - vdup(); - gen_cast(&boolean); - c = vtop->c.i; - vpop(); - next(); - if (tok != ':' || !gnu_ext) { - vpop(); - gexpr(); - } - if (!c) - vpop(); - skip(':'); - expr_eq(); - if (c) - vpop(); - } - } else { - expr_lor(); - if (tok == '?') { - next(); - if (vtop != vstack) { - /* needed to avoid having different registers saved in - each branch */ - if (is_float(vtop->type.t)) { - rc = RC_FLOAT; + expr_lor(); + if (tok == '?') { + next(); + c = condition_3way(); + g = (tok == ':' && gnu_ext); + if (c < 0) { + /* needed to avoid having different registers saved in + each branch */ + if (is_float(vtop->type.t)) { + rc = RC_FLOAT; #ifdef TCC_TARGET_X86_64 - if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - rc = RC_ST0; - } -#endif + if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { + rc = RC_ST0; } - else - rc = RC_INT; - gv(rc); - save_regs(1); - } - if (tok == ':' && gnu_ext) { +#endif + } else + rc = RC_INT; + gv(rc); + save_regs(1); + if (g) gv_dup(); - tt = gtst(1, 0); - } else { - tt = gtst(1, 0); + tt = gvtst(1, 0); + + } else { + if (!g) + vpop(); + tt = 0; + } + + if (1) { + if (c == 0) + nocode_wanted++; + if (!g) gexpr(); - } + type1 = vtop->type; sv = *vtop; /* save value to handle it later */ vtop--; /* no vpop so that FP stack is not flushed */ skip(':'); - u = gjmp(0); + + u = 0; + if (c < 0) + u = gjmp(0); gsym(tt); - expr_eq(); - type2 = vtop->type; + if (c == 0) + nocode_wanted--; + if (c == 1) + nocode_wanted++; + expr_cond(); + if (c == 1) + nocode_wanted--; + + type2 = vtop->type; t1 = type1.t; bt1 = t1 & VT_BTYPE; t2 = type2.t; bt2 = t2 & VT_BTYPE; + type.ref = NULL; + /* cast operands to correct type according to ISOC rules */ if (is_float(bt1) || is_float(bt2)) { if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { type.t = VT_LDOUBLE; + } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) { type.t = VT_DOUBLE; } else { @@ -3644,36 +5488,58 @@ static void expr_eq(void) } } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { /* cast to biggest op */ - type.t = VT_LLONG; + type.t = VT_LLONG | VT_LONG; + if (bt1 == VT_LLONG) + type.t &= t1; + if (bt2 == VT_LLONG) + type.t &= t2; /* convert to unsigned if it does not fit in a long long */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) + if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) || + (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED)) type.t |= VT_UNSIGNED; } else if (bt1 == VT_PTR || bt2 == VT_PTR) { - /* XXX: test pointer compatibility */ - type = type1; + /* If one is a null ptr constant the result type + is the other. */ + if (is_null_pointer (vtop)) + type = type1; + else if (is_null_pointer (&sv)) + type = type2; + /* XXX: test pointer compatibility, C99 has more elaborate + rules here. */ + else + type = type1; } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { /* XXX: test function pointer compatibility */ - type = type1; + type = bt1 == VT_FUNC ? type1 : type2; } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { /* XXX: test structure compatibility */ - type = type1; + type = bt1 == VT_STRUCT ? type1 : type2; } else if (bt1 == VT_VOID || bt2 == VT_VOID) { /* NOTE: as an extension, we accept void on only one side */ type.t = VT_VOID; } else { /* integer operations */ - type.t = VT_INT; + type.t = VT_INT | (VT_LONG & (t1 | t2)); /* convert to unsigned if it does not fit in an integer */ - if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || - (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) + if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) || + (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED)) type.t |= VT_UNSIGNED; } - + /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so + that `(expr ? a : b).mem` does not error with "lvalue expected" */ + islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE); + islv &= c < 0; + /* now we convert second operand */ - gen_cast(&type); - if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) - gaddrof(); + if (c != 1) { + gen_cast(&type); + if (islv) { + mk_pointer(&vtop->type); + gaddrof(); + } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) + gaddrof(); + } + rc = RC_INT; if (is_float(type.t)) { rc = RC_FLOAT; @@ -3685,28 +5551,64 @@ static void expr_eq(void) } else if ((type.t & VT_BTYPE) == VT_LLONG) { /* for long longs, we use fixed registers to avoid having to handle a complicated move */ - rc = RC_IRET; + rc = RC_IRET; + } + + tt = r2 = 0; + if (c < 0) { + r2 = gv(rc); + tt = gjmp(0); } - - r2 = gv(rc); + gsym(u); + /* this is horrible, but we must also convert first operand */ - tt = gjmp(0); - gsym(u); - /* put again first value and cast it */ - *vtop = sv; - gen_cast(&type); - if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) - gaddrof(); - r1 = gv(rc); - move_reg(r2, r1); - vtop->r = r2; - gsym(tt); + if (c != 0) { + *vtop = sv; + gen_cast(&type); + if (islv) { + mk_pointer(&vtop->type); + gaddrof(); + } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) + gaddrof(); + } + + if (c < 0) { + r1 = gv(rc); + move_reg(r2, r1, type.t); + vtop->r = r2; + gsym(tt); + if (islv) + indir(); + } } } } -static void gexpr(void) +static void expr_eq(void) +{ + int t; + + expr_cond(); + if (tok == '=' || + (tok >= TOK_A_MOD && tok <= TOK_A_DIV) || + tok == TOK_A_XOR || tok == TOK_A_OR || + tok == TOK_A_SHL || tok == TOK_A_SAR) { + test_lvalue(); + t = tok; + next(); + if (t == '=') { + expr_eq(); + } else { + vdup(); + expr_eq(); + gen_op(t & 0x7f); + } + vstore(); + } +} + +ST_FUNC void gexpr(void) { while (1) { expr_eq(); @@ -3717,47 +5619,20 @@ static void gexpr(void) } } -/* parse an expression and return its type without any side effect. */ -static void expr_type(CType *type) -{ - int saved_nocode_wanted; - - saved_nocode_wanted = nocode_wanted; - nocode_wanted = 1; - gexpr(); - *type = vtop->type; - vpop(); - nocode_wanted = saved_nocode_wanted; -} - -/* parse a unary expression and return its type without any side - effect. */ -static void unary_type(CType *type) -{ - int a; - - a = nocode_wanted; - nocode_wanted = 1; - unary(); - *type = vtop->type; - vpop(); - nocode_wanted = a; -} - /* parse a constant expression and return value in vtop. */ static void expr_const1(void) { - int a; - a = const_wanted; - const_wanted = 1; - expr_eq(); - const_wanted = a; + const_wanted++; + nocode_wanted++; + expr_cond(); + nocode_wanted--; + const_wanted--; } /* parse an integer constant and return its value. */ -static int expr_const(void) +static inline int64_t expr_const64(void) { - int c; + int64_t c; expr_const1(); if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) expect("constant expression"); @@ -3766,6 +5641,18 @@ static int expr_const(void) return c; } +/* parse an integer constant and return its value. + Complain if it doesn't fit 32bit (signed or unsigned). */ +ST_FUNC int expr_const(void) +{ + int c; + int64_t wc = expr_const64(); + c = wc; + if (c != wc && (unsigned)c != wc) + tcc_error("constant exceeds 32 bit"); + return c; +} + /* return the label token if current token is a label, otherwise return zero */ static int is_label(void) @@ -3779,7 +5666,6 @@ static int is_label(void) last_tok = tok; next(); if (tok == ':') { - next(); return last_tok; } else { unget_tok(last_tok); @@ -3787,19 +5673,147 @@ static int is_label(void) } } -static void block(int *bsym, int *csym, int *case_sym, int *def_sym, - int case_reg, int is_expr) +#ifndef TCC_TARGET_ARM64 +static void gfunc_return(CType *func_type) +{ + if ((func_type->t & VT_BTYPE) == VT_STRUCT) { + CType type, ret_type; + int ret_align, ret_nregs, regsize; + ret_nregs = gfunc_sret(func_type, func_var, &ret_type, + &ret_align, ®size); + if (0 == ret_nregs) { + /* if returning structure, must copy it to implicit + first pointer arg location */ + type = *func_type; + mk_pointer(&type); + vset(&type, VT_LOCAL | VT_LVAL, func_vc); + indir(); + vswap(); + /* copy structure value to pointer */ + vstore(); + } else { + /* returning structure packed into registers */ + int r, size, addr, align; + size = type_size(func_type,&align); + if ((vtop->r != (VT_LOCAL | VT_LVAL) || + (vtop->c.i & (ret_align-1))) + && (align & (ret_align-1))) { + loc = (loc - size) & -ret_align; + addr = loc; + type = *func_type; + vset(&type, VT_LOCAL | VT_LVAL, addr); + vswap(); + vstore(); + vpop(); + vset(&ret_type, VT_LOCAL | VT_LVAL, addr); + } + vtop->type = ret_type; + if (is_float(ret_type.t)) + r = rc_fret(ret_type.t); + else + r = RC_IRET; + + if (ret_nregs == 1) + gv(r); + else { + for (;;) { + vdup(); + gv(r); + vpop(); + if (--ret_nregs == 0) + break; + /* We assume that when a structure is returned in multiple + registers, their classes are consecutive values of the + suite s(n) = 2^n */ + r <<= 1; + vtop->c.i += regsize; + } + } + } + } else if (is_float(func_type->t)) { + gv(rc_fret(func_type->t)); + } else { + gv(RC_IRET); + } + vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ +} +#endif + +static int case_cmp(const void *pa, const void *pb) +{ + int64_t a = (*(struct case_t**) pa)->v1; + int64_t b = (*(struct case_t**) pb)->v1; + return a < b ? -1 : a > b; +} + +static void gcase(struct case_t **base, int len, int *bsym) { - int a, b, c, d; + struct case_t *p; + int e; + int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG; + gv(RC_INT); + while (len > 4) { + /* binary search */ + p = base[len/2]; + vdup(); + if (ll) + vpushll(p->v2); + else + vpushi(p->v2); + gen_op(TOK_LE); + e = gtst(1, 0); + vdup(); + if (ll) + vpushll(p->v1); + else + vpushi(p->v1); + gen_op(TOK_GE); + gtst_addr(0, p->sym); /* v1 <= x <= v2 */ + /* x < v1 */ + gcase(base, len/2, bsym); + if (cur_switch->def_sym) + gjmp_addr(cur_switch->def_sym); + else + *bsym = gjmp(*bsym); + /* x > v2 */ + gsym(e); + e = len/2 + 1; + base += e; len -= e; + } + /* linear scan */ + while (len--) { + p = *base++; + vdup(); + if (ll) + vpushll(p->v2); + else + vpushi(p->v2); + if (p->v1 == p->v2) { + gen_op(TOK_EQ); + gtst_addr(0, p->sym); + } else { + gen_op(TOK_LE); + e = gtst(1, 0); + vdup(); + if (ll) + vpushll(p->v1); + else + vpushi(p->v1); + gen_op(TOK_GE); + gtst_addr(0, p->sym); + gsym(e); + } + } +} + +static void block(int *bsym, int *csym, int is_expr) +{ + int a, b, c, d, cond; Sym *s; /* generate line number info */ - if (tcc_state->do_debug && - (last_line_num != file->line_num || last_ind != ind)) { - put_stabn(N_SLINE, 0, file->line_num, ind - func_ind); - last_ind = ind; - last_line_num = file->line_num; - } + if (tcc_state->do_debug) + tcc_debug_line(tcc_state); if (is_expr) { /* default return value is (void) */ @@ -3809,40 +5823,63 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, if (tok == TOK_IF) { /* if test */ + int saved_nocode_wanted = nocode_wanted; next(); skip('('); gexpr(); skip(')'); - a = gtst(1, 0); - block(bsym, csym, case_sym, def_sym, case_reg, 0); + cond = condition_3way(); + if (cond == 1) + a = 0, vpop(); + else + a = gvtst(1, 0); + if (cond == 0) + nocode_wanted |= 0x20000000; + block(bsym, csym, 0); + if (cond != 1) + nocode_wanted = saved_nocode_wanted; c = tok; if (c == TOK_ELSE) { next(); d = gjmp(0); gsym(a); - block(bsym, csym, case_sym, def_sym, case_reg, 0); + if (cond == 1) + nocode_wanted |= 0x20000000; + block(bsym, csym, 0); gsym(d); /* patch else jmp */ + if (cond != 0) + nocode_wanted = saved_nocode_wanted; } else gsym(a); } else if (tok == TOK_WHILE) { + int saved_nocode_wanted; + nocode_wanted &= ~0x20000000; next(); d = ind; + vla_sp_restore(); skip('('); gexpr(); skip(')'); - a = gtst(1, 0); + a = gvtst(1, 0); b = 0; - block(&a, &b, case_sym, def_sym, case_reg, 0); + ++local_scope; + saved_nocode_wanted = nocode_wanted; + block(&a, &b, 0); + nocode_wanted = saved_nocode_wanted; + --local_scope; gjmp_addr(d); gsym(a); gsym_addr(b, d); } else if (tok == '{') { Sym *llabel; - + int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope; + next(); /* record local declaration stack position */ s = local_stack; llabel = local_label_stack; + ++local_scope; + /* handle local labels declarations */ if (tok == TOK_LABEL) { next(); @@ -3860,193 +5897,188 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, } } while (tok != '}') { - decl(VT_LOCAL); + if ((a = is_label())) + unget_tok(a); + else + decl(VT_LOCAL); if (tok != '}') { if (is_expr) vpop(); - block(bsym, csym, case_sym, def_sym, case_reg, is_expr); + block(bsym, csym, is_expr); } } /* pop locally defined labels */ - label_pop(&local_label_stack, llabel); + label_pop(&local_label_stack, llabel, is_expr); /* pop locally defined symbols */ - if(is_expr) { - /* XXX: this solution makes only valgrind happy... - triggered by gcc.c-torture/execute/20000917-1.c */ - Sym *p; - switch(vtop->type.t & VT_BTYPE) { - case VT_PTR: - case VT_STRUCT: - case VT_ENUM: - case VT_FUNC: - for(p=vtop->type.ref;p;p=p->prev) - if(p->prev==s) - error("unsupported expression type"); - } + --local_scope; + /* In the is_expr case (a statement expression is finished here), + vtop might refer to symbols on the local_stack. Either via the + type or via vtop->sym. We can't pop those nor any that in turn + might be referred to. To make it easier we don't roll back + any symbols in that case; some upper level call to block() will + do that. We do have to remove such symbols from the lookup + tables, though. sym_pop will do that. */ + sym_pop(&local_stack, s, is_expr); + + /* Pop VLA frames and restore stack pointer if required */ + if (vlas_in_scope > saved_vlas_in_scope) { + vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc; + vla_sp_restore(); } - sym_pop(&local_stack, s); + vlas_in_scope = saved_vlas_in_scope; + next(); } else if (tok == TOK_RETURN) { next(); if (tok != ';') { gexpr(); gen_assign_cast(&func_vt); - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { - CType type; - /* if returning structure, must copy it to implicit - first pointer arg location */ -#ifdef TCC_ARM_EABI - int align, size; - size = type_size(&func_vt,&align); - if(size <= 4) - { - if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3)) - && (align & 3)) - { - int addr; - loc = (loc - size) & -4; - addr = loc; - type = func_vt; - vset(&type, VT_LOCAL | VT_LVAL, addr); - vswap(); - vstore(); - vset(&int_type, VT_LOCAL | VT_LVAL, addr); - } - vtop->type = int_type; - gv(RC_IRET); - } else { -#endif - type = func_vt; - mk_pointer(&type); - vset(&type, VT_LOCAL | VT_LVAL, func_vc); - indir(); - vswap(); - /* copy structure value to pointer */ - vstore(); -#ifdef TCC_ARM_EABI - } -#endif - } else if (is_float(func_vt.t)) { - gv(rc_fret(func_vt.t)); - } else { - gv(RC_IRET); - } - vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ + if ((func_vt.t & VT_BTYPE) == VT_VOID) + vtop--; + else + gfunc_return(&func_vt); } skip(';'); - rsym = gjmp(rsym); /* jmp */ + /* jump unless last stmt in top-level block */ + if (tok != '}' || local_scope != 1) + rsym = gjmp(rsym); + nocode_wanted |= 0x20000000; } else if (tok == TOK_BREAK) { /* compute jump */ if (!bsym) - error("cannot break"); + tcc_error("cannot break"); *bsym = gjmp(*bsym); next(); skip(';'); + nocode_wanted |= 0x20000000; } else if (tok == TOK_CONTINUE) { /* compute jump */ if (!csym) - error("cannot continue"); + tcc_error("cannot continue"); + vla_sp_restore_root(); *csym = gjmp(*csym); next(); skip(';'); } else if (tok == TOK_FOR) { int e; + int saved_nocode_wanted; + nocode_wanted &= ~0x20000000; next(); skip('('); + s = local_stack; + ++local_scope; if (tok != ';') { - gexpr(); - vpop(); + /* c99 for-loop init decl? */ + if (!decl0(VT_LOCAL, 1, NULL)) { + /* no, regular for-loop init expr */ + gexpr(); + vpop(); + } } skip(';'); d = ind; c = ind; + vla_sp_restore(); a = 0; b = 0; if (tok != ';') { gexpr(); - a = gtst(1, 0); + a = gvtst(1, 0); } skip(';'); if (tok != ')') { e = gjmp(0); c = ind; + vla_sp_restore(); gexpr(); vpop(); gjmp_addr(d); gsym(e); } skip(')'); - block(&a, &b, case_sym, def_sym, case_reg, 0); + saved_nocode_wanted = nocode_wanted; + block(&a, &b, 0); + nocode_wanted = saved_nocode_wanted; gjmp_addr(c); gsym(a); gsym_addr(b, c); + --local_scope; + sym_pop(&local_stack, s, 0); + } else if (tok == TOK_DO) { + int saved_nocode_wanted; + nocode_wanted &= ~0x20000000; next(); a = 0; b = 0; d = ind; - block(&a, &b, case_sym, def_sym, case_reg, 0); + vla_sp_restore(); + saved_nocode_wanted = nocode_wanted; + block(&a, &b, 0); skip(TOK_WHILE); skip('('); gsym(b); - gexpr(); - c = gtst(0, 0); - gsym_addr(c, d); + gexpr(); + c = gvtst(0, 0); + gsym_addr(c, d); + nocode_wanted = saved_nocode_wanted; skip(')'); gsym(a); skip(';'); } else if (tok == TOK_SWITCH) { + struct switch_t *saved, sw; + int saved_nocode_wanted = nocode_wanted; + SValue switchval; next(); skip('('); gexpr(); - /* XXX: other types than integer */ - case_reg = gv(RC_INT); - vpop(); skip(')'); + switchval = *vtop--; a = 0; b = gjmp(0); /* jump to first case */ - c = 0; - block(&a, csym, &b, &c, case_reg, 0); - /* if no default, jmp after switch */ - if (c == 0) - c = ind; - /* default label */ - gsym_addr(b, c); + sw.p = NULL; sw.n = 0; sw.def_sym = 0; + saved = cur_switch; + cur_switch = &sw; + block(&a, csym, 0); + nocode_wanted = saved_nocode_wanted; + a = gjmp(a); /* add implicit break */ + /* case lookup */ + gsym(b); + qsort(sw.p, sw.n, sizeof(void*), case_cmp); + for (b = 1; b < sw.n; b++) + if (sw.p[b - 1]->v2 >= sw.p[b]->v1) + tcc_error("duplicate case value"); + /* Our switch table sorting is signed, so the compared + value needs to be as well when it's 64bit. */ + if ((switchval.type.t & VT_BTYPE) == VT_LLONG) + switchval.type.t &= ~VT_UNSIGNED; + vpushv(&switchval); + gcase(sw.p, sw.n, &a); + vpop(); + if (sw.def_sym) + gjmp_addr(sw.def_sym); + dynarray_reset(&sw.p, &sw.n); + cur_switch = saved; /* break label */ gsym(a); } else if (tok == TOK_CASE) { - int v1, v2; - if (!case_sym) + struct case_t *cr = tcc_malloc(sizeof(struct case_t)); + if (!cur_switch) expect("switch"); + nocode_wanted &= ~0x20000000; next(); - v1 = expr_const(); - v2 = v1; + cr->v1 = cr->v2 = expr_const64(); if (gnu_ext && tok == TOK_DOTS) { next(); - v2 = expr_const(); - if (v2 < v1) - warning("empty case range"); + cr->v2 = expr_const64(); + if (cr->v2 < cr->v1) + tcc_warning("empty case range"); } - /* since a case is like a label, we must skip it with a jmp */ - b = gjmp(0); - gsym(*case_sym); - vseti(case_reg, 0); - vpushi(v1); - if (v1 == v2) { - gen_op(TOK_EQ); - *case_sym = gtst(1, 0); - } else { - gen_op(TOK_GE); - *case_sym = gtst(1, 0); - vseti(case_reg, 0); - vpushi(v2); - gen_op(TOK_LE); - *case_sym = gtst(1, *case_sym); - } - gsym(b); + cr->sym = ind; + dynarray_add(&cur_switch->p, &cur_switch->n, cr); skip(':'); is_expr = 0; goto block_after_label; @@ -4054,11 +6086,11 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, if (tok == TOK_DEFAULT) { next(); skip(':'); - if (!def_sym) + if (!cur_switch) expect("switch"); - if (*def_sym) - error("too many 'default'"); - *def_sym = ind; + if (cur_switch->def_sym) + tcc_error("too many 'default'"); + cur_switch->def_sym = ind; is_expr = 0; goto block_after_label; } else @@ -4080,11 +6112,11 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, if (s->r == LABEL_DECLARED) s->r = LABEL_FORWARD; } - /* label already defined */ - if (s->r & LABEL_FORWARD) - s->next = (void *)gjmp((long)s->next); + vla_sp_restore_root(); + if (s->r & LABEL_FORWARD) + s->jnext = gjmp(s->jnext); else - gjmp_addr((long)s->next); + gjmp_addr(s->jnext); next(); } else { expect("label identifier"); @@ -4096,24 +6128,27 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, b = is_label(); if (b) { /* label case */ + next(); s = label_find(b); if (s) { if (s->r == LABEL_DEFINED) - error("duplicate label '%s'", get_tok_str(s->v, NULL)); - gsym((long)s->next); + tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL)); + gsym(s->jnext); s->r = LABEL_DEFINED; } else { s = label_push(&global_label_stack, b, LABEL_DEFINED); } - s->next = (void *)ind; + s->jnext = ind; + vla_sp_restore(); /* we accept this, but it is a mistake */ block_after_label: + nocode_wanted &= ~0x20000000; if (tok == '}') { - warning("deprecated use of label at end of compound statement"); + tcc_warning("deprecated use of label at end of compound statement"); } else { if (is_expr) vpop(); - block(bsym, csym, case_sym, def_sym, case_reg, is_expr); + block(bsym, csym, is_expr); } } else { /* expression case */ @@ -4131,104 +6166,176 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, } } +/* This skips over a stream of tokens containing balanced {} and () + pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started + with a '{'). If STR then allocates and stores the skipped tokens + in *STR. This doesn't check if () and {} are nested correctly, + i.e. "({)}" is accepted. */ +static void skip_or_save_block(TokenString **str) +{ + int braces = tok == '{'; + int level = 0; + if (str) + *str = tok_str_alloc(); + + while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) { + int t; + if (tok == TOK_EOF) { + if (str || level > 0) + tcc_error("unexpected end of file"); + else + break; + } + if (str) + tok_str_add_tok(*str); + t = tok; + next(); + if (t == '{' || t == '(') { + level++; + } else if (t == '}' || t == ')') { + level--; + if (level == 0 && braces && t == '}') + break; + } + } + if (str) { + tok_str_add(*str, -1); + tok_str_add(*str, 0); + } +} + +#define EXPR_CONST 1 +#define EXPR_ANY 2 + +static void parse_init_elem(int expr_type) +{ + int saved_global_expr; + switch(expr_type) { + case EXPR_CONST: + /* compound literals must be allocated globally in this case */ + saved_global_expr = global_expr; + global_expr = 1; + expr_const1(); + global_expr = saved_global_expr; + /* NOTE: symbols are accepted, as well as lvalue for anon symbols + (compound literals). */ + if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST + && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL) + || vtop->sym->v < SYM_FIRST_ANOM)) +#ifdef TCC_TARGET_PE + || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport) +#endif + ) + tcc_error("initializer element is not constant"); + break; + case EXPR_ANY: + expr_eq(); + break; + } +} + +/* put zeros for variable based init */ +static void init_putz(Section *sec, unsigned long c, int size) +{ + if (sec) { + /* nothing to do because globals are already set to zero */ + } else { + vpush_global_sym(&func_old_type, TOK_memset); + vseti(VT_LOCAL, c); +#ifdef TCC_TARGET_ARM + vpushs(size); + vpushi(0); +#else + vpushi(0); + vpushs(size); +#endif + gfunc_call(3); + } +} + /* t is the array or struct type. c is the array or struct - address. cur_index/cur_field is the pointer to the current - value. 'size_only' is true if only size info is needed (only used - in arrays) */ -static void decl_designator(CType *type, Section *sec, unsigned long c, - int *cur_index, Sym **cur_field, - int size_only) + address. cur_field is the pointer to the current + field, for arrays the 'c' member contains the current start + index. 'size_only' is true if only size info is needed (only used + in arrays). al contains the already initialized length of the + current container (starting at c). This returns the new length of that. */ +static int decl_designator(CType *type, Section *sec, unsigned long c, + Sym **cur_field, int size_only, int al) { Sym *s, *f; - int notfirst, index, index_last, align, l, nb_elems, elem_size; - CType type1; + int index, index_last, align, l, nb_elems, elem_size; + unsigned long corig = c; - notfirst = 0; elem_size = 0; nb_elems = 1; if (gnu_ext && (l = is_label()) != 0) goto struct_field; - while (tok == '[' || tok == '.') { + /* NOTE: we only support ranges for last designator */ + while (nb_elems == 1 && (tok == '[' || tok == '.')) { if (tok == '[') { if (!(type->t & VT_ARRAY)) expect("array type"); - s = type->ref; next(); - index = expr_const(); - if (index < 0 || (s->c >= 0 && index >= s->c)) - expect("invalid index"); + index = index_last = expr_const(); if (tok == TOK_DOTS && gnu_ext) { next(); index_last = expr_const(); - if (index_last < 0 || - (s->c >= 0 && index_last >= s->c) || - index_last < index) - expect("invalid index"); - } else { - index_last = index; } skip(']'); - if (!notfirst) - *cur_index = index_last; + s = type->ref; + if (index < 0 || (s->c >= 0 && index_last >= s->c) || + index_last < index) + tcc_error("invalid index"); + if (cur_field) + (*cur_field)->c = index_last; type = pointed_type(type); elem_size = type_size(type, &align); c += index * elem_size; - /* NOTE: we only support ranges for last designator */ nb_elems = index_last - index + 1; - if (nb_elems != 1) { - notfirst = 1; - break; - } } else { next(); l = tok; - next(); struct_field: + next(); if ((type->t & VT_BTYPE) != VT_STRUCT) expect("struct/union type"); - s = type->ref; - l |= SYM_FIELD; - f = s->next; - while (f) { - if (f->v == l) - break; - f = f->next; - } + f = find_field(type, l); if (!f) expect("field"); - if (!notfirst) + if (cur_field) *cur_field = f; - /* XXX: fix this mess by using explicit storage field */ - type1 = f->type; - type1.t |= (type->t & ~VT_TYPE); - type = &type1; + type = &f->type; c += f->c; } - notfirst = 1; + cur_field = NULL; } - if (notfirst) { + if (!cur_field) { if (tok == '=') { next(); - } else { - if (!gnu_ext) - expect("="); + } else if (!gnu_ext) { + expect("="); } } else { if (type->t & VT_ARRAY) { - index = *cur_index; + index = (*cur_field)->c; + if (type->ref->c >= 0 && index >= type->ref->c) + tcc_error("index too large"); type = pointed_type(type); c += index * type_size(type, &align); } else { f = *cur_field; + while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD)) + *cur_field = f = f->next; if (!f) - error("too many field init"); - /* XXX: fix this mess by using explicit storage field */ - type1 = f->type; - type1.t |= (type->t & ~VT_TYPE); - type = &type1; + tcc_error("too many field init"); + type = &f->type; c += f->c; } } + /* must put zero in holes (note that doing it that way + ensures that it even works with designators) */ + if (!size_only && c - corig > al) + init_putz(sec, corig + al, c - corig - al); decl_initializer(type, sec, c, 0, size_only); /* XXX: make it more general */ @@ -4237,108 +6344,211 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, uint8_t *src, *dst; int i; - if (!sec) - error("range init not supported yet for dynamic storage"); - c_end = c + nb_elems * elem_size; - if (c_end > sec->data_allocated) - section_realloc(sec, c_end); - src = sec->data + c; - dst = src; - for(i = 1; i < nb_elems; i++) { - dst += elem_size; - memcpy(dst, src, elem_size); - } + if (!sec) { + vset(type, VT_LOCAL|VT_LVAL, c); + for (i = 1; i < nb_elems; i++) { + vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i); + vswap(); + vstore(); + } + vpop(); + } else if (!NODATA_WANTED) { + c_end = c + nb_elems * elem_size; + if (c_end > sec->data_allocated) + section_realloc(sec, c_end); + src = sec->data + c; + dst = src; + for(i = 1; i < nb_elems; i++) { + dst += elem_size; + memcpy(dst, src, elem_size); + } + } } + c += nb_elems * type_size(type, &align); + if (c - corig > al) + al = c - corig; + return al; } -#define EXPR_VAL 0 -#define EXPR_CONST 1 -#define EXPR_ANY 2 - /* store a value or an expression directly in global data or in local array */ -static void init_putv(CType *type, Section *sec, unsigned long c, - int v, int expr_type) +static void init_putv(CType *type, Section *sec, unsigned long c) { - int saved_global_expr, bt, bit_pos, bit_size; + int bt; void *ptr; - unsigned long long bit_mask; CType dtype; - switch(expr_type) { - case EXPR_VAL: - vpushi(v); - break; - case EXPR_CONST: - /* compound literals must be allocated globally in this case */ - saved_global_expr = global_expr; - global_expr = 1; - expr_const1(); - global_expr = saved_global_expr; - /* NOTE: symbols are accepted */ - if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST) - error("initializer element is not constant"); - break; - case EXPR_ANY: - expr_eq(); - break; - } - dtype = *type; dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ if (sec) { + int size, align; /* XXX: not portable */ /* XXX: generate error if incorrect relocation */ gen_assign_cast(&dtype); bt = type->t & VT_BTYPE; - /* we'll write at most 12 bytes */ - if (c + 12 > sec->data_allocated) { - section_realloc(sec, c + 12); + + if ((vtop->r & VT_SYM) + && bt != VT_PTR + && bt != VT_FUNC + && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT) + || (type->t & VT_BITFIELD)) + && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM) + ) + tcc_error("initializer element is not computable at load time"); + + if (NODATA_WANTED) { + vtop--; + return; } + + size = type_size(type, &align); + section_reserve(sec, c + size); ptr = sec->data + c; + /* XXX: make code faster ? */ - if (!(type->t & VT_BITFIELD)) { - bit_pos = 0; - bit_size = 32; - bit_mask = -1LL; - } else { - bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; - bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; - bit_mask = (1LL << bit_size) - 1; - } - if ((vtop->r & VT_SYM) && - (bt == VT_BYTE || - bt == VT_SHORT || - bt == VT_DOUBLE || - bt == VT_LDOUBLE || - bt == VT_LLONG || - (bt == VT_INT && bit_size != 32))) - error("initializer element is not computable at load time"); - switch(bt) { - case VT_BOOL: - vtop->c.i = (vtop->c.i != 0); - case VT_BYTE: - *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - case VT_SHORT: - *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - case VT_DOUBLE: - *(double *)ptr = vtop->c.d; - break; - case VT_LDOUBLE: - *(long double *)ptr = vtop->c.ld; - break; - case VT_LLONG: - *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos; - break; - default: - if (vtop->r & VT_SYM) { - greloc(sec, vtop->sym, c, R_DATA_32); - } - *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos; - break; - } + if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) && + vtop->sym->v >= SYM_FIRST_ANOM && + /* XXX This rejects compound literals like + '(void *){ptr}'. The problem is that '&sym' is + represented the same way, which would be ruled out + by the SYM_FIRST_ANOM check above, but also '"string"' + in 'char *p = "string"' is represented the same + with the type being VT_PTR and the symbol being an + anonymous one. That is, there's no difference in vtop + between '(void *){x}' and '&(void *){x}'. Ignore + pointer typed entities here. Hopefully no real code + will every use compound literals with scalar type. */ + (vtop->type.t & VT_BTYPE) != VT_PTR) { + /* These come from compound literals, memcpy stuff over. */ + Section *ssec; + ElfW(Sym) *esym; + ElfW_Rel *rel; + esym = &((ElfW(Sym) *)symtab_section->data)[vtop->sym->c]; + ssec = tcc_state->sections[esym->st_shndx]; + memmove (ptr, ssec->data + esym->st_value, size); + if (ssec->reloc) { + /* We need to copy over all memory contents, and that + includes relocations. Use the fact that relocs are + created it order, so look from the end of relocs + until we hit one before the copied region. */ + int num_relocs = ssec->reloc->data_offset / sizeof(*rel); + rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset); + while (num_relocs--) { + rel--; + if (rel->r_offset >= esym->st_value + size) + continue; + if (rel->r_offset < esym->st_value) + break; + /* Note: if the same fields are initialized multiple + times (possible with designators) then we possibly + add multiple relocations for the same offset here. + That would lead to wrong code, the last reloc needs + to win. We clean this up later after the whole + initializer is parsed. */ + put_elf_reloca(symtab_section, sec, + c + rel->r_offset - esym->st_value, + ELFW(R_TYPE)(rel->r_info), + ELFW(R_SYM)(rel->r_info), +#if PTR_SIZE == 8 + rel->r_addend +#else + 0 +#endif + ); + } + } + } else { + if (type->t & VT_BITFIELD) { + int bit_pos, bit_size, bits, n; + unsigned char *p, v, m; + bit_pos = BIT_POS(vtop->type.t); + bit_size = BIT_SIZE(vtop->type.t); + p = (unsigned char*)ptr + (bit_pos >> 3); + bit_pos &= 7, bits = 0; + while (bit_size) { + n = 8 - bit_pos; + if (n > bit_size) + n = bit_size; + v = vtop->c.i >> bits << bit_pos; + m = ((1 << n) - 1) << bit_pos; + *p = (*p & ~m) | (v & m); + bits += n, bit_size -= n, bit_pos = 0, ++p; + } + } else + switch(bt) { + /* XXX: when cross-compiling we assume that each type has the + same representation on host and target, which is likely to + be wrong in the case of long double */ + case VT_BOOL: + vtop->c.i = vtop->c.i != 0; + case VT_BYTE: + *(char *)ptr |= vtop->c.i; + break; + case VT_SHORT: + *(short *)ptr |= vtop->c.i; + break; + case VT_FLOAT: + *(float*)ptr = vtop->c.f; + break; + case VT_DOUBLE: + *(double *)ptr = vtop->c.d; + break; + case VT_LDOUBLE: +#if defined TCC_IS_NATIVE_387 + if (sizeof (long double) >= 10) /* zero pad ten-byte LD */ + memcpy(ptr, &vtop->c.ld, 10); +#ifdef __TINYC__ + else if (sizeof (long double) == sizeof (double)) + __asm__("fldl %1\nfstpt %0\n" : "=m" (ptr) : "m" (vtop->c.ld)); +#endif + else +#endif + if (sizeof(long double) == LDOUBLE_SIZE) + *(long double*)ptr = vtop->c.ld; + else if (sizeof(double) == LDOUBLE_SIZE) + *(double *)ptr = (double)vtop->c.ld; + else + tcc_error("can't cross compile long double constants"); + break; +#if PTR_SIZE != 8 + case VT_LLONG: + *(long long *)ptr |= vtop->c.i; + break; +#else + case VT_LLONG: +#endif + case VT_PTR: + { + addr_t val = vtop->c.i; +#if PTR_SIZE == 8 + if (vtop->r & VT_SYM) + greloca(sec, vtop->sym, c, R_DATA_PTR, val); + else + *(addr_t *)ptr |= val; +#else + if (vtop->r & VT_SYM) + greloc(sec, vtop->sym, c, R_DATA_PTR); + *(addr_t *)ptr |= val; +#endif + break; + } + default: + { + int val = vtop->c.i; +#if PTR_SIZE == 8 + if (vtop->r & VT_SYM) + greloca(sec, vtop->sym, c, R_DATA_PTR, val); + else + *(int *)ptr |= val; +#else + if (vtop->r & VT_SYM) + greloc(sec, vtop->sym, c, R_DATA_PTR); + *(int *)ptr |= val; +#endif + break; + } + } + } vtop--; } else { vset(&dtype, VT_LOCAL|VT_LVAL, c); @@ -4348,20 +6558,6 @@ static void init_putv(CType *type, Section *sec, unsigned long c, } } -/* put zeros for variable based init */ -static void init_putz(CType *t, Section *sec, unsigned long c, int size) -{ - if (sec) { - /* nothing to do because globals are already set to zero */ - } else { - vpush_global_sym(&func_old_type, TOK_memset); - vseti(VT_LOCAL, c); - vpushi(0); - vpushi(size); - gfunc_call(3); - } -} - /* 't' contains the type and storage info. 'c' is the offset of the object in section 'sec'. If 'sec' is NULL, it means stack based allocation. 'first' is true if array '{' must be read (multi @@ -4370,21 +6566,45 @@ static void init_putz(CType *t, Section *sec, unsigned long c, int size) static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only) { - int index, array_length, n, no_oblock, nb, parlevel, i; - int size1, align1, expr_type; + int len, n, no_oblock, nb, i; + int size1, align1; + int have_elem; Sym *s, *f; + Sym indexsym; CType *t1; - if (type->t & VT_ARRAY) { + /* If we currently are at an '}' or ',' we have read an initializer + element in one of our callers, and not yet consumed it. */ + have_elem = tok == '}' || tok == ','; + if (!have_elem && tok != '{' && + /* In case of strings we have special handling for arrays, so + don't consume them as initializer value (which would commit them + to some anonymous symbol). */ + tok != TOK_LSTR && tok != TOK_STR && + !size_only) { + parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST); + have_elem = 1; + } + + if (have_elem && + !(type->t & VT_ARRAY) && + /* Use i_c_parameter_t, to strip toplevel qualifiers. + The source type might have VT_CONSTANT set, which is + of course assignable to non-const elements. */ + is_compatible_unqualified_types(type, &vtop->type)) { + init_putv(type, sec, c); + } else if (type->t & VT_ARRAY) { s = type->ref; n = s->c; - array_length = 0; t1 = pointed_type(type); size1 = type_size(t1, &align1); no_oblock = 1; if ((first && tok != TOK_LSTR && tok != TOK_STR) || tok == '{') { + if (tok != '{') + tcc_error("character array initializer must be a literal," + " optionally enclosed in braces"); skip('{'); no_oblock = 0; } @@ -4398,115 +6618,92 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, (t1->t & VT_BTYPE) == VT_INT #endif ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) { + len = 0; while (tok == TOK_STR || tok == TOK_LSTR) { int cstr_len, ch; - CString *cstr; - cstr = tokc.cstr; /* compute maximum number of chars wanted */ if (tok == TOK_STR) - cstr_len = cstr->size; + cstr_len = tokc.str.size; else - cstr_len = cstr->size / sizeof(nwchar_t); + cstr_len = tokc.str.size / sizeof(nwchar_t); cstr_len--; nb = cstr_len; - if (n >= 0 && nb > (n - array_length)) - nb = n - array_length; + if (n >= 0 && nb > (n - len)) + nb = n - len; if (!size_only) { if (cstr_len > nb) - warning("initializer-string for array is too long"); + tcc_warning("initializer-string for array is too long"); /* in order to go faster for common case (char string in global variable, we handle it specifically */ if (sec && tok == TOK_STR && size1 == 1) { - memcpy(sec->data + c + array_length, cstr->data, nb); + if (!NODATA_WANTED) + memcpy(sec->data + c + len, tokc.str.data, nb); } else { for(i=0;i<nb;i++) { if (tok == TOK_STR) - ch = ((unsigned char *)cstr->data)[i]; + ch = ((unsigned char *)tokc.str.data)[i]; else - ch = ((nwchar_t *)cstr->data)[i]; - init_putv(t1, sec, c + (array_length + i) * size1, - ch, EXPR_VAL); + ch = ((nwchar_t *)tokc.str.data)[i]; + vpushi(ch); + init_putv(t1, sec, c + (len + i) * size1); } } } - array_length += nb; + len += nb; next(); } /* only add trailing zero if enough storage (no warning in this case since it is standard) */ - if (n < 0 || array_length < n) { + if (n < 0 || len < n) { if (!size_only) { - init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL); + vpushi(0); + init_putv(t1, sec, c + (len * size1)); } - array_length++; + len++; } + len *= size1; } else { - index = 0; - while (tok != '}') { - decl_designator(type, sec, c, &index, NULL, size_only); - if (n >= 0 && index >= n) - error("index too large"); - /* must put zero in holes (note that doing it that way - ensures that it even works with designators) */ - if (!size_only && array_length < index) { - init_putz(t1, sec, c + array_length * size1, - (index - array_length) * size1); - } - index++; - if (index > array_length) - array_length = index; - /* special test for multi dimensional arrays (may not - be strictly correct if designators are used at the - same time) */ - if (index >= n && no_oblock) - break; - if (tok == '}') - break; - skip(','); - } + indexsym.c = 0; + f = &indexsym; + + do_init_list: + len = 0; + while (tok != '}' || have_elem) { + len = decl_designator(type, sec, c, &f, size_only, len); + have_elem = 0; + if (type->t & VT_ARRAY) { + ++indexsym.c; + /* special test for multi dimensional arrays (may not + be strictly correct if designators are used at the + same time) */ + if (no_oblock && len >= n*size1) + break; + } else { + if (s->type.t == VT_UNION) + f = NULL; + else + f = f->next; + if (no_oblock && f == NULL) + break; + } + + if (tok == '}') + break; + skip(','); + } } + /* put zeros at the end */ + if (!size_only && len < n*size1) + init_putz(sec, c + len, n*size1 - len); if (!no_oblock) skip('}'); - /* put zeros at the end */ - if (!size_only && n >= 0 && array_length < n) { - init_putz(t1, sec, c + array_length * size1, - (n - array_length) * size1); - } - /* patch type size if needed */ + /* patch type size if needed, which happens only for array types */ if (n < 0) - s->c = array_length; - } else if ((type->t & VT_BTYPE) == VT_STRUCT && - (sec || !first || tok == '{')) { - int par_count; - - /* NOTE: the previous test is a specific case for automatic - struct/union init */ - /* XXX: union needs only one init */ - - /* XXX: this test is incorrect for local initializers - beginning with ( without {. It would be much more difficult - to do it correctly (ideally, the expression parser should - be used in all cases) */ - par_count = 0; - if (tok == '(') { - AttributeDef ad1; - CType type1; - next(); - while (tok == '(') { - par_count++; - next(); - } - if (!parse_btype(&type1, &ad1)) - expect("cast"); - type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); -#if 0 - if (!is_assignable_types(type, &type1)) - error("invalid type for cast"); -#endif - skip(')'); - } + s->c = size1 == 1 ? len : ((len + size1 - 1)/size1); + } else if ((type->t & VT_BTYPE) == VT_STRUCT) { + size1 = 1; no_oblock = 1; if (first || tok == '{') { skip('{'); @@ -4514,77 +6711,68 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, } s = type->ref; f = s->next; - array_length = 0; - index = 0; n = s->c; - while (tok != '}') { - decl_designator(type, sec, c, NULL, &f, size_only); - index = f->c; - if (!size_only && array_length < index) { - init_putz(type, sec, c + array_length, - index - array_length); - } - index = index + type_size(&f->type, &align1); - if (index > array_length) - array_length = index; - f = f->next; - if (no_oblock && f == NULL) - break; - if (tok == '}') - break; - skip(','); - } - /* put zeros at the end */ - if (!size_only && array_length < n) { - init_putz(type, sec, c + array_length, - n - array_length); - } - if (!no_oblock) - skip('}'); - while (par_count) { - skip(')'); - par_count--; - } + goto do_init_list; } else if (tok == '{') { next(); decl_initializer(type, sec, c, first, size_only); skip('}'); } else if (size_only) { + /* If we supported only ISO C we wouldn't have to accept calling + this on anything than an array size_only==1 (and even then + only on the outermost level, so no recursion would be needed), + because initializing a flex array member isn't supported. + But GNU C supports it, so we need to recurse even into + subfields of structs and arrays when size_only is set. */ /* just skip expression */ - parlevel = 0; - while ((parlevel > 0 || (tok != '}' && tok != ',')) && - tok != -1) { - if (tok == '(') - parlevel++; - else if (tok == ')') - parlevel--; - next(); - } + skip_or_save_block(NULL); } else { - /* currently, we always use constant expression for globals - (may change for scripting case) */ - expr_type = EXPR_CONST; - if (!sec) - expr_type = EXPR_ANY; - init_putv(type, sec, c, 0, expr_type); + if (!have_elem) { + /* This should happen only when we haven't parsed + the init element above for fear of committing a + string constant to memory too early. */ + if (tok != TOK_STR && tok != TOK_LSTR) + expect("string constant"); + parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST); + } + init_putv(type, sec, c); } } /* parse an initializer for type 't' if 'has_init' is non zero, and allocate space in local or global data space ('r' is either VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated - variable 'v' of scope 'scope' is declared before initializers are - parsed. If 'v' is zero, then a reference to the new object is put - in the value stack. If 'has_init' is 2, a special parsing is done - to handle string constants. */ + variable 'v' of scope 'scope' is declared before initializers + are parsed. If 'v' is zero, then a reference to the new object + is put in the value stack. If 'has_init' is 2, a special parsing + is done to handle string constants. */ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope) { - int size, align, addr, data_offset; - int level; - ParseState saved_parse_state = {0}; - TokenString init_str; + int size, align, addr; + TokenString *init_str = NULL; + Section *sec; + Sym *flexible_array; + Sym *sym = NULL; + int saved_nocode_wanted = nocode_wanted; +#ifdef CONFIG_TCC_BCHECK + int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED; +#endif + + if (type->t & VT_STATIC) + nocode_wanted |= NODATA_WANTED ? 0x40000000 : 0x80000000; + + flexible_array = NULL; + if ((type->t & VT_BTYPE) == VT_STRUCT) { + Sym *field = type->ref->next; + if (field) { + while (field->next) + field = field->next; + if (field->type.t & VT_ARRAY && field->type.ref->c < 0) + flexible_array = field; + } + } size = type_size(type, &align); /* If unknown size, we must evaluate it before @@ -4593,96 +6781,99 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, (e.g. string pointers or ISOC99 compound literals). It also simplifies local initializers handling */ - tok_str_new(&init_str); - if (size < 0) { + if (size < 0 || (flexible_array && has_init)) { if (!has_init) - error("unknown type size"); + tcc_error("unknown type size"); /* get all init string */ if (has_init == 2) { + init_str = tok_str_alloc(); /* only get strings */ while (tok == TOK_STR || tok == TOK_LSTR) { - tok_str_add_tok(&init_str); + tok_str_add_tok(init_str); next(); } + tok_str_add(init_str, -1); + tok_str_add(init_str, 0); } else { - level = 0; - while (level > 0 || (tok != ',' && tok != ';')) { - if (tok < 0) - error("unexpected end of file in initializer"); - tok_str_add_tok(&init_str); - if (tok == '{') - level++; - else if (tok == '}') { - level--; - if (level <= 0) { - next(); - break; - } - } - next(); - } + skip_or_save_block(&init_str); } - tok_str_add(&init_str, -1); - tok_str_add(&init_str, 0); - - /* compute size */ - save_parse_state(&saved_parse_state); + unget_tok(0); - macro_ptr = init_str.str; + /* compute size */ + begin_macro(init_str, 1); next(); decl_initializer(type, NULL, 0, 1, 1); /* prepare second initializer parsing */ - macro_ptr = init_str.str; + macro_ptr = init_str->str; next(); /* if still unknown size, error */ size = type_size(type, &align); if (size < 0) - error("unknown type size"); + tcc_error("unknown type size"); } + /* If there's a flex member and it was used in the initializer + adjust size. */ + if (flexible_array && + flexible_array->type.ref->c > 0) + size += flexible_array->type.ref->c + * pointed_size(&flexible_array->type); /* take into account specified alignment if bigger */ - if (ad->aligned) { - if (ad->aligned > align) - align = ad->aligned; - } else if (ad->packed) { + if (ad->a.aligned) { + int speca = 1 << (ad->a.aligned - 1); + if (speca > align) + align = speca; + } else if (ad->a.packed) { align = 1; } + + if (NODATA_WANTED) + size = 0, align = 1; + if ((r & VT_VALMASK) == VT_LOCAL) { sec = NULL; - if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) +#ifdef CONFIG_TCC_BCHECK + if (bcheck && (type->t & VT_ARRAY)) { loc--; + } +#endif loc = (loc - size) & -align; addr = loc; +#ifdef CONFIG_TCC_BCHECK /* handles bounds */ /* XXX: currently, since we do only one pass, we cannot track '&' operators, so we add only arrays */ - if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) { - unsigned long *bounds_ptr; + if (bcheck && (type->t & VT_ARRAY)) { + addr_t *bounds_ptr; /* add padding between regions */ loc--; /* then add local bound info */ - bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long)); + bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t)); bounds_ptr[0] = addr; bounds_ptr[1] = size; } +#endif if (v) { /* local variable */ - sym_push(v, type, r, addr); +#ifdef CONFIG_TCC_ASM + if (ad->asm_label) { + int reg = asm_parse_regvar(ad->asm_label); + if (reg >= 0) + r = (r & ~VT_VALMASK) | reg; + } +#endif + sym = sym_push(v, type, r, addr); + sym->a = ad->a; } else { /* push local reference */ vset(type, r, addr); } } else { - Sym *sym; - - sym = NULL; if (v && scope == VT_CONST) { /* see if the symbol was already defined */ sym = sym_find(v); if (sym) { - if (!is_compatible_types(&sym->type, type)) - error("incompatible types for redefinition of '%s'", - get_tok_str(v, NULL)); + patch_storage(sym, ad, type); if (sym->type.t & VT_EXTERN) { /* if the variable is extern, it was not allocated */ sym->type.t &= ~VT_EXTERN; @@ -4692,16 +6883,17 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, sym->type.ref->c < 0 && type->ref->c >= 0) sym->type.ref->c = type->ref->c; - } else { + } else if (!has_init) { /* we accept several definitions of the same global variable. this is tricky, because we must play with the SHN_COMMON type of the symbol */ - /* XXX: should check if the variable was already - initialized. It is incorrect to initialized it - twice */ /* no init data, we won't add more to the symbol */ - if (!has_init) - goto no_alloc; + goto no_alloc; + } else if (sym->c) { + ElfW(Sym) *esym; + esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; + if (esym->st_shndx == data_section->sh_num) + tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); } } } @@ -4714,294 +6906,296 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, else if (tcc_state->nocommon) sec = bss_section; } + if (sec) { - data_offset = sec->data_offset; - data_offset = (data_offset + align - 1) & -align; - addr = data_offset; - /* very important to increment global pointer at this time - because initializers themselves can create new initializers */ - data_offset += size; + addr = section_add(sec, size, align); +#ifdef CONFIG_TCC_BCHECK /* add padding if bound check */ - if (tcc_state->do_bounds_check) - data_offset++; - sec->data_offset = data_offset; - /* allocate section space to put the data */ - if (sec->sh_type != SHT_NOBITS && - data_offset > sec->data_allocated) - section_realloc(sec, data_offset); - /* align section if needed */ - if (align > sec->sh_addralign) - sec->sh_addralign = align; + if (bcheck) + section_add(sec, 1, 1); +#endif } else { - addr = 0; /* avoid warning */ + addr = align; /* SHN_COMMON is special, symbol value is align */ + sec = common_section; } if (v) { - if (scope != VT_CONST || !sym) { + if (!sym) { sym = sym_push(v, type, r | VT_SYM, 0); + patch_storage(sym, ad, NULL); } + /* Local statics have a scope until now (for + warnings), remove it here. */ + sym->sym_scope = 0; /* update symbol definition */ - if (sec) { - put_extern_sym(sym, sec, addr, size); - } else { - ElfW(Sym) *esym; - /* put a common area */ - put_extern_sym(sym, NULL, align, size); - /* XXX: find a nicer way */ - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - esym->st_shndx = SHN_COMMON; - } + put_extern_sym(sym, sec, addr, size); } else { - CValue cval; - /* push global reference */ sym = get_sym_ref(type, sec, addr, size); - cval.ul = 0; - vsetc(type, VT_CONST | VT_SYM, &cval); - vtop->sym = sym; + vpushsym(type, sym); + vtop->r |= r; } +#ifdef CONFIG_TCC_BCHECK /* handles bounds now because the symbol must be defined before for the relocation */ - if (tcc_state->do_bounds_check) { - unsigned long *bounds_ptr; + if (bcheck) { + addr_t *bounds_ptr; - greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32); + greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0); /* then add global bound info */ - bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long)); + bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t)); bounds_ptr[0] = 0; /* relocated */ bounds_ptr[1] = size; } +#endif } - if (has_init) { - decl_initializer(type, sec, addr, 1, 0); - /* restore parse state if needed */ - if (init_str.str) { - tok_str_free(init_str.str); - restore_parse_state(&saved_parse_state); - } - } - no_alloc: ; -} -void put_func_debug(Sym *sym) -{ - char buf[512]; + if (type->t & VT_VLA) { + int a; - /* stabs info */ - /* XXX: we put here a dummy type */ - snprintf(buf, sizeof(buf), "%s:%c1", - funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); - put_stabs_r(buf, N_FUN, 0, file->line_num, 0, - cur_text_section, sym->c); - /* //gr gdb wants a line at the function */ - put_stabn(N_SLINE, 0, file->line_num, 0); - last_ind = 0; - last_line_num = 0; -} + if (NODATA_WANTED) + goto no_alloc; -/* parse an old style function declaration list */ -/* XXX: check multiple parameter */ -static void func_decl_list(Sym *func_sym) -{ - AttributeDef ad; - int v; - Sym *s; - CType btype, type; - - /* parse each declaration */ - while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) { - if (!parse_btype(&btype, &ad)) - expect("declaration list"); - if (((btype.t & VT_BTYPE) == VT_ENUM || - (btype.t & VT_BTYPE) == VT_STRUCT) && - tok == ';') { - /* we accept no variable after */ - } else { - for(;;) { - type = btype; - type_decl(&type, &ad, &v, TYPE_DIRECT); - /* find parameter in function parameter list */ - s = func_sym->next; - while (s != NULL) { - if ((s->v & ~SYM_FIELD) == v) - goto found; - s = s->next; - } - error("declaration for parameter '%s' but no such parameter", - get_tok_str(v, NULL)); - found: - /* check that no storage specifier except 'register' was given */ - if (type.t & VT_STORAGE) - error("storage class specified for '%s'", get_tok_str(v, NULL)); - convert_parameter_type(&type); - /* we can add the type (NOTE: it could be local to the function) */ - s->type = type; - /* accept other parameters */ - if (tok == ',') - next(); - else - break; - } + /* save current stack pointer */ + if (vlas_in_scope == 0) { + if (vla_sp_root_loc == -1) + vla_sp_root_loc = (loc -= PTR_SIZE); + gen_vla_sp_save(vla_sp_root_loc); } - skip(';'); + + vla_runtime_type_size(type, &a); + gen_vla_alloc(type, a); + gen_vla_sp_save(addr); + vla_sp_loc = addr; + vlas_in_scope++; + + } else if (has_init) { + size_t oldreloc_offset = 0; + if (sec && sec->reloc) + oldreloc_offset = sec->reloc->data_offset; + decl_initializer(type, sec, addr, 1, 0); + if (sec && sec->reloc) + squeeze_multi_relocs(sec, oldreloc_offset); + /* patch flexible array member size back to -1, */ + /* for possible subsequent similar declarations */ + if (flexible_array) + flexible_array->type.ref->c = -1; } + + no_alloc: + /* restore parse state if needed */ + if (init_str) { + end_macro(); + next(); + } + + nocode_wanted = saved_nocode_wanted; } /* parse a function defined by symbol 'sym' and generate its code in 'cur_text_section' */ static void gen_function(Sym *sym) { - int saved_nocode_wanted = nocode_wanted; nocode_wanted = 0; ind = cur_text_section->data_offset; /* NOTE: we patch the symbol size later */ put_extern_sym(sym, cur_text_section, ind, 0); funcname = get_tok_str(sym->v, NULL); func_ind = ind; + /* Initialize VLA state */ + vla_sp_loc = -1; + vla_sp_root_loc = -1; /* put debug symbol */ - if (tcc_state->do_debug) - put_func_debug(sym); + tcc_debug_funcstart(tcc_state, sym); /* push a dummy symbol to enable local sym storage */ sym_push2(&local_stack, SYM_FIELD, 0, 0); + local_scope = 1; /* for function parameters */ gfunc_prolog(&sym->type); + local_scope = 0; rsym = 0; - block(NULL, NULL, NULL, NULL, 0, 0); + block(NULL, NULL, 0); + nocode_wanted = 0; gsym(rsym); gfunc_epilog(); cur_text_section->data_offset = ind; - label_pop(&global_label_stack, NULL); - sym_pop(&local_stack, NULL); /* reset local stack */ + label_pop(&global_label_stack, NULL, 0); + /* reset local stack */ + local_scope = 0; + sym_pop(&local_stack, NULL, 0); /* end of function */ /* patch symbol size */ ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = ind - func_ind; - if (tcc_state->do_debug) { - put_stabn(N_FUN, 0, 0, ind - func_ind); - } + tcc_debug_funcend(tcc_state, ind - func_ind); /* It's better to crash than to generate wrong code */ cur_text_section = NULL; funcname = ""; /* for safety */ func_vt.t = VT_VOID; /* for safety */ + func_var = 0; /* for safety */ ind = 0; /* for safety */ - nocode_wanted = saved_nocode_wanted; + nocode_wanted = 0x80000000; + check_vstack(); } -static void gen_inline_functions(void) +static void gen_inline_functions(TCCState *s) { Sym *sym; - CType *type; - int *str, inline_generated; + int inline_generated, i, ln; + struct InlineFunc *fn; + ln = file->line_num; /* iterate while inline function are referenced */ - for(;;) { + do { inline_generated = 0; - for(sym = global_stack; sym != NULL; sym = sym->prev) { - type = &sym->type; - if (((type->t & VT_BTYPE) == VT_FUNC) && - (type->t & (VT_STATIC | VT_INLINE)) == - (VT_STATIC | VT_INLINE) && - sym->c != 0) { + for (i = 0; i < s->nb_inline_fns; ++i) { + fn = s->inline_fns[i]; + sym = fn->sym; + if (sym && sym->c) { /* the function was used: generate its code and convert it to a normal function */ - str = INLINE_DEF(sym->r); - sym->r = VT_SYM | VT_CONST; + fn->sym = NULL; + if (file) + pstrcpy(file->filename, sizeof file->filename, fn->filename); sym->type.t &= ~VT_INLINE; - macro_ptr = str; + begin_macro(fn->func_str, 1); next(); cur_text_section = text_section; gen_function(sym); - macro_ptr = NULL; /* fail safe */ + end_macro(); - tok_str_free(str); inline_generated = 1; } } - if (!inline_generated) - break; - } + } while (inline_generated); + file->line_num = ln; +} - /* free all remaining inline function tokens */ - for(sym = global_stack; sym != NULL; sym = sym->prev) { - type = &sym->type; - if (((type->t & VT_BTYPE) == VT_FUNC) && - (type->t & (VT_STATIC | VT_INLINE)) == - (VT_STATIC | VT_INLINE)) { - //gr printf("sym %d %s\n", sym->r, get_tok_str(sym->v, NULL)); - if (sym->r == (VT_SYM | VT_CONST)) //gr beware! - continue; - str = INLINE_DEF(sym->r); - tok_str_free(str); - sym->r = 0; /* fail safe */ - } +ST_FUNC void free_inline_functions(TCCState *s) +{ + int i; + /* free tokens of unused inline functions */ + for (i = 0; i < s->nb_inline_fns; ++i) { + struct InlineFunc *fn = s->inline_fns[i]; + if (fn->sym) + tok_str_free(fn->func_str); } + dynarray_reset(&s->inline_fns, &s->nb_inline_fns); } -/* 'l' is VT_LOCAL or VT_CONST to define default storage type */ -static void decl(int l) +/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP + if parsing old style parameter decl list (and FUNC_SYM is set then) */ +static int decl0(int l, int is_for_loop_init, Sym *func_sym) { int v, has_init, r; CType type, btype; Sym *sym; AttributeDef ad; - + while (1) { if (!parse_btype(&btype, &ad)) { - /* skip redundant ';' */ - /* XXX: find more elegant solution */ - if (tok == ';') { + if (is_for_loop_init) + return 0; + /* skip redundant ';' if not in old parameter decl scope */ + if (tok == ';' && l != VT_CMP) { next(); continue; } - if (l == VT_CONST && - (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { + if (l != VT_CONST) + break; + if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { /* global asm block */ asm_global_instr(); continue; } - /* special test for old K&R protos without explicit int - type. Only accepted when defining global data */ - if (l == VT_LOCAL || tok < TOK_DEFINE) + if (tok >= TOK_UIDENT) { + /* special test for old K&R protos without explicit int + type. Only accepted when defining global data */ + btype.t = VT_INT; + } else { + if (tok != TOK_EOF) + expect("declaration"); break; - btype.t = VT_INT; + } } - if (((btype.t & VT_BTYPE) == VT_ENUM || - (btype.t & VT_BTYPE) == VT_STRUCT) && - tok == ';') { - /* we accept no variable after */ - next(); - continue; + if (tok == ';') { + if ((btype.t & VT_BTYPE) == VT_STRUCT) { + int v = btype.ref->v; + if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM) + tcc_warning("unnamed struct/union that defines no instances"); + next(); + continue; + } + if (IS_ENUM(btype.t)) { + next(); + continue; + } } while (1) { /* iterate thru each declaration */ type = btype; + /* If the base type itself was an array type of unspecified + size (like in 'typedef int arr[]; arr x = {1};') then + we will overwrite the unknown size by the real one for + this decl. We need to unshare the ref symbol holding + that size. */ + if ((type.t & VT_ARRAY) && type.ref->c < 0) { + type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c); + } type_decl(&type, &ad, &v, TYPE_DIRECT); #if 0 { char buf[500]; - type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL)); + type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL)); printf("type = '%s'\n", buf); } #endif if ((type.t & VT_BTYPE) == VT_FUNC) { + if ((type.t & VT_STATIC) && (l == VT_LOCAL)) { + tcc_error("function without file scope cannot be static"); + } /* if old style function prototype, we accept a declaration list */ sym = type.ref; - if (sym->c == FUNC_OLD) - func_decl_list(sym); + if (sym->f.func_type == FUNC_OLD && l == VT_CONST) + decl0(VT_CMP, 0, sym); } + if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { + ad.asm_label = asm_label_instr(); + /* parse one last attribute list, after asm label */ + parse_attribute(&ad); + if (tok == '{') + expect(";"); + } + +#ifdef TCC_TARGET_PE + if (ad.a.dllimport || ad.a.dllexport) { + if (type.t & (VT_STATIC|VT_TYPEDEF)) + tcc_error("cannot have dll linkage with static or typedef"); + if (ad.a.dllimport) { + if ((type.t & VT_BTYPE) == VT_FUNC) + ad.a.dllimport = 0; + else + type.t |= VT_EXTERN; + } + } +#endif if (tok == '{') { - if (l == VT_LOCAL) - error("cannot use local functions"); + if (l != VT_CONST) + tcc_error("cannot use local functions"); if ((type.t & VT_BTYPE) != VT_FUNC) expect("function definition"); - /* reject abstract declarators in function definition */ + /* reject abstract declarators in function definition + make old style params without decl have int type */ sym = type.ref; - while ((sym = sym->next) != NULL) + while ((sym = sym->next) != NULL) { if (!(sym->v & ~SYM_FIELD)) - expect("identifier"); + expect("identifier"); + if (sym->type.t == VT_VOID) + sym->type = int_type; + } /* XXX: cannot do better now: convert extern line to static inline */ if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE)) @@ -5009,114 +7203,167 @@ static void decl(int l) sym = sym_find(v); if (sym) { + Sym *ref; if ((sym->type.t & VT_BTYPE) != VT_FUNC) goto func_error1; - /* specific case: if not func_call defined, we put - the one of the prototype */ - /* XXX: should have default value */ - r = sym->type.ref->r; - if (FUNC_CALL(r) != FUNC_CDECL - && FUNC_CALL(type.ref->r) == FUNC_CDECL) - FUNC_CALL(type.ref->r) = FUNC_CALL(r); - if (FUNC_EXPORT(r)) - FUNC_EXPORT(type.ref->r) = 1; + + ref = sym->type.ref; + + /* use func_call from prototype if not defined */ + if (ref->f.func_call != FUNC_CDECL + && type.ref->f.func_call == FUNC_CDECL) + type.ref->f.func_call = ref->f.func_call; + + /* use static from prototype */ + if (sym->type.t & VT_STATIC) + type.t = (type.t & ~VT_EXTERN) | VT_STATIC; + + /* If the definition has no visibility use the + one from prototype. */ + if (!type.ref->a.visibility) + type.ref->a.visibility = ref->a.visibility; + /* apply other storage attributes from prototype */ + type.ref->a.dllexport |= ref->a.dllexport; + type.ref->a.weak |= ref->a.weak; if (!is_compatible_types(&sym->type, &type)) { func_error1: - error("incompatible types for redefinition of '%s'", + tcc_error("incompatible types for redefinition of '%s'", get_tok_str(v, NULL)); } + if (ref->f.func_body) + tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); /* if symbol is already defined, then put complete type */ sym->type = type; + } else { /* put function symbol */ sym = global_identifier_push(v, type.t, 0); sym->type.ref = type.ref; } + sym->type.ref->f.func_body = 1; + sym->r = VT_SYM | VT_CONST; + patch_storage(sym, &ad, NULL); + /* static inline functions are just recorded as a kind of macro. Their code will be emitted at the end of the compilation unit only if they are used */ if ((type.t & (VT_INLINE | VT_STATIC)) == (VT_INLINE | VT_STATIC)) { - TokenString func_str; - int block_level; + struct InlineFunc *fn; + const char *filename; - tok_str_new(&func_str); - - block_level = 0; - for(;;) { - int t; - if (tok == TOK_EOF) - error("unexpected end of file"); - tok_str_add_tok(&func_str); - t = tok; - next(); - if (t == '{') { - block_level++; - } else if (t == '}') { - block_level--; - if (block_level == 0) - break; - } - } - tok_str_add(&func_str, -1); - tok_str_add(&func_str, 0); - INLINE_DEF(sym->r) = func_str.str; + filename = file ? file->filename : ""; + fn = tcc_malloc(sizeof *fn + strlen(filename)); + strcpy(fn->filename, filename); + fn->sym = sym; + skip_or_save_block(&fn->func_str); + dynarray_add(&tcc_state->inline_fns, + &tcc_state->nb_inline_fns, fn); } else { /* compute text section */ cur_text_section = ad.section; if (!cur_text_section) cur_text_section = text_section; - sym->r = VT_SYM | VT_CONST; gen_function(sym); } break; } else { - if (btype.t & VT_TYPEDEF) { + if (l == VT_CMP) { + /* find parameter in function parameter list */ + for (sym = func_sym->next; sym; sym = sym->next) + if ((sym->v & ~SYM_FIELD) == v) + goto found; + tcc_error("declaration for parameter '%s' but no such parameter", + get_tok_str(v, NULL)); +found: + if (type.t & VT_STORAGE) /* 'register' is okay */ + tcc_error("storage class specified for '%s'", + get_tok_str(v, NULL)); + if (sym->type.t != VT_VOID) + tcc_error("redefinition of parameter '%s'", + get_tok_str(v, NULL)); + convert_parameter_type(&type); + sym->type = type; + } else if (type.t & VT_TYPEDEF) { /* save typedefed type */ /* XXX: test storage specifiers ? */ - sym = sym_push(v, &type, 0, 0); - sym->type.t |= VT_TYPEDEF; - } else if ((type.t & VT_BTYPE) == VT_FUNC) { - /* external function definition */ - /* specific case for func_call attribute */ - if (ad.func_attr) - type.ref->r = ad.func_attr; - external_sym(v, &type, 0); + sym = sym_find(v); + if (sym && sym->sym_scope == local_scope) { + if (!is_compatible_types(&sym->type, &type) + || !(sym->type.t & VT_TYPEDEF)) + tcc_error("incompatible redefinition of '%s'", + get_tok_str(v, NULL)); + sym->type = type; + } else { + sym = sym_push(v, &type, 0, 0); + } + sym->a = ad.a; + sym->f = ad.f; } else { - /* not lvalue if array */ r = 0; - if (!(type.t & VT_ARRAY)) + if ((type.t & VT_BTYPE) == VT_FUNC) { + /* external function definition */ + /* specific case for func_call attribute */ + type.ref->f = ad.f; + } else if (!(type.t & VT_ARRAY)) { + /* not lvalue if array */ r |= lvalue_type(type.t); + } has_init = (tok == '='); - if ((btype.t & VT_EXTERN) || + if (has_init && (type.t & VT_VLA)) + tcc_error("variable length array cannot be initialized"); + if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) || + ((type.t & VT_BTYPE) == VT_FUNC) || ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && !has_init && l == VT_CONST && type.ref->c < 0)) { - /* external variable */ + /* external variable or function */ /* NOTE: as GCC, uninitialized global static arrays of null size are considered as extern */ - external_sym(v, &type, r); + sym = external_sym(v, &type, r, &ad); + if (ad.alias_target) { + Section tsec; + ElfW(Sym) *esym; + Sym *alias_target; + alias_target = sym_find(ad.alias_target); + if (!alias_target || !alias_target->c) + tcc_error("unsupported forward __alias__ attribute"); + esym = &((ElfW(Sym) *)symtab_section->data)[alias_target->c]; + tsec.sh_num = esym->st_shndx; + /* Local statics have a scope until now (for + warnings), remove it here. */ + sym->sym_scope = 0; + put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0); + } } else { - type.t |= (btype.t & VT_STATIC); /* Retain "static". */ if (type.t & VT_STATIC) r |= VT_CONST; else r |= l; if (has_init) next(); - decl_initializer_alloc(&type, &ad, r, - has_init, v, l); + decl_initializer_alloc(&type, &ad, r, has_init, v, l); } } if (tok != ',') { + if (is_for_loop_init) + return 1; skip(';'); break; } next(); } + ad.a.aligned = 0; } } + return 0; +} + +static void decl(int l) +{ + decl0(l, 0, NULL); } +/* ------------------------------------------------------------------------- */ diff --git a/tinyc/include/tcclib.h b/tinyc/tcclib.h index 42f8f3f57..8d59e4c9a 100644 --- a/tinyc/include/tcclib.h +++ b/tinyc/tcclib.h @@ -39,6 +39,7 @@ int getchar(void); char *gets(char *s); int ungetc(int c, FILE *stream); int fflush(FILE *stream); +int putchar (int c); int printf(const char *format, ...); int fprintf(FILE *stream, const char *format, ...); @@ -64,6 +65,7 @@ void *memcpy(void *dest, const void *src, size_t n); void *memmove(void *dest, const void *src, size_t n); void *memset(void *s, int c, size_t n); char *strdup(const char *s); +size_t strlen(const char *s); /* dlfcn.h */ #define RTLD_LAZY 0x001 diff --git a/tinyc/tccpe.c b/tinyc/tccpe.c index 1e3fdb369..a67023dd2 100644 --- a/tinyc/tccpe.c +++ b/tinyc/tccpe.c @@ -18,32 +18,54 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef TCC_TARGET_PE +#include "tcc.h" -#define ST_FN static -#define ST_DATA static -#define PUB_FN +#define PE_MERGE_DATA +/* #define PE_PRINT_SECTIONS */ #ifndef _WIN32 #define stricmp strcasecmp #define strnicmp strncasecmp +#include <sys/stat.h> /* chmod() */ #endif -#ifndef MAX_PATH -#define MAX_PATH 260 -#endif +#ifdef TCC_TARGET_X86_64 +# define ADDR3264 ULONGLONG +# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64 +# define REL_TYPE_DIRECT R_X86_64_64 +# define R_XXX_THUNKFIX R_X86_64_PC32 +# define R_XXX_RELATIVE R_X86_64_RELATIVE +# define IMAGE_FILE_MACHINE 0x8664 +# define RSRC_RELTYPE 3 + +#elif defined TCC_TARGET_ARM +# define ADDR3264 DWORD +# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW +# define REL_TYPE_DIRECT R_ARM_ABS32 +# define R_XXX_THUNKFIX R_ARM_ABS32 +# define R_XXX_RELATIVE R_ARM_RELATIVE +# define IMAGE_FILE_MACHINE 0x01C0 +# define RSRC_RELTYPE 7 /* ??? (not tested) */ + +#elif defined TCC_TARGET_I386 +# define ADDR3264 DWORD +# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW +# define REL_TYPE_DIRECT R_386_32 +# define R_XXX_THUNKFIX R_386_32 +# define R_XXX_RELATIVE R_386_RELATIVE +# define IMAGE_FILE_MACHINE 0x014C +# define RSRC_RELTYPE 7 /* DIR32NB */ -#define PE_MERGE_DATA -// #define PE_PRINT_SECTIONS +#endif -/* ----------------------------------------------------------- */ #ifndef IMAGE_NT_SIGNATURE /* ----------------------------------------------------------- */ /* definitions below are from winnt.h */ typedef unsigned char BYTE; typedef unsigned short WORD; -typedef unsigned long DWORD; +typedef unsigned int DWORD; +typedef unsigned long long ULONGLONG; #pragma pack(push, 1) typedef struct _IMAGE_DOS_HEADER { /* DOS .EXE header */ @@ -100,10 +122,11 @@ typedef struct _IMAGE_OPTIONAL_HEADER { DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; +#ifndef TCC_TARGET_X86_64 DWORD BaseOfData; - +#endif /* NT additional fields. */ - DWORD ImageBase; + ADDR3264 ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; @@ -118,16 +141,14 @@ typedef struct _IMAGE_OPTIONAL_HEADER { DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; + ADDR3264 SizeOfStackReserve; + ADDR3264 SizeOfStackCommit; + ADDR3264 SizeOfHeapReserve; + ADDR3264 SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[16]; - -} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; - +} IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, IMAGE_OPTIONAL_HEADER; #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 /* Export Directory */ #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 /* Import Directory */ @@ -167,6 +188,31 @@ typedef struct _IMAGE_SECTION_HEADER { #define IMAGE_SIZEOF_SECTION_HEADER 40 +typedef struct _IMAGE_EXPORT_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + DWORD AddressOfFunctions; + DWORD AddressOfNames; + DWORD AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + union { + DWORD Characteristics; + DWORD OriginalFirstThunk; + }; + DWORD TimeDateStamp; + DWORD ForwarderChain; + DWORD Name; + DWORD FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR; + typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; @@ -183,6 +229,7 @@ typedef struct _IMAGE_BASE_RELOCATION { #define IMAGE_REL_BASED_MIPS_JMPADDR 5 #define IMAGE_REL_BASED_SECTION 6 #define IMAGE_REL_BASED_REL32 7 +#define IMAGE_REL_BASED_DIR64 10 #pragma pack(pop) @@ -190,36 +237,26 @@ typedef struct _IMAGE_BASE_RELOCATION { #endif /* ndef IMAGE_NT_SIGNATURE */ /* ----------------------------------------------------------- */ -#pragma pack(push, 1) +#ifndef IMAGE_REL_BASED_DIR64 +# define IMAGE_REL_BASED_DIR64 10 +#endif +#pragma pack(push, 1) struct pe_header { IMAGE_DOS_HEADER doshdr; BYTE dosstub[0x40]; DWORD nt_sig; IMAGE_FILE_HEADER filehdr; +#ifdef TCC_TARGET_X86_64 + IMAGE_OPTIONAL_HEADER64 opthdr; +#else +#ifdef _WIN64 + IMAGE_OPTIONAL_HEADER32 opthdr; +#else IMAGE_OPTIONAL_HEADER opthdr; -}; - -struct pe_import_header { - DWORD first_entry; - DWORD time_date; - DWORD forwarder; - DWORD lib_name_offset; - DWORD first_thunk; -}; - -struct pe_export_header { - DWORD Characteristics; - DWORD TimeDateStamp; - DWORD Version; - DWORD Name; - DWORD Base; - DWORD NumberOfFunctions; - DWORD NumberOfNames; - DWORD AddressOfFunctions; - DWORD AddressOfNames; - DWORD AddressOfNameOrdinals; +#endif +#endif }; struct pe_reloc_header { @@ -237,93 +274,8 @@ struct pe_rsrc_reloc { DWORD size; WORD type; }; - #pragma pack(pop) -/* ----------------------------------------------------------- */ -ST_DATA struct pe_header pe_header = { -{ - /* IMAGE_DOS_HEADER doshdr */ - 0x5A4D, /*WORD e_magic; Magic number */ - 0x0090, /*WORD e_cblp; Bytes on last page of file */ - 0x0003, /*WORD e_cp; Pages in file */ - 0x0000, /*WORD e_crlc; Relocations */ - - 0x0004, /*WORD e_cparhdr; Size of header in paragraphs */ - 0x0000, /*WORD e_minalloc; Minimum extra paragraphs needed */ - 0xFFFF, /*WORD e_maxalloc; Maximum extra paragraphs needed */ - 0x0000, /*WORD e_ss; Initial (relative) SS value */ - - 0x00B8, /*WORD e_sp; Initial SP value */ - 0x0000, /*WORD e_csum; Checksum */ - 0x0000, /*WORD e_ip; Initial IP value */ - 0x0000, /*WORD e_cs; Initial (relative) CS value */ - 0x0040, /*WORD e_lfarlc; File address of relocation table */ - 0x0000, /*WORD e_ovno; Overlay number */ - {0,0,0,0}, /*WORD e_res[4]; Reserved words */ - 0x0000, /*WORD e_oemid; OEM identifier (for e_oeminfo) */ - 0x0000, /*WORD e_oeminfo; OEM information; e_oemid specific */ - {0,0,0,0,0,0,0,0,0,0}, /*WORD e_res2[10]; Reserved words */ - 0x00000080 /*DWORD e_lfanew; File address of new exe header */ -},{ - /* BYTE dosstub[0x40] */ - /* 14 code bytes + "This program cannot be run in DOS mode.\r\r\n$" + 6 * 0x00 */ - 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68, - 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f, - 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20, - 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -}, - 0x00004550, /* DWORD nt_sig = IMAGE_NT_SIGNATURE */ -{ - /* IMAGE_FILE_HEADER filehdr */ - 0x014C, /*WORD Machine; */ - 0x0003, /*WORD NumberOfSections; */ - 0x00000000, /*DWORD TimeDateStamp; */ - 0x00000000, /*DWORD PointerToSymbolTable; */ - 0x00000000, /*DWORD NumberOfSymbols; */ - 0x00E0, /*WORD SizeOfOptionalHeader; */ - 0x030F /*WORD Characteristics; */ -},{ - /* IMAGE_OPTIONAL_HEADER opthdr */ - /* Standard fields. */ - 0x010B, /*WORD Magic; */ - 0x06, /*BYTE MajorLinkerVersion; */ - 0x00, /*BYTE MinorLinkerVersion; */ - 0x00000000, /*DWORD SizeOfCode; */ - 0x00000000, /*DWORD SizeOfInitializedData; */ - 0x00000000, /*DWORD SizeOfUninitializedData; */ - 0x00000000, /*DWORD AddressOfEntryPoint; */ - 0x00000000, /*DWORD BaseOfCode; */ - 0x00000000, /*DWORD BaseOfData; */ - - /* NT additional fields. */ - 0x00400000, /*DWORD ImageBase; */ - 0x00001000, /*DWORD SectionAlignment; */ - 0x00000200, /*DWORD FileAlignment; */ - 0x0004, /*WORD MajorOperatingSystemVersion; */ - 0x0000, /*WORD MinorOperatingSystemVersion; */ - 0x0000, /*WORD MajorImageVersion; */ - 0x0000, /*WORD MinorImageVersion; */ - 0x0004, /*WORD MajorSubsystemVersion; */ - 0x0000, /*WORD MinorSubsystemVersion; */ - 0x00000000, /*DWORD Win32VersionValue; */ - 0x00000000, /*DWORD SizeOfImage; */ - 0x00000200, /*DWORD SizeOfHeaders; */ - 0x00000000, /*DWORD CheckSum; */ - 0x0002, /*WORD Subsystem; */ - 0x0000, /*WORD DllCharacteristics; */ - 0x00100000, /*DWORD SizeOfStackReserve; */ - 0x00001000, /*DWORD SizeOfStackCommit; */ - 0x00100000, /*DWORD SizeOfHeapReserve; */ - 0x00001000, /*DWORD SizeOfHeapCommit; */ - 0x00000000, /*DWORD LoaderFlags; */ - 0x00000010, /*DWORD NumberOfRvaAndSizes; */ - - /* IMAGE_DATA_DIRECTORY DataDirectory[16]; */ - {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, - {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}} -}}; - /* ------------------------------------------------------------- */ /* internal temporary structures */ @@ -343,6 +295,7 @@ enum { sec_data , sec_bss , sec_idata , + sec_pdata , sec_other , sec_rsrc , sec_stab , @@ -350,11 +303,12 @@ enum { sec_last }; -ST_DATA DWORD pe_sec_flags[] = { +static const DWORD pe_sec_flags[] = { 0x60000020, /* ".text" , */ 0xC0000040, /* ".data" , */ 0xC0000080, /* ".bss" , */ 0x40000040, /* ".idata" , */ + 0x40000040, /* ".pdata" , */ 0xE0000060, /* < other > , */ 0x40000040, /* ".rsrc" , */ 0x42000802, /* ".stab" , */ @@ -391,7 +345,8 @@ struct pe_info { const char *filename; int type; DWORD sizeofheaders; - DWORD imagebase; + ADDR3264 imagebase; + const char *start_symbol; DWORD start_addr; DWORD imp_offs; DWORD imp_size; @@ -399,113 +354,74 @@ struct pe_info { DWORD iat_size; DWORD exp_offs; DWORD exp_size; + int subsystem; + DWORD section_align; + DWORD file_align; struct section_info *sec_info; int sec_count; struct pe_import_info **imp_info; int imp_count; }; -/* ------------------------------------------------------------- */ - #define PE_NUL 0 #define PE_DLL 1 #define PE_GUI 2 #define PE_EXE 3 - -void error_noabort(const char *, ...); - -#ifdef _WIN32 -void dbg_printf (const char *fmt, ...) -{ - char buffer[4000]; - va_list arg; - int x; - va_start(arg, fmt); - x = vsprintf (buffer, fmt, arg); - strcpy(buffer+x, "\n"); - OutputDebugString(buffer); -} -#endif +#define PE_RUN 4 /* --------------------------------------------*/ -ST_FN const char* get_alt_symbol(char *buffer, const char *symbol) +static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym) { - const char *p; - p = strrchr(symbol, '@'); - if (p && isnum(p[1]) && symbol[0] == '_') { /* stdcall decor */ - strcpy(buffer, symbol+1)[p-symbol-1] = 0; - } else if (symbol[0] != '_') { /* try non-ansi function */ - buffer[0] = '_', strcpy(buffer + 1, symbol); - } else if (0 == memcmp(symbol, "__imp__", 7)) { /* mingw 2.0 */ - strcpy(buffer, symbol + 6); - } else if (0 == memcmp(symbol, "_imp___", 7)) { /* mingw 3.7 */ - strcpy(buffer, symbol + 6); - } else { - return symbol; - } - return buffer; + const char *name = (char*)symtab_section->link->data + sym->st_name; + if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & ST_PE_STDCALL)) + return name + 1; + return name; } -ST_FN int pe_find_import(TCCState * s1, const char *symbol) +static int pe_find_import(TCCState * s1, ElfW(Sym) *sym) { char buffer[200]; - const char *s; - int sym_index, n = 0; + const char *s, *p; + int sym_index = 0, n = 0; + int a, err = 0; + do { - s = n ? get_alt_symbol(buffer, symbol) : symbol; + s = pe_export_name(s1, sym); + a = 0; + if (n) { + /* second try: */ + if (sym->st_other & ST_PE_STDCALL) { + /* try w/0 stdcall deco (windows API convention) */ + p = strrchr(s, '@'); + if (!p || s[0] != '_') + break; + strcpy(buffer, s+1)[p-s-1] = 0; + } else if (s[0] != '_') { /* try non-ansi function */ + buffer[0] = '_', strcpy(buffer + 1, s); + } else if (0 == memcmp(s, "__imp_", 6)) { /* mingw 2.0 */ + strcpy(buffer, s + 6), a = 1; + } else if (0 == memcmp(s, "_imp__", 6)) { /* mingw 3.7 */ + strcpy(buffer, s + 6), a = 1; + } else { + continue; + } + s = buffer; + } sym_index = find_elf_sym(s1->dynsymtab_section, s); - // printf("find %d %s\n", sym_index, s); + // printf("find (%d) %d %s\n", n, sym_index, s); + if (sym_index + && ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT + && 0 == (sym->st_other & ST_PE_IMPORT) + && 0 == a + ) err = -1, sym_index = 0; } while (0 == sym_index && ++n < 2); - return sym_index; -} - -#if defined _WIN32 || defined __CYGWIN__ - -#ifdef __CYGWIN__ -# include <dlfcn.h> -# define LoadLibrary(s) dlopen(s, RTLD_NOW) -# define GetProcAddress(h,s) dlsym(h, s) -#else -# define dlclose(h) FreeLibrary(h) -#endif - -/* for the -run option: dynamically load symbol from dll */ -void *resolve_sym(struct TCCState *s1, const char *symbol, int type) -{ - char buffer[100]; - int sym_index, dll_index; - void *addr, **m; - DLLReference *dllref; - - sym_index = pe_find_import(s1, symbol); - if (0 == sym_index) - return NULL; - dll_index = ((Elf32_Sym *)s1->dynsymtab_section->data + sym_index)->st_value; - dllref = s1->loaded_dlls[dll_index-1]; - if ( !dllref->handle ) - { - dllref->handle = LoadLibrary(dllref->name); - } - addr = GetProcAddress(dllref->handle, symbol); - if (NULL == addr) - addr = GetProcAddress(dllref->handle, get_alt_symbol(buffer, symbol)); - - if (addr && STT_OBJECT == type) { - /* need to return a pointer to the address for data objects */ - m = (void**)tcc_malloc(sizeof addr), *m = addr, addr = m; -#ifdef MEM_DEBUG - /* yep, we don't free it */ - mem_cur_size -= sizeof (void*); -#endif - } - return addr; + return n == 2 ? err : sym_index; } -#endif /*----------------------------------------------------------------------------*/ -ST_FN int dynarray_assoc(void **pp, int n, int key) +static int dynarray_assoc(void **pp, int n, int key) { int i; for (i = 0; i < n; ++i, ++pp) @@ -521,96 +437,224 @@ ST_FN DWORD umin(DWORD a, DWORD b) } #endif -ST_FN DWORD umax(DWORD a, DWORD b) +static DWORD umax(DWORD a, DWORD b) { return a < b ? b : a; } -ST_FN void pe_fpad(FILE *fp, DWORD new_pos) +static DWORD pe_file_align(struct pe_info *pe, DWORD n) { - DWORD pos = ftell(fp); - while (++pos <= new_pos) - fputc(0, fp); + return (n + (pe->file_align - 1)) & ~(pe->file_align - 1); } -ST_FN DWORD pe_file_align(DWORD n) +static DWORD pe_virtual_align(struct pe_info *pe, DWORD n) { - return (n + (0x200 - 1)) & ~(0x200 - 1); + return (n + (pe->section_align - 1)) & ~(pe->section_align - 1); } -ST_FN DWORD pe_virtual_align(DWORD n) -{ - return (n + (0x1000 - 1)) & ~(0x1000 - 1); -} - -ST_FN void pe_align_section(Section *s, int a) +static void pe_align_section(Section *s, int a) { int i = s->data_offset & (a-1); if (i) section_ptr_add(s, a - i); } -ST_FN void pe_set_datadir(int dir, DWORD addr, DWORD size) +static void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size) +{ + hdr->opthdr.DataDirectory[dir].VirtualAddress = addr; + hdr->opthdr.DataDirectory[dir].Size = size; +} + +static int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum) +{ + if (psum) { + DWORD sum = *psum; + WORD *p = data; + int i; + for (i = len; i > 0; i -= 2) { + sum += (i >= 2) ? *p++ : *(BYTE*)p; + sum = (sum + (sum >> 16)) & 0xFFFF; + } + *psum = sum; + } + return len == fwrite(data, 1, len, fp) ? 0 : -1; +} + +static void pe_fpad(FILE *fp, DWORD new_pos) { - pe_header.opthdr.DataDirectory[dir].VirtualAddress = addr; - pe_header.opthdr.DataDirectory[dir].Size = size; + DWORD pos = ftell(fp); + while (++pos <= new_pos) + fputc(0, fp); } /*----------------------------------------------------------------------------*/ -ST_FN int pe_write(struct pe_info *pe) +static int pe_write(struct pe_info *pe) { + static const struct pe_header pe_template = { + { + /* IMAGE_DOS_HEADER doshdr */ + 0x5A4D, /*WORD e_magic; Magic number */ + 0x0090, /*WORD e_cblp; Bytes on last page of file */ + 0x0003, /*WORD e_cp; Pages in file */ + 0x0000, /*WORD e_crlc; Relocations */ + + 0x0004, /*WORD e_cparhdr; Size of header in paragraphs */ + 0x0000, /*WORD e_minalloc; Minimum extra paragraphs needed */ + 0xFFFF, /*WORD e_maxalloc; Maximum extra paragraphs needed */ + 0x0000, /*WORD e_ss; Initial (relative) SS value */ + + 0x00B8, /*WORD e_sp; Initial SP value */ + 0x0000, /*WORD e_csum; Checksum */ + 0x0000, /*WORD e_ip; Initial IP value */ + 0x0000, /*WORD e_cs; Initial (relative) CS value */ + 0x0040, /*WORD e_lfarlc; File address of relocation table */ + 0x0000, /*WORD e_ovno; Overlay number */ + {0,0,0,0}, /*WORD e_res[4]; Reserved words */ + 0x0000, /*WORD e_oemid; OEM identifier (for e_oeminfo) */ + 0x0000, /*WORD e_oeminfo; OEM information; e_oemid specific */ + {0,0,0,0,0,0,0,0,0,0}, /*WORD e_res2[10]; Reserved words */ + 0x00000080 /*DWORD e_lfanew; File address of new exe header */ + },{ + /* BYTE dosstub[0x40] */ + /* 14 code bytes + "This program cannot be run in DOS mode.\r\r\n$" + 6 * 0x00 */ + 0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68, + 0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f, + 0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20, + 0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }, + 0x00004550, /* DWORD nt_sig = IMAGE_NT_SIGNATURE */ + { + /* IMAGE_FILE_HEADER filehdr */ + IMAGE_FILE_MACHINE, /*WORD Machine; */ + 0x0003, /*WORD NumberOfSections; */ + 0x00000000, /*DWORD TimeDateStamp; */ + 0x00000000, /*DWORD PointerToSymbolTable; */ + 0x00000000, /*DWORD NumberOfSymbols; */ +#if defined(TCC_TARGET_X86_64) + 0x00F0, /*WORD SizeOfOptionalHeader; */ + 0x022F /*WORD Characteristics; */ +#define CHARACTERISTICS_DLL 0x222E +#elif defined(TCC_TARGET_I386) + 0x00E0, /*WORD SizeOfOptionalHeader; */ + 0x030F /*WORD Characteristics; */ +#define CHARACTERISTICS_DLL 0x230E +#elif defined(TCC_TARGET_ARM) + 0x00E0, /*WORD SizeOfOptionalHeader; */ + 0x010F, /*WORD Characteristics; */ +#define CHARACTERISTICS_DLL 0x230F +#endif +},{ + /* IMAGE_OPTIONAL_HEADER opthdr */ + /* Standard fields. */ +#ifdef TCC_TARGET_X86_64 + 0x020B, /*WORD Magic; */ +#else + 0x010B, /*WORD Magic; */ +#endif + 0x06, /*BYTE MajorLinkerVersion; */ + 0x00, /*BYTE MinorLinkerVersion; */ + 0x00000000, /*DWORD SizeOfCode; */ + 0x00000000, /*DWORD SizeOfInitializedData; */ + 0x00000000, /*DWORD SizeOfUninitializedData; */ + 0x00000000, /*DWORD AddressOfEntryPoint; */ + 0x00000000, /*DWORD BaseOfCode; */ +#ifndef TCC_TARGET_X86_64 + 0x00000000, /*DWORD BaseOfData; */ +#endif + /* NT additional fields. */ +#if defined(TCC_TARGET_ARM) + 0x00100000, /*DWORD ImageBase; */ +#else + 0x00400000, /*DWORD ImageBase; */ +#endif + 0x00001000, /*DWORD SectionAlignment; */ + 0x00000200, /*DWORD FileAlignment; */ + 0x0004, /*WORD MajorOperatingSystemVersion; */ + 0x0000, /*WORD MinorOperatingSystemVersion; */ + 0x0000, /*WORD MajorImageVersion; */ + 0x0000, /*WORD MinorImageVersion; */ + 0x0004, /*WORD MajorSubsystemVersion; */ + 0x0000, /*WORD MinorSubsystemVersion; */ + 0x00000000, /*DWORD Win32VersionValue; */ + 0x00000000, /*DWORD SizeOfImage; */ + 0x00000200, /*DWORD SizeOfHeaders; */ + 0x00000000, /*DWORD CheckSum; */ + 0x0002, /*WORD Subsystem; */ + 0x0000, /*WORD DllCharacteristics; */ + 0x00100000, /*DWORD SizeOfStackReserve; */ + 0x00001000, /*DWORD SizeOfStackCommit; */ + 0x00100000, /*DWORD SizeOfHeapReserve; */ + 0x00001000, /*DWORD SizeOfHeapCommit; */ + 0x00000000, /*DWORD LoaderFlags; */ + 0x00000010, /*DWORD NumberOfRvaAndSizes; */ + + /* IMAGE_DATA_DIRECTORY DataDirectory[16]; */ + {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}} + }}; + + struct pe_header pe_header = pe_template; + int i; FILE *op; - DWORD file_offset, r; + DWORD file_offset, sum; + struct section_info *si; + IMAGE_SECTION_HEADER *psh; op = fopen(pe->filename, "wb"); if (NULL == op) { - error_noabort("could not write '%s': %s", pe->filename, strerror(errno)); - return 1; + tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno)); + return -1; } - pe->sizeofheaders = pe_file_align( - sizeof pe_header + pe->sizeofheaders = pe_file_align(pe, + sizeof (struct pe_header) + pe->sec_count * sizeof (IMAGE_SECTION_HEADER) ); file_offset = pe->sizeofheaders; - pe_fpad(op, file_offset); if (2 == pe->s1->verbose) printf("-------------------------------" "\n virt file size section" "\n"); - for (i = 0; i < pe->sec_count; ++i) { - struct section_info *si = pe->sec_info + i; - const char *sh_name = si->name; - unsigned long addr = si->sh_addr - pe->imagebase; - unsigned long size = si->sh_size; - IMAGE_SECTION_HEADER *psh = &si->ish; + DWORD addr, size; + const char *sh_name; + + si = pe->sec_info + i; + sh_name = si->name; + addr = si->sh_addr - pe->imagebase; + size = si->sh_size; + psh = &si->ish; if (2 == pe->s1->verbose) - printf("%6lx %6lx %6lx %s\n", - addr, file_offset, size, sh_name); + printf("%6x %6x %6x %s\n", + (unsigned)addr, (unsigned)file_offset, (unsigned)size, sh_name); switch (si->cls) { case sec_text: pe_header.opthdr.BaseOfCode = addr; - pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr; break; case sec_data: +#ifndef TCC_TARGET_X86_64 pe_header.opthdr.BaseOfData = addr; +#endif break; case sec_bss: break; case sec_reloc: - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size); + pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size); break; case sec_rsrc: - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size); + pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size); + break; + + case sec_pdata: + pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXCEPTION, addr, size); break; case sec_stab: @@ -619,69 +663,91 @@ ST_FN int pe_write(struct pe_info *pe) if (pe->thunk == pe->s1->sections[si->ord]) { if (pe->imp_size) { - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IMPORT, + pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IMPORT, pe->imp_offs + addr, pe->imp_size); - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IAT, + pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IAT, pe->iat_offs + addr, pe->iat_size); } if (pe->exp_size) { - pe_set_datadir(IMAGE_DIRECTORY_ENTRY_EXPORT, + pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXPORT, pe->exp_offs + addr, pe->exp_size); } } - strcpy((char*)psh->Name, sh_name); + strncpy((char*)psh->Name, sh_name, sizeof psh->Name); psh->Characteristics = pe_sec_flags[si->cls]; psh->VirtualAddress = addr; psh->Misc.VirtualSize = size; pe_header.opthdr.SizeOfImage = - umax(pe_virtual_align(size + addr), pe_header.opthdr.SizeOfImage); + umax(pe_virtual_align(pe, size + addr), pe_header.opthdr.SizeOfImage); if (si->data_size) { - psh->PointerToRawData = r = file_offset; - fwrite(si->data, 1, si->data_size, op); - file_offset = pe_file_align(file_offset + si->data_size); - psh->SizeOfRawData = file_offset - r; - pe_fpad(op, file_offset); + psh->PointerToRawData = file_offset; + file_offset = pe_file_align(pe, file_offset + si->data_size); + psh->SizeOfRawData = file_offset - psh->PointerToRawData; + if (si->cls == sec_text) + pe_header.opthdr.SizeOfCode += psh->SizeOfRawData; + else + pe_header.opthdr.SizeOfInitializedData += psh->SizeOfRawData; } } - // pe_header.filehdr.TimeDateStamp = time(NULL); + //pe_header.filehdr.TimeDateStamp = time(NULL); pe_header.filehdr.NumberOfSections = pe->sec_count; + pe_header.opthdr.AddressOfEntryPoint = pe->start_addr; pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders; pe_header.opthdr.ImageBase = pe->imagebase; + pe_header.opthdr.Subsystem = pe->subsystem; + if (pe->s1->pe_stack_size) + pe_header.opthdr.SizeOfStackReserve = pe->s1->pe_stack_size; if (PE_DLL == pe->type) - pe_header.filehdr.Characteristics = 0x230E; - else if (PE_GUI != pe->type) - pe_header.opthdr.Subsystem = 3; + pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL; + pe_header.filehdr.Characteristics |= pe->s1->pe_characteristics; - fseek(op, SEEK_SET, 0); - fwrite(&pe_header, 1, sizeof pe_header, op); + sum = 0; + pe_fwrite(&pe_header, sizeof pe_header, op, &sum); for (i = 0; i < pe->sec_count; ++i) - fwrite(&pe->sec_info[i].ish, 1, sizeof(IMAGE_SECTION_HEADER), op); + pe_fwrite(&pe->sec_info[i].ish, sizeof(IMAGE_SECTION_HEADER), op, &sum); + pe_fpad(op, pe->sizeofheaders); + for (i = 0; i < pe->sec_count; ++i) { + si = pe->sec_info + i; + psh = &si->ish; + if (si->data_size) { + pe_fwrite(si->data, si->data_size, op, &sum); + file_offset = psh->PointerToRawData + psh->SizeOfRawData; + pe_fpad(op, file_offset); + } + } + + pe_header.opthdr.CheckSum = sum + file_offset; + fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET); + pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL); fclose (op); +#ifndef _WIN32 + chmod(pe->filename, 0777); +#endif if (2 == pe->s1->verbose) printf("-------------------------------\n"); if (pe->s1->verbose) - printf("<- %s (%lu bytes)\n", pe->filename, file_offset); + printf("<- %s (%u bytes)\n", pe->filename, (unsigned)file_offset); return 0; } /*----------------------------------------------------------------------------*/ -ST_FN struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index) +static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index) { int i; int dll_index; struct pe_import_info *p; struct import_symbol *s; + ElfW(Sym) *isym; - dll_index = ((Elf32_Sym *)pe->s1->dynsymtab_section->data + sym_index)->st_value; - if (0 == dll_index) - return NULL; + isym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index; + dll_index = isym->st_size; i = dynarray_assoc ((void**)pe->imp_info, pe->imp_count, dll_index); if (-1 != i) { @@ -690,7 +756,7 @@ ST_FN struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index) } p = tcc_mallocz(sizeof *p); p->dll_index = dll_index; - dynarray_add((void***)&pe->imp_info, &pe->imp_count, p); + dynarray_add(&pe->imp_info, &pe->imp_count, p); found_dll: i = dynarray_assoc ((void**)p->symbols, p->sym_count, sym_index); @@ -698,13 +764,23 @@ found_dll: return p->symbols[i]; s = tcc_mallocz(sizeof *s); - dynarray_add((void***)&p->symbols, &p->sym_count, s); + dynarray_add(&p->symbols, &p->sym_count, s); s->sym_index = sym_index; return s; } +void pe_free_imports(struct pe_info *pe) +{ + int i; + for (i = 0; i < pe->imp_count; ++i) { + struct pe_import_info *p = pe->imp_info[i]; + dynarray_reset(&p->symbols, &p->sym_count); + } + dynarray_reset(&pe->imp_info, &pe->imp_count); +} + /*----------------------------------------------------------------------------*/ -ST_FN void pe_build_imports(struct pe_info *pe) +static void pe_build_imports(struct pe_info *pe) { int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i; DWORD rva_base = pe->thunk->sh_addr - pe->imagebase; @@ -719,122 +795,146 @@ ST_FN void pe_build_imports(struct pe_info *pe) pe_align_section(pe->thunk, 16); pe->imp_offs = dll_ptr = pe->thunk->data_offset; - pe->imp_size = (ndlls + 1) * sizeof(struct pe_import_header); + pe->imp_size = (ndlls + 1) * sizeof(IMAGE_IMPORT_DESCRIPTOR); pe->iat_offs = dll_ptr + pe->imp_size; - pe->iat_size = (sym_cnt + ndlls) * sizeof(DWORD); + pe->iat_size = (sym_cnt + ndlls) * sizeof(ADDR3264); section_ptr_add(pe->thunk, pe->imp_size + 2*pe->iat_size); thk_ptr = pe->iat_offs; ent_ptr = pe->iat_offs + pe->iat_size; for (i = 0; i < pe->imp_count; ++i) { - struct pe_import_header *hdr; - int k, n, v; + IMAGE_IMPORT_DESCRIPTOR *hdr; + int k, n, dllindex; + ADDR3264 v; struct pe_import_info *p = pe->imp_info[i]; - const char *name = pe->s1->loaded_dlls[p->dll_index-1]->name; + const char *name; + DLLReference *dllref; + + dllindex = p->dll_index; + if (dllindex) + name = (dllref = pe->s1->loaded_dlls[dllindex-1])->name; + else + name = "", dllref = NULL; /* put the dll name into the import header */ v = put_elf_str(pe->thunk, name); - - hdr = (struct pe_import_header*)(pe->thunk->data + dll_ptr); - hdr->first_thunk = thk_ptr + rva_base; - hdr->first_entry = ent_ptr + rva_base; - hdr->lib_name_offset = v + rva_base; + hdr = (IMAGE_IMPORT_DESCRIPTOR*)(pe->thunk->data + dll_ptr); + hdr->FirstThunk = thk_ptr + rva_base; + hdr->OriginalFirstThunk = ent_ptr + rva_base; + hdr->Name = v + rva_base; for (k = 0, n = p->sym_count; k <= n; ++k) { if (k < n) { - DWORD iat_index = p->symbols[k]->iat_index; + int iat_index = p->symbols[k]->iat_index; int sym_index = p->symbols[k]->sym_index; - Elf32_Sym *imp_sym = (Elf32_Sym *)pe->s1->dynsymtab_section->data + sym_index; - Elf32_Sym *org_sym = (Elf32_Sym *)symtab_section->data + iat_index; - const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name; + ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index; + ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index; + const char *name = (char*)pe->s1->dynsymtab_section->link->data + imp_sym->st_name; + int ordinal; org_sym->st_value = thk_ptr; org_sym->st_shndx = pe->thunk->sh_num; - v = pe->thunk->data_offset + rva_base; - section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */ - put_elf_str(pe->thunk, name); + + if (dllref) + v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */ + else + ordinal = 0, v = imp_sym->st_value; /* address from tcc_add_symbol() */ + +#ifdef TCC_IS_NATIVE + if (pe->type == PE_RUN) { + if (dllref) { + if ( !dllref->handle ) + dllref->handle = LoadLibrary(dllref->name); + v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name); + } + if (!v) + tcc_error_noabort("can't build symbol '%s'", name); + } else +#endif + if (ordinal) { + v = ordinal | (ADDR3264)1 << (sizeof(ADDR3264)*8 - 1); + } else { + v = pe->thunk->data_offset + rva_base; + section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */ + put_elf_str(pe->thunk, name); + } } else { v = 0; /* last entry is zero */ } - *(DWORD*)(pe->thunk->data+thk_ptr) = - *(DWORD*)(pe->thunk->data+ent_ptr) = v; - thk_ptr += sizeof (DWORD); - ent_ptr += sizeof (DWORD); + + *(ADDR3264*)(pe->thunk->data+thk_ptr) = + *(ADDR3264*)(pe->thunk->data+ent_ptr) = v; + thk_ptr += sizeof (ADDR3264); + ent_ptr += sizeof (ADDR3264); } - dll_ptr += sizeof(struct pe_import_header); - dynarray_reset(&p->symbols, &p->sym_count); + dll_ptr += sizeof(IMAGE_IMPORT_DESCRIPTOR); } - dynarray_reset(&pe->imp_info, &pe->imp_count); } /* ------------------------------------------------------------- */ -/* - For now only functions are exported. Export of data - would work, but import requires compiler support to - do an additional indirection. - - For instance: - __declspec(dllimport) extern int something; - needs to be translated to: - - *(int*)something -*/ +struct pe_sort_sym +{ + int index; + const char *name; +}; -ST_FN int sym_cmp(const void *va, const void *vb) +static int sym_cmp(const void *va, const void *vb) { - const char *ca = ((const char **)va)[1]; - const char *cb = ((const char **)vb)[1]; + const char *ca = (*(struct pe_sort_sym**)va)->name; + const char *cb = (*(struct pe_sort_sym**)vb)->name; return strcmp(ca, cb); } -ST_FN void pe_build_exports(struct pe_info *pe) +static void pe_build_exports(struct pe_info *pe) { - Elf32_Sym *sym; + ElfW(Sym) *sym; int sym_index, sym_end; DWORD rva_base, func_o, name_o, ord_o, str_o; - struct pe_export_header *hdr; - int sym_count, n, ord, *sorted, *sp; + IMAGE_EXPORT_DIRECTORY *hdr; + int sym_count, ord; + struct pe_sort_sym **sorted, *p; FILE *op; - char buf[MAX_PATH]; + char buf[260]; const char *dllname; const char *name; rva_base = pe->thunk->sh_addr - pe->imagebase; - sym_count = 0, n = 1, sorted = NULL, op = NULL; + sym_count = 0, sorted = NULL, op = NULL; - sym_end = symtab_section->data_offset / sizeof(Elf32_Sym); + sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); for (sym_index = 1; sym_index < sym_end; ++sym_index) { - sym = (Elf32_Sym*)symtab_section->data + sym_index; - name = symtab_section->link->data + sym->st_name; - if ((sym->st_other & 1) + sym = (ElfW(Sym)*)symtab_section->data + sym_index; + name = pe_export_name(pe->s1, sym); + if ((sym->st_other & ST_PE_EXPORT) /* export only symbols from actually written sections */ && pe->s1->sections[sym->st_shndx]->sh_addr) { - dynarray_add((void***)&sorted, &sym_count, (void*)n); - dynarray_add((void***)&sorted, &sym_count, (void*)name); + p = tcc_malloc(sizeof *p); + p->index = sym_index; + p->name = name; + dynarray_add(&sorted, &sym_count, p); } - ++n; #if 0 - if (sym->st_other & 1) + if (sym->st_other & ST_PE_EXPORT) printf("export: %s\n", name); - if (sym->st_other & 2) + if (sym->st_other & ST_PE_STDCALL) printf("stdcall: %s\n", name); #endif } if (0 == sym_count) return; - sym_count /= 2; - qsort (sorted, sym_count, 2 * sizeof sorted[0], sym_cmp); + qsort (sorted, sym_count, sizeof *sorted, sym_cmp); + pe_align_section(pe->thunk, 16); dllname = tcc_basename(pe->filename); pe->exp_offs = pe->thunk->data_offset; - func_o = pe->exp_offs + sizeof(struct pe_export_header); + func_o = pe->exp_offs + sizeof(IMAGE_EXPORT_DIRECTORY); name_o = func_o + sym_count * sizeof (DWORD); ord_o = name_o + sym_count * sizeof (DWORD); str_o = ord_o + sym_count * sizeof(WORD); @@ -852,24 +952,24 @@ ST_FN void pe_build_exports(struct pe_info *pe) #if 1 /* automatically write exports to <output-filename>.def */ - strcpy(buf, pe->filename); + pstrcpy(buf, sizeof buf, pe->filename); strcpy(tcc_fileextension(buf), ".def"); op = fopen(buf, "w"); if (NULL == op) { - error_noabort("could not create '%s': %s", buf, strerror(errno)); + tcc_error_noabort("could not create '%s': %s", buf, strerror(errno)); } else { fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname); if (pe->s1->verbose) - printf("<- %s (%d symbols)\n", buf, sym_count); + printf("<- %s (%d symbol%s)\n", buf, sym_count, &"s"[sym_count < 2]); } #endif - for (sp = sorted, ord = 0; ord < sym_count; ++ord, sp += 2) + for (ord = 0; ord < sym_count; ++ord) { - sym_index = sp[0], name = (const char *)sp[1]; + p = sorted[ord], sym_index = p->index, name = p->name; /* insert actual address later in pe_relocate_rva */ put_elf_reloc(symtab_section, pe->thunk, - func_o, R_386_RELATIVE, sym_index); + func_o, R_XXX_RELATIVE, sym_index); *(DWORD*)(pe->thunk->data + name_o) = pe->thunk->data_offset + rva_base; *(WORD*)(pe->thunk->data + ord_o) @@ -878,20 +978,21 @@ ST_FN void pe_build_exports(struct pe_info *pe) func_o += sizeof (DWORD); name_o += sizeof (DWORD); ord_o += sizeof (WORD); - if (op) fprintf(op, "%s\n", name); } pe->exp_size = pe->thunk->data_offset - pe->exp_offs; - tcc_free(sorted); + dynarray_reset(&sorted, &sym_count); + if (op) + fclose(op); } /* ------------------------------------------------------------- */ -ST_FN void pe_build_reloc (struct pe_info *pe) +static void pe_build_reloc (struct pe_info *pe) { DWORD offset, block_ptr, addr; int count, i; - Elf32_Rel *rel, *rel_end; + ElfW_Rel *rel, *rel_end; Section *s = NULL, *sr; offset = addr = block_ptr = count = i = 0; @@ -899,10 +1000,10 @@ ST_FN void pe_build_reloc (struct pe_info *pe) for(;;) { if (rel < rel_end) { - int type = ELF32_R_TYPE(rel->r_info); + int type = ELFW(R_TYPE)(rel->r_info); addr = rel->r_offset + s->sh_addr; ++ rel; - if (type != R_386_32) + if (type != REL_TYPE_DIRECT) continue; if (count == 0) { /* new block */ block_ptr = pe->reloc->data_offset; @@ -911,7 +1012,7 @@ ST_FN void pe_build_reloc (struct pe_info *pe) } if ((addr -= offset) < (1<<12)) { /* one block spans 4k addresses */ WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD)); - *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12; + *wp = addr | PE_IMAGE_REL<<12; ++count; continue; } @@ -920,8 +1021,8 @@ ST_FN void pe_build_reloc (struct pe_info *pe) } else if (i < pe->sec_count) { sr = (s = pe->s1->sections[pe->sec_info[i++].ord])->reloc; if (sr) { - rel = (Elf32_Rel *)sr->data; - rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); + rel = (ElfW_Rel *)sr->data; + rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); } continue; } @@ -943,7 +1044,7 @@ ST_FN void pe_build_reloc (struct pe_info *pe) } /* ------------------------------------------------------------- */ -ST_FN int pe_section_class(Section *s) +static int pe_section_class(Section *s) { int type, flags; const char *name; @@ -961,6 +1062,8 @@ ST_FN int pe_section_class(Section *s) return sec_rsrc; if (0 == strcmp(name, ".iedat")) return sec_idata; + if (0 == strcmp(name, ".pdata")) + return sec_pdata; return sec_other; } else if (type == SHT_NOBITS) { if (flags & SHF_WRITE) @@ -975,7 +1078,7 @@ ST_FN int pe_section_class(Section *s) return -1; } -ST_FN int pe_assign_addresses (struct pe_info *pe) +static int pe_assign_addresses (struct pe_info *pe) { int i, k, o, c; DWORD addr; @@ -983,6 +1086,9 @@ ST_FN int pe_assign_addresses (struct pe_info *pe) struct section_info *si; Section *s; + if (PE_DLL == pe->type) + pe->reloc = new_section(pe->s1, ".reloc", SHT_PROGBITS, 0); + // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC); section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int)); @@ -1010,16 +1116,19 @@ ST_FN int pe_assign_addresses (struct pe_info *pe) #ifdef PE_MERGE_DATA if (c == sec_bss && pe->sec_count && si[-1].cls == sec_data) { /* append .bss to .data */ - s->sh_addr = addr = ((addr-1) | 15) + 1; + s->sh_addr = addr = ((addr-1) | (s->sh_addralign-1)) + 1; addr += s->data_offset; si[-1].sh_size = addr - si[-1].sh_addr; continue; } #endif + if (c == sec_stab && 0 == pe->s1->do_debug) + continue; + strcpy(si->name, s->name); si->cls = c; si->ord = k; - si->sh_addr = s->sh_addr = addr = pe_virtual_align(addr); + si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr); si->sh_flags = s->sh_flags; if (c == sec_data && NULL == pe->thunk) @@ -1058,7 +1167,7 @@ ST_FN int pe_assign_addresses (struct pe_info *pe) type == SHT_NOBITS ? "nobits" : type == SHT_SYMTAB ? "symtab" : type == SHT_STRTAB ? "strtab" : - type == SHT_REL ? "rel" : "???", + type == SHT_RELX ? "rel" : "???", s->data_offset, flags & SHF_ALLOC ? "alloc" : "", flags & SHF_WRITE ? "write" : "", @@ -1073,48 +1182,73 @@ ST_FN int pe_assign_addresses (struct pe_info *pe) } /* ------------------------------------------------------------- */ -ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s) +static void pe_relocate_rva (struct pe_info *pe, Section *s) { Section *sr = s->reloc; - Elf32_Rel *rel, *rel_end; - rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); - for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) - if (ELF32_R_TYPE(rel->r_info) == R_386_RELATIVE) { - int sym_index = ELF32_R_SYM(rel->r_info); + ElfW_Rel *rel, *rel_end; + rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); + for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) { + if (ELFW(R_TYPE)(rel->r_info) == R_XXX_RELATIVE) { + int sym_index = ELFW(R_SYM)(rel->r_info); DWORD addr = s->sh_addr; if (sym_index) { - Elf32_Sym *sym = (Elf32_Sym *)symtab_section->data + sym_index; + ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index; addr = sym->st_value; } + // printf("reloc rva %08x %08x %s\n", (DWORD)rel->r_offset, addr, s->name); *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase; } + } +} + +/*----------------------------------------------------------------------------*/ + +static int pe_isafunc(int sym_index) +{ + Section *sr = text_section->reloc; + ElfW_Rel *rel, *rel_end; + Elf32_Word info = ELF32_R_INFO(sym_index, R_386_PC32); + if (!sr) + return 0; + rel_end = (ElfW_Rel *)(sr->data + sr->data_offset); + for (rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) + if (rel->r_info == info) + return 1; + return 0; } /*----------------------------------------------------------------------------*/ -ST_FN int pe_check_symbols(struct pe_info *pe) +static int pe_check_symbols(struct pe_info *pe) { - Elf32_Sym *sym; + ElfW(Sym) *sym; int sym_index, sym_end; int ret = 0; pe_align_section(text_section, 8); - sym_end = symtab_section->data_offset / sizeof(Elf32_Sym); + sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); for (sym_index = 1; sym_index < sym_end; ++sym_index) { - sym = (Elf32_Sym*)symtab_section->data + sym_index; + sym = (ElfW(Sym) *)symtab_section->data + sym_index; if (sym->st_shndx == SHN_UNDEF) { - const char *name = symtab_section->link->data + sym->st_name; - unsigned type = ELF32_ST_TYPE(sym->st_info); - int imp_sym = pe_find_import(pe->s1, name); + const char *name = (char*)symtab_section->link->data + sym->st_name; + unsigned type = ELFW(ST_TYPE)(sym->st_info); + int imp_sym = pe_find_import(pe->s1, sym); struct import_symbol *is; - if (0 == imp_sym) + if (imp_sym <= 0) goto not_found; + + if (type == STT_NOTYPE) { + /* symbols from assembler have no type, find out which */ + if (pe_isafunc(sym_index)) + type = STT_FUNC; + else + type = STT_OBJECT; + } + is = pe_add_import(pe, imp_sym); - if (!is) - goto not_found; if (type == STT_FUNC) { unsigned long offset = is->thk_offset; @@ -1123,30 +1257,45 @@ ST_FN int pe_check_symbols(struct pe_info *pe) } else { char buffer[100]; + WORD *p; offset = text_section->data_offset; /* add the 'jmp IAT[x]' instruction */ - *(WORD*)section_ptr_add(text_section, 8) = 0x25FF; - +#ifdef TCC_TARGET_ARM + p = section_ptr_add(text_section, 8+4); // room for code and address + (*(DWORD*)(p)) = 0xE59FC000; // arm code ldr ip, [pc] ; PC+8+0 = 0001xxxx + (*(DWORD*)(p+2)) = 0xE59CF000; // arm code ldr pc, [ip] +#else + p = section_ptr_add(text_section, 8); + *p = 0x25FF; +#ifdef TCC_TARGET_X86_64 + *(DWORD*)(p+1) = (DWORD)-4; +#endif +#endif /* add a helper symbol, will be patched later in pe_build_imports */ sprintf(buffer, "IAT.%s", name); is->iat_index = put_elf_sym( symtab_section, 0, sizeof(DWORD), - ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), + ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 0, SHN_UNDEF, buffer); +#ifdef TCC_TARGET_ARM + put_elf_reloc(symtab_section, text_section, + offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position +#else put_elf_reloc(symtab_section, text_section, - offset + 2, R_386_32, is->iat_index); + offset + 2, R_XXX_THUNKFIX, is->iat_index); +#endif is->thk_offset = offset; } /* tcc_realloc might have altered sym's address */ - sym = (Elf32_Sym*)symtab_section->data + sym_index; + sym = (ElfW(Sym) *)symtab_section->data + sym_index; /* patch the original symbol */ sym->st_value = offset; sym->st_shndx = text_section->sh_num; - sym->st_other &= ~1; /* do not export */ + sym->st_other &= ~ST_PE_EXPORT; /* do not export */ continue; } @@ -1159,13 +1308,17 @@ ST_FN int pe_check_symbols(struct pe_info *pe) } not_found: - error_noabort("undefined symbol '%s'", name); - ret = 1; + if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) + /* STB_WEAK undefined symbols are accepted */ + continue; + tcc_error_noabort("undefined symbol '%s'%s", name, + imp_sym < 0 ? ", missing __declspec(dllimport)?":""); + ret = -1; } else if (pe->s1->rdynamic - && ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { + && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { /* if -rdynamic option, then export all non local symbols */ - sym->st_other |= 1; + sym->st_other |= ST_PE_EXPORT; } } return ret; @@ -1173,9 +1326,9 @@ ST_FN int pe_check_symbols(struct pe_info *pe) /*----------------------------------------------------------------------------*/ #ifdef PE_PRINT_SECTIONS -ST_FN void pe_print_section(FILE * f, Section * s) +static void pe_print_section(FILE * f, Section * s) { - /* just if you'r curious */ + /* just if you're curious */ BYTE *p, *e, b; int i, n, l, m; p = s->data; @@ -1187,8 +1340,8 @@ ST_FN void pe_print_section(FILE * f, Section * s) fprintf(f, "\nlink \"%s\"", s->link->name); if (s->reloc) fprintf(f, "\nreloc \"%s\"", s->reloc->name); - fprintf(f, "\nv_addr %08X", s->sh_addr); - fprintf(f, "\ncontents %08X", l); + fprintf(f, "\nv_addr %08X", (unsigned)s->sh_addr); + fprintf(f, "\ncontents %08X", (unsigned)l); fprintf(f, "\n\n"); if (s->sh_type == SHT_NOBITS) @@ -1198,9 +1351,9 @@ ST_FN void pe_print_section(FILE * f, Section * s) return; if (s->sh_type == SHT_SYMTAB) - m = sizeof(Elf32_Sym); - if (s->sh_type == SHT_REL) - m = sizeof(Elf32_Rel); + m = sizeof(ElfW(Sym)); + else if (s->sh_type == SHT_RELX) + m = sizeof(ElfW_Rel); else m = 16; @@ -1209,7 +1362,7 @@ ST_FN void pe_print_section(FILE * f, Section * s) fprintf(f, " %02x", i); n = 56; - if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_REL) { + if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_RELX) { const char *fields1[] = { "name", "value", @@ -1256,25 +1409,28 @@ ST_FN void pe_print_section(FILE * f, Section * s) } if (s->sh_type == SHT_SYMTAB) { - Elf32_Sym *sym = (Elf32_Sym *) (p + i); + ElfW(Sym) *sym = (ElfW(Sym) *) (p + i); const char *name = s->link->data + sym->st_name; fprintf(f, " %04X %04X %04X %02X %02X %02X %04X \"%s\"", - sym->st_name, - sym->st_value, - sym->st_size, - ELF32_ST_BIND(sym->st_info), - ELF32_ST_TYPE(sym->st_info), - sym->st_other, sym->st_shndx, name); - - } else if (s->sh_type == SHT_REL) { - Elf32_Rel *rel = (Elf32_Rel *) (p + i); - Elf32_Sym *sym = - (Elf32_Sym *) s->link->data + ELF32_R_SYM(rel->r_info); + (unsigned)sym->st_name, + (unsigned)sym->st_value, + (unsigned)sym->st_size, + (unsigned)ELFW(ST_BIND)(sym->st_info), + (unsigned)ELFW(ST_TYPE)(sym->st_info), + (unsigned)sym->st_other, + (unsigned)sym->st_shndx, + name); + + } else if (s->sh_type == SHT_RELX) { + ElfW_Rel *rel = (ElfW_Rel *) (p + i); + ElfW(Sym) *sym = + (ElfW(Sym) *) s->link->data + ELFW(R_SYM)(rel->r_info); const char *name = s->link->link->data + sym->st_name; fprintf(f, " %04X %02X %04X \"%s\"", - rel->r_offset, - ELF32_R_TYPE(rel->r_info), - ELF32_R_SYM(rel->r_info), name); + (unsigned)rel->r_offset, + (unsigned)ELFW(R_TYPE)(rel->r_info), + (unsigned)ELFW(R_SYM)(rel->r_info), + name); } else { fprintf(f, " "); for (n = 0; n < m; ++n) { @@ -1292,12 +1448,12 @@ ST_FN void pe_print_section(FILE * f, Section * s) fprintf(f, "\n\n"); } -ST_FN void pe_print_sections(TCCState *s1, const char *fname) +static void pe_print_sections(TCCState *s1, const char *fname) { Section *s; FILE *f; int i; - f = fopen(fname, "wt"); + f = fopen(fname, "w"); for (i = 1; i < s1->nb_sections; ++i) { s = s1->sections[i]; pe_print_section(f, s); @@ -1307,111 +1463,247 @@ ST_FN void pe_print_sections(TCCState *s1, const char *fname) } #endif -/* ------------------------------------------------------------- - * This is for compiled windows resources in 'coff' format - * as generated by 'windres.exe -O coff ...'. - */ +/* ------------------------------------------------------------- */ +/* helper function for load/store to insert one more indirection */ -PUB_FN int pe_test_res_file(void *v, int size) +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 +ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2) { - struct pe_rsrc_header *p = (struct pe_rsrc_header *)v; - return - size >= IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_SHORT_NAME /* = 28 */ - && p->filehdr.Machine == 0x014C - && 1 == p->filehdr.NumberOfSections - && 0 == strcmp(p->sectionhdr.Name, ".rsrc") - ; + int r2; + if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST)) + return sv; + if (!sv->sym->a.dllimport) + return sv; + // printf("import %04x %04x %04x %s\n", sv->type.t, sv->sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL)); + memset(v2, 0, sizeof *v2); + v2->type.t = VT_PTR; + v2->r = VT_CONST | VT_SYM | VT_LVAL; + v2->sym = sv->sym; + + r2 = get_reg(RC_INT); + load(r2, v2); + v2->r = r2; + if ((uint32_t)sv->c.i) { + vpushv(v2); + vpushi(sv->c.i); + gen_opi('+'); + *v2 = *vtop--; + } + v2->type.t = sv->type.t; + v2->r |= sv->r & VT_LVAL; + return v2; +} +#endif + +ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value) +{ + return set_elf_sym( + s1->dynsymtab_section, + value, + dllindex, /* st_size */ + ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), + 0, + value ? SHN_ABS : SHN_UNDEF, + name + ); +} + +static int add_dllref(TCCState *s1, const char *dllname) +{ + DLLReference *dllref; + int i; + for (i = 0; i < s1->nb_loaded_dlls; ++i) + if (0 == strcmp(s1->loaded_dlls[i]->name, dllname)) + return i + 1; + dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); + strcpy(dllref->name, dllname); + dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); + return s1->nb_loaded_dlls; } -ST_FN int read_n(int fd, void *ptr, unsigned size) +/* ------------------------------------------------------------- */ + +static int read_mem(int fd, unsigned offset, void *buffer, unsigned len) { - return size == read(fd, ptr, size); + lseek(fd, offset, SEEK_SET); + return len == read(fd, buffer, len); } -PUB_FN int pe_load_res_file(TCCState *s1, int fd) +/* ------------------------------------------------------------- */ + +PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp) +{ + int l, i, n, n0, ret; + char *p; + int fd; + + IMAGE_SECTION_HEADER ish; + IMAGE_EXPORT_DIRECTORY ied; + IMAGE_DOS_HEADER dh; + IMAGE_FILE_HEADER ih; + DWORD sig, ref, addr, ptr, namep; + + int pef_hdroffset, opt_hdroffset, sec_hdroffset; + + n = n0 = 0; + p = NULL; + ret = -1; + + fd = open(filename, O_RDONLY | O_BINARY); + if (fd < 0) + goto the_end_1; + ret = 1; + if (!read_mem(fd, 0, &dh, sizeof dh)) + goto the_end; + if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig)) + goto the_end; + if (sig != 0x00004550) + goto the_end; + pef_hdroffset = dh.e_lfanew + sizeof sig; + if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih)) + goto the_end; + opt_hdroffset = pef_hdroffset + sizeof ih; + if (ih.Machine == 0x014C) { + IMAGE_OPTIONAL_HEADER32 oh; + sec_hdroffset = opt_hdroffset + sizeof oh; + if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh)) + goto the_end; + if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes) + goto the_end_0; + addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + } else if (ih.Machine == 0x8664) { + IMAGE_OPTIONAL_HEADER64 oh; + sec_hdroffset = opt_hdroffset + sizeof oh; + if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh)) + goto the_end; + if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes) + goto the_end_0; + addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + } else + goto the_end; + + //printf("addr: %08x\n", addr); + for (i = 0; i < ih.NumberOfSections; ++i) { + if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish)) + goto the_end; + //printf("vaddr: %08x\n", ish.VirtualAddress); + if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData) + goto found; + } + goto the_end_0; + +found: + ref = ish.VirtualAddress - ish.PointerToRawData; + if (!read_mem(fd, addr - ref, &ied, sizeof ied)) + goto the_end; + + namep = ied.AddressOfNames - ref; + for (i = 0; i < ied.NumberOfNames; ++i) { + if (!read_mem(fd, namep, &ptr, sizeof ptr)) + goto the_end; + namep += sizeof ptr; + for (l = 0;;) { + if (n+1 >= n0) + p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256); + if (!read_mem(fd, ptr - ref + l++, p + n, 1)) { + tcc_free(p), p = NULL; + goto the_end; + } + if (p[n++] == 0) + break; + } + } + if (p) + p[n] = 0; +the_end_0: + ret = 0; +the_end: + close(fd); +the_end_1: + *pp = p; + return ret; +} + +/* ------------------------------------------------------------- + * This is for compiled windows resources in 'coff' format + * as generated by 'windres.exe -O coff ...'. + */ + +static int pe_load_res(TCCState *s1, int fd) { struct pe_rsrc_header hdr; Section *rsrc_section; int i, ret = -1; BYTE *ptr; + unsigned offs; - lseek (fd, 0, SEEK_SET); - if (!read_n(fd, &hdr, sizeof hdr)) + if (!read_mem(fd, 0, &hdr, sizeof hdr)) goto quit; - if (!pe_test_res_file(&hdr, sizeof hdr)) + + if (hdr.filehdr.Machine != IMAGE_FILE_MACHINE + || hdr.filehdr.NumberOfSections != 1 + || strcmp((char*)hdr.sectionhdr.Name, ".rsrc") != 0) goto quit; rsrc_section = new_section(s1, ".rsrc", SHT_PROGBITS, SHF_ALLOC); ptr = section_ptr_add(rsrc_section, hdr.sectionhdr.SizeOfRawData); - lseek (fd, hdr.sectionhdr.PointerToRawData, SEEK_SET); - if (!read_n(fd, ptr, hdr.sectionhdr.SizeOfRawData)) + offs = hdr.sectionhdr.PointerToRawData; + if (!read_mem(fd, offs, ptr, hdr.sectionhdr.SizeOfRawData)) goto quit; - - lseek (fd, hdr.sectionhdr.PointerToRelocations, SEEK_SET); + offs = hdr.sectionhdr.PointerToRelocations; for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i) { struct pe_rsrc_reloc rel; - if (!read_n(fd, &rel, sizeof rel)) + if (!read_mem(fd, offs, &rel, sizeof rel)) goto quit; // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type); - if (rel.type != 7) /* DIR32NB */ + if (rel.type != RSRC_RELTYPE) goto quit; put_elf_reloc(symtab_section, rsrc_section, - rel.offset, R_386_RELATIVE, 0); + rel.offset, R_XXX_RELATIVE, 0); + offs += sizeof rel; } ret = 0; quit: - if (ret) - error_noabort("unrecognized resource file format"); return ret; } /* ------------------------------------------------------------- */ -ST_FN char *trimfront(char *p) + +static char *trimfront(char *p) { while (*p && (unsigned char)*p <= ' ') - ++p; + ++p; return p; } -ST_FN char *trimback(char *a, char *e) +static char *trimback(char *a, char *e) { while (e > a && (unsigned char)e[-1] <= ' ') - --e; + --e; *e = 0;; return a; } -ST_FN char *get_line(char *line, int size, FILE *fp) -{ - if (NULL == fgets(line, size, fp)) - return NULL; - trimback(line, strchr(line, 0)); - return trimfront(line); -} - /* ------------------------------------------------------------- */ -PUB_FN int pe_load_def_file(TCCState *s1, int fd) +static int pe_load_def(TCCState *s1, int fd) { - DLLReference *dllref; - int state = 0, ret = -1; - char line[400], dllname[80], *p; - FILE *fp = fdopen(dup(fd), "rb"); + int state = 0, ret = -1, dllindex = 0, ord; + char line[400], dllname[80], *p, *x; + FILE *fp; - if (NULL == fp) - goto quit; - - for (;;) { - p = get_line(line, sizeof line, fp); - if (NULL == p) - break; + fp = fdopen(dup(fd), "rb"); + while (fgets(line, sizeof line, fp)) + { + p = trimfront(trimback(line, strchr(line, 0))); if (0 == *p || ';' == *p) continue; + switch (state) { case 0: if (0 != strnicmp(p, "LIBRARY", 7)) goto quit; - strcpy(dllname, trimfront(p+7)); + pstrcpy(dllname, sizeof dllname, trimfront(p+7)); ++state; continue; @@ -1422,95 +1714,251 @@ PUB_FN int pe_load_def_file(TCCState *s1, int fd) continue; case 2: - dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); - strcpy(dllref->name, dllname); - dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); + dllindex = add_dllref(s1, dllname); ++state; - + /* fall through */ default: - add_elf_sym(s1->dynsymtab_section, - s1->nb_loaded_dlls, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), 0, - text_section->sh_num, p); + /* get ordinal and will store in sym->st_value */ + ord = 0; + x = strchr(p, ' '); + if (x) { + *x = 0, x = strrchr(x + 1, '@'); + if (x) { + char *d; + ord = (int)strtol(x + 1, &d, 10); + if (*d) + ord = 0; + } + } + pe_putimport(s1, dllindex, p, ord); continue; } } ret = 0; quit: - if (fp) - fclose(fp); - if (ret) - error_noabort("unrecognized export definition file format"); + fclose(fp); + return ret; +} + +/* ------------------------------------------------------------- */ +static int pe_load_dll(TCCState *s1, const char *filename) +{ + char *p, *q; + int index, ret; + + ret = tcc_get_dllexports(filename, &p); + if (ret) { + return -1; + } else if (p) { + index = add_dllref(s1, tcc_basename(filename)); + for (q = p; *q; q += 1 + strlen(q)) + pe_putimport(s1, index, q, 0); + tcc_free(p); + } + return 0; +} + +/* ------------------------------------------------------------- */ +ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd) +{ + int ret = -1; + char buf[10]; + if (0 == strcmp(tcc_fileextension(filename), ".def")) + ret = pe_load_def(s1, fd); + else if (pe_load_res(s1, fd) == 0) + ret = 0; + else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4)) + ret = pe_load_dll(s1, filename); return ret; } /* ------------------------------------------------------------- */ +#ifdef TCC_TARGET_X86_64 +static unsigned pe_add_uwwind_info(TCCState *s1) +{ + if (NULL == s1->uw_pdata) { + s1->uw_pdata = find_section(tcc_state, ".pdata"); + s1->uw_pdata->sh_addralign = 4; + s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL); + } + + if (0 == s1->uw_offs) { + /* As our functions all have the same stackframe, we use one entry for all */ + static const unsigned char uw_info[] = { + 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags + 0x04, // UBYTE Size of prolog + 0x02, // UBYTE Count of unwind codes + 0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled) + // USHORT * n Unwind codes array + // 0x0b, 0x01, 0xff, 0xff, // stack size + 0x04, 0x03, // set frame ptr (mov rsp -> rbp) + 0x01, 0x50 // push reg (rbp) + }; -ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) + Section *s = text_section; + unsigned char *p; + + section_ptr_add(s, -s->data_offset & 3); /* align */ + s1->uw_offs = s->data_offset; + p = section_ptr_add(s, sizeof uw_info); + memcpy(p, uw_info, sizeof uw_info); + } + + return s1->uw_offs; +} + +ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) +{ + TCCState *s1 = tcc_state; + Section *pd; + unsigned o, n, d; + struct /* _RUNTIME_FUNCTION */ { + DWORD BeginAddress; + DWORD EndAddress; + DWORD UnwindData; + } *p; + + d = pe_add_uwwind_info(s1); + pd = s1->uw_pdata; + o = pd->data_offset; + p = section_ptr_add(pd, sizeof *p); + + /* record this function */ + p->BeginAddress = start; + p->EndAddress = end; + p->UnwindData = d; + + /* put relocations on it */ + for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress) + put_elf_reloc(symtab_section, pd, o, R_X86_64_RELATIVE, s1->uw_sym); +} +#endif +/* ------------------------------------------------------------- */ +#ifdef TCC_TARGET_X86_64 +#define PE_STDSYM(n,s) n +#else +#define PE_STDSYM(n,s) "_" n s +#endif + +static void pe_add_runtime(TCCState *s1, struct pe_info *pe) { const char *start_symbol; - unsigned long addr = 0; int pe_type = 0; + int unicode_entry = 0; - if (find_elf_sym(symtab_section, "_WinMain@16")) + if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16"))) pe_type = PE_GUI; else + if (find_elf_sym(symtab_section, PE_STDSYM("wWinMain","@16"))) { + pe_type = PE_GUI; + unicode_entry = PE_GUI; + } + else if (TCC_OUTPUT_DLL == s1->output_type) { pe_type = PE_DLL; /* need this for 'tccelf.c:relocate_section()' */ s1->output_type = TCC_OUTPUT_EXE; } + else { + pe_type = PE_EXE; + if (find_elf_sym(symtab_section, "wmain")) + unicode_entry = PE_EXE; + } start_symbol = TCC_OUTPUT_MEMORY == s1->output_type - ? PE_GUI == pe_type ? "_runwinmain" : NULL - : PE_DLL == pe_type ? "__dllstart@12" - : PE_GUI == pe_type ? "_winstart" : "_start" + ? PE_GUI == pe_type ? (unicode_entry ? "__runwwinmain" : "__runwinmain") + : (unicode_entry ? "__runwmain" : "__runmain") + : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12") + : PE_GUI == pe_type ? (unicode_entry ? "__wwinstart": "__winstart") + : (unicode_entry ? "__wstart" : "__start") ; + if (!s1->leading_underscore || strchr(start_symbol, '@')) + ++start_symbol; + /* grab the startup code from libtcc1 */ - if (start_symbol) - add_elf_sym(symtab_section, - 0, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - SHN_UNDEF, start_symbol); +#ifdef TCC_IS_NATIVE + if (TCC_OUTPUT_MEMORY != s1->output_type || s1->runtime_main) +#endif + set_elf_sym(symtab_section, + 0, 0, + ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, + SHN_UNDEF, start_symbol); + + tcc_add_pragma_libs(s1); if (0 == s1->nostdlib) { - tcc_add_library(s1, "tcc1"); -#ifdef __CYGWIN__ - tcc_add_library(s1, "cygwin1"); -#else - tcc_add_library(s1, "msvcrt"); -#endif - tcc_add_library(s1, "kernel32"); - if (PE_DLL == pe_type || PE_GUI == pe_type) { - tcc_add_library(s1, "user32"); - tcc_add_library(s1, "gdi32"); + static const char *libs[] = { + TCC_LIBTCC1, "msvcrt", "kernel32", "", "user32", "gdi32", NULL + }; + const char **pp, *p; + for (pp = libs; 0 != (p = *pp); ++pp) { + if (0 == *p) { + if (PE_DLL != pe_type && PE_GUI != pe_type) + break; + } else if (pp == libs && tcc_add_dll(s1, p, 0) >= 0) { + continue; + } else { + tcc_add_library_err(s1, p); + } } } - if (start_symbol) { - addr = (unsigned long)tcc_get_symbol_err(s1, start_symbol); - if (s1->output_type == TCC_OUTPUT_MEMORY && addr) - /* for -run GUI's, put '_runwinmain' instead of 'main' */ - add_elf_sym(symtab_section, - addr, 0, - ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, - text_section->sh_num, "main"); + if (TCC_OUTPUT_MEMORY == s1->output_type) + pe_type = PE_RUN; + pe->type = pe_type; + pe->start_symbol = start_symbol; +} + +static void pe_set_options(TCCState * s1, struct pe_info *pe) +{ + if (PE_DLL == pe->type) { + /* XXX: check if is correct for arm-pe target */ + pe->imagebase = 0x10000000; + } else { +#if defined(TCC_TARGET_ARM) + pe->imagebase = 0x00010000; +#else + pe->imagebase = 0x00400000; +#endif } - if (pe) { - pe->type = pe_type; - pe->start_addr = addr; +#if defined(TCC_TARGET_ARM) + /* we use "console" subsystem by default */ + pe->subsystem = 9; +#else + if (PE_DLL == pe->type || PE_GUI == pe->type) + pe->subsystem = 2; + else + pe->subsystem = 3; +#endif + /* Allow override via -Wl,-subsystem=... option */ + if (s1->pe_subsystem != 0) + pe->subsystem = s1->pe_subsystem; + + /* set default file/section alignment */ + if (pe->subsystem == 1) { + pe->section_align = 0x20; + pe->file_align = 0x20; + } else { + pe->section_align = 0x1000; + pe->file_align = 0x200; } -} -PUB_FN void pe_add_runtime(TCCState *s1) -{ - pe_add_runtime_ex(s1, NULL); + if (s1->section_align != 0) + pe->section_align = s1->section_align; + if (s1->pe_file_align != 0) + pe->file_align = s1->pe_file_align; + + if ((pe->subsystem >= 10) && (pe->subsystem <= 12)) + pe->imagebase = 0; + + if (s1->has_text_addr) + pe->imagebase = s1->text_addr; } -PUB_FN int pe_output_file(TCCState * s1, const char *filename) +ST_FUNC int pe_output_file(TCCState *s1, const char *filename) { int ret; struct pe_info pe; @@ -1520,20 +1968,18 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename) pe.filename = filename; pe.s1 = s1; - pe_add_runtime_ex(s1, &pe); - relocate_common_syms(); /* assign bss adresses */ + tcc_add_bcheck(s1); + pe_add_runtime(s1, &pe); + relocate_common_syms(); /* assign bss addresses */ tcc_add_linker_symbols(s1); + pe_set_options(s1, &pe); ret = pe_check_symbols(&pe); - if (0 == ret) { - if (PE_DLL == pe.type) { - pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0); - pe.imagebase = 0x10000000; - } else { - pe.imagebase = 0x00400000; - } + if (ret) + ; + else if (filename) { pe_assign_addresses(&pe); - relocate_syms(s1, 0); + relocate_syms(s1, s1->symtab, 0); for (i = 1; i < s1->nb_sections; ++i) { Section *s = s1->sections[i]; if (s->reloc) { @@ -1541,13 +1987,24 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename) pe_relocate_rva(&pe, s); } } + pe.start_addr = (DWORD) + ((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol) + - pe.imagebase); if (s1->nb_errors) - ret = 1; + ret = -1; else ret = pe_write(&pe); tcc_free(pe.sec_info); + } else { +#ifdef TCC_IS_NATIVE + pe.thunk = data_section; + pe_build_imports(&pe); + s1->runtime_main = pe.start_symbol; +#endif } + pe_free_imports(&pe); + #ifdef PE_PRINT_SECTIONS pe_print_sections(s1, "tcc.log"); #endif @@ -1555,5 +2012,3 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename) } /* ------------------------------------------------------------- */ -#endif /* def TCC_TARGET_PE */ -/* ------------------------------------------------------------- */ diff --git a/tinyc/tccpp.c b/tinyc/tccpp.c index ff17d8bed..76f9e428e 100644 --- a/tinyc/tccpp.c +++ b/tinyc/tccpp.c @@ -18,6 +18,45 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "tcc.h" + +/********************************************************/ +/* global variables */ + +ST_DATA int tok_flags; +ST_DATA int parse_flags; + +ST_DATA struct BufferedFile *file; +ST_DATA int ch, tok; +ST_DATA CValue tokc; +ST_DATA const int *macro_ptr; +ST_DATA CString tokcstr; /* current parsed string, if any */ + +/* display benchmark infos */ +ST_DATA int total_lines; +ST_DATA int total_bytes; +ST_DATA int tok_ident; +ST_DATA TokenSym **table_ident; + +/* ------------------------------------------------------------------------- */ + +static TokenSym *hash_ident[TOK_HASH_SIZE]; +static char token_buf[STRING_MAX_SIZE + 1]; +static CString cstr_buf; +static CString macro_equal_buf; +static TokenString tokstr_buf; +static unsigned char isidnum_table[256 - CH_EOF]; +static int pp_debug_tok, pp_debug_symv; +static int pp_once; +static int pp_expr; +static int pp_counter; +static void tok_print(const char *msg, const int *str); + +static struct TinyAlloc *toksym_alloc; +static struct TinyAlloc *tokstr_alloc; +static struct TinyAlloc *cstr_alloc; + +static TokenString *macro_stack; static const char tcc_keywords[] = #define DEF(id, str) str "\0" @@ -26,23 +65,350 @@ static const char tcc_keywords[] = ; /* WARNING: the content of this string encodes token numbers */ -static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266"; +static const unsigned char tok_two_chars[] = +/* outdated -- gr + "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253" + "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266"; +*/{ + '<','=', TOK_LE, + '>','=', TOK_GE, + '!','=', TOK_NE, + '&','&', TOK_LAND, + '|','|', TOK_LOR, + '+','+', TOK_INC, + '-','-', TOK_DEC, + '=','=', TOK_EQ, + '<','<', TOK_SHL, + '>','>', TOK_SAR, + '+','=', TOK_A_ADD, + '-','=', TOK_A_SUB, + '*','=', TOK_A_MUL, + '/','=', TOK_A_DIV, + '%','=', TOK_A_MOD, + '&','=', TOK_A_AND, + '^','=', TOK_A_XOR, + '|','=', TOK_A_OR, + '-','>', TOK_ARROW, + '.','.', TOK_TWODOTS, + '#','#', TOK_TWOSHARPS, + 0 +}; -/* true if isid(c) || isnum(c) */ -static unsigned char isidnum_table[256-CH_EOF]; +static void next_nomacro_spc(void); +ST_FUNC void skip(int c) +{ + if (tok != c) + tcc_error("'%c' expected (got \"%s\")", c, get_tok_str(tok, &tokc)); + next(); +} -struct macro_level { - struct macro_level *prev; - int *p; -}; +ST_FUNC void expect(const char *msg) +{ + tcc_error("%s expected", msg); +} -static void next_nomacro(void); -static void next_nomacro_spc(void); -static void macro_subst(TokenString *tok_str, Sym **nested_list, - const int *macro_str, struct macro_level **can_read_stream); +/* ------------------------------------------------------------------------- */ +/* Custom allocator for tiny objects */ + +#define USE_TAL + +#ifndef USE_TAL +#define tal_free(al, p) tcc_free(p) +#define tal_realloc(al, p, size) tcc_realloc(p, size) +#define tal_new(a,b,c) +#define tal_delete(a) +#else +#if !defined(MEM_DEBUG) +#define tal_free(al, p) tal_free_impl(al, p) +#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size) +#define TAL_DEBUG_PARAMS +#else +#define TAL_DEBUG 1 +//#define TAL_INFO 1 /* collect and dump allocators stats */ +#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__) +#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__) +#define TAL_DEBUG_PARAMS , const char *file, int line +#define TAL_DEBUG_FILE_LEN 40 +#endif + +#define TOKSYM_TAL_SIZE (768 * 1024) /* allocator for tiny TokenSym in table_ident */ +#define TOKSTR_TAL_SIZE (768 * 1024) /* allocator for tiny TokenString instances */ +#define CSTR_TAL_SIZE (256 * 1024) /* allocator for tiny CString instances */ +#define TOKSYM_TAL_LIMIT 256 /* prefer unique limits to distinguish allocators debug msgs */ +#define TOKSTR_TAL_LIMIT 128 /* 32 * sizeof(int) */ +#define CSTR_TAL_LIMIT 1024 + +typedef struct TinyAlloc { + unsigned limit; + unsigned size; + uint8_t *buffer; + uint8_t *p; + unsigned nb_allocs; + struct TinyAlloc *next, *top; +#ifdef TAL_INFO + unsigned nb_peak; + unsigned nb_total; + unsigned nb_missed; + uint8_t *peak_p; +#endif +} TinyAlloc; +typedef struct tal_header_t { + unsigned size; +#ifdef TAL_DEBUG + int line_num; /* negative line_num used for double free check */ + char file_name[TAL_DEBUG_FILE_LEN + 1]; +#endif +} tal_header_t; + +/* ------------------------------------------------------------------------- */ + +static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size) +{ + TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc)); + al->p = al->buffer = tcc_malloc(size); + al->limit = limit; + al->size = size; + if (pal) *pal = al; + return al; +} +static void tal_delete(TinyAlloc *al) +{ + TinyAlloc *next; + +tail_call: + if (!al) + return; +#ifdef TAL_INFO + fprintf(stderr, "limit=%5d, size=%5g MB, nb_peak=%6d, nb_total=%8d, nb_missed=%6d, usage=%5.1f%%\n", + al->limit, al->size / 1024.0 / 1024.0, al->nb_peak, al->nb_total, al->nb_missed, + (al->peak_p - al->buffer) * 100.0 / al->size); +#endif +#ifdef TAL_DEBUG + if (al->nb_allocs > 0) { + uint8_t *p; + fprintf(stderr, "TAL_DEBUG: memory leak %d chunk(s) (limit= %d)\n", + al->nb_allocs, al->limit); + p = al->buffer; + while (p < al->p) { + tal_header_t *header = (tal_header_t *)p; + if (header->line_num > 0) { + fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n", + header->file_name, header->line_num, header->size); + } + p += header->size + sizeof(tal_header_t); + } +#if MEM_DEBUG-0 == 2 + exit(2); +#endif + } +#endif + next = al->next; + tcc_free(al->buffer); + tcc_free(al); + al = next; + goto tail_call; +} + +static void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS) +{ + if (!p) + return; +tail_call: + if (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size) { +#ifdef TAL_DEBUG + tal_header_t *header = (((tal_header_t *)p) - 1); + if (header->line_num < 0) { + fprintf(stderr, "%s:%d: TAL_DEBUG: double frees chunk from\n", + file, line); + fprintf(stderr, "%s:%d: %d bytes\n", + header->file_name, (int)-header->line_num, (int)header->size); + } else + header->line_num = -header->line_num; +#endif + al->nb_allocs--; + if (!al->nb_allocs) + al->p = al->buffer; + } else if (al->next) { + al = al->next; + goto tail_call; + } + else + tcc_free(p); +} + +static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_PARAMS) +{ + tal_header_t *header; + void *ret; + int is_own; + unsigned adj_size = (size + 3) & -4; + TinyAlloc *al = *pal; + +tail_call: + is_own = (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size); + if ((!p || is_own) && size <= al->limit) { + if (al->p + adj_size + sizeof(tal_header_t) < al->buffer + al->size) { + header = (tal_header_t *)al->p; + header->size = adj_size; +#ifdef TAL_DEBUG + { int ofs = strlen(file) - TAL_DEBUG_FILE_LEN; + strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN); + header->file_name[TAL_DEBUG_FILE_LEN] = 0; + header->line_num = line; } +#endif + ret = al->p + sizeof(tal_header_t); + al->p += adj_size + sizeof(tal_header_t); + if (is_own) { + header = (((tal_header_t *)p) - 1); + memcpy(ret, p, header->size); +#ifdef TAL_DEBUG + header->line_num = -header->line_num; +#endif + } else { + al->nb_allocs++; + } +#ifdef TAL_INFO + if (al->nb_peak < al->nb_allocs) + al->nb_peak = al->nb_allocs; + if (al->peak_p < al->p) + al->peak_p = al->p; + al->nb_total++; +#endif + return ret; + } else if (is_own) { + al->nb_allocs--; + ret = tal_realloc(*pal, 0, size); + header = (((tal_header_t *)p) - 1); + memcpy(ret, p, header->size); +#ifdef TAL_DEBUG + header->line_num = -header->line_num; +#endif + return ret; + } + if (al->next) { + al = al->next; + } else { + TinyAlloc *bottom = al, *next = al->top ? al->top : al; + + al = tal_new(pal, next->limit, next->size * 2); + al->next = next; + bottom->top = al; + } + goto tail_call; + } + if (is_own) { + al->nb_allocs--; + ret = tcc_malloc(size); + header = (((tal_header_t *)p) - 1); + memcpy(ret, p, header->size); +#ifdef TAL_DEBUG + header->line_num = -header->line_num; +#endif + } else if (al->next) { + al = al->next; + goto tail_call; + } else + ret = tcc_realloc(p, size); +#ifdef TAL_INFO + al->nb_missed++; +#endif + return ret; +} + +#endif /* USE_TAL */ + +/* ------------------------------------------------------------------------- */ +/* CString handling */ +static void cstr_realloc(CString *cstr, int new_size) +{ + int size; + + size = cstr->size_allocated; + if (size < 8) + size = 8; /* no need to allocate a too small first string */ + while (size < new_size) + size = size * 2; + cstr->data = tal_realloc(cstr_alloc, cstr->data, size); + cstr->size_allocated = size; +} + +/* add a byte */ +ST_INLN void cstr_ccat(CString *cstr, int ch) +{ + int size; + size = cstr->size + 1; + if (size > cstr->size_allocated) + cstr_realloc(cstr, size); + ((unsigned char *)cstr->data)[size - 1] = ch; + cstr->size = size; +} + +ST_FUNC void cstr_cat(CString *cstr, const char *str, int len) +{ + int size; + if (len <= 0) + len = strlen(str) + 1 + len; + size = cstr->size + len; + if (size > cstr->size_allocated) + cstr_realloc(cstr, size); + memmove(((unsigned char *)cstr->data) + cstr->size, str, len); + cstr->size = size; +} + +/* add a wide char */ +ST_FUNC void cstr_wccat(CString *cstr, int ch) +{ + int size; + size = cstr->size + sizeof(nwchar_t); + if (size > cstr->size_allocated) + cstr_realloc(cstr, size); + *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch; + cstr->size = size; +} + +ST_FUNC void cstr_new(CString *cstr) +{ + memset(cstr, 0, sizeof(CString)); +} + +/* free string and reset it to NULL */ +ST_FUNC void cstr_free(CString *cstr) +{ + tal_free(cstr_alloc, cstr->data); + cstr_new(cstr); +} + +/* reset string to empty */ +ST_FUNC void cstr_reset(CString *cstr) +{ + cstr->size = 0; +} + +/* XXX: unicode ? */ +static void add_char(CString *cstr, int c) +{ + if (c == '\'' || c == '\"' || c == '\\') { + /* XXX: could be more precise if char or string */ + cstr_ccat(cstr, '\\'); + } + if (c >= 32 && c <= 126) { + cstr_ccat(cstr, c); + } else { + cstr_ccat(cstr, '\\'); + if (c == '\n') { + cstr_ccat(cstr, 'n'); + } else { + cstr_ccat(cstr, '0' + ((c >> 6) & 7)); + cstr_ccat(cstr, '0' + ((c >> 3) & 7)); + cstr_ccat(cstr, '0' + (c & 7)); + } + } +} + +/* ------------------------------------------------------------------------- */ /* allocate a new token */ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) { @@ -50,18 +416,16 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) int i; if (tok_ident >= SYM_FIRST_ANOM) - error("memory full"); + tcc_error("memory full (symbols)"); /* expand token table if needed */ i = tok_ident - TOK_IDENT; if ((i % TOK_ALLOC_INCR) == 0) { ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *)); - if (!ptable) - error("memory full"); table_ident = ptable; } - ts = tcc_malloc(sizeof(TokenSym) + len); + ts = tal_realloc(toksym_alloc, 0, sizeof(TokenSym) + len); table_ident[i] = ts; ts->tok = tok_ident++; ts->sym_define = NULL; @@ -77,10 +441,11 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) } #define TOK_HASH_INIT 1 -#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c)) +#define TOK_HASH_FUNC(h, c) ((h) + ((h) << 5) + ((h) >> 27) + (c)) + /* find a token and add it if not found */ -static TokenSym *tok_alloc(const char *str, int len) +ST_FUNC TokenSym *tok_alloc(const char *str, int len) { TokenSym *ts, **pts; int i; @@ -105,31 +470,27 @@ static TokenSym *tok_alloc(const char *str, int len) /* XXX: buffer overflow */ /* XXX: float tokens */ -char *get_tok_str(int v, CValue *cv) +ST_FUNC const char *get_tok_str(int v, CValue *cv) { - static char buf[STRING_MAX_SIZE + 1]; - static CString cstr_buf; - CString *cstr; - unsigned char *q; char *p; int i, len; - /* NOTE: to go faster, we give a fixed buffer for small strings */ cstr_reset(&cstr_buf); - cstr_buf.data = buf; - cstr_buf.size_allocated = sizeof(buf); - p = buf; + p = cstr_buf.data; switch(v) { case TOK_CINT: case TOK_CUINT: - /* XXX: not quite exact, but only useful for testing */ - sprintf(p, "%u", cv->ui); - break; + case TOK_CLONG: + case TOK_CULONG: case TOK_CLLONG: case TOK_CULLONG: /* XXX: not quite exact, but only useful for testing */ - sprintf(p, "%Lu", cv->ull); +#ifdef _WIN32 + sprintf(p, "%u", (unsigned)cv->i); +#else + sprintf(p, "%llu", (unsigned long long)cv->i); +#endif break; case TOK_LCHAR: cstr_ccat(&cstr_buf, 'L'); @@ -140,29 +501,39 @@ char *get_tok_str(int v, CValue *cv) cstr_ccat(&cstr_buf, '\0'); break; case TOK_PPNUM: - cstr = cv->cstr; - len = cstr->size - 1; - for(i=0;i<len;i++) - add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]); - cstr_ccat(&cstr_buf, '\0'); - break; + case TOK_PPSTR: + return (char*)cv->str.data; case TOK_LSTR: cstr_ccat(&cstr_buf, 'L'); case TOK_STR: - cstr = cv->cstr; cstr_ccat(&cstr_buf, '\"'); if (v == TOK_STR) { - len = cstr->size - 1; + len = cv->str.size - 1; for(i=0;i<len;i++) - add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]); + add_char(&cstr_buf, ((unsigned char *)cv->str.data)[i]); } else { - len = (cstr->size / sizeof(nwchar_t)) - 1; + len = (cv->str.size / sizeof(nwchar_t)) - 1; for(i=0;i<len;i++) - add_char(&cstr_buf, ((nwchar_t *)cstr->data)[i]); + add_char(&cstr_buf, ((nwchar_t *)cv->str.data)[i]); } cstr_ccat(&cstr_buf, '\"'); cstr_ccat(&cstr_buf, '\0'); break; + + case TOK_CFLOAT: + cstr_cat(&cstr_buf, "<float>", 0); + break; + case TOK_CDOUBLE: + cstr_cat(&cstr_buf, "<double>", 0); + break; + case TOK_CLDOUBLE: + cstr_cat(&cstr_buf, "<long double>", 0); + break; + case TOK_LINENUM: + cstr_cat(&cstr_buf, "<linenumber>", 0); + break; + + /* above tokens have value, the ones below don't */ case TOK_LT: v = '<'; goto addv; @@ -175,19 +546,25 @@ char *get_tok_str(int v, CValue *cv) return strcpy(p, "<<="); case TOK_A_SAR: return strcpy(p, ">>="); + case TOK_EOF: + return strcpy(p, "<eof>"); default: if (v < TOK_IDENT) { /* search in two bytes table */ - q = tok_two_chars; + const unsigned char *q = tok_two_chars; while (*q) { if (q[2] == v) { *p++ = q[0]; *p++ = q[1]; *p = '\0'; - return buf; + return cstr_buf.data; } q += 3; } + if (v >= 127) { + sprintf(cstr_buf.data, "<%02x>", v); + return cstr_buf.data; + } addv: *p++ = v; *p = '\0'; @@ -205,15 +582,18 @@ char *get_tok_str(int v, CValue *cv) return cstr_buf.data; } -/* fill input buffer and peek next char */ -static int tcc_peekc_slow(BufferedFile *bf) +/* return the current character, handling end of block if necessary + (but not stray) */ +ST_FUNC int handle_eob(void) { + BufferedFile *bf = file; int len; + /* only tries to read if really end of buffer */ if (bf->buf_ptr >= bf->buf_end) { - if (bf->fd != -1) { + if (bf->fd >= 0) { #if defined(PARSE_DEBUG) - len = 8; + len = 1; #else len = IO_BUF_SIZE; #endif @@ -236,15 +616,8 @@ static int tcc_peekc_slow(BufferedFile *bf) } } -/* return the current character, handling end of block if necessary - (but not stray) */ -static int handle_eob(void) -{ - return tcc_peekc_slow(file); -} - /* read next char from current input file and handle end of input buffer */ -static inline void inp(void) +ST_INLN void inp(void) { ch = *(++(file->buf_ptr)); /* end of buffer/file handling */ @@ -277,7 +650,7 @@ static int handle_stray_noerror(void) static void handle_stray(void) { if (handle_stray_noerror()) - error("stray '\\' in program"); + tcc_error("stray '\\' in program"); } /* skip the stray and handle the \\n case. Output an error if @@ -286,20 +659,21 @@ static int handle_stray1(uint8_t *p) { int c; + file->buf_ptr = p; if (p >= file->buf_end) { - file->buf_ptr = p; c = handle_eob(); + if (c != '\\') + return c; p = file->buf_ptr; - if (c == '\\') - goto parse_stray; - } else { - parse_stray: - file->buf_ptr = p; - ch = *p; - handle_stray(); - p = file->buf_ptr; - c = *p; } + ch = *p; + if (handle_stray_noerror()) { + if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS)) + tcc_error("stray '\\' in program"); + *--file->buf_ptr = '\\'; + } + p = file->buf_ptr; + c = *p; return c; } @@ -329,14 +703,13 @@ static int handle_stray1(uint8_t *p) /* input with '\[\r]\n' handling. Note that this function cannot handle other characters after '\', so you cannot call it inside strings or comments */ -static void minp(void) +ST_FUNC void minp(void) { inp(); if (ch == '\\') handle_stray(); } - /* single line C++ comments */ static uint8_t *parse_line_comment(uint8_t *p) { @@ -375,10 +748,10 @@ static uint8_t *parse_line_comment(uint8_t *p) } /* C comments */ -static uint8_t *parse_comment(uint8_t *p) +ST_FUNC uint8_t *parse_comment(uint8_t *p) { int c; - + p++; for(;;) { /* fast skip loop */ @@ -408,6 +781,8 @@ static uint8_t *parse_comment(uint8_t *p) file->buf_ptr = p; c = handle_eob(); p = file->buf_ptr; + if (c == CH_EOF) + tcc_error("unexpected end of file in comment"); if (c == '\\') { /* skip '\[\r]\n', otherwise just skip the stray */ while (c == '\\') { @@ -437,7 +812,7 @@ static uint8_t *parse_comment(uint8_t *p) c = handle_eob(); p = file->buf_ptr; if (c == CH_EOF) { - error("unexpected end of file in comment"); + tcc_error("unexpected end of file in comment"); } else if (c == '\\') { p++; } @@ -448,17 +823,24 @@ static uint8_t *parse_comment(uint8_t *p) return p; } +ST_FUNC int set_idnum(int c, int val) +{ + int prev = isidnum_table[c - CH_EOF]; + isidnum_table[c - CH_EOF] = val; + return prev; +} + #define cinp minp static inline void skip_spaces(void) { - while (is_space(ch)) + while (isidnum_table[ch - CH_EOF] & IS_SPC) cinp(); } static inline int check_space(int t, int *spc) { - if (is_space(t)) { + if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) { if (*spc) return 1; *spc = 1; @@ -484,7 +866,7 @@ static uint8_t *parse_pp_string(uint8_t *p, if (c == CH_EOF) { unterminated_string: /* XXX: indicate line number of start of string */ - error("missing terminating %c character", sep); + tcc_error("missing terminating %c character", sep); } else if (c == '\\') { /* escape : just skip \[\r]\n */ PEEKC_EOB(c, p); @@ -532,7 +914,7 @@ static uint8_t *parse_pp_string(uint8_t *p, /* skip block of text until #else, #elif or #endif. skip also pairs of #if/#endif */ -void preprocess_skip(void) +static void preprocess_skip(void) { int a, start_of_line, c, in_warn_or_error; uint8_t *p; @@ -604,7 +986,12 @@ redo_start: a--; else if( tok == TOK_ERROR || tok == TOK_WARNING) in_warn_or_error = 1; - } + else if (tok == TOK_LINEFEED) + goto redo_start; + else if (parse_flags & PARSE_FLAG_ASM_FILE) + p = parse_line_comment(p - 1); + } else if (parse_flags & PARSE_FLAG_ASM_FILE) + p = parse_line_comment(p - 1); break; _default: default: @@ -617,35 +1004,12 @@ _default: file->buf_ptr = p; } -/* ParseState handling */ - -/* XXX: currently, no include file info is stored. Thus, we cannot display - accurate messages if the function or data definition spans multiple - files */ - -/* save current parse state in 's' */ -void save_parse_state(ParseState *s) -{ - s->line_num = file->line_num; - s->macro_ptr = macro_ptr; - s->tok = tok; - s->tokc = tokc; -} - -/* restore parse state from 's' */ -void restore_parse_state(ParseState *s) -{ - file->line_num = s->line_num; - macro_ptr = s->macro_ptr; - tok = s->tok; - tokc = s->tokc; -} - +#if 0 /* return the number of additional 'ints' necessary to store the token */ -static inline int tok_ext_size(int t) +static inline int tok_size(const int *p) { - switch(t) { + switch(*p) { /* 4 bytes */ case TOK_CINT: case TOK_CUINT: @@ -653,77 +1017,125 @@ static inline int tok_ext_size(int t) case TOK_LCHAR: case TOK_CFLOAT: case TOK_LINENUM: - return 1; + return 1 + 1; case TOK_STR: case TOK_LSTR: case TOK_PPNUM: - error("unsupported token"); - return 1; + case TOK_PPSTR: + return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2); + case TOK_CLONG: + case TOK_CULONG: + return 1 + LONG_SIZE / 4; case TOK_CDOUBLE: case TOK_CLLONG: case TOK_CULLONG: - return 2; + return 1 + 2; case TOK_CLDOUBLE: - return LDOUBLE_SIZE / 4; + return 1 + LDOUBLE_SIZE / 4; default: - return 0; + return 1 + 0; } } +#endif /* token string handling */ - -static inline void tok_str_new(TokenString *s) +ST_INLN void tok_str_new(TokenString *s) { s->str = NULL; - s->len = 0; + s->len = s->lastlen = 0; s->allocated_len = 0; s->last_line_num = -1; } -static void tok_str_free(int *str) +ST_FUNC TokenString *tok_str_alloc(void) { - tcc_free(str); + TokenString *str = tal_realloc(tokstr_alloc, 0, sizeof *str); + tok_str_new(str); + return str; } -static int *tok_str_realloc(TokenString *s) +ST_FUNC int *tok_str_dup(TokenString *s) { - int *str, len; + int *str; - if (s->allocated_len == 0) { - len = 8; - } else { - len = s->allocated_len * 2; - } - str = tcc_realloc(s->str, len * sizeof(int)); - if (!str) - error("memory full"); - s->allocated_len = len; - s->str = str; + str = tal_realloc(tokstr_alloc, 0, s->len * sizeof(int)); + memcpy(str, s->str, s->len * sizeof(int)); return str; } -static void tok_str_add(TokenString *s, int t) +ST_FUNC void tok_str_free_str(int *str) +{ + tal_free(tokstr_alloc, str); +} + +ST_FUNC void tok_str_free(TokenString *str) +{ + tok_str_free_str(str->str); + tal_free(tokstr_alloc, str); +} + +ST_FUNC int *tok_str_realloc(TokenString *s, int new_size) +{ + int *str, size; + + size = s->allocated_len; + if (size < 16) + size = 16; + while (size < new_size) + size = size * 2; + if (size > s->allocated_len) { + str = tal_realloc(tokstr_alloc, s->str, size * sizeof(int)); + s->allocated_len = size; + s->str = str; + } + return s->str; +} + +ST_FUNC void tok_str_add(TokenString *s, int t) { int len, *str; len = s->len; str = s->str; if (len >= s->allocated_len) - str = tok_str_realloc(s); + str = tok_str_realloc(s, len + 1); str[len++] = t; s->len = len; } +ST_FUNC void begin_macro(TokenString *str, int alloc) +{ + str->alloc = alloc; + str->prev = macro_stack; + str->prev_ptr = macro_ptr; + str->save_line_num = file->line_num; + macro_ptr = str->str; + macro_stack = str; +} + +ST_FUNC void end_macro(void) +{ + TokenString *str = macro_stack; + macro_stack = str->prev; + macro_ptr = str->prev_ptr; + file->line_num = str->save_line_num; + if (str->alloc == 2) { + str->alloc = 3; /* just mark as finished */ + } else { + tok_str_free(str); + } +} + static void tok_str_add2(TokenString *s, int t, CValue *cv) { int len, *str; - len = s->len; + len = s->lastlen = s->len; str = s->str; /* allocate space for worst case */ - if (len + TOK_MAX_SIZE > s->allocated_len) - str = tok_str_realloc(s); + if (len + TOK_MAX_SIZE >= s->allocated_len) + str = tok_str_realloc(s, len + TOK_MAX_SIZE + 1); str[len++] = t; switch(t) { case TOK_CINT: @@ -732,31 +1144,34 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) case TOK_LCHAR: case TOK_CFLOAT: case TOK_LINENUM: +#if LONG_SIZE == 4 + case TOK_CLONG: + case TOK_CULONG: +#endif str[len++] = cv->tab[0]; break; case TOK_PPNUM: + case TOK_PPSTR: case TOK_STR: case TOK_LSTR: { - int nb_words; - CString *cstr; - - nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2; - while ((len + nb_words) > s->allocated_len) - str = tok_str_realloc(s); - cstr = (CString *)(str + len); - cstr->data = NULL; - cstr->size = cv->cstr->size; - cstr->data_allocated = NULL; - cstr->size_allocated = cstr->size; - memcpy((char *)cstr + sizeof(CString), - cv->cstr->data, cstr->size); + /* Insert the string into the int array. */ + size_t nb_words = + 1 + (cv->str.size + sizeof(int) - 1) / sizeof(int); + if (len + nb_words >= s->allocated_len) + str = tok_str_realloc(s, len + nb_words + 1); + str[len] = cv->str.size; + memcpy(&str[len + 1], cv->str.data, cv->str.size); len += nb_words; } break; case TOK_CDOUBLE: case TOK_CLLONG: case TOK_CULLONG: +#if LONG_SIZE == 8 + case TOK_CLONG: + case TOK_CULONG: +#endif #if LDOUBLE_SIZE == 8 case TOK_CLDOUBLE: #endif @@ -785,7 +1200,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) } /* add the current parse token in token string 's' */ -static void tok_str_add_tok(TokenString *s) +ST_FUNC void tok_str_add_tok(TokenString *s) { CValue cval; @@ -798,84 +1213,115 @@ static void tok_str_add_tok(TokenString *s) tok_str_add2(s, tok, &tokc); } +/* get a token from an integer array and increment pointer + accordingly. we code it as a macro to avoid pointer aliasing. */ +static inline void TOK_GET(int *t, const int **pp, CValue *cv) +{ + const int *p = *pp; + int n, *tab; + + tab = cv->tab; + switch(*t = *p++) { +#if LONG_SIZE == 4 + case TOK_CLONG: +#endif + case TOK_CINT: + case TOK_CCHAR: + case TOK_LCHAR: + case TOK_LINENUM: + cv->i = *p++; + break; +#if LONG_SIZE == 4 + case TOK_CULONG: +#endif + case TOK_CUINT: + cv->i = (unsigned)*p++; + break; + case TOK_CFLOAT: + tab[0] = *p++; + break; + case TOK_STR: + case TOK_LSTR: + case TOK_PPNUM: + case TOK_PPSTR: + cv->str.size = *p++; + cv->str.data = p; + p += (cv->str.size + sizeof(int) - 1) / sizeof(int); + break; + case TOK_CDOUBLE: + case TOK_CLLONG: + case TOK_CULLONG: +#if LONG_SIZE == 8 + case TOK_CLONG: + case TOK_CULONG: +#endif + n = 2; + goto copy; + case TOK_CLDOUBLE: #if LDOUBLE_SIZE == 16 -#define LDOUBLE_GET(p, cv) \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; \ - cv.tab[2] = p[2]; \ - cv.tab[3] = p[3]; + n = 4; #elif LDOUBLE_SIZE == 12 -#define LDOUBLE_GET(p, cv) \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; \ - cv.tab[2] = p[2]; + n = 3; #elif LDOUBLE_SIZE == 8 -#define LDOUBLE_GET(p, cv) \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; + n = 2; #else -#error add long double size support +# error add long double size support #endif + copy: + do + *tab++ = *p++; + while (--n); + break; + default: + break; + } + *pp = p; +} +static int macro_is_equal(const int *a, const int *b) +{ + CValue cv; + int t; -/* get a token from an integer array and increment pointer - accordingly. we code it as a macro to avoid pointer aliasing. */ -#define TOK_GET(t, p, cv) \ -{ \ - t = *p++; \ - switch(t) { \ - case TOK_CINT: \ - case TOK_CUINT: \ - case TOK_CCHAR: \ - case TOK_LCHAR: \ - case TOK_CFLOAT: \ - case TOK_LINENUM: \ - cv.tab[0] = *p++; \ - break; \ - case TOK_STR: \ - case TOK_LSTR: \ - case TOK_PPNUM: \ - cv.cstr = (CString *)p; \ - cv.cstr->data = (char *)p + sizeof(CString);\ - p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\ - break; \ - case TOK_CDOUBLE: \ - case TOK_CLLONG: \ - case TOK_CULLONG: \ - cv.tab[0] = p[0]; \ - cv.tab[1] = p[1]; \ - p += 2; \ - break; \ - case TOK_CLDOUBLE: \ - LDOUBLE_GET(p, cv); \ - p += LDOUBLE_SIZE / 4; \ - break; \ - default: \ - break; \ - } \ + if (!a || !b) + return 1; + + while (*a && *b) { + /* first time preallocate macro_equal_buf, next time only reset position to start */ + cstr_reset(¯o_equal_buf); + TOK_GET(&t, &a, &cv); + cstr_cat(¯o_equal_buf, get_tok_str(t, &cv), 0); + TOK_GET(&t, &b, &cv); + if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv))) + return 0; + } + return !(*a || *b); } /* defines handling */ -static inline void define_push(int v, int macro_type, int *str, Sym *first_arg) +ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg) { - Sym *s; + Sym *s, *o; - s = sym_push2(&define_stack, v, macro_type, (long)str); + o = define_find(v); + s = sym_push2(&define_stack, v, macro_type, 0); + s->d = str; s->next = first_arg; table_ident[v - TOK_IDENT]->sym_define = s; + + if (o && !macro_is_equal(o->d, s->d)) + tcc_warning("%s redefined", get_tok_str(v, NULL)); } /* undefined a define symbol. Its name is just set to zero */ -static void define_undef(Sym *s) +ST_FUNC void define_undef(Sym *s) { - int v; - v = s->v; + int v = s->v; if (v >= TOK_IDENT && v < tok_ident) table_ident[v - TOK_IDENT]->sym_define = NULL; - s->v = 0; } -static inline Sym *define_find(int v) +ST_INLN Sym *define_find(int v) { v -= TOK_IDENT; if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) @@ -884,28 +1330,31 @@ static inline Sym *define_find(int v) } /* free define stack until top reaches 'b' */ -static void free_defines(Sym *b) +ST_FUNC void free_defines(Sym *b) { - Sym *top, *top1; - int v; - - top = define_stack; - while (top != b) { - top1 = top->prev; - /* do not free args or predefined defines */ - if (top->c) - tok_str_free((int *)top->c); - v = top->v; - if (v >= TOK_IDENT && v < tok_ident) - table_ident[v - TOK_IDENT]->sym_define = NULL; + while (define_stack != b) { + Sym *top = define_stack; + define_stack = top->prev; + tok_str_free_str(top->d); + define_undef(top); sym_free(top); - top = top1; } - define_stack = b; + + /* restore remaining (-D or predefined) symbols if they were + #undef'd in the file */ + while (b) { + int v = b->v; + if (v >= TOK_IDENT && v < tok_ident) { + Sym **d = &table_ident[v - TOK_IDENT]->sym_define; + if (!*d) + *d = b; + } + b = b->prev; + } } /* label lookup */ -static Sym *label_find(int v) +ST_FUNC Sym *label_find(int v) { v -= TOK_IDENT; if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) @@ -913,7 +1362,7 @@ static Sym *label_find(int v) return table_ident[v]->sym_label; } -static Sym *label_push(Sym **ptop, int v, int flags) +ST_FUNC Sym *label_push(Sym **ptop, int v, int flags) { Sym *s, **ps; s = sym_push2(ptop, v, 0, 0); @@ -932,37 +1381,55 @@ static Sym *label_push(Sym **ptop, int v, int flags) /* pop labels until element last is reached. Look if any labels are undefined. Define symbols if '&&label' was used. */ -static void label_pop(Sym **ptop, Sym *slast) +ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) { Sym *s, *s1; for(s = *ptop; s != slast; s = s1) { s1 = s->prev; if (s->r == LABEL_DECLARED) { - warning("label '%s' declared but not used", get_tok_str(s->v, NULL)); + tcc_warning("label '%s' declared but not used", get_tok_str(s->v, NULL)); } else if (s->r == LABEL_FORWARD) { - error("label '%s' used but not defined", + tcc_error("label '%s' used but not defined", get_tok_str(s->v, NULL)); } else { if (s->c) { /* define corresponding symbol. A size of 1 is put. */ - put_extern_sym(s, cur_text_section, (long)s->next, 1); + put_extern_sym(s, cur_text_section, s->jnext, 1); } } /* remove label */ table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok; - sym_free(s); + if (!keep) + sym_free(s); } - *ptop = slast; + if (!keep) + *ptop = slast; +} + +/* fake the nth "#if defined test_..." for tcc -dt -run */ +static void maybe_run_test(TCCState *s) +{ + const char *p; + if (s->include_stack_ptr != s->include_stack) + return; + p = get_tok_str(tok, NULL); + if (0 != memcmp(p, "test_", 5)) + return; + if (0 != --s->run_test) + return; + fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp); + define_push(tok, MACRO_OBJ, NULL, NULL); } /* eval an expression for #if/#elif */ static int expr_preprocess(void) { int c, t; - TokenString str; + TokenString *str; - tok_str_new(&str); + str = tok_str_alloc(); + pp_expr = 1; while (tok != TOK_LINEFEED && tok != TOK_EOF) { next(); /* do macro subst */ if (tok == TOK_DEFINED) { @@ -970,9 +1437,16 @@ static int expr_preprocess(void) t = tok; if (t == '(') next_nomacro(); + if (tok < TOK_IDENT) + expect("identifier"); + if (tcc_state->run_test) + maybe_run_test(tcc_state); c = define_find(tok) != 0; - if (t == '(') + if (t == '(') { next_nomacro(); + if (tok != ')') + expect("')'"); + } tok = TOK_CINT; tokc.i = c; } else if (tok >= TOK_IDENT) { @@ -980,55 +1454,45 @@ static int expr_preprocess(void) tok = TOK_CINT; tokc.i = 0; } - tok_str_add_tok(&str); + tok_str_add_tok(str); } - tok_str_add(&str, -1); /* simulate end of file */ - tok_str_add(&str, 0); + pp_expr = 0; + tok_str_add(str, -1); /* simulate end of file */ + tok_str_add(str, 0); /* now evaluate C constant expression */ - macro_ptr = str.str; + begin_macro(str, 1); next(); c = expr_const(); - macro_ptr = NULL; - tok_str_free(str.str); + end_macro(); return c != 0; } -#if defined(PARSE_DEBUG) || defined(PP_DEBUG) -static void tok_print(int *str) -{ - int t; - CValue cval; - - printf("<"); - while (1) { - TOK_GET(t, str, cval); - if (!t) - break; - printf("%s", get_tok_str(t, &cval)); - } - printf(">\n"); -} -#endif /* parse after #define */ -static void parse_define(void) +ST_FUNC void parse_define(void) { Sym *s, *first, **ps; int v, t, varg, is_vaargs, spc; - TokenString str; - + int saved_parse_flags = parse_flags; + v = tok; - if (v < TOK_IDENT) - error("invalid macro name '%s'", get_tok_str(tok, &tokc)); + if (v < TOK_IDENT || v == TOK_DEFINED) + tcc_error("invalid macro name '%s'", get_tok_str(tok, &tokc)); /* XXX: should check if same macro (ANSI) */ first = NULL; t = MACRO_OBJ; + /* We have to parse the whole define as if not in asm mode, in particular + no line comment with '#' must be ignored. Also for function + macros the argument list must be parsed without '.' being an ID + character. */ + parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES); /* '(' must be just after macro definition for MACRO_FUNC */ next_nomacro_spc(); if (tok == '(') { + int dotid = set_idnum('.', 0); next_nomacro(); ps = &first; - while (tok != ')') { + if (tok != ')') for (;;) { varg = tok; next_nomacro(); is_vaargs = 0; @@ -1040,129 +1504,161 @@ static void parse_define(void) next_nomacro(); } if (varg < TOK_IDENT) - error("badly punctuated parameter list"); + bad_list: + tcc_error("bad macro parameter list"); s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0); *ps = s; ps = &s->next; - if (tok != ',') + if (tok == ')') break; + if (tok != ',' || is_vaargs) + goto bad_list; next_nomacro(); } - if (tok == ')') - next_nomacro_spc(); + next_nomacro_spc(); t = MACRO_FUNC; + set_idnum('.', dotid); } - tok_str_new(&str); + + tokstr_buf.len = 0; spc = 2; - /* EOF testing necessary for '-D' handling */ + parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED; + /* The body of a macro definition should be parsed such that identifiers + are parsed like the file mode determines (i.e. with '.' being an + ID character in asm mode). But '#' should be retained instead of + regarded as line comment leader, so still don't set ASM_FILE + in parse_flags. */ while (tok != TOK_LINEFEED && tok != TOK_EOF) { - /* remove spaces around ## and after '#' */ + /* remove spaces around ## and after '#' */ if (TOK_TWOSHARPS == tok) { + if (2 == spc) + goto bad_twosharp; if (1 == spc) - --str.len; - spc = 2; + --tokstr_buf.len; + spc = 3; + tok = TOK_PPJOIN; } else if ('#' == tok) { - spc = 2; + spc = 4; } else if (check_space(tok, &spc)) { goto skip; } - tok_str_add2(&str, tok, &tokc); + tok_str_add2(&tokstr_buf, tok, &tokc); skip: next_nomacro_spc(); } + + parse_flags = saved_parse_flags; if (spc == 1) - --str.len; /* remove trailing space */ - tok_str_add(&str, 0); -#ifdef PP_DEBUG - printf("define %s %d: ", get_tok_str(v, NULL), t); - tok_print(str.str); -#endif - define_push(v, t, str.str, first); + --tokstr_buf.len; /* remove trailing space */ + tok_str_add(&tokstr_buf, 0); + if (3 == spc) +bad_twosharp: + tcc_error("'##' cannot appear at either end of macro"); + define_push(v, t, tok_str_dup(&tokstr_buf), first); } -static inline int hash_cached_include(int type, const char *filename) +static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add) { const unsigned char *s; unsigned int h; + CachedInclude *e; + int i; h = TOK_HASH_INIT; - h = TOK_HASH_FUNC(h, type); - s = filename; + s = (unsigned char *) filename; while (*s) { +#ifdef _WIN32 + h = TOK_HASH_FUNC(h, toup(*s)); +#else h = TOK_HASH_FUNC(h, *s); +#endif s++; } h &= (CACHED_INCLUDES_HASH_SIZE - 1); - return h; -} -/* XXX: use a token or a hash table to accelerate matching ? */ -static CachedInclude *search_cached_include(TCCState *s1, - int type, const char *filename) -{ - CachedInclude *e; - int i, h; - h = hash_cached_include(type, filename); i = s1->cached_includes_hash[h]; for(;;) { if (i == 0) break; e = s1->cached_includes[i - 1]; - if (e->type == type && !PATHCMP(e->filename, filename)) + if (0 == PATHCMP(e->filename, filename)) return e; i = e->hash_next; } - return NULL; -} - -static inline void add_cached_include(TCCState *s1, int type, - const char *filename, int ifndef_macro) -{ - CachedInclude *e; - int h; + if (!add) + return NULL; - if (search_cached_include(s1, type, filename)) - return; -#ifdef INC_DEBUG - printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL)); -#endif e = tcc_malloc(sizeof(CachedInclude) + strlen(filename)); - if (!e) - return; - e->type = type; strcpy(e->filename, filename); - e->ifndef_macro = ifndef_macro; - dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e); + e->ifndef_macro = e->once = 0; + dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e); /* add in hash table */ - h = hash_cached_include(type, filename); e->hash_next = s1->cached_includes_hash[h]; s1->cached_includes_hash[h] = s1->nb_cached_includes; +#ifdef INC_DEBUG + printf("adding cached '%s'\n", filename); +#endif + return e; } static void pragma_parse(TCCState *s1) { - int val; - - next(); - if (tok == TOK_pack) { - /* - This may be: - #pragma pack(1) // set - #pragma pack() // reset to default - #pragma pack(push,1) // push & set - #pragma pack(pop) // restore previous - */ + next_nomacro(); + if (tok == TOK_push_macro || tok == TOK_pop_macro) { + int t = tok, v; + Sym *s; + + if (next(), tok != '(') + goto pragma_err; + if (next(), tok != TOK_STR) + goto pragma_err; + v = tok_alloc(tokc.str.data, tokc.str.size - 1)->tok; + if (next(), tok != ')') + goto pragma_err; + if (t == TOK_push_macro) { + while (NULL == (s = define_find(v))) + define_push(v, 0, NULL, NULL); + s->type.ref = s; /* set push boundary */ + } else { + for (s = define_stack; s; s = s->prev) + if (s->v == v && s->type.ref == s) { + s->type.ref = NULL; + break; + } + } + if (s) + table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL; + else + tcc_warning("unbalanced #pragma pop_macro"); + pp_debug_tok = t, pp_debug_symv = v; + + } else if (tok == TOK_once) { + search_cached_include(s1, file->filename, 1)->once = pp_once; + + } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) { + /* tcc -E: keep pragmas below unchanged */ + unget_tok(' '); + unget_tok(TOK_PRAGMA); + unget_tok('#'); + unget_tok(TOK_LINEFEED); + + } else if (tok == TOK_pack) { + /* This may be: + #pragma pack(1) // set + #pragma pack() // reset to default + #pragma pack(push,1) // push & set + #pragma pack(pop) // restore previous */ next(); skip('('); if (tok == TOK_ASM_pop) { next(); if (s1->pack_stack_ptr <= s1->pack_stack) { stk_error: - error("out of pack stack"); + tcc_error("out of pack stack"); } s1->pack_stack_ptr--; } else { - val = 0; + int val = 0; if (tok != ')') { if (tok == TOK_ASM_push) { next(); @@ -1171,23 +1667,51 @@ static void pragma_parse(TCCState *s1) s1->pack_stack_ptr++; skip(','); } - if (tok != TOK_CINT) { - pack_error: - error("invalid pack pragma"); - } + if (tok != TOK_CINT) + goto pragma_err; val = tokc.i; if (val < 1 || val > 16 || (val & (val - 1)) != 0) - goto pack_error; + goto pragma_err; next(); } *s1->pack_stack_ptr = val; - skip(')'); } + if (tok != ')') + goto pragma_err; + + } else if (tok == TOK_comment) { + char *p; int t; + next(); + skip('('); + t = tok; + next(); + skip(','); + if (tok != TOK_STR) + goto pragma_err; + p = tcc_strdup((char *)tokc.str.data); + next(); + if (tok != ')') + goto pragma_err; + if (t == TOK_lib) { + dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p); + } else { + if (t == TOK_option) + tcc_set_options(s1, p); + tcc_free(p); + } + + } else if (s1->warn_unsupported) { + tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc)); } + return; + +pragma_err: + tcc_error("malformed #pragma directive"); + return; } /* is_bof is true if first non space token at beginning of file */ -static void preprocess(int is_bof) +ST_FUNC void preprocess(int is_bof) { TCCState *s1 = tcc_state; int i, c, n, saved_parse_flags; @@ -1195,17 +1719,26 @@ static void preprocess(int is_bof) Sym *s; saved_parse_flags = parse_flags; - parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | - PARSE_FLAG_LINEFEED; + parse_flags = PARSE_FLAG_PREPROCESS + | PARSE_FLAG_TOK_NUM + | PARSE_FLAG_TOK_STR + | PARSE_FLAG_LINEFEED + | (parse_flags & PARSE_FLAG_ASM_FILE) + ; + next_nomacro(); redo: switch(tok) { case TOK_DEFINE: + pp_debug_tok = tok; next_nomacro(); + pp_debug_symv = tok; parse_define(); break; case TOK_UNDEF: + pp_debug_tok = tok; next_nomacro(); + pp_debug_symv = tok; s = define_find(tok); /* undefine symbol by putting an invalid name */ if (s) @@ -1242,116 +1775,93 @@ static void preprocess(int is_bof) inp(); #endif } else { - /* computed #include : either we have only strings or - we have anything enclosed in '<>' */ + int len; + /* computed #include : concatenate everything up to linefeed, + the result must be one of the two accepted forms. + Don't convert pp-tokens to tokens here. */ + parse_flags = (PARSE_FLAG_PREPROCESS + | PARSE_FLAG_LINEFEED + | (parse_flags & PARSE_FLAG_ASM_FILE)); next(); buf[0] = '\0'; - if (tok == TOK_STR) { - while (tok != TOK_LINEFEED) { - if (tok != TOK_STR) { - include_syntax: - error("'#include' expects \"FILENAME\" or <FILENAME>"); - } - pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data); - next(); - } - c = '\"'; - } else { - int len; - while (tok != TOK_LINEFEED) { - pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); - next(); - } - len = strlen(buf); - /* check syntax and remove '<>' */ - if (len < 2 || buf[0] != '<' || buf[len - 1] != '>') - goto include_syntax; - memmove(buf, buf + 1, len - 2); - buf[len - 2] = '\0'; - c = '>'; - } + while (tok != TOK_LINEFEED) { + pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); + next(); + } + len = strlen(buf); + /* check syntax and remove '<>|""' */ + if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') && + (buf[0] != '<' || buf[len-1] != '>')))) + tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); + c = buf[len-1]; + memmove(buf, buf + 1, len - 2); + buf[len - 2] = '\0'; } if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) - error("#include recursion too deep"); - - n = s1->nb_include_paths + s1->nb_sysinclude_paths; - for (i = -2; i < n; ++i) { + tcc_error("#include recursion too deep"); + /* store current file in stack, but increment stack later below */ + *s1->include_stack_ptr = file; + i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0; + n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths; + for (; i < n; ++i) { char buf1[sizeof file->filename]; - BufferedFile *f; CachedInclude *e; const char *path; - int size; - if (i == -2) { + if (i == 0) { /* check absolute include path */ if (!IS_ABSPATH(buf)) continue; buf1[0] = 0; - } else if (i == -1) { - /* search in current dir if "header.h" */ + } else if (i == 1) { + /* search in file's dir if "header.h" */ if (c != '\"') continue; - size = tcc_basename(file->filename) - file->filename; - memcpy(buf1, file->filename, size); - buf1[size] = '\0'; + /* https://savannah.nongnu.org/bugs/index.php?50847 */ + path = file->true_filename; + pstrncpy(buf1, path, tcc_basename(path) - path); } else { /* search in all the include paths */ - if (i < s1->nb_include_paths) - path = s1->include_paths[i]; - else - path = s1->sysinclude_paths[i - s1->nb_include_paths]; + int j = i - 2, k = j - s1->nb_include_paths; + path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k]; pstrcpy(buf1, sizeof(buf1), path); pstrcat(buf1, sizeof(buf1), "/"); } pstrcat(buf1, sizeof(buf1), buf); - - e = search_cached_include(s1, c, buf1); - if (e && define_find(e->ifndef_macro)) { + e = search_cached_include(s1, buf1, 0); + if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) { /* no need to parse the include because the 'ifndef macro' - is defined */ + is defined (or had #pragma once) */ #ifdef INC_DEBUG - printf("%s: skipping %s\n", file->filename, buf); + printf("%s: skipping cached %s\n", file->filename, buf1); #endif - f = NULL; - } else { - f = tcc_open(s1, buf1); - if (!f) - continue; + goto include_done; } - if (tok == TOK_INCLUDE_NEXT) { - tok = TOK_INCLUDE; - if (f) - tcc_close(f); + if (tcc_open(s1, buf1) < 0) continue; - } - - if (!f) - goto include_done; + file->include_next_index = i + 1; #ifdef INC_DEBUG - printf("%s: including %s\n", file->filename, buf1); + printf("%s: including %s\n", file->prev->filename, file->filename); #endif - - /* XXX: fix current line init */ - /* push current file in stack */ - *s1->include_stack_ptr++ = file; - f->inc_type = c; - pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1); - file = f; + /* update target deps */ + dynarray_add(&s1->target_deps, &s1->nb_target_deps, + tcc_strdup(buf1)); + /* push current file in stack */ + ++s1->include_stack_ptr; /* add include file debug info */ - if (tcc_state->do_debug) { + if (s1->do_debug) put_stabs(file->filename, N_BINCL, 0, 0, 0); - } tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; ch = file->buf_ptr[0]; goto the_end; } - error("include file '%s' not found", buf); + tcc_error("include file '%s' not found", buf); include_done: break; case TOK_IFNDEF: @@ -1365,7 +1875,7 @@ include_done: do_ifdef: next_nomacro(); if (tok < TOK_IDENT) - error("invalid argument for '#if%sdef'", c ? "n" : ""); + tcc_error("invalid argument for '#if%sdef'", c ? "n" : ""); if (is_bof) { if (c) { #ifdef INC_DEBUG @@ -1377,30 +1887,34 @@ include_done: c = (define_find(tok) != 0) ^ c; do_if: if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE) - error("memory full"); + tcc_error("memory full (ifdef)"); *s1->ifdef_stack_ptr++ = c; goto test_skip; case TOK_ELSE: if (s1->ifdef_stack_ptr == s1->ifdef_stack) - error("#else without matching #if"); + tcc_error("#else without matching #if"); if (s1->ifdef_stack_ptr[-1] & 2) - error("#else after #else"); + tcc_error("#else after #else"); c = (s1->ifdef_stack_ptr[-1] ^= 3); - goto test_skip; + goto test_else; case TOK_ELIF: if (s1->ifdef_stack_ptr == s1->ifdef_stack) - error("#elif without matching #if"); + tcc_error("#elif without matching #if"); c = s1->ifdef_stack_ptr[-1]; if (c > 1) - error("#elif after #else"); + tcc_error("#elif after #else"); /* last #if/#elif expression was true: we skip */ - if (c == 1) - goto skip; - c = expr_preprocess(); - s1->ifdef_stack_ptr[-1] = c; + if (c == 1) { + c = 0; + } else { + c = expr_preprocess(); + s1->ifdef_stack_ptr[-1] = c; + } + test_else: + if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1) + file->ifndef_macro = 0; test_skip: if (!(c & 1)) { - skip: preprocess_skip(); is_bof = 0; goto redo; @@ -1408,7 +1922,7 @@ include_done: break; case TOK_ENDIF: if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr) - error("#endif without matching #if"); + tcc_error("#endif without matching #if"); s1->ifdef_stack_ptr--; /* '#ifndef macro' was at the start of file. Now we check if an '#endif' is exactly at the end of file */ @@ -1424,18 +1938,33 @@ include_done: goto the_end; } break; + case TOK_PPNUM: + n = strtoul((char*)tokc.str.data, &q, 10); + goto _line_num; case TOK_LINE: next(); if (tok != TOK_CINT) - error("#line"); - file->line_num = tokc.i - 1; /* the line number will be incremented after */ + _line_err: + tcc_error("wrong #line format"); + n = tokc.i; + _line_num: next(); if (tok != TOK_LINEFEED) { - if (tok != TOK_STR) - error("#line"); - pstrcpy(file->filename, sizeof(file->filename), - (char *)tokc.cstr->data); + if (tok == TOK_STR) { + if (file->true_filename == file->filename) + file->true_filename = tcc_strdup(file->filename); + pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data); + } else if (parse_flags & PARSE_FLAG_ASM_FILE) + break; + else + goto _line_err; + --n; } + if (file->fd > 0) + total_lines += file->line_num - n; + file->line_num = n; + if (s1->do_debug) + put_stabs(file->filename, N_BINCL, 0, 0, 0); break; case TOK_ERROR: case TOK_WARNING: @@ -1454,22 +1983,26 @@ include_done: } *q = '\0'; if (c == TOK_ERROR) - error("#error %s", buf); + tcc_error("#error %s", buf); else - warning("#warning %s", buf); + tcc_warning("#warning %s", buf); break; case TOK_PRAGMA: pragma_parse(s1); break; + case TOK_LINEFEED: + goto the_end; default: - if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) { - /* '!' is ignored to allow C scripts. numbers are ignored - to emulate cpp behaviour */ - } else { - if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS)) - warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); - } - break; + /* ignore gas line comment in an 'S' file. */ + if (saved_parse_flags & PARSE_FLAG_ASM_FILE) + goto ignore; + if (tok == '!' && is_bof) + /* '!' is ignored at beginning to allow C scripts. */ + goto ignore; + tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); + ignore: + file->buf_ptr = parse_line_comment(file->buf_ptr - 1); + goto the_end; } /* ignore other preprocess commands or #! for C scripts */ while (tok != TOK_LINEFEED) @@ -1565,18 +2098,84 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long default: invalid_escape: if (c >= '!' && c <= '~') - warning("unknown escape sequence: \'\\%c\'", c); + tcc_warning("unknown escape sequence: \'\\%c\'", c); else - warning("unknown escape sequence: \'\\x%x\'", c); + tcc_warning("unknown escape sequence: \'\\x%x\'", c); break; } + } else if (is_long && c >= 0x80) { + /* assume we are processing UTF-8 sequence */ + /* reference: The Unicode Standard, Version 10.0, ch3.9 */ + + int cont; /* count of continuation bytes */ + int skip; /* how many bytes should skip when error occurred */ + int i; + + /* decode leading byte */ + if (c < 0xC2) { + skip = 1; goto invalid_utf8_sequence; + } else if (c <= 0xDF) { + cont = 1; n = c & 0x1f; + } else if (c <= 0xEF) { + cont = 2; n = c & 0xf; + } else if (c <= 0xF4) { + cont = 3; n = c & 0x7; + } else { + skip = 1; goto invalid_utf8_sequence; + } + + /* decode continuation bytes */ + for (i = 1; i <= cont; i++) { + int l = 0x80, h = 0xBF; + + /* adjust limit for second byte */ + if (i == 1) { + switch (c) { + case 0xE0: l = 0xA0; break; + case 0xED: h = 0x9F; break; + case 0xF0: l = 0x90; break; + case 0xF4: h = 0x8F; break; + } + } + + if (p[i] < l || p[i] > h) { + skip = i; goto invalid_utf8_sequence; + } + + n = (n << 6) | (p[i] & 0x3f); + } + + /* advance pointer */ + p += 1 + cont; + c = n; + goto add_char_nonext; + + /* error handling */ + invalid_utf8_sequence: + tcc_warning("ill-formed UTF-8 subsequence starting with: \'\\x%x\'", c); + c = 0xFFFD; + p += skip; + goto add_char_nonext; + } p++; add_char_nonext: if (!is_long) cstr_ccat(outstr, c); - else + else { +#ifdef TCC_TARGET_PE + /* store as UTF-16 */ + if (c < 0x10000) { + cstr_wccat(outstr, c); + } else { + c -= 0x10000; + cstr_wccat(outstr, (c >> 10) + 0xD800); + cstr_wccat(outstr, (c & 0x3FF) + 0xDC00); + } +#else cstr_wccat(outstr, c); +#endif + } } /* add a trailing '\0' */ if (!is_long) @@ -1585,11 +2184,59 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long cstr_wccat(outstr, '\0'); } +static void parse_string(const char *s, int len) +{ + uint8_t buf[1000], *p = buf; + int is_long, sep; + + if ((is_long = *s == 'L')) + ++s, --len; + sep = *s++; + len -= 2; + if (len >= sizeof buf) + p = tcc_malloc(len + 1); + memcpy(p, s, len); + p[len] = 0; + + cstr_reset(&tokcstr); + parse_escape_string(&tokcstr, p, is_long); + if (p != buf) + tcc_free(p); + + if (sep == '\'') { + int char_size, i, n, c; + /* XXX: make it portable */ + if (!is_long) + tok = TOK_CCHAR, char_size = 1; + else + tok = TOK_LCHAR, char_size = sizeof(nwchar_t); + n = tokcstr.size / char_size - 1; + if (n < 1) + tcc_error("empty character constant"); + if (n > 1) + tcc_warning("multi-character character constant"); + for (c = i = 0; i < n; ++i) { + if (is_long) + c = ((nwchar_t *)tokcstr.data)[i]; + else + c = (c << 8) | ((char *)tokcstr.data)[i]; + } + tokc.i = c; + } else { + tokc.str.size = tokcstr.size; + tokc.str.data = tokcstr.data; + if (!is_long) + tok = TOK_STR; + else + tok = TOK_LSTR; + } +} + /* we use 64 bit numbers */ #define BN_SIZE 2 /* bn = (bn << shift) | or_val */ -void bn_lshift(unsigned int *bn, int shift, int or_val) +static void bn_lshift(unsigned int *bn, int shift, int or_val) { int i; unsigned int v; @@ -1600,7 +2247,7 @@ void bn_lshift(unsigned int *bn, int shift, int or_val) } } -void bn_zero(unsigned int *bn) +static void bn_zero(unsigned int *bn) { int i; for(i=0;i<BN_SIZE;i++) { @@ -1610,7 +2257,7 @@ void bn_zero(unsigned int *bn) /* parse number in null terminated string 'p' and return it in the current token */ -void parse_number(const char *p) +static void parse_number(const char *p) { int b, t, shift, frac_bits, s, exp_val, ch; char *q; @@ -1652,7 +2299,7 @@ void parse_number(const char *p) break; if (q >= token_buf + STRING_MAX_SIZE) { num_too_long: - error("number too long"); + tcc_error("number too long"); } *q++ = ch; ch = *p++; @@ -1670,7 +2317,7 @@ void parse_number(const char *p) if (b == 16) shift = 4; else - shift = 2; + shift = 1; bn_zero(bn); q = token_buf; while (1) { @@ -1701,7 +2348,7 @@ void parse_number(const char *p) break; } if (t >= b) - error("invalid digit"); + tcc_error("invalid digit"); bn_lshift(bn, shift, t); frac_bits += shift; ch = *p++; @@ -1738,9 +2385,14 @@ void parse_number(const char *p) tokc.f = (float)d; } else if (t == 'L') { ch = *p++; +#ifdef TCC_TARGET_PE + tok = TOK_CDOUBLE; + tokc.d = d; +#else tok = TOK_CLDOUBLE; /* XXX: not large enough */ tokc.ld = (long double)d; +#endif } else { tok = TOK_CDOUBLE; tokc.d = d; @@ -1789,8 +2441,13 @@ void parse_number(const char *p) tokc.f = strtof(token_buf, NULL); } else if (t == 'L') { ch = *p++; +#ifdef TCC_TARGET_PE + tok = TOK_CDOUBLE; + tokc.d = strtod(token_buf, NULL); +#else tok = TOK_CLDOUBLE; tokc.ld = strtold(token_buf, NULL); +#endif } else { tok = TOK_CDOUBLE; tokc.d = strtod(token_buf, NULL); @@ -1798,7 +2455,8 @@ void parse_number(const char *p) } } else { unsigned long long n, n1; - int lcount, ucount; + int lcount, ucount, ov = 0; + const char *p1; /* integer number */ *q = '\0'; @@ -1811,71 +2469,80 @@ void parse_number(const char *p) while(1) { t = *q++; /* no need for checks except for base 10 / 8 errors */ - if (t == '\0') { + if (t == '\0') break; - } else if (t >= 'a') { + else if (t >= 'a') t = t - 'a' + 10; - } else if (t >= 'A') { + else if (t >= 'A') t = t - 'A' + 10; - } else { + else t = t - '0'; - if (t >= b) - error("invalid digit"); - } + if (t >= b) + tcc_error("invalid digit"); n1 = n; n = n * b + t; /* detect overflow */ - /* XXX: this test is not reliable */ - if (n < n1) - error("integer constant overflow"); + if (n1 >= 0x1000000000000000ULL && n / b != n1) + ov = 1; } - - /* XXX: not exactly ANSI compliant */ - if ((n & 0xffffffff00000000LL) != 0) { - if ((n >> 63) != 0) - tok = TOK_CULLONG; - else - tok = TOK_CLLONG; - } else if (n > 0x7fffffff) { - tok = TOK_CUINT; - } else { - tok = TOK_CINT; - } - lcount = 0; - ucount = 0; + + /* Determine the characteristics (unsigned and/or 64bit) the type of + the constant must have according to the constant suffix(es) */ + lcount = ucount = 0; + p1 = p; for(;;) { t = toup(ch); if (t == 'L') { if (lcount >= 2) - error("three 'l's in integer constant"); + tcc_error("three 'l's in integer constant"); + if (lcount && *(p - 1) != ch) + tcc_error("incorrect integer suffix: %s", p1); lcount++; - if (lcount == 2) { - if (tok == TOK_CINT) - tok = TOK_CLLONG; - else if (tok == TOK_CUINT) - tok = TOK_CULLONG; - } ch = *p++; } else if (t == 'U') { if (ucount >= 1) - error("two 'u's in integer constant"); + tcc_error("two 'u's in integer constant"); ucount++; - if (tok == TOK_CINT) - tok = TOK_CUINT; - else if (tok == TOK_CLLONG) - tok = TOK_CULLONG; ch = *p++; } else { break; } } - if (tok == TOK_CINT || tok == TOK_CUINT) - tokc.ui = n; - else - tokc.ull = n; + + /* Determine if it needs 64 bits and/or unsigned in order to fit */ + if (ucount == 0 && b == 10) { + if (lcount <= (LONG_SIZE == 4)) { + if (n >= 0x80000000U) + lcount = (LONG_SIZE == 4) + 1; + } + if (n >= 0x8000000000000000ULL) + ov = 1, ucount = 1; + } else { + if (lcount <= (LONG_SIZE == 4)) { + if (n >= 0x100000000ULL) + lcount = (LONG_SIZE == 4) + 1; + else if (n >= 0x80000000U) + ucount = 1; + } + if (n >= 0x8000000000000000ULL) + ucount = 1; + } + + if (ov) + tcc_warning("integer constant overflow"); + + tok = TOK_CINT; + if (lcount) { + tok = TOK_CLONG; + if (lcount == 2) + tok = TOK_CLLONG; + } + if (ucount) + ++tok; /* TOK_CU... */ + tokc.i = n; } if (ch) - error("invalid number\n"); + tcc_error("invalid number\n"); } @@ -1893,7 +2560,7 @@ void parse_number(const char *p) /* return next token without macro substitution */ static inline void next_nomacro1(void) { - int t, c, is_long; + int t, c, is_long, len; TokenSym *ts; uint8_t *p, *p1; unsigned int h; @@ -1906,7 +2573,11 @@ static inline void next_nomacro1(void) case '\t': tok = c; p++; - goto keep_tok_flags; + if (parse_flags & PARSE_FLAG_SPACES) + goto keep_tok_flags; + while (isidnum_table[*p - CH_EOF] & IS_SPC) + ++p; + goto redo_no_start; case '\f': case '\v': case '\r': @@ -1914,22 +2585,12 @@ static inline void next_nomacro1(void) goto redo_no_start; case '\\': /* first look if it is in fact an end of buffer */ - if (p >= file->buf_end) { - file->buf_ptr = p; - handle_eob(); - p = file->buf_ptr; - if (p >= file->buf_end) - goto parse_eof; - else - goto redo_no_start; - } else { - file->buf_ptr = p; - ch = *p; - handle_stray(); - p = file->buf_ptr; + c = handle_stray1(p); + p = file->buf_ptr; + if (c == '\\') + goto parse_simple; + if (c != CH_EOF) goto redo_no_start; - } - parse_eof: { TCCState *s1 = tcc_state; if ((parse_flags & PARSE_FLAG_LINEFEED) @@ -1937,8 +2598,11 @@ static inline void next_nomacro1(void) tok_flags |= TOK_FLAG_EOF; tok = TOK_LINEFEED; goto keep_tok_flags; - } else if (s1->include_stack_ptr == s1->include_stack || - !(parse_flags & PARSE_FLAG_PREPROCESS)) { + } else if (!(parse_flags & PARSE_FLAG_PREPROCESS)) { + tok = TOK_EOF; + } else if (s1->ifdef_stack_ptr != file->ifdef_stack_ptr) { + tcc_error("missing #endif"); + } else if (s1->include_stack_ptr == s1->include_stack) { /* no include left : end of file. */ tok = TOK_EOF; } else { @@ -1951,8 +2615,9 @@ static inline void next_nomacro1(void) #ifdef INC_DEBUG printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL)); #endif - add_cached_include(s1, file->inc_type, file->inc_filename, - file->ifndef_macro_saved); + search_cached_include(s1, file->filename, 1) + ->ifndef_macro = file->ifndef_macro_saved; + tok_flags &= ~TOK_FLAG_ENDIF; } /* add end of include file debug info */ @@ -1960,10 +2625,11 @@ static inline void next_nomacro1(void) put_stabd(N_EINCL, 0, 0); } /* pop include stack */ - tcc_close(file); + tcc_close(); s1->include_stack_ptr--; - file = *s1->include_stack_ptr; p = file->buf_ptr; + if (p == file->buffer) + tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL; goto redo_no_start; } } @@ -1973,6 +2639,7 @@ static inline void next_nomacro1(void) file->line_num++; tok_flags |= TOK_FLAG_BOL; p++; +maybe_newline: if (0 == (parse_flags & PARSE_FLAG_LINEFEED)) goto redo_no_start; tok = TOK_LINEFEED; @@ -1986,13 +2653,13 @@ static inline void next_nomacro1(void) file->buf_ptr = p; preprocess(tok_flags & TOK_FLAG_BOF); p = file->buf_ptr; - goto redo_no_start; + goto maybe_newline; } else { if (c == '#') { p++; tok = TOK_TWOSHARPS; } else { - if (parse_flags & PARSE_FLAG_ASM_COMMENTS) { + if (parse_flags & PARSE_FLAG_ASM_FILE) { p = parse_line_comment(p - 1); goto redo_no_start; } else { @@ -2001,6 +2668,12 @@ static inline void next_nomacro1(void) } } break; + + /* dollar is allowed to start identifiers when not parsing asm */ + case '$': + if (!(isidnum_table[c - CH_EOF] & IS_ID) + || (parse_flags & PARSE_FLAG_ASM_FILE)) + goto parse_simple; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': @@ -2021,21 +2694,14 @@ static inline void next_nomacro1(void) p1 = p; h = TOK_HASH_INIT; h = TOK_HASH_FUNC(h, c); - p++; - for(;;) { - c = *p; - if (!isidnum_table[c-CH_EOF]) - break; + while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) h = TOK_HASH_FUNC(h, c); - p++; - } + len = p - p1; if (c != '\\') { TokenSym **pts; - int len; /* fast case : no stray found, so we have the full token and we have already hashed it */ - len = p - p1; h &= (TOK_HASH_SIZE - 1); pts = &hash_ident[h]; for(;;) { @@ -2046,20 +2712,17 @@ static inline void next_nomacro1(void) goto token_found; pts = &(ts->hash_next); } - ts = tok_alloc_new(pts, p1, len); + ts = tok_alloc_new(pts, (char *) p1, len); token_found: ; } else { /* slower case */ cstr_reset(&tokcstr); - - while (p1 < p) { - cstr_ccat(&tokcstr, *p1); - p1++; - } + cstr_cat(&tokcstr, (char *) p1, len); p--; PEEKC(c, p); parse_ident_slow: - while (isidnum_table[c-CH_EOF]) { + while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) + { cstr_ccat(&tokcstr, c); PEEKC(c, p); } @@ -2084,41 +2747,57 @@ static inline void next_nomacro1(void) } } break; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - - cstr_reset(&tokcstr); + t = c; + PEEKC(c, p); /* after the first digit, accept digits, alpha, '.' or sign if prefixed by 'eEpP' */ parse_num: + cstr_reset(&tokcstr); for(;;) { + cstr_ccat(&tokcstr, t); + if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM)) + || c == '.' + || ((c == '+' || c == '-') + && (((t == 'e' || t == 'E') + && !(parse_flags & PARSE_FLAG_ASM_FILE + /* 0xe+1 is 3 tokens in asm */ + && ((char*)tokcstr.data)[0] == '0' + && toup(((char*)tokcstr.data)[1]) == 'X')) + || t == 'p' || t == 'P')))) + break; t = c; - cstr_ccat(&tokcstr, c); PEEKC(c, p); - if (!(isnum(c) || isid(c) || c == '.' || - ((c == '+' || c == '-') && - (t == 'e' || t == 'E' || t == 'p' || t == 'P')))) - break; } /* We add a trailing '\0' to ease parsing */ cstr_ccat(&tokcstr, '\0'); - tokc.cstr = &tokcstr; + tokc.str.size = tokcstr.size; + tokc.str.data = tokcstr.data; tok = TOK_PPNUM; break; + case '.': /* special dot handling because it can also start a number */ PEEKC(c, p); if (isnum(c)) { - cstr_reset(&tokcstr); - cstr_ccat(&tokcstr, '.'); + t = '.'; goto parse_num; + } else if ((isidnum_table['.' - CH_EOF] & IS_ID) + && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) { + *--p = c = '.'; + goto parse_ident_fast; } else if (c == '.') { PEEKC(c, p); - if (c != '.') - expect("'.'"); - PEEKC(c, p); - tok = TOK_DOTS; + if (c == '.') { + p++; + tok = TOK_DOTS; + } else { + *--p = '.'; /* may underflow into file->unget[] */ + tok = '.'; + } } else { tok = '.'; } @@ -2127,48 +2806,16 @@ static inline void next_nomacro1(void) case '\"': is_long = 0; str_const: - { - CString str; - int sep; - - sep = c; - - /* parse the string */ - cstr_new(&str); - p = parse_pp_string(p, sep, &str); - cstr_ccat(&str, '\0'); - - /* eval the escape (should be done as TOK_PPNUM) */ - cstr_reset(&tokcstr); - parse_escape_string(&tokcstr, str.data, is_long); - cstr_free(&str); - - if (sep == '\'') { - int char_size; - /* XXX: make it portable */ - if (!is_long) - char_size = 1; - else - char_size = sizeof(nwchar_t); - if (tokcstr.size <= char_size) - error("empty character constant"); - if (tokcstr.size > 2 * char_size) - warning("multi-character character constant"); - if (!is_long) { - tokc.i = *(int8_t *)tokcstr.data; - tok = TOK_CCHAR; - } else { - tokc.i = *(nwchar_t *)tokcstr.data; - tok = TOK_LCHAR; - } - } else { - tokc.cstr = &tokcstr; - if (!is_long) - tok = TOK_STR; - else - tok = TOK_LSTR; - } - } + cstr_reset(&tokcstr); + if (is_long) + cstr_ccat(&tokcstr, 'L'); + cstr_ccat(&tokcstr, c); + p = parse_pp_string(p, c, &tokcstr); + cstr_ccat(&tokcstr, c); + cstr_ccat(&tokcstr, '\0'); + tokc.str.size = tokcstr.size; + tokc.str.data = tokcstr.data; + tok = TOK_PPSTR; break; case '<': @@ -2188,7 +2835,6 @@ static inline void next_nomacro1(void) tok = TOK_LT; } break; - case '>': PEEKC(c, p); if (c == '=') { @@ -2273,10 +2919,13 @@ static inline void next_nomacro1(void) PEEKC(c, p); if (c == '*') { p = parse_comment(p); - goto redo_no_start; + /* comments replaced by a blank */ + tok = ' '; + goto keep_tok_flags; } else if (c == '/') { p = parse_line_comment(p); - goto redo_no_start; + tok = ' '; + goto keep_tok_flags; } else if (c == '=') { p++; tok = TOK_A_DIV; @@ -2297,20 +2946,24 @@ static inline void next_nomacro1(void) case ':': case '?': case '~': - case '$': /* only used in assembler */ - case '@': /* dito */ + case '@': /* only used in assembler */ + parse_simple: tok = c; p++; break; default: - error("unrecognized character \\x%02x", c); + if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */ + goto parse_ident_fast; + if (parse_flags & PARSE_FLAG_ASM_FILE) + goto parse_simple; + tcc_error("unrecognized character \\x%02x", c); break; } tok_flags = 0; keep_tok_flags: file->buf_ptr = p; #if defined(PARSE_DEBUG) - printf("token = %s\n", get_tok_str(tok, &tokc)); + printf("token = %d %s\n", tok, get_tok_str(tok, &tokc)); #endif } @@ -2322,7 +2975,7 @@ static void next_nomacro_spc(void) redo: tok = *macro_ptr; if (tok) { - TOK_GET(tok, macro_ptr, tokc); + TOK_GET(&tok, ¯o_ptr, &tokc); if (tok == TOK_LINENUM) { file->line_num = tokc.i; goto redo; @@ -2331,72 +2984,92 @@ static void next_nomacro_spc(void) } else { next_nomacro1(); } + //printf("token = %s\n", get_tok_str(tok, &tokc)); } -static void next_nomacro(void) +ST_FUNC void next_nomacro(void) { do { next_nomacro_spc(); - } while (is_space(tok)); + } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC)); } -/* substitute args in macro_str and return allocated string */ -static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) + +static void macro_subst( + TokenString *tok_str, + Sym **nested_list, + const int *macro_str + ); + +/* substitute arguments in replacement lists in macro_str by the values in + args (field d) and return allocated string */ +static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) { - int *st, last_tok, t, spc; + int t, t0, t1, spc; + const int *st; Sym *s; CValue cval; TokenString str; CString cstr; tok_str_new(&str); - last_tok = 0; + t0 = t1 = 0; while(1) { - TOK_GET(t, macro_str, cval); + TOK_GET(&t, ¯o_str, &cval); if (!t) break; if (t == '#') { /* stringize */ - TOK_GET(t, macro_str, cval); + TOK_GET(&t, ¯o_str, &cval); if (!t) - break; + goto bad_stringy; s = sym_find2(args, t); if (s) { cstr_new(&cstr); - st = (int *)s->c; + cstr_ccat(&cstr, '\"'); + st = s->d; spc = 0; - while (*st) { - TOK_GET(t, st, cval); - if (!check_space(t, &spc)) - cstr_cat(&cstr, get_tok_str(t, &cval)); + while (*st >= 0) { + TOK_GET(&t, &st, &cval); + if (t != TOK_PLCHLDR + && t != TOK_NOSUBST + && 0 == check_space(t, &spc)) { + const char *s = get_tok_str(t, &cval); + while (*s) { + if (t == TOK_PPSTR && *s != '\'') + add_char(&cstr, *s); + else + cstr_ccat(&cstr, *s); + ++s; + } + } } cstr.size -= spc; + cstr_ccat(&cstr, '\"'); cstr_ccat(&cstr, '\0'); #ifdef PP_DEBUG - printf("stringize: %s\n", (char *)cstr.data); + printf("\nstringize: <%s>\n", (char *)cstr.data); #endif /* add string */ - cval.cstr = &cstr; - tok_str_add2(&str, TOK_STR, &cval); + cval.str.size = cstr.size; + cval.str.data = cstr.data; + tok_str_add2(&str, TOK_PPSTR, &cval); cstr_free(&cstr); } else { - tok_str_add2(&str, t, &cval); + bad_stringy: + expect("macro parameter after '#'"); } } else if (t >= TOK_IDENT) { s = sym_find2(args, t); if (s) { - st = (int *)s->c; + int l0 = str.len; + st = s->d; /* if '##' is present before or after, no arg substitution */ - if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) { - /* special case for var arg macros : ## eats the - ',' if empty VA_ARGS variable. */ - /* XXX: test of the ',' is not 100% - reliable. should fix it to avoid security - problems */ - if (gnu_ext && s->type.t && - last_tok == TOK_TWOSHARPS && - str.len >= 2 && str.str[str.len - 2] == ',') { - if (*st == 0) { + if (*macro_str == TOK_PPJOIN || t1 == TOK_PPJOIN) { + /* special case for var arg macros : ## eats the ',' + if empty VA_ARGS variable. */ + if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) { + if (*st <= 0) { /* suppress ',' '##' */ str.len -= 2; } else { @@ -2404,28 +3077,39 @@ static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) str.len--; goto add_var; } - } else { - int t1; - add_var: - for(;;) { - TOK_GET(t1, st, cval); - if (!t1) - break; - tok_str_add2(&str, t1, &cval); - } } } else { - /* NOTE: the stream cannot be read when macro - substituing an argument */ - macro_subst(&str, nested_list, st, NULL); + add_var: + if (!s->next) { + /* Expand arguments tokens and store them. In most + cases we could also re-expand each argument if + used multiple times, but not if the argument + contains the __COUNTER__ macro. */ + TokenString str2; + sym_push2(&s->next, s->v, s->type.t, 0); + tok_str_new(&str2); + macro_subst(&str2, nested_list, st); + tok_str_add(&str2, 0); + s->next->d = str2.str; + } + st = s->next->d; } + for(;;) { + int t2; + TOK_GET(&t2, &st, &cval); + if (t2 <= 0) + break; + tok_str_add2(&str, t2, &cval); + } + if (str.len == l0) /* expanded to empty string */ + tok_str_add(&str, TOK_PLCHLDR); } else { tok_str_add(&str, t); } } else { tok_str_add2(&str, t, &cval); } - last_tok = t; + t0 = t1, t1 = t; } tok_str_add(&str, 0); return str.str; @@ -2437,25 +3121,182 @@ static char const ab_month_name[12][4] = "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2) +{ + CString cstr; + int n, ret = 1; + + cstr_new(&cstr); + if (t1 != TOK_PLCHLDR) + cstr_cat(&cstr, get_tok_str(t1, v1), -1); + n = cstr.size; + if (t2 != TOK_PLCHLDR) + cstr_cat(&cstr, get_tok_str(t2, v2), -1); + cstr_ccat(&cstr, '\0'); + + tcc_open_bf(tcc_state, ":paste:", cstr.size); + memcpy(file->buffer, cstr.data, cstr.size); + tok_flags = 0; + for (;;) { + next_nomacro1(); + if (0 == *file->buf_ptr) + break; + if (is_space(tok)) + continue; + tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid" + " preprocessing token", n, cstr.data, (char*)cstr.data + n); + ret = 0; + break; + } + tcc_close(); + //printf("paste <%s>\n", (char*)cstr.data); + cstr_free(&cstr); + return ret; +} + +/* handle the '##' operator. Return NULL if no '##' seen. Otherwise + return the resulting string (which must be freed). */ +static inline int *macro_twosharps(const int *ptr0) +{ + int t; + CValue cval; + TokenString macro_str1; + int start_of_nosubsts = -1; + const int *ptr; + + /* we search the first '##' */ + for (ptr = ptr0;;) { + TOK_GET(&t, &ptr, &cval); + if (t == TOK_PPJOIN) + break; + if (t == 0) + return NULL; + } + + tok_str_new(¯o_str1); + + //tok_print(" $$$", ptr0); + for (ptr = ptr0;;) { + TOK_GET(&t, &ptr, &cval); + if (t == 0) + break; + if (t == TOK_PPJOIN) + continue; + while (*ptr == TOK_PPJOIN) { + int t1; CValue cv1; + /* given 'a##b', remove nosubsts preceding 'a' */ + if (start_of_nosubsts >= 0) + macro_str1.len = start_of_nosubsts; + /* given 'a##b', remove nosubsts preceding 'b' */ + while ((t1 = *++ptr) == TOK_NOSUBST) + ; + if (t1 && t1 != TOK_PPJOIN) { + TOK_GET(&t1, &ptr, &cv1); + if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) { + if (paste_tokens(t, &cval, t1, &cv1)) { + t = tok, cval = tokc; + } else { + tok_str_add2(¯o_str1, t, &cval); + t = t1, cval = cv1; + } + } + } + } + if (t == TOK_NOSUBST) { + if (start_of_nosubsts < 0) + start_of_nosubsts = macro_str1.len; + } else { + start_of_nosubsts = -1; + } + tok_str_add2(¯o_str1, t, &cval); + } + tok_str_add(¯o_str1, 0); + //tok_print(" ###", macro_str1.str); + return macro_str1.str; +} + +/* peek or read [ws_str == NULL] next token from function macro call, + walking up macro levels up to the file if necessary */ +static int next_argstream(Sym **nested_list, TokenString *ws_str) +{ + int t; + const int *p; + Sym *sa; + + for (;;) { + if (macro_ptr) { + p = macro_ptr, t = *p; + if (ws_str) { + while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t) + tok_str_add(ws_str, t), t = *++p; + } + if (t == 0) { + end_macro(); + /* also, end of scope for nested defined symbol */ + sa = *nested_list; + while (sa && sa->v == 0) + sa = sa->prev; + if (sa) + sa->v = 0; + continue; + } + } else { + ch = handle_eob(); + if (ws_str) { + while (is_space(ch) || ch == '\n' || ch == '/') { + if (ch == '/') { + int c; + uint8_t *p = file->buf_ptr; + PEEKC(c, p); + if (c == '*') { + p = parse_comment(p); + file->buf_ptr = p - 1; + } else if (c == '/') { + p = parse_line_comment(p); + file->buf_ptr = p - 1; + } else + break; + ch = ' '; + } + if (ch == '\n') + file->line_num++; + if (!(ch == '\f' || ch == '\v' || ch == '\r')) + tok_str_add(ws_str, ch); + cinp(); + } + } + t = ch; + } + + if (ws_str) + return t; + next_nomacro_spc(); + return tok; + } +} + /* do macro substitution of current token with macro 's' and add result to (tok_str,tok_len). 'nested_list' is the list of all macros we got inside to avoid recursing. Return non zero if no substitution needs to be done */ -static int macro_subst_tok(TokenString *tok_str, - Sym **nested_list, Sym *s, struct macro_level **can_read_stream) +static int macro_subst_tok( + TokenString *tok_str, + Sym **nested_list, + Sym *s) { Sym *args, *sa, *sa1; - int mstr_allocated, parlevel, *mstr, t, t1, *p, spc; + int parlevel, t, t1, spc; TokenString str; char *cstrval; CValue cval; CString cstr; char buf[32]; - + /* if symbol is a macro, prepare substitution */ /* special macros */ - if (tok == TOK___LINE__) { - snprintf(buf, sizeof(buf), "%d", file->line_num); + if (tok == TOK___LINE__ || tok == TOK___COUNTER__) { + t = tok == TOK___LINE__ ? file->line_num : pp_counter++; + snprintf(buf, sizeof(buf), "%d", t); cstrval = buf; t1 = TOK_PPNUM; goto add_cstr1; @@ -2480,65 +3321,71 @@ static int macro_subst_tok(TokenString *tok_str, t1 = TOK_STR; add_cstr1: cstr_new(&cstr); - cstr_cat(&cstr, cstrval); - cstr_ccat(&cstr, '\0'); - cval.cstr = &cstr; + cstr_cat(&cstr, cstrval, 0); + cval.str.size = cstr.size; + cval.str.data = cstr.data; tok_str_add2(tok_str, t1, &cval); cstr_free(&cstr); - } else { - mstr = (int *)s->c; - mstr_allocated = 0; + } else if (s->d) { + int saved_parse_flags = parse_flags; + int *joined_str = NULL; + int *mstr = s->d; + if (s->type.t == MACRO_FUNC) { - /* NOTE: we do not use next_nomacro to avoid eating the - next token. XXX: find better solution */ - redo: - if (macro_ptr) { - p = macro_ptr; - while (is_space(t = *p) || TOK_LINEFEED == t) - ++p; - if (t == 0 && can_read_stream) { - /* end of macro stream: we must look at the token - after in the file */ - struct macro_level *ml = *can_read_stream; - macro_ptr = NULL; - if (ml) - { - macro_ptr = ml->p; - ml->p = NULL; - *can_read_stream = ml -> prev; - } - goto redo; + /* whitespace between macro name and argument list */ + TokenString ws_str; + tok_str_new(&ws_str); + + spc = 0; + parse_flags |= PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED + | PARSE_FLAG_ACCEPT_STRAYS; + + /* get next token from argument stream */ + t = next_argstream(nested_list, &ws_str); + if (t != '(') { + /* not a macro substitution after all, restore the + * macro token plus all whitespace we've read. + * whitespace is intentionally not merged to preserve + * newlines. */ + parse_flags = saved_parse_flags; + tok_str_add(tok_str, tok); + if (parse_flags & PARSE_FLAG_SPACES) { + int i; + for (i = 0; i < ws_str.len; i++) + tok_str_add(tok_str, ws_str.str[i]); } + tok_str_free_str(ws_str.str); + return 0; } else { - /* XXX: incorrect with comments */ - ch = file->buf_ptr[0]; - while (is_space(ch) || ch == '\n') - cinp(); - t = ch; + tok_str_free_str(ws_str.str); } - if (t != '(') /* no macro subst */ - return -1; - + do { + next_nomacro(); /* eat '(' */ + } while (tok == TOK_PLCHLDR); + /* argument macro */ - next_nomacro(); - next_nomacro(); args = NULL; sa = s->next; /* NOTE: empty args are allowed, except if no args */ for(;;) { + do { + next_argstream(nested_list, NULL); + } while (is_space(tok) || TOK_LINEFEED == tok); + empty_arg: /* handle '()' case */ if (!args && !sa && tok == ')') break; if (!sa) - error("macro '%s' used with too many args", + tcc_error("macro '%s' used with too many args", get_tok_str(s->v, 0)); tok_str_new(&str); parlevel = spc = 0; /* NOTE: non zero sa->t indicates VA_ARGS */ while ((parlevel > 0 || (tok != ')' && - (tok != ',' || sa->type.t))) && - tok != -1) { + (tok != ',' || sa->type.t)))) { + if (tok == TOK_EOF || tok == 0) + break; if (tok == '(') parlevel++; else if (tok == ')') @@ -2547,335 +3394,273 @@ static int macro_subst_tok(TokenString *tok_str, tok = ' '; if (!check_space(tok, &spc)) tok_str_add2(&str, tok, &tokc); - next_nomacro_spc(); + next_argstream(nested_list, NULL); } + if (parlevel) + expect(")"); str.len -= spc; + tok_str_add(&str, -1); tok_str_add(&str, 0); - sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str); + sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0); + sa1->d = str.str; sa = sa->next; if (tok == ')') { /* special case for gcc var args: add an empty var arg argument if it is omitted */ if (sa && sa->type.t && gnu_ext) - continue; - else - break; + goto empty_arg; + break; } if (tok != ',') expect(","); - next_nomacro(); } if (sa) { - error("macro '%s' used with too few args", + tcc_error("macro '%s' used with too few args", get_tok_str(s->v, 0)); } + parse_flags = saved_parse_flags; + /* now subst each arg */ mstr = macro_arg_subst(nested_list, mstr, args); /* free memory */ sa = args; while (sa) { sa1 = sa->prev; - tok_str_free((int *)sa->c); + tok_str_free_str(sa->d); + if (sa->next) { + tok_str_free_str(sa->next->d); + sym_free(sa->next); + } sym_free(sa); sa = sa1; } - mstr_allocated = 1; } + sym_push2(nested_list, s->v, 0, 0); - macro_subst(tok_str, nested_list, mstr, can_read_stream); + parse_flags = saved_parse_flags; + joined_str = macro_twosharps(mstr); + macro_subst(tok_str, nested_list, joined_str ? joined_str : mstr); + /* pop nested defined symbol */ sa1 = *nested_list; *nested_list = sa1->prev; sym_free(sa1); - if (mstr_allocated) - tok_str_free(mstr); + if (joined_str) + tok_str_free_str(joined_str); + if (mstr != s->d) + tok_str_free_str(mstr); } return 0; } -/* handle the '##' operator. Return NULL if no '##' seen. Otherwise - return the resulting string (which must be freed). */ -static inline int *macro_twosharps(const int *macro_str) -{ - TokenSym *ts; - const int *ptr, *saved_macro_ptr; - int t; - const char *p1, *p2; - CValue cval; - TokenString macro_str1; - CString cstr; - - /* we search the first '##' */ - for(ptr = macro_str;;) { - TOK_GET(t, ptr, cval); - if (t == TOK_TWOSHARPS) - break; - /* nothing more to do if end of string */ - if (t == 0) - return NULL; - } - - /* we saw '##', so we need more processing to handle it */ - cstr_new(&cstr); - tok_str_new(¯o_str1); - saved_macro_ptr = macro_ptr; - /* XXX: get rid of the use of macro_ptr here */ - macro_ptr = (int *)macro_str; - for(;;) { - next_nomacro_spc(); - if (tok == 0) - break; - if (tok == TOK_TWOSHARPS) - continue; - while (*macro_ptr == TOK_TWOSHARPS) { - t = *++macro_ptr; - if (t && t != TOK_TWOSHARPS) { - TOK_GET(t, macro_ptr, cval); - /* We concatenate the two tokens if we have an - identifier or a preprocessing number */ - cstr_reset(&cstr); - p1 = get_tok_str(tok, &tokc); - cstr_cat(&cstr, p1); - p2 = get_tok_str(t, &cval); - cstr_cat(&cstr, p2); - cstr_ccat(&cstr, '\0'); - - if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && - (t >= TOK_IDENT || t == TOK_PPNUM)) { - if (tok == TOK_PPNUM) { - /* if number, then create a number token */ - /* NOTE: no need to allocate because - tok_str_add2() does it */ - cstr_reset(&tokcstr); - tokcstr = cstr; - cstr_new(&cstr); - tokc.cstr = &tokcstr; - } else { - /* if identifier, we must do a test to - validate we have a correct identifier */ - if (t == TOK_PPNUM) { - const char *p; - int c; - - p = p2; - for(;;) { - c = *p; - if (c == '\0') - break; - p++; - if (!isnum(c) && !isid(c)) - goto error_pasting; - } - } - ts = tok_alloc(cstr.data, strlen(cstr.data)); - tok = ts->tok; /* modify current token */ - } - } else { - const char *str = cstr.data; - const unsigned char *q; - - /* we look for a valid token */ - /* XXX: do more extensive checks */ - if (!strcmp(str, ">>=")) { - tok = TOK_A_SAR; - } else if (!strcmp(str, "<<=")) { - tok = TOK_A_SHL; - } else if (strlen(str) == 2) { - /* search in two bytes table */ - q = tok_two_chars; - for(;;) { - if (!*q) - goto error_pasting; - if (q[0] == str[0] && q[1] == str[1]) - break; - q += 3; - } - tok = q[2]; - } else { - error_pasting: - /* NOTE: because get_tok_str use a static buffer, - we must save it */ - cstr_reset(&cstr); - p1 = get_tok_str(tok, &tokc); - cstr_cat(&cstr, p1); - cstr_ccat(&cstr, '\0'); - p2 = get_tok_str(t, &cval); - warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2); - /* cannot merge tokens: just add them separately */ - tok_str_add2(¯o_str1, tok, &tokc); - /* XXX: free associated memory ? */ - tok = t; - tokc = cval; - } - } - } - } - tok_str_add2(¯o_str1, tok, &tokc); - } - macro_ptr = (int *)saved_macro_ptr; - cstr_free(&cstr); - tok_str_add(¯o_str1, 0); - return macro_str1.str; -} - - /* do macro substitution of macro_str and add result to (tok_str,tok_len). 'nested_list' is the list of all macros we got inside to avoid recursing. */ -static void macro_subst(TokenString *tok_str, Sym **nested_list, - const int *macro_str, struct macro_level ** can_read_stream) +static void macro_subst( + TokenString *tok_str, + Sym **nested_list, + const int *macro_str + ) { Sym *s; - int *macro_str1; - const int *ptr; - int t, ret, spc; + int t, spc, nosubst; CValue cval; - struct macro_level ml; - /* first scan for '##' operator handling */ - ptr = macro_str; - macro_str1 = macro_twosharps(ptr); - if (macro_str1) - ptr = macro_str1; - spc = 0; + spc = nosubst = 0; + while (1) { - /* NOTE: ptr == NULL can only happen if tokens are read from - file stream due to a macro function call */ - if (ptr == NULL) - break; - TOK_GET(t, ptr, cval); - if (t == 0) + TOK_GET(&t, ¯o_str, &cval); + if (t <= 0) break; - s = define_find(t); - if (s != NULL) { - /* if nested substitution, do nothing */ - if (sym_find2(*nested_list, t)) + + if (t >= TOK_IDENT && 0 == nosubst) { + s = define_find(t); + if (s == NULL) goto no_subst; - ml.p = macro_ptr; - if (can_read_stream) - ml.prev = *can_read_stream, *can_read_stream = &ml; - macro_ptr = (int *)ptr; - tok = t; - ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream); - ptr = (int *)macro_ptr; - macro_ptr = ml.p; - if (can_read_stream && *can_read_stream == &ml) - *can_read_stream = ml.prev; - if (ret != 0) + + /* if nested substitution, do nothing */ + if (sym_find2(*nested_list, t)) { + /* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */ + tok_str_add2(tok_str, TOK_NOSUBST, NULL); goto no_subst; + } + + { + TokenString str; + str.str = (int*)macro_str; + begin_macro(&str, 2); + + tok = t; + macro_subst_tok(tok_str, nested_list, s); + + if (str.alloc == 3) { + /* already finished by reading function macro arguments */ + break; + } + + macro_str = macro_ptr; + end_macro (); + } + if (tok_str->len) + spc = is_space(t = tok_str->str[tok_str->lastlen]); } else { - no_subst: - if (!check_space(t, &spc)) + if (t == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS)) + tcc_error("stray '\\' in program"); +no_subst: + if (!check_space(t, &spc)) tok_str_add2(tok_str, t, &cval); + + if (nosubst) { + if (nosubst > 1 && (spc || (++nosubst == 3 && t == '('))) + continue; + nosubst = 0; + } + if (t == TOK_NOSUBST) + nosubst = 1; } + /* GCC supports 'defined' as result of a macro substitution */ + if (t == TOK_DEFINED && pp_expr) + nosubst = 2; } - if (macro_str1) - tok_str_free(macro_str1); } /* return next token with macro substitution */ -static void next(void) +ST_FUNC void next(void) { - Sym *nested_list, *s; - TokenString str; - struct macro_level *ml; - redo: if (parse_flags & PARSE_FLAG_SPACES) next_nomacro_spc(); else next_nomacro(); - if (!macro_ptr) { - /* if not reading from macro substituted string, then try - to substitute macros */ - if (tok >= TOK_IDENT && - (parse_flags & PARSE_FLAG_PREPROCESS)) { - s = define_find(tok); - if (s) { - /* we have a macro: we try to substitute */ - tok_str_new(&str); - nested_list = NULL; - ml = NULL; - if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) { - /* substitution done, NOTE: maybe empty */ - tok_str_add(&str, 0); - macro_ptr = str.str; - macro_ptr_allocated = str.str; - goto redo; - } - } + + if (macro_ptr) { + if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) { + /* discard preprocessor markers */ + goto redo; + } else if (tok == 0) { + /* end of macro or unget token string */ + end_macro(); + goto redo; } - } else { - if (tok == 0) { - /* end of macro or end of unget buffer */ - if (unget_buffer_enabled) { - macro_ptr = unget_saved_macro_ptr; - unget_buffer_enabled = 0; - } else { - /* end of macro string: free it */ - tok_str_free(macro_ptr_allocated); - macro_ptr = NULL; - } + } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) { + Sym *s; + /* if reading from file, try to substitute macros */ + s = define_find(tok); + if (s) { + Sym *nested_list = NULL; + tokstr_buf.len = 0; + macro_subst_tok(&tokstr_buf, &nested_list, s); + tok_str_add(&tokstr_buf, 0); + begin_macro(&tokstr_buf, 2); goto redo; } } - /* convert preprocessor tokens into C tokens */ - if (tok == TOK_PPNUM && - (parse_flags & PARSE_FLAG_TOK_NUM)) { - parse_number((char *)tokc.cstr->data); + if (tok == TOK_PPNUM) { + if (parse_flags & PARSE_FLAG_TOK_NUM) + parse_number((char *)tokc.str.data); + } else if (tok == TOK_PPSTR) { + if (parse_flags & PARSE_FLAG_TOK_STR) + parse_string((char *)tokc.str.data, tokc.str.size - 1); } } /* push back current token and set current token to 'last_tok'. Only identifier case handled for labels. */ -static inline void unget_tok(int last_tok) +ST_INLN void unget_tok(int last_tok) { - int i, n; - int *q; - unget_saved_macro_ptr = macro_ptr; - unget_buffer_enabled = 1; - q = unget_saved_buffer; - macro_ptr = q; - *q++ = tok; - n = tok_ext_size(tok) - 1; - for(i=0;i<n;i++) - *q++ = tokc.tab[i]; - *q = 0; /* end of token string */ + + TokenString *str = tok_str_alloc(); + tok_str_add2(str, tok, &tokc); + tok_str_add(str, 0); + begin_macro(str, 1); tok = last_tok; } - -/* better than nothing, but needs extension to handle '-E' option - correctly too */ -static void preprocess_init(TCCState *s1) +ST_FUNC void preprocess_start(TCCState *s1, int is_asm) { + CString cstr; + int i; + s1->include_stack_ptr = s1->include_stack; - /* XXX: move that before to avoid having to initialize - file->ifdef_stack_ptr ? */ s1->ifdef_stack_ptr = s1->ifdef_stack; file->ifdef_stack_ptr = s1->ifdef_stack_ptr; - - /* XXX: not ANSI compliant: bound checking says error */ - vtop = vstack - 1; + pp_expr = 0; + pp_counter = 0; + pp_debug_tok = pp_debug_symv = 0; + pp_once++; + pvtop = vtop = vstack - 1; s1->pack_stack[0] = 0; s1->pack_stack_ptr = s1->pack_stack; + + set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0); + set_idnum('.', is_asm ? IS_ID : 0); + + cstr_new(&cstr); + cstr_cat(&cstr, "\"", -1); + cstr_cat(&cstr, file->filename, -1); + cstr_cat(&cstr, "\"", 0); + tcc_define_symbol(s1, "__BASE_FILE__", cstr.data); + + cstr_reset(&cstr); + for (i = 0; i < s1->nb_cmd_include_files; i++) { + cstr_cat(&cstr, "#include \"", -1); + cstr_cat(&cstr, s1->cmd_include_files[i], -1); + cstr_cat(&cstr, "\"\n", -1); + } + if (cstr.size) { + *s1->include_stack_ptr++ = file; + tcc_open_bf(s1, "<command line>", cstr.size); + memcpy(file->buffer, cstr.data, cstr.size); + } + cstr_free(&cstr); + + if (is_asm) + tcc_define_symbol(s1, "__ASSEMBLER__", NULL); + + parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0; + tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; } -void preprocess_new() +/* cleanup from error/setjmp */ +ST_FUNC void preprocess_end(TCCState *s1) +{ + while (macro_stack) + end_macro(); + macro_ptr = NULL; +} + +ST_FUNC void tccpp_new(TCCState *s) { int i, c; const char *p, *r; - TokenSym *ts; + + /* might be used in error() before preprocess_start() */ + s->include_stack_ptr = s->include_stack; + s->ppfp = stdout; /* init isid table */ - for(i=CH_EOF;i<256;i++) - isidnum_table[i-CH_EOF] = isid(i) || isnum(i); + for(i = CH_EOF; i<128; i++) + set_idnum(i, + is_space(i) ? IS_SPC + : isid(i) ? IS_ID + : isnum(i) ? IS_NUM + : 0); + + for(i = 128; i<256; i++) + set_idnum(i, IS_ID); + + /* init allocators */ + tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE); + tal_new(&tokstr_alloc, TOKSTR_TAL_LIMIT, TOKSTR_TAL_SIZE); + tal_new(&cstr_alloc, CSTR_TAL_LIMIT, CSTR_TAL_SIZE); - /* add all tokens */ - table_ident = NULL; memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *)); + cstr_new(&cstr_buf); + cstr_realloc(&cstr_buf, STRING_MAX_SIZE); + tok_str_new(&tokstr_buf); + tok_str_realloc(&tokstr_buf, TOKSTR_MAX_SIZE); tok_ident = TOK_IDENT; p = tcc_keywords; @@ -2886,50 +3671,233 @@ void preprocess_new() if (c == '\0') break; } - ts = tok_alloc(p, r - p - 1); + tok_alloc(p, r - p - 1); p = r; } } +ST_FUNC void tccpp_delete(TCCState *s) +{ + int i, n; + + /* free -D and compiler defines */ + free_defines(NULL); + + /* free tokens */ + n = tok_ident - TOK_IDENT; + for(i = 0; i < n; i++) + tal_free(toksym_alloc, table_ident[i]); + tcc_free(table_ident); + table_ident = NULL; + + /* free static buffers */ + cstr_free(&tokcstr); + cstr_free(&cstr_buf); + cstr_free(¯o_equal_buf); + tok_str_free_str(tokstr_buf.str); + + /* free allocators */ + tal_delete(toksym_alloc); + toksym_alloc = NULL; + tal_delete(tokstr_alloc); + tokstr_alloc = NULL; + tal_delete(cstr_alloc); + cstr_alloc = NULL; +} + +/* ------------------------------------------------------------------------- */ +/* tcc -E [-P[1]] [-dD} support */ + +static void tok_print(const char *msg, const int *str) +{ + FILE *fp; + int t, s = 0; + CValue cval; + + fp = tcc_state->ppfp; + fprintf(fp, "%s", msg); + while (str) { + TOK_GET(&t, &str, &cval); + if (!t) + break; + fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1; + } + fprintf(fp, "\n"); +} + +static void pp_line(TCCState *s1, BufferedFile *f, int level) +{ + int d = f->line_num - f->line_ref; + + if (s1->dflag & 4) + return; + + if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) { + ; + } else if (level == 0 && f->line_ref && d < 8) { + while (d > 0) + fputs("\n", s1->ppfp), --d; + } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) { + fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename); + } else { + fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename, + level > 0 ? " 1" : level < 0 ? " 2" : ""); + } + f->line_ref = f->line_num; +} + +static void define_print(TCCState *s1, int v) +{ + FILE *fp; + Sym *s; + + s = define_find(v); + if (NULL == s || NULL == s->d) + return; + + fp = s1->ppfp; + fprintf(fp, "#define %s", get_tok_str(v, NULL)); + if (s->type.t == MACRO_FUNC) { + Sym *a = s->next; + fprintf(fp,"("); + if (a) + for (;;) { + fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL)); + if (!(a = a->next)) + break; + fprintf(fp,","); + } + fprintf(fp,")"); + } + tok_print("", s->d); +} + +static void pp_debug_defines(TCCState *s1) +{ + int v, t; + const char *vs; + FILE *fp; + + t = pp_debug_tok; + if (t == 0) + return; + + file->line_num--; + pp_line(s1, file, 0); + file->line_ref = ++file->line_num; + + fp = s1->ppfp; + v = pp_debug_symv; + vs = get_tok_str(v, NULL); + if (t == TOK_DEFINE) { + define_print(s1, v); + } else if (t == TOK_UNDEF) { + fprintf(fp, "#undef %s\n", vs); + } else if (t == TOK_push_macro) { + fprintf(fp, "#pragma push_macro(\"%s\")\n", vs); + } else if (t == TOK_pop_macro) { + fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs); + } + pp_debug_tok = 0; +} + +static void pp_debug_builtins(TCCState *s1) +{ + int v; + for (v = TOK_IDENT; v < tok_ident; ++v) + define_print(s1, v); +} + +/* Add a space between tokens a and b to avoid unwanted textual pasting */ +static int pp_need_space(int a, int b) +{ + return 'E' == a ? '+' == b || '-' == b + : '+' == a ? TOK_INC == b || '+' == b + : '-' == a ? TOK_DEC == b || '-' == b + : a >= TOK_IDENT ? b >= TOK_IDENT + : a == TOK_PPNUM ? b >= TOK_IDENT + : 0; +} + +/* maybe hex like 0x1e */ +static int pp_check_he0xE(int t, const char *p) +{ + if (t == TOK_PPNUM && toup(strchr(p, 0)[-1]) == 'E') + return 'E'; + return t; +} + /* Preprocess the current file */ -static int tcc_preprocess(TCCState *s1) +ST_FUNC int tcc_preprocess(TCCState *s1) { - Sym *define_start; - BufferedFile *file_ref; - int token_seen, line_ref; + BufferedFile **iptr; + int token_seen, spcs, level; + const char *p; + char white[400]; + + parse_flags = PARSE_FLAG_PREPROCESS + | (parse_flags & PARSE_FLAG_ASM_FILE) + | PARSE_FLAG_LINEFEED + | PARSE_FLAG_SPACES + | PARSE_FLAG_ACCEPT_STRAYS + ; + /* Credits to Fabrice Bellard's initial revision to demonstrate its + capability to compile and run itself, provided all numbers are + given as decimals. tcc -E -P10 will do. */ + if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_P10) + parse_flags |= PARSE_FLAG_TOK_NUM, s1->Pflag = 1; + +#ifdef PP_BENCH + /* for PP benchmarks */ + do next(); while (tok != TOK_EOF); + return 0; +#endif - preprocess_init(s1); - define_start = define_stack; - ch = file->buf_ptr[0]; - tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; - parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS | - PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES; - token_seen = 0; - line_ref = 0; - file_ref = NULL; + if (s1->dflag & 1) { + pp_debug_builtins(s1); + s1->dflag &= ~1; + } + token_seen = TOK_LINEFEED, spcs = 0; + pp_line(s1, file, 0); for (;;) { + iptr = s1->include_stack_ptr; next(); - if (tok == TOK_EOF) { + if (tok == TOK_EOF) break; + + level = s1->include_stack_ptr - iptr; + if (level) { + if (level > 0) + pp_line(s1, *iptr, 0); + pp_line(s1, file, level); + } + if (s1->dflag & 7) { + pp_debug_defines(s1); + if (s1->dflag & 4) + continue; + } + + if (is_space(tok)) { + if (spcs < sizeof white - 1) + white[spcs++] = tok; + continue; } else if (tok == TOK_LINEFEED) { - if (!token_seen) + spcs = 0; + if (token_seen == TOK_LINEFEED) continue; - ++line_ref; - token_seen = 0; - } else if (!token_seen) { - int d = file->line_num - line_ref; - if (file != file_ref || d < 0 || d >= 8) - fprintf(s1->outfile, "# %d \"%s\"\n", file->line_num, file->filename); - else - while (d) - fputs("\n", s1->outfile), --d; - line_ref = (file_ref = file)->line_num; - token_seen = 1; + ++file->line_ref; + } else if (token_seen == TOK_LINEFEED) { + pp_line(s1, file, 0); + } else if (spcs == 0 && pp_need_space(token_seen, tok)) { + white[spcs++] = ' '; } - fputs(get_tok_str(tok, &tokc), s1->outfile); + + white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0; + fputs(p = get_tok_str(tok, &tokc), s1->ppfp); + token_seen = pp_check_he0xE(tok, p); } - free_defines(define_start); return 0; } +/* ------------------------------------------------------------------------- */ diff --git a/tinyc/tccrun.c b/tinyc/tccrun.c new file mode 100644 index 000000000..b9a052b19 --- /dev/null +++ b/tinyc/tccrun.c @@ -0,0 +1,840 @@ +/* + * TCC - Tiny C Compiler - Support for -run switch + * + * Copyright (c) 2001-2004 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "tcc.h" + +/* only native compiler supports -run */ +#ifdef TCC_IS_NATIVE + +#ifndef _WIN32 +# include <sys/mman.h> +#endif + +#ifdef CONFIG_TCC_BACKTRACE +# ifndef _WIN32 +# include <signal.h> +# ifndef __OpenBSD__ +# include <sys/ucontext.h> +# endif +# else +# define ucontext_t CONTEXT +# endif +ST_DATA int rt_num_callers = 6; +ST_DATA const char **rt_bound_error_msg; +ST_DATA void *rt_prog_main; +static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level); +static void rt_error(ucontext_t *uc, const char *fmt, ...); +static void set_exception_handler(void); +#endif + +static void set_pages_executable(void *ptr, unsigned long length); +static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff); + +#ifdef _WIN64 +static void *win64_add_function_table(TCCState *s1); +static void win64_del_function_table(void *); +#endif + +/* ------------------------------------------------------------- */ +/* Do all relocations (needed before using tcc_get_symbol()) + Returns -1 on error. */ + +LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) +{ + int size; + addr_t ptr_diff = 0; + + if (TCC_RELOCATE_AUTO != ptr) + return tcc_relocate_ex(s1, ptr, 0); + + size = tcc_relocate_ex(s1, NULL, 0); + if (size < 0) + return -1; + +#ifdef HAVE_SELINUX +{ + /* Using mmap instead of malloc */ + void *prx; + char tmpfname[] = "/tmp/.tccrunXXXXXX"; + int fd = mkstemp(tmpfname); + unlink(tmpfname); + ftruncate(fd, size); + + ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED || prx == MAP_FAILED) + tcc_error("tccrun: could not map memory"); + dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size); + dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx); + ptr_diff = (char*)prx - (char*)ptr; +} +#else + ptr = tcc_malloc(size); +#endif + tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */ + dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr); + return 0; +} + +ST_FUNC void tcc_run_free(TCCState *s1) +{ + int i; + + for (i = 0; i < s1->nb_runtime_mem; ++i) { +#ifdef HAVE_SELINUX + unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++]; + munmap(s1->runtime_mem[i++], size); + munmap(s1->runtime_mem[i], size); +#else +#ifdef _WIN64 + win64_del_function_table(*(void**)s1->runtime_mem[i]); +#endif + tcc_free(s1->runtime_mem[i]); +#endif + } + tcc_free(s1->runtime_mem); +} + +/* launch the compiled program with the given arguments */ +LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) +{ + int (*prog_main)(int, char **); + + s1->runtime_main = "main"; + if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main)) + return 0; + if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) + return -1; + prog_main = tcc_get_symbol_err(s1, s1->runtime_main); + +#ifdef CONFIG_TCC_BACKTRACE + if (s1->do_debug) { + set_exception_handler(); + rt_prog_main = prog_main; + } +#endif + + errno = 0; /* clean errno value */ + +#ifdef CONFIG_TCC_BCHECK + if (s1->do_bounds_check) { + void (*bound_init)(void); + void (*bound_exit)(void); + void (*bound_new_region)(void *p, addr_t size); + int (*bound_delete_region)(void *p); + int i, ret; + + /* set error function */ + rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg"); + /* XXX: use .init section so that it also work in binary ? */ + bound_init = tcc_get_symbol_err(s1, "__bound_init"); + bound_exit = tcc_get_symbol_err(s1, "__bound_exit"); + bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region"); + bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region"); + + bound_init(); + /* mark argv area as valid */ + bound_new_region(argv, argc*sizeof(argv[0])); + for (i=0; i<argc; ++i) + bound_new_region(argv[i], strlen(argv[i]) + 1); + + ret = (*prog_main)(argc, argv); + + /* unmark argv area */ + for (i=0; i<argc; ++i) + bound_delete_region(argv[i]); + bound_delete_region(argv); + bound_exit(); + return ret; + } +#endif + return (*prog_main)(argc, argv); +} + +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 + #define RUN_SECTION_ALIGNMENT 63 +#else + #define RUN_SECTION_ALIGNMENT 15 +#endif + +/* relocate code. Return -1 on error, required size if ptr is NULL, + otherwise copy code into buffer passed by the caller */ +static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff) +{ + Section *s; + unsigned offset, length, fill, i, k; + addr_t mem; + + if (NULL == ptr) { + s1->nb_errors = 0; +#ifdef TCC_TARGET_PE + pe_output_file(s1, NULL); +#else + tcc_add_runtime(s1); + relocate_common_syms(); + tcc_add_linker_symbols(s1); + build_got_entries(s1); +#endif + if (s1->nb_errors) + return -1; + } + + offset = 0, mem = (addr_t)ptr; + fill = -mem & RUN_SECTION_ALIGNMENT; +#ifdef _WIN64 + offset += sizeof (void*); +#endif + for (k = 0; k < 2; ++k) { + for(i = 1; i < s1->nb_sections; i++) { + s = s1->sections[i]; + if (0 == (s->sh_flags & SHF_ALLOC)) + continue; + if (k != !(s->sh_flags & SHF_EXECINSTR)) + continue; + offset += fill; + if (!mem) + s->sh_addr = 0; + else if (s->sh_flags & SHF_EXECINSTR) + s->sh_addr = mem + offset + ptr_diff; + else + s->sh_addr = mem + offset; +#if 0 + if (mem) + printf("%-16s +%02lx %p %04x\n", + s->name, fill, (void*)s->sh_addr, (unsigned)s->data_offset); +#endif + offset += s->data_offset; + fill = -(mem + offset) & 15; + } +#if RUN_SECTION_ALIGNMENT > 15 + /* To avoid that x86 processors would reload cached instructions each time + when data is written in the near, we need to make sure that code and data + do not share the same 64 byte unit */ + fill = -(mem + offset) & RUN_SECTION_ALIGNMENT; +#endif + } + + /* relocate symbols */ + relocate_syms(s1, s1->symtab, 1); + if (s1->nb_errors) + return -1; + + if (0 == mem) + return offset + RUN_SECTION_ALIGNMENT; + + /* relocate each section */ + for(i = 1; i < s1->nb_sections; i++) { + s = s1->sections[i]; + if (s->reloc) + relocate_section(s1, s); + } + relocate_plt(s1); + +#ifdef _WIN64 + *(void**)ptr = win64_add_function_table(s1); +#endif + + for(i = 1; i < s1->nb_sections; i++) { + s = s1->sections[i]; + if (0 == (s->sh_flags & SHF_ALLOC)) + continue; + length = s->data_offset; + ptr = (void*)s->sh_addr; + if (s->sh_flags & SHF_EXECINSTR) + ptr = (char*)ptr - ptr_diff; + if (NULL == s->data || s->sh_type == SHT_NOBITS) + memset(ptr, 0, length); + else + memcpy(ptr, s->data, length); + /* mark executable sections as executable in memory */ + if (s->sh_flags & SHF_EXECINSTR) + set_pages_executable((char*)ptr + ptr_diff, length); + } + return 0; +} + +/* ------------------------------------------------------------- */ +/* allow to run code in memory */ + +static void set_pages_executable(void *ptr, unsigned long length) +{ +#ifdef _WIN32 + unsigned long old_protect; + VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); +#else + void __clear_cache(void *beginning, void *end); +# ifndef HAVE_SELINUX + addr_t start, end; +# ifndef PAGESIZE +# define PAGESIZE 4096 +# endif + start = (addr_t)ptr & ~(PAGESIZE - 1); + end = (addr_t)ptr + length; + end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); + if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC)) + tcc_error("mprotect failed: did you mean to configure --with-selinux?"); +# endif +# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 + __clear_cache(ptr, (char *)ptr + length); +# endif +#endif +} + +#ifdef _WIN64 +static void *win64_add_function_table(TCCState *s1) +{ + void *p = NULL; + if (s1->uw_pdata) { + p = (void*)s1->uw_pdata->sh_addr; + RtlAddFunctionTable( + (RUNTIME_FUNCTION*)p, + s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION), + text_section->sh_addr + ); + s1->uw_pdata = NULL; + } + return p;; +} + +static void win64_del_function_table(void *p) +{ + if (p) { + RtlDeleteFunctionTable((RUNTIME_FUNCTION*)p); + } +} +#endif + +/* ------------------------------------------------------------- */ +#ifdef CONFIG_TCC_BACKTRACE + +ST_FUNC void tcc_set_num_callers(int n) +{ + rt_num_callers = n; +} + +/* print the position in the source file of PC value 'pc' by reading + the stabs debug information */ +static addr_t rt_printline(addr_t wanted_pc, const char *msg) +{ + char func_name[128], last_func_name[128]; + addr_t func_addr, last_pc, pc; + const char *incl_files[INCLUDE_STACK_SIZE]; + int incl_index, len, last_line_num, i; + const char *str, *p; + + Stab_Sym *stab_sym = NULL, *stab_sym_end, *sym; + int stab_len = 0; + char *stab_str = NULL; + + if (stab_section) { + stab_len = stab_section->data_offset; + stab_sym = (Stab_Sym *)stab_section->data; + stab_str = (char *) stabstr_section->data; + } + + func_name[0] = '\0'; + func_addr = 0; + incl_index = 0; + last_func_name[0] = '\0'; + last_pc = (addr_t)-1; + last_line_num = 1; + + if (!stab_sym) + goto no_stabs; + + stab_sym_end = (Stab_Sym*)((char*)stab_sym + stab_len); + for (sym = stab_sym + 1; sym < stab_sym_end; ++sym) { + switch(sym->n_type) { + /* function start or end */ + case N_FUN: + if (sym->n_strx == 0) { + /* we test if between last line and end of function */ + pc = sym->n_value + func_addr; + if (wanted_pc >= last_pc && wanted_pc < pc) + goto found; + func_name[0] = '\0'; + func_addr = 0; + } else { + str = stab_str + sym->n_strx; + p = strchr(str, ':'); + if (!p) { + pstrcpy(func_name, sizeof(func_name), str); + } else { + len = p - str; + if (len > sizeof(func_name) - 1) + len = sizeof(func_name) - 1; + memcpy(func_name, str, len); + func_name[len] = '\0'; + } + func_addr = sym->n_value; + } + break; + /* line number info */ + case N_SLINE: + pc = sym->n_value + func_addr; + if (wanted_pc >= last_pc && wanted_pc < pc) + goto found; + last_pc = pc; + last_line_num = sym->n_desc; + /* XXX: slow! */ + strcpy(last_func_name, func_name); + break; + /* include files */ + case N_BINCL: + str = stab_str + sym->n_strx; + add_incl: + if (incl_index < INCLUDE_STACK_SIZE) { + incl_files[incl_index++] = str; + } + break; + case N_EINCL: + if (incl_index > 1) + incl_index--; + break; + case N_SO: + if (sym->n_strx == 0) { + incl_index = 0; /* end of translation unit */ + } else { + str = stab_str + sym->n_strx; + /* do not add path */ + len = strlen(str); + if (len > 0 && str[len - 1] != '/') + goto add_incl; + } + break; + } + } + +no_stabs: + /* second pass: we try symtab symbols (no line number info) */ + incl_index = 0; + if (symtab_section) + { + ElfW(Sym) *sym, *sym_end; + int type; + + sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); + for(sym = (ElfW(Sym) *)symtab_section->data + 1; + sym < sym_end; + sym++) { + type = ELFW(ST_TYPE)(sym->st_info); + if (type == STT_FUNC || type == STT_GNU_IFUNC) { + if (wanted_pc >= sym->st_value && + wanted_pc < sym->st_value + sym->st_size) { + pstrcpy(last_func_name, sizeof(last_func_name), + (char *) strtab_section->data + sym->st_name); + func_addr = sym->st_value; + goto found; + } + } + } + } + /* did not find any info: */ + fprintf(stderr, "%s %p ???\n", msg, (void*)wanted_pc); + fflush(stderr); + return 0; + found: + i = incl_index; + if (i > 0) + fprintf(stderr, "%s:%d: ", incl_files[--i], last_line_num); + fprintf(stderr, "%s %p", msg, (void*)wanted_pc); + if (last_func_name[0] != '\0') + fprintf(stderr, " %s()", last_func_name); + if (--i >= 0) { + fprintf(stderr, " (included from "); + for (;;) { + fprintf(stderr, "%s", incl_files[i]); + if (--i < 0) + break; + fprintf(stderr, ", "); + } + fprintf(stderr, ")"); + } + fprintf(stderr, "\n"); + fflush(stderr); + return func_addr; +} + +/* emit a run time error at position 'pc' */ +static void rt_error(ucontext_t *uc, const char *fmt, ...) +{ + va_list ap; + addr_t pc; + int i; + + fprintf(stderr, "Runtime error: "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + + for(i=0;i<rt_num_callers;i++) { + if (rt_get_caller_pc(&pc, uc, i) < 0) + break; + pc = rt_printline(pc, i ? "by" : "at"); + if (pc == (addr_t)rt_prog_main && pc) + break; + } +} + +/* ------------------------------------------------------------- */ +#ifndef _WIN32 + +/* signal handler for fatal errors */ +static void sig_error(int signum, siginfo_t *siginf, void *puc) +{ + ucontext_t *uc = puc; + + switch(signum) { + case SIGFPE: + switch(siginf->si_code) { + case FPE_INTDIV: + case FPE_FLTDIV: + rt_error(uc, "division by zero"); + break; + default: + rt_error(uc, "floating point exception"); + break; + } + break; + case SIGBUS: + case SIGSEGV: + if (rt_bound_error_msg && *rt_bound_error_msg) + rt_error(uc, *rt_bound_error_msg); + else + rt_error(uc, "dereferencing invalid pointer"); + break; + case SIGILL: + rt_error(uc, "illegal instruction"); + break; + case SIGABRT: + rt_error(uc, "abort() called"); + break; + default: + rt_error(uc, "caught signal %d", signum); + break; + } + exit(255); +} + +#ifndef SA_SIGINFO +# define SA_SIGINFO 0x00000004u +#endif + +/* Generate a stack backtrace when a CPU exception occurs. */ +static void set_exception_handler(void) +{ + struct sigaction sigact; + /* install TCC signal handlers to print debug info on fatal + runtime errors */ + sigact.sa_flags = SA_SIGINFO | SA_RESETHAND; + sigact.sa_sigaction = sig_error; + sigemptyset(&sigact.sa_mask); + sigaction(SIGFPE, &sigact, NULL); + sigaction(SIGILL, &sigact, NULL); + sigaction(SIGSEGV, &sigact, NULL); + sigaction(SIGBUS, &sigact, NULL); + sigaction(SIGABRT, &sigact, NULL); +} + +/* ------------------------------------------------------------- */ +#ifdef __i386__ + +/* fix for glibc 2.1 */ +#ifndef REG_EIP +#define REG_EIP EIP +#define REG_EBP EBP +#endif + +/* return the PC at frame level 'level'. Return negative if not found */ +static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) +{ + addr_t fp; + int i; + + if (level == 0) { +#if defined(__APPLE__) + *paddr = uc->uc_mcontext->__ss.__eip; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + *paddr = uc->uc_mcontext.mc_eip; +#elif defined(__dietlibc__) + *paddr = uc->uc_mcontext.eip; +#elif defined(__NetBSD__) + *paddr = uc->uc_mcontext.__gregs[_REG_EIP]; +#elif defined(__OpenBSD__) + *paddr = uc->sc_eip; +#else + *paddr = uc->uc_mcontext.gregs[REG_EIP]; +#endif + return 0; + } else { +#if defined(__APPLE__) + fp = uc->uc_mcontext->__ss.__ebp; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + fp = uc->uc_mcontext.mc_ebp; +#elif defined(__dietlibc__) + fp = uc->uc_mcontext.ebp; +#elif defined(__NetBSD__) + fp = uc->uc_mcontext.__gregs[_REG_EBP]; +#elif defined(__OpenBSD__) + *paddr = uc->sc_ebp; +#else + fp = uc->uc_mcontext.gregs[REG_EBP]; +#endif + for(i=1;i<level;i++) { + /* XXX: check address validity with program info */ + if (fp <= 0x1000 || fp >= 0xc0000000) + return -1; + fp = ((addr_t *)fp)[0]; + } + *paddr = ((addr_t *)fp)[1]; + return 0; + } +} + +/* ------------------------------------------------------------- */ +#elif defined(__x86_64__) + +/* return the PC at frame level 'level'. Return negative if not found */ +static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) +{ + addr_t fp; + int i; + + if (level == 0) { + /* XXX: only support linux */ +#if defined(__APPLE__) + *paddr = uc->uc_mcontext->__ss.__rip; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + *paddr = uc->uc_mcontext.mc_rip; +#elif defined(__NetBSD__) + *paddr = uc->uc_mcontext.__gregs[_REG_RIP]; +#else + *paddr = uc->uc_mcontext.gregs[REG_RIP]; +#endif + return 0; + } else { +#if defined(__APPLE__) + fp = uc->uc_mcontext->__ss.__rbp; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + fp = uc->uc_mcontext.mc_rbp; +#elif defined(__NetBSD__) + fp = uc->uc_mcontext.__gregs[_REG_RBP]; +#else + fp = uc->uc_mcontext.gregs[REG_RBP]; +#endif + for(i=1;i<level;i++) { + /* XXX: check address validity with program info */ + if (fp <= 0x1000) + return -1; + fp = ((addr_t *)fp)[0]; + } + *paddr = ((addr_t *)fp)[1]; + return 0; + } +} + +/* ------------------------------------------------------------- */ +#elif defined(__arm__) + +/* return the PC at frame level 'level'. Return negative if not found */ +static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) +{ + addr_t fp, sp; + int i; + + if (level == 0) { + /* XXX: only supports linux */ +#if defined(__linux__) + *paddr = uc->uc_mcontext.arm_pc; +#else + return -1; +#endif + return 0; + } else { +#if defined(__linux__) + fp = uc->uc_mcontext.arm_fp; + sp = uc->uc_mcontext.arm_sp; + if (sp < 0x1000) + sp = 0x1000; +#else + return -1; +#endif + /* XXX: specific to tinycc stack frames */ + if (fp < sp + 12 || fp & 3) + return -1; + for(i = 1; i < level; i++) { + sp = ((addr_t *)fp)[-2]; + if (sp < fp || sp - fp > 16 || sp & 3) + return -1; + fp = ((addr_t *)fp)[-3]; + if (fp <= sp || fp - sp < 12 || fp & 3) + return -1; + } + /* XXX: check address validity with program info */ + *paddr = ((addr_t *)fp)[-1]; + return 0; + } +} + +/* ------------------------------------------------------------- */ +#elif defined(__aarch64__) + +static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) +{ + if (level < 0) + return -1; + else if (level == 0) { + *paddr = uc->uc_mcontext.pc; + return 0; + } + else { + addr_t *fp = (addr_t *)uc->uc_mcontext.regs[29]; + int i; + for (i = 1; i < level; i++) + fp = (addr_t *)fp[0]; + *paddr = fp[1]; + return 0; + } +} + +/* ------------------------------------------------------------- */ +#else + +#warning add arch specific rt_get_caller_pc() +static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) +{ + return -1; +} + +#endif /* !__i386__ */ + +/* ------------------------------------------------------------- */ +#else /* WIN32 */ + +static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info) +{ + EXCEPTION_RECORD *er = ex_info->ExceptionRecord; + CONTEXT *uc = ex_info->ContextRecord; + switch (er->ExceptionCode) { + case EXCEPTION_ACCESS_VIOLATION: + if (rt_bound_error_msg && *rt_bound_error_msg) + rt_error(uc, *rt_bound_error_msg); + else + rt_error(uc, "access violation"); + break; + case EXCEPTION_STACK_OVERFLOW: + rt_error(uc, "stack overflow"); + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + rt_error(uc, "division by zero"); + break; + default: + rt_error(uc, "exception caught"); + break; + } + return EXCEPTION_EXECUTE_HANDLER; +} + +/* Generate a stack backtrace when a CPU exception occurs. */ +static void set_exception_handler(void) +{ + SetUnhandledExceptionFilter(cpu_exception_handler); +} + +/* return the PC at frame level 'level'. Return non zero if not found */ +static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level) +{ + addr_t fp, pc; + int i; +#ifdef _WIN64 + pc = uc->Rip; + fp = uc->Rbp; +#else + pc = uc->Eip; + fp = uc->Ebp; +#endif + if (level > 0) { + for(i=1;i<level;i++) { + /* XXX: check address validity with program info */ + if (fp <= 0x1000 || fp >= 0xc0000000) + return -1; + fp = ((addr_t*)fp)[0]; + } + pc = ((addr_t*)fp)[1]; + } + *paddr = pc; + return 0; +} + +#endif /* _WIN32 */ +#endif /* CONFIG_TCC_BACKTRACE */ +/* ------------------------------------------------------------- */ +#ifdef CONFIG_TCC_STATIC + +/* dummy function for profiling */ +ST_FUNC void *dlopen(const char *filename, int flag) +{ + return NULL; +} + +ST_FUNC void dlclose(void *p) +{ +} + +ST_FUNC const char *dlerror(void) +{ + return "error"; +} + +typedef struct TCCSyms { + char *str; + void *ptr; +} TCCSyms; + + +/* add the symbol you want here if no dynamic linking is done */ +static TCCSyms tcc_syms[] = { +#if !defined(CONFIG_TCCBOOT) +#define TCCSYM(a) { #a, &a, }, + TCCSYM(printf) + TCCSYM(fprintf) + TCCSYM(fopen) + TCCSYM(fclose) +#undef TCCSYM +#endif + { NULL, NULL }, +}; + +ST_FUNC void *dlsym(void *handle, const char *symbol) +{ + TCCSyms *p; + p = tcc_syms; + while (p->str != NULL) { + if (!strcmp(p->str, symbol)) + return p->ptr; + p++; + } + return NULL; +} + +#endif /* CONFIG_TCC_STATIC */ +#endif /* TCC_IS_NATIVE */ +/* ------------------------------------------------------------- */ diff --git a/tinyc/tcctok.h b/tinyc/tcctok.h index 2be032fa4..317f64cd7 100644 --- a/tinyc/tcctok.h +++ b/tinyc/tcctok.h @@ -36,7 +36,9 @@ DEF(TOK_RESTRICT2, "__restrict") DEF(TOK_RESTRICT3, "__restrict__") DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */ - + + DEF(TOK_GENERIC, "_Generic") + DEF(TOK_FLOAT, "float") DEF(TOK_DOUBLE, "double") DEF(TOK_BOOL, "_Bool") @@ -59,6 +61,10 @@ DEF(TOK_ASM2, "__asm") DEF(TOK_ASM3, "__asm__") +#ifdef TCC_TARGET_ARM64 + DEF(TOK_UINT128, "__uint128_t") +#endif + /*********************************************************************/ /* the following are not keywords. They are included to ease parsing */ /* preprocessor only */ @@ -81,10 +87,16 @@ DEF(TOK___TIME__, "__TIME__") DEF(TOK___FUNCTION__, "__FUNCTION__") DEF(TOK___VA_ARGS__, "__VA_ARGS__") - + DEF(TOK___COUNTER__, "__COUNTER__") + /* special identifiers */ DEF(TOK___FUNC__, "__func__") - + +/* special floating point values */ + DEF(TOK___NAN__, "__nan__") + DEF(TOK___SNAN__, "__snan__") + DEF(TOK___INF__, "__inf__") + /* attribute identifiers */ /* XXX: handle all tokens generically since speed is not critical */ DEF(TOK_SECTION1, "section") @@ -93,6 +105,10 @@ DEF(TOK_ALIGNED2, "__aligned__") DEF(TOK_PACKED1, "packed") DEF(TOK_PACKED2, "__packed__") + DEF(TOK_WEAK1, "weak") + DEF(TOK_WEAK2, "__weak__") + DEF(TOK_ALIAS1, "alias") + DEF(TOK_ALIAS2, "__alias__") DEF(TOK_UNUSED1, "unused") DEF(TOK_UNUSED2, "__unused__") DEF(TOK_CDECL1, "cdecl") @@ -104,47 +120,84 @@ DEF(TOK_FASTCALL1, "fastcall") DEF(TOK_FASTCALL2, "__fastcall") DEF(TOK_FASTCALL3, "__fastcall__") + DEF(TOK_REGPARM1, "regparm") + DEF(TOK_REGPARM2, "__regparm__") + + DEF(TOK_MODE, "__mode__") + DEF(TOK_MODE_QI, "__QI__") + DEF(TOK_MODE_DI, "__DI__") + DEF(TOK_MODE_HI, "__HI__") + DEF(TOK_MODE_SI, "__SI__") + DEF(TOK_MODE_word, "__word__") + DEF(TOK_DLLEXPORT, "dllexport") + DEF(TOK_DLLIMPORT, "dllimport") DEF(TOK_NORETURN1, "noreturn") DEF(TOK_NORETURN2, "__noreturn__") + DEF(TOK_VISIBILITY1, "visibility") + DEF(TOK_VISIBILITY2, "__visibility__") + DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") + DEF(TOK_builtin_choose_expr, "__builtin_choose_expr") DEF(TOK_builtin_constant_p, "__builtin_constant_p") DEF(TOK_builtin_frame_address, "__builtin_frame_address") -#ifdef TCC_TARGET_X86_64 - DEF(TOK_builtin_malloc, "__builtin_malloc") - DEF(TOK_builtin_free, "__builtin_free") - DEF(TOK_malloc, "malloc") - DEF(TOK_free, "free") + DEF(TOK_builtin_return_address, "__builtin_return_address") + DEF(TOK_builtin_expect, "__builtin_expect") + /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/ +#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64 + DEF(TOK_builtin_va_start, "__builtin_va_start") +#elif defined TCC_TARGET_X86_64 + DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types") +#elif defined TCC_TARGET_ARM64 + DEF(TOK___va_start, "__va_start") + DEF(TOK___va_arg, "__va_arg") #endif - DEF(TOK_REGPARM1, "regparm") - DEF(TOK_REGPARM2, "__regparm__") /* pragma */ DEF(TOK_pack, "pack") -#if !defined(TCC_TARGET_I386) +#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64) /* already defined for assembler */ DEF(TOK_ASM_push, "push") DEF(TOK_ASM_pop, "pop") #endif + DEF(TOK_comment, "comment") + DEF(TOK_lib, "lib") + DEF(TOK_push_macro, "push_macro") + DEF(TOK_pop_macro, "pop_macro") + DEF(TOK_once, "once") + DEF(TOK_option, "option") /* builtin functions or variables */ -#ifdef TCC_ARM_EABI - DEF(TOK_memcpy, "__aeabi_memcpy") - DEF(TOK_memcpy4, "__aeabi_memcpy4") - DEF(TOK_memcpy8, "__aeabi_memcpy8") - DEF(TOK_memset, "__aeabi_memset") - DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") - DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") -#else +#ifndef TCC_ARM_EABI DEF(TOK_memcpy, "memcpy") + DEF(TOK_memmove, "memmove") DEF(TOK_memset, "memset") DEF(TOK___divdi3, "__divdi3") DEF(TOK___moddi3, "__moddi3") DEF(TOK___udivdi3, "__udivdi3") DEF(TOK___umoddi3, "__umoddi3") + DEF(TOK___ashrdi3, "__ashrdi3") + DEF(TOK___lshrdi3, "__lshrdi3") + DEF(TOK___ashldi3, "__ashldi3") + DEF(TOK___floatundisf, "__floatundisf") + DEF(TOK___floatundidf, "__floatundidf") +# ifndef TCC_ARM_VFP + DEF(TOK___floatundixf, "__floatundixf") + DEF(TOK___fixunsxfdi, "__fixunsxfdi") +# endif + DEF(TOK___fixunssfdi, "__fixunssfdi") + DEF(TOK___fixunsdfdi, "__fixunsdfdi") #endif -#if defined(TCC_TARGET_ARM) -#ifdef TCC_ARM_EABI + +#if defined TCC_TARGET_ARM +# ifdef TCC_ARM_EABI + DEF(TOK_memcpy, "__aeabi_memcpy") + DEF(TOK_memcpy4, "__aeabi_memcpy4") + DEF(TOK_memcpy8, "__aeabi_memcpy8") + DEF(TOK_memmove, "__aeabi_memmove") + DEF(TOK_memset, "__aeabi_memset") + DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") + DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") DEF(TOK___aeabi_idivmod, "__aeabi_idivmod") DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod") DEF(TOK___divsi3, "__aeabi_idiv") @@ -153,24 +206,33 @@ DEF(TOK___floatdidf, "__aeabi_l2d") DEF(TOK___fixsfdi, "__aeabi_f2lz") DEF(TOK___fixdfdi, "__aeabi_d2lz") -#else + DEF(TOK___ashrdi3, "__aeabi_lasr") + DEF(TOK___lshrdi3, "__aeabi_llsr") + DEF(TOK___ashldi3, "__aeabi_llsl") + DEF(TOK___floatundisf, "__aeabi_ul2f") + DEF(TOK___floatundidf, "__aeabi_ul2d") + DEF(TOK___fixunssfdi, "__aeabi_f2ulz") + DEF(TOK___fixunsdfdi, "__aeabi_d2ulz") +# else DEF(TOK___modsi3, "__modsi3") DEF(TOK___umodsi3, "__umodsi3") DEF(TOK___divsi3, "__divsi3") DEF(TOK___udivsi3, "__udivsi3") DEF(TOK___floatdisf, "__floatdisf") DEF(TOK___floatdidf, "__floatdidf") -#ifndef TCC_ARM_VFP +# ifndef TCC_ARM_VFP DEF(TOK___floatdixf, "__floatdixf") DEF(TOK___fixunssfsi, "__fixunssfsi") DEF(TOK___fixunsdfsi, "__fixunsdfsi") DEF(TOK___fixunsxfsi, "__fixunsxfsi") DEF(TOK___fixxfdi, "__fixxfdi") -#endif +# endif DEF(TOK___fixsfdi, "__fixsfdi") DEF(TOK___fixdfdi, "__fixdfdi") +# endif #endif -#elif defined(TCC_TARGET_C67) + +#if defined TCC_TARGET_C67 DEF(TOK__divi, "_divi") DEF(TOK__divu, "_divu") DEF(TOK__divf, "_divf") @@ -178,34 +240,45 @@ DEF(TOK__remi, "_remi") DEF(TOK__remu, "_remu") #endif -#ifdef TCC_TARGET_I386 - DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control") - DEF(TOK___tcc_fpu_control, "__tcc_fpu_control") -#endif -#ifdef TCC_ARM_EABI - DEF(TOK___ashrdi3, "__aeabi_lasr") - DEF(TOK___lshrdi3, "__aeabi_llsr") - DEF(TOK___ashldi3, "__aeabi_llsl") - DEF(TOK___floatundisf, "__aeabi_ul2f") - DEF(TOK___floatundidf, "__aeabi_ul2d") - DEF(TOK___fixunssfdi, "__aeabi_f2ulz") - DEF(TOK___fixunsdfdi, "__aeabi_d2ulz") -#else - DEF(TOK___ashrdi3, "__ashrdi3") - DEF(TOK___lshrdi3, "__lshrdi3") - DEF(TOK___ashldi3, "__ashldi3") - DEF(TOK___floatundisf, "__floatundisf") - DEF(TOK___floatundidf, "__floatundidf") -#ifndef TCC_ARM_VFP - DEF(TOK___floatundixf, "__floatundixf") - DEF(TOK___fixunsxfdi, "__fixunsxfdi") + +#if defined TCC_TARGET_I386 + DEF(TOK___fixsfdi, "__fixsfdi") + DEF(TOK___fixdfdi, "__fixdfdi") + DEF(TOK___fixxfdi, "__fixxfdi") #endif - DEF(TOK___fixunssfdi, "__fixunssfdi") - DEF(TOK___fixunsdfdi, "__fixunsdfdi") + +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 + DEF(TOK_alloca, "alloca") #endif -#ifdef TCC_TARGET_PE + +#if defined TCC_TARGET_PE DEF(TOK___chkstk, "__chkstk") #endif +#ifdef TCC_TARGET_ARM64 + DEF(TOK___arm64_clear_cache, "__arm64_clear_cache") + DEF(TOK___addtf3, "__addtf3") + DEF(TOK___subtf3, "__subtf3") + DEF(TOK___multf3, "__multf3") + DEF(TOK___divtf3, "__divtf3") + DEF(TOK___extendsftf2, "__extendsftf2") + DEF(TOK___extenddftf2, "__extenddftf2") + DEF(TOK___trunctfsf2, "__trunctfsf2") + DEF(TOK___trunctfdf2, "__trunctfdf2") + DEF(TOK___fixtfsi, "__fixtfsi") + DEF(TOK___fixtfdi, "__fixtfdi") + DEF(TOK___fixunstfsi, "__fixunstfsi") + DEF(TOK___fixunstfdi, "__fixunstfdi") + DEF(TOK___floatsitf, "__floatsitf") + DEF(TOK___floatditf, "__floatditf") + DEF(TOK___floatunsitf, "__floatunsitf") + DEF(TOK___floatunditf, "__floatunditf") + DEF(TOK___eqtf2, "__eqtf2") + DEF(TOK___netf2, "__netf2") + DEF(TOK___lttf2, "__lttf2") + DEF(TOK___letf2, "__letf2") + DEF(TOK___gttf2, "__gttf2") + DEF(TOK___getf2, "__getf2") +#endif /* bound checking symbols */ #ifdef CONFIG_TCC_BCHECK @@ -216,254 +289,62 @@ DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8") DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12") DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16") + DEF(TOK___bound_main_arg, "__bound_main_arg") DEF(TOK___bound_local_new, "__bound_local_new") DEF(TOK___bound_local_delete, "__bound_local_delete") -#if 0 +# ifdef TCC_TARGET_PE DEF(TOK_malloc, "malloc") DEF(TOK_free, "free") DEF(TOK_realloc, "realloc") DEF(TOK_memalign, "memalign") DEF(TOK_calloc, "calloc") -#endif - DEF(TOK_memmove, "memmove") +# endif DEF(TOK_strlen, "strlen") DEF(TOK_strcpy, "strcpy") - DEF(TOK_alloca, "alloca") #endif /* Tiny Assembler */ + DEF_ASMDIR(byte) /* must be first directive */ + DEF_ASMDIR(word) + DEF_ASMDIR(align) + DEF_ASMDIR(balign) + DEF_ASMDIR(p2align) + DEF_ASMDIR(set) + DEF_ASMDIR(skip) + DEF_ASMDIR(space) + DEF_ASMDIR(string) + DEF_ASMDIR(asciz) + DEF_ASMDIR(ascii) + DEF_ASMDIR(file) + DEF_ASMDIR(globl) + DEF_ASMDIR(global) + DEF_ASMDIR(weak) + DEF_ASMDIR(hidden) + DEF_ASMDIR(ident) + DEF_ASMDIR(size) + DEF_ASMDIR(type) + DEF_ASMDIR(text) + DEF_ASMDIR(data) + DEF_ASMDIR(bss) + DEF_ASMDIR(previous) + DEF_ASMDIR(pushsection) + DEF_ASMDIR(popsection) + DEF_ASMDIR(fill) + DEF_ASMDIR(rept) + DEF_ASMDIR(endr) + DEF_ASMDIR(org) + DEF_ASMDIR(quad) +#if defined(TCC_TARGET_I386) + DEF_ASMDIR(code16) + DEF_ASMDIR(code32) +#elif defined(TCC_TARGET_X86_64) + DEF_ASMDIR(code64) +#endif + DEF_ASMDIR(short) + DEF_ASMDIR(long) + DEF_ASMDIR(int) + DEF_ASMDIR(section) /* must be last directive */ - DEF_ASM(byte) - DEF_ASM(align) - DEF_ASM(skip) - DEF_ASM(space) - DEF_ASM(string) - DEF_ASM(asciz) - DEF_ASM(ascii) - DEF_ASM(globl) - DEF_ASM(global) - DEF_ASM(text) - DEF_ASM(data) - DEF_ASM(bss) - DEF_ASM(previous) - DEF_ASM(fill) - DEF_ASM(org) - DEF_ASM(quad) - -#ifdef TCC_TARGET_I386 - -/* WARNING: relative order of tokens is important. */ - DEF_ASM(al) - DEF_ASM(cl) - DEF_ASM(dl) - DEF_ASM(bl) - DEF_ASM(ah) - DEF_ASM(ch) - DEF_ASM(dh) - DEF_ASM(bh) - DEF_ASM(ax) - DEF_ASM(cx) - DEF_ASM(dx) - DEF_ASM(bx) - DEF_ASM(sp) - DEF_ASM(bp) - DEF_ASM(si) - DEF_ASM(di) - DEF_ASM(eax) - DEF_ASM(ecx) - DEF_ASM(edx) - DEF_ASM(ebx) - DEF_ASM(esp) - DEF_ASM(ebp) - DEF_ASM(esi) - DEF_ASM(edi) - DEF_ASM(mm0) - DEF_ASM(mm1) - DEF_ASM(mm2) - DEF_ASM(mm3) - DEF_ASM(mm4) - DEF_ASM(mm5) - DEF_ASM(mm6) - DEF_ASM(mm7) - DEF_ASM(xmm0) - DEF_ASM(xmm1) - DEF_ASM(xmm2) - DEF_ASM(xmm3) - DEF_ASM(xmm4) - DEF_ASM(xmm5) - DEF_ASM(xmm6) - DEF_ASM(xmm7) - DEF_ASM(cr0) - DEF_ASM(cr1) - DEF_ASM(cr2) - DEF_ASM(cr3) - DEF_ASM(cr4) - DEF_ASM(cr5) - DEF_ASM(cr6) - DEF_ASM(cr7) - DEF_ASM(tr0) - DEF_ASM(tr1) - DEF_ASM(tr2) - DEF_ASM(tr3) - DEF_ASM(tr4) - DEF_ASM(tr5) - DEF_ASM(tr6) - DEF_ASM(tr7) - DEF_ASM(db0) - DEF_ASM(db1) - DEF_ASM(db2) - DEF_ASM(db3) - DEF_ASM(db4) - DEF_ASM(db5) - DEF_ASM(db6) - DEF_ASM(db7) - DEF_ASM(dr0) - DEF_ASM(dr1) - DEF_ASM(dr2) - DEF_ASM(dr3) - DEF_ASM(dr4) - DEF_ASM(dr5) - DEF_ASM(dr6) - DEF_ASM(dr7) - DEF_ASM(es) - DEF_ASM(cs) - DEF_ASM(ss) - DEF_ASM(ds) - DEF_ASM(fs) - DEF_ASM(gs) - DEF_ASM(st) - - DEF_BWL(mov) - - /* generic two operands */ - DEF_BWL(add) - DEF_BWL(or) - DEF_BWL(adc) - DEF_BWL(sbb) - DEF_BWL(and) - DEF_BWL(sub) - DEF_BWL(xor) - DEF_BWL(cmp) - - /* unary ops */ - DEF_BWL(inc) - DEF_BWL(dec) - DEF_BWL(not) - DEF_BWL(neg) - DEF_BWL(mul) - DEF_BWL(imul) - DEF_BWL(div) - DEF_BWL(idiv) - - DEF_BWL(xchg) - DEF_BWL(test) - - /* shifts */ - DEF_BWL(rol) - DEF_BWL(ror) - DEF_BWL(rcl) - DEF_BWL(rcr) - DEF_BWL(shl) - DEF_BWL(shr) - DEF_BWL(sar) - - DEF_ASM(shldw) - DEF_ASM(shldl) - DEF_ASM(shld) - DEF_ASM(shrdw) - DEF_ASM(shrdl) - DEF_ASM(shrd) - - DEF_ASM(pushw) - DEF_ASM(pushl) - DEF_ASM(push) - DEF_ASM(popw) - DEF_ASM(popl) - DEF_ASM(pop) - DEF_BWL(in) - DEF_BWL(out) - - DEF_WL(movzb) - - DEF_ASM(movzwl) - DEF_ASM(movsbw) - DEF_ASM(movsbl) - DEF_ASM(movswl) - - DEF_WL(lea) - - DEF_ASM(les) - DEF_ASM(lds) - DEF_ASM(lss) - DEF_ASM(lfs) - DEF_ASM(lgs) - - DEF_ASM(call) - DEF_ASM(jmp) - DEF_ASM(lcall) - DEF_ASM(ljmp) - - DEF_ASMTEST(j) - - DEF_ASMTEST(set) - DEF_ASMTEST(cmov) - - DEF_WL(bsf) - DEF_WL(bsr) - DEF_WL(bt) - DEF_WL(bts) - DEF_WL(btr) - DEF_WL(btc) - - DEF_WL(lsl) - - /* generic FP ops */ - DEF_FP(add) - DEF_FP(mul) - - DEF_ASM(fcom) - DEF_ASM(fcom_1) /* non existent op, just to have a regular table */ - DEF_FP1(com) - - DEF_FP(comp) - DEF_FP(sub) - DEF_FP(subr) - DEF_FP(div) - DEF_FP(divr) - - DEF_BWL(xadd) - DEF_BWL(cmpxchg) - - /* string ops */ - DEF_BWL(cmps) - DEF_BWL(scmp) - DEF_BWL(ins) - DEF_BWL(outs) - DEF_BWL(lods) - DEF_BWL(slod) - DEF_BWL(movs) - DEF_BWL(smov) - DEF_BWL(scas) - DEF_BWL(ssca) - DEF_BWL(stos) - DEF_BWL(ssto) - - /* generic asm ops */ - -#define ALT(x) -#define DEF_ASM_OP0(name, opcode) DEF_ASM(name) -#define DEF_ASM_OP0L(name, opcode, group, instr_type) -#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) -#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) -#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) -#include "i386-asm.h" - -#define ALT(x) -#define DEF_ASM_OP0(name, opcode) -#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name) -#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name) -#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name) -#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name) -#include "i386-asm.h" - +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 +#include "i386-tok.h" #endif diff --git a/tinyc/tcctools.c b/tinyc/tcctools.c new file mode 100644 index 000000000..53d88be6a --- /dev/null +++ b/tinyc/tcctools.c @@ -0,0 +1,546 @@ +/* -------------------------------------------------------------- */ +/* + * TCC - Tiny C Compiler + * + * tcctools.c - extra tools and and -m32/64 support + * + */ + +/* -------------------------------------------------------------- */ +/* + * This program is for making libtcc1.a without ar + * tiny_libmaker - tiny elf lib maker + * usage: tiny_libmaker [lib] files... + * Copyright (c) 2007 Timppa + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tcc.h" + +//#define ARMAG "!<arch>\n" +#define ARFMAG "`\n" + +typedef struct { + char ar_name[16]; + char ar_date[12]; + char ar_uid[6]; + char ar_gid[6]; + char ar_mode[8]; + char ar_size[10]; + char ar_fmag[2]; +} ArHdr; + +static unsigned long le2belong(unsigned long ul) { + return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) + + ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8); +} + +/* Returns 1 if s contains any of the chars of list, else 0 */ +static int contains_any(const char *s, const char *list) { + const char *l; + for (; *s; s++) { + for (l = list; *l; l++) { + if (*s == *l) + return 1; + } + } + return 0; +} + +static int ar_usage(int ret) { + fprintf(stderr, "usage: tcc -ar [rcsv] lib file...\n"); + fprintf(stderr, "create library ([abdioptxN] not supported).\n"); + return ret; +} + +ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv) +{ + static ArHdr arhdr = { + "/ ", + " ", + "0 ", + "0 ", + "0 ", + " ", + ARFMAG + }; + + static ArHdr arhdro = { + " ", + " ", + "0 ", + "0 ", + "0 ", + " ", + ARFMAG + }; + + FILE *fi, *fh = NULL, *fo = NULL; + ElfW(Ehdr) *ehdr; + ElfW(Shdr) *shdr; + ElfW(Sym) *sym; + int i, fsize, i_lib, i_obj; + char *buf, *shstr, *symtab = NULL, *strtab = NULL; + int symtabsize = 0;//, strtabsize = 0; + char *anames = NULL; + int *afpos = NULL; + int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs; + char tfile[260], stmp[20]; + char *file, *name; + int ret = 2; + const char *ops_conflict = "habdioptxN"; // unsupported but destructive if ignored. + int verbose = 0; + + i_lib = 0; i_obj = 0; // will hold the index of the lib and first obj + for (i = 1; i < argc; i++) { + const char *a = argv[i]; + if (*a == '-' && strstr(a, ".")) + ret = 1; // -x.y is always invalid (same as gnu ar) + if ((*a == '-') || (i == 1 && !strstr(a, "."))) { // options argument + if (contains_any(a, ops_conflict)) + ret = 1; + if (strstr(a, "v")) + verbose = 1; + } else { // lib or obj files: don't abort - keep validating all args. + if (!i_lib) // first file is the lib + i_lib = i; + else if (!i_obj) // second file is the first obj + i_obj = i; + } + } + + if (!i_obj) // i_obj implies also i_lib. we require both. + ret = 1; + + if (ret == 1) + return ar_usage(ret); + + if ((fh = fopen(argv[i_lib], "wb")) == NULL) + { + fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]); + goto the_end; + } + + sprintf(tfile, "%s.tmp", argv[i_lib]); + if ((fo = fopen(tfile, "wb+")) == NULL) + { + fprintf(stderr, "tcc: ar: can't create temporary file %s\n", tfile); + goto the_end; + } + + funcmax = 250; + afpos = tcc_realloc(NULL, funcmax * sizeof *afpos); // 250 func + memcpy(&arhdro.ar_mode, "100666", 6); + + // i_obj = first input object file + while (i_obj < argc) + { + if (*argv[i_obj] == '-') { // by now, all options start with '-' + i_obj++; + continue; + } + if ((fi = fopen(argv[i_obj], "rb")) == NULL) { + fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_obj]); + goto the_end; + } + if (verbose) + printf("a - %s\n", argv[i_obj]); + + fseek(fi, 0, SEEK_END); + fsize = ftell(fi); + fseek(fi, 0, SEEK_SET); + buf = tcc_malloc(fsize + 1); + fread(buf, fsize, 1, fi); + fclose(fi); + + // elf header + ehdr = (ElfW(Ehdr) *)buf; + if (ehdr->e_ident[4] != ELFCLASSW) + { + fprintf(stderr, "tcc: ar: Unsupported Elf Class: %s\n", argv[i_obj]); + goto the_end; + } + + shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize); + shstr = (char *)(buf + shdr->sh_offset); + for (i = 0; i < ehdr->e_shnum; i++) + { + shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize); + if (!shdr->sh_offset) + continue; + if (shdr->sh_type == SHT_SYMTAB) + { + symtab = (char *)(buf + shdr->sh_offset); + symtabsize = shdr->sh_size; + } + if (shdr->sh_type == SHT_STRTAB) + { + if (!strcmp(shstr + shdr->sh_name, ".strtab")) + { + strtab = (char *)(buf + shdr->sh_offset); + //strtabsize = shdr->sh_size; + } + } + } + + if (symtab && symtabsize) + { + int nsym = symtabsize / sizeof(ElfW(Sym)); + //printf("symtab: info size shndx name\n"); + for (i = 1; i < nsym; i++) + { + sym = (ElfW(Sym) *) (symtab + i * sizeof(ElfW(Sym))); + if (sym->st_shndx && + (sym->st_info == 0x10 + || sym->st_info == 0x11 + || sym->st_info == 0x12 + )) { + //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name); + istrlen = strlen(strtab + sym->st_name)+1; + anames = tcc_realloc(anames, strpos+istrlen); + strcpy(anames + strpos, strtab + sym->st_name); + strpos += istrlen; + if (++funccnt >= funcmax) { + funcmax += 250; + afpos = tcc_realloc(afpos, funcmax * sizeof *afpos); // 250 func more + } + afpos[funccnt] = fpos; + } + } + } + + file = argv[i_obj]; + for (name = strchr(file, 0); + name > file && name[-1] != '/' && name[-1] != '\\'; + --name); + istrlen = strlen(name); + if (istrlen >= sizeof(arhdro.ar_name)) + istrlen = sizeof(arhdro.ar_name) - 1; + memset(arhdro.ar_name, ' ', sizeof(arhdro.ar_name)); + memcpy(arhdro.ar_name, name, istrlen); + arhdro.ar_name[istrlen] = '/'; + sprintf(stmp, "%-10d", fsize); + memcpy(&arhdro.ar_size, stmp, 10); + fwrite(&arhdro, sizeof(arhdro), 1, fo); + fwrite(buf, fsize, 1, fo); + tcc_free(buf); + i_obj++; + fpos += (fsize + sizeof(arhdro)); + } + hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int); + fpos = 0; + if ((hofs & 1)) // align + hofs++, fpos = 1; + // write header + fwrite("!<arch>\n", 8, 1, fh); + sprintf(stmp, "%-10d", (int)(strpos + (funccnt+1) * sizeof(int))); + memcpy(&arhdr.ar_size, stmp, 10); + fwrite(&arhdr, sizeof(arhdr), 1, fh); + afpos[0] = le2belong(funccnt); + for (i=1; i<=funccnt; i++) + afpos[i] = le2belong(afpos[i] + hofs); + fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh); + fwrite(anames, strpos, 1, fh); + if (fpos) + fwrite("", 1, 1, fh); + // write objects + fseek(fo, 0, SEEK_END); + fsize = ftell(fo); + fseek(fo, 0, SEEK_SET); + buf = tcc_malloc(fsize + 1); + fread(buf, fsize, 1, fo); + fwrite(buf, fsize, 1, fh); + tcc_free(buf); + ret = 0; +the_end: + if (anames) + tcc_free(anames); + if (afpos) + tcc_free(afpos); + if (fh) + fclose(fh); + if (fo) + fclose(fo), remove(tfile); + return ret; +} + +/* -------------------------------------------------------------- */ +/* + * tiny_impdef creates an export definition file (.def) from a dll + * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]" + * + * Copyright (c) 2005,2007 grischka + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef TCC_TARGET_PE + +ST_FUNC int tcc_tool_impdef(TCCState *s1, int argc, char **argv) +{ + int ret, v, i; + char infile[260]; + char outfile[260]; + + const char *file; + char *p, *q; + FILE *fp, *op; + +#ifdef _WIN32 + char path[260]; +#endif + + infile[0] = outfile[0] = 0; + fp = op = NULL; + ret = 1; + p = NULL; + v = 0; + + for (i = 1; i < argc; ++i) { + const char *a = argv[i]; + if ('-' == a[0]) { + if (0 == strcmp(a, "-v")) { + v = 1; + } else if (0 == strcmp(a, "-o")) { + if (++i == argc) + goto usage; + strcpy(outfile, argv[i]); + } else + goto usage; + } else if (0 == infile[0]) + strcpy(infile, a); + else + goto usage; + } + + if (0 == infile[0]) { +usage: + fprintf(stderr, + "usage: tcc -impdef library.dll [-v] [-o outputfile]\n" + "create export definition file (.def) from dll\n" + ); + goto the_end; + } + + if (0 == outfile[0]) { + strcpy(outfile, tcc_basename(infile)); + q = strrchr(outfile, '.'); + if (NULL == q) + q = strchr(outfile, 0); + strcpy(q, ".def"); + } + + file = infile; +#ifdef _WIN32 + if (SearchPath(NULL, file, ".dll", sizeof path, path, NULL)) + file = path; +#endif + ret = tcc_get_dllexports(file, &p); + if (ret || !p) { + fprintf(stderr, "tcc: impdef: %s '%s'\n", + ret == -1 ? "can't find file" : + ret == 1 ? "can't read symbols" : + ret == 0 ? "no symbols found in" : + "unknown file type", file); + ret = 1; + goto the_end; + } + + if (v) + printf("-> %s\n", file); + + op = fopen(outfile, "w"); + if (NULL == op) { + fprintf(stderr, "tcc: impdef: could not create output file: %s\n", outfile); + goto the_end; + } + + fprintf(op, "LIBRARY %s\n\nEXPORTS\n", tcc_basename(file)); + for (q = p, i = 0; *q; ++i) { + fprintf(op, "%s\n", q); + q += strlen(q) + 1; + } + + if (v) + printf("<- %s (%d symbol%s)\n", outfile, i, &"s"[i<2]); + + ret = 0; + +the_end: + /* cannot free memory received from tcc_get_dllexports + if it came from a dll */ + /* if (p) + tcc_free(p); */ + if (fp) + fclose(fp); + if (op) + fclose(op); + return ret; +} + +#endif /* TCC_TARGET_PE */ + +/* -------------------------------------------------------------- */ +/* + * TCC - Tiny C Compiler + * + * Copyright (c) 2001-2004 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */ + +#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64 + +ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option) +{ + tcc_error("-m%d not implemented.", option); +} + +#else +#ifdef _WIN32 +#include <process.h> + +static char *str_replace(const char *str, const char *p, const char *r) +{ + const char *s, *s0; + char *d, *d0; + int sl, pl, rl; + + sl = strlen(str); + pl = strlen(p); + rl = strlen(r); + for (d0 = NULL;; d0 = tcc_malloc(sl + 1)) { + for (d = d0, s = str; s0 = s, s = strstr(s, p), s; s += pl) { + if (d) { + memcpy(d, s0, sl = s - s0), d += sl; + memcpy(d, r, rl), d += rl; + } else + sl += rl - pl; + } + if (d) { + strcpy(d, s0); + return d0; + } + } +} + +static int execvp_win32(const char *prog, char **argv) +{ + int ret; char **p; + /* replace all " by \" */ + for (p = argv; *p; ++p) + if (strchr(*p, '"')) + *p = str_replace(*p, "\"", "\\\""); + ret = _spawnvp(P_NOWAIT, prog, (const char *const*)argv); + if (-1 == ret) + return ret; + _cwait(&ret, ret, WAIT_CHILD); + exit(ret); +} +#define execvp execvp_win32 +#endif /* _WIN32 */ + +ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int target) +{ + char program[4096]; + char *a0 = argv[0]; + int prefix = tcc_basename(a0) - a0; + + snprintf(program, sizeof program, + "%.*s%s" +#ifdef TCC_TARGET_PE + "-win32" +#endif + "-tcc" +#ifdef _WIN32 + ".exe" +#endif + , prefix, a0, target == 64 ? "x86_64" : "i386"); + + if (strcmp(a0, program)) + execvp(argv[0] = program, argv); + tcc_error("could not run '%s'", program); +} + +#endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */ +/* -------------------------------------------------------------- */ +/* enable commandline wildcard expansion (tcc -o x.exe *.c) */ + +#ifdef _WIN32 +int _CRT_glob = 1; +#ifndef _CRT_glob +int _dowildcard = 1; +#endif +#endif + +/* -------------------------------------------------------------- */ +/* generate xxx.d file */ + +ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename) +{ + FILE *depout; + char buf[1024]; + int i; + + if (!filename) { + /* compute filename automatically: dir/file.o -> dir/file.d */ + snprintf(buf, sizeof buf, "%.*s.d", + (int)(tcc_fileextension(target) - target), target); + filename = buf; + } + + if (s->verbose) + printf("<- %s\n", filename); + + /* XXX return err codes instead of error() ? */ + depout = fopen(filename, "w"); + if (!depout) + tcc_error("could not open '%s'", filename); + + fprintf(depout, "%s: \\\n", target); + for (i=0; i<s->nb_target_deps; ++i) + fprintf(depout, " %s \\\n", s->target_deps[i]); + fprintf(depout, "\n"); + fclose(depout); +} + +/* -------------------------------------------------------------- */ diff --git a/tinyc/tests/42test.h b/tinyc/tests/42test.h new file mode 100644 index 000000000..5db7d1c47 --- /dev/null +++ b/tinyc/tests/42test.h @@ -0,0 +1,13 @@ +/* This file is to test compute #include directives. It's named so + that it starts with a pre-processing number which isn't a valid + number (42test.h). Including this must work. */ +#ifndef INC42_FIRST +int have_included_42test_h; +#define INC42_FIRST +#elif !defined INC42_SECOND +#define INC42_SECOND +int have_included_42test_h_second; +#else +#define INC42_THIRD +int have_included_42test_h_third; +#endif diff --git a/tinyc/tests/abitest.c b/tinyc/tests/abitest.c new file mode 100644 index 000000000..4a192bd23 --- /dev/null +++ b/tinyc/tests/abitest.c @@ -0,0 +1,691 @@ +#include <libtcc.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC +#if defined(_WIN32) && defined(__GNUC__) +#define LONG_DOUBLE double +#define LONG_DOUBLE_LITERAL(x) x +#else +#define LONG_DOUBLE long double +#define LONG_DOUBLE_LITERAL(x) x ## L +#endif + +static int g_argc; +static char **g_argv; + +static void set_options(TCCState *s, int argc, char **argv) +{ + int i; + for (i = 1; i < argc; ++i) { + char *a = argv[i]; + if (a[0] == '-') { + if (a[1] == 'B') + tcc_set_lib_path(s, a+2); + else if (a[1] == 'I') + tcc_add_include_path(s, a+2); + else if (a[1] == 'L') + tcc_add_library_path(s, a+2); + } + } +} + +typedef int (*callback_type) (void*); + +/* + * Compile source code and call a callback with a pointer to the symbol "f". + */ +static int run_callback(const char *src, callback_type callback) { + TCCState *s; + int result; + void *ptr; + + s = tcc_new(); + if (!s) + return -1; + + set_options(s, g_argc, g_argv); + + if (tcc_set_output_type(s, TCC_OUTPUT_MEMORY) == -1) + return -1; + if (tcc_compile_string(s, src) == -1) + return -1; + if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1) + return -1; + + ptr = tcc_get_symbol(s, "f"); + if (!ptr) + return -1; + result = callback(ptr); + + tcc_delete(s); + + return result; +} + +#define STR2(x) #x +#define STR(x) STR2(x) + +#define RET_PRIMITIVE_TEST(name, type, val) \ + static int ret_ ## name ## _test_callback(void *ptr) { \ + type (*callback) (type) = (type(*)(type))ptr; \ + type x = val; \ + type y = callback(x); \ + return (y == x+x) ? 0 : -1; \ + } \ + \ + static int ret_ ## name ## _test(void) { \ + const char *src = STR(type) " f(" STR(type) " x) {return x+x;}"; \ + return run_callback(src, ret_ ## name ## _test_callback); \ + } + +RET_PRIMITIVE_TEST(int, int, 70000) +RET_PRIMITIVE_TEST(longlong, long long, 4333369356528LL) +RET_PRIMITIVE_TEST(float, float, 63.0) +RET_PRIMITIVE_TEST(double, double, 14789798.0) +RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0)) + +/* + * ret_2float_test: + * + * On x86-64, a struct with 2 floats should be packed into a single + * SSE register (VT_DOUBLE is used for this purpose). + */ +typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type; +typedef ret_2float_test_type (*ret_2float_test_function_type) (ret_2float_test_type); + +static int ret_2float_test_callback(void *ptr) { + ret_2float_test_function_type f = (ret_2float_test_function_type)ptr; + ret_2float_test_type a = {10, 35}; + ret_2float_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int ret_2float_test(void) { + const char *src = + "typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;" + "ret_2float_test_type f(ret_2float_test_type a) {\n" + " ret_2float_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_2float_test_callback); +} + +/* + * ret_2double_test: + * + * On x86-64, a struct with 2 doubles should be passed in two SSE + * registers. + */ +typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type; +typedef ret_2double_test_type (*ret_2double_test_function_type) (ret_2double_test_type); + +static int ret_2double_test_callback(void *ptr) { + ret_2double_test_function_type f = (ret_2double_test_function_type)ptr; + ret_2double_test_type a = {10, 35}; + ret_2double_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int ret_2double_test(void) { + const char *src = + "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;" + "ret_2double_test_type f(ret_2double_test_type a) {\n" + " ret_2double_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_2double_test_callback); +} + +/* + * ret_8plus2double_test: + * + * This catches a corner case in the x86_64 ABI code: the first 7 + * arguments fit into registers, the 8th doesn't, but the 9th argument + * fits into the 8th XMM register. + * + * Note that the purpose of the 10th argument is to avoid a situation + * in which gcc would accidentally put the double at the right + * address, thus causing a success message even though TCC actually + * generated incorrect code. + */ +typedef ret_2double_test_type (*ret_8plus2double_test_function_type) (double, double, double, double, double, double, double, ret_2double_test_type, double, double); + +static int ret_8plus2double_test_callback(void *ptr) { + ret_8plus2double_test_function_type f = (ret_8plus2double_test_function_type)ptr; + ret_2double_test_type a = {10, 35}; + ret_2double_test_type r; + r = f(0, 0, 0, 0, 0, 0, 0, a, 37, 38); + return ((r.x == 37) && (r.y == 37)) ? 0 : -1; +} + +static int ret_8plus2double_test(void) { + const char *src = + "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;" + "ret_2double_test_type f(double x1, double x2, double x3, double x4, double x5, double x6, double x7, ret_2double_test_type a, double x8, double x9) {\n" + " ret_2double_test_type r = { x8, x8 };\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_8plus2double_test_callback); +} + +/* + * ret_mixed_test: + * + * On x86-64, a struct with a double and a 64-bit integer should be + * passed in one SSE register and one integer register. + */ +typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type; +typedef ret_mixed_test_type (*ret_mixed_test_function_type) (ret_mixed_test_type); + +static int ret_mixed_test_callback(void *ptr) { + ret_mixed_test_function_type f = (ret_mixed_test_function_type)ptr; + ret_mixed_test_type a = {10, 35}; + ret_mixed_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int ret_mixed_test(void) { + const char *src = + "typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;" + "ret_mixed_test_type f(ret_mixed_test_type a) {\n" + " ret_mixed_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_mixed_test_callback); +} + +/* + * ret_mixed2_test: + * + * On x86-64, a struct with two floats and two 32-bit integers should + * be passed in one SSE register and one integer register. + */ +typedef struct ret_mixed2_test_type_s {float x,x2; int y,y2;} ret_mixed2_test_type; +typedef ret_mixed2_test_type (*ret_mixed2_test_function_type) (ret_mixed2_test_type); + +static int ret_mixed2_test_callback(void *ptr) { + ret_mixed2_test_function_type f = (ret_mixed2_test_function_type)ptr; + ret_mixed2_test_type a = {10, 5, 35, 7 }; + ret_mixed2_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int ret_mixed2_test(void) { + const char *src = + "typedef struct ret_mixed2_test_type_s {float x, x2; int y,y2;} ret_mixed2_test_type;" + "ret_mixed2_test_type f(ret_mixed2_test_type a) {\n" + " ret_mixed2_test_type r = {a.x*5, 0, a.y*3, 0};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_mixed2_test_callback); +} + +/* + * ret_mixed3_test: + * + * On x86-64, this struct should be passed in two integer registers. + */ +typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type; +typedef ret_mixed3_test_type (*ret_mixed3_test_function_type) (ret_mixed3_test_type); + +static int ret_mixed3_test_callback(void *ptr) { + ret_mixed3_test_function_type f = (ret_mixed3_test_function_type)ptr; + ret_mixed3_test_type a = {10, 5, 35, 7 }; + ret_mixed3_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y2 == a.y*3)) ? 0 : -1; +} + +static int ret_mixed3_test(void) { + const char *src = + "typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;" + "ret_mixed3_test_type f(ret_mixed3_test_type a) {\n" + " ret_mixed3_test_type r = {a.x*5, 0, 0, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_mixed3_test_callback); +} + +/* + * reg_pack_test: return a small struct which should be packed into + * registers (Win32) during return. + */ +typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type; +typedef reg_pack_test_type (*reg_pack_test_function_type) (reg_pack_test_type); + +static int reg_pack_test_callback(void *ptr) { + reg_pack_test_function_type f = (reg_pack_test_function_type)ptr; + reg_pack_test_type a = {10, 35}; + reg_pack_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int reg_pack_test(void) { + const char *src = + "typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;" + "reg_pack_test_type f(reg_pack_test_type a) {\n" + " reg_pack_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, reg_pack_test_callback); +} + +/* + * reg_pack_longlong_test: return a small struct which should be packed into + * registers (x86-64) during return. + */ +typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type; +typedef reg_pack_longlong_test_type (*reg_pack_longlong_test_function_type) (reg_pack_longlong_test_type); + +static int reg_pack_longlong_test_callback(void *ptr) { + reg_pack_longlong_test_function_type f = (reg_pack_longlong_test_function_type)ptr; + reg_pack_longlong_test_type a = {10, 35}; + reg_pack_longlong_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int reg_pack_longlong_test(void) { + const char *src = + "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;" + "reg_pack_longlong_test_type f(reg_pack_longlong_test_type a) {\n" + " reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, reg_pack_longlong_test_callback); +} + +/* + * ret_6plus2longlong_test: + * + * This catches a corner case in the x86_64 ABI code: the first 5 + * arguments fit into registers, the 6th doesn't, but the 7th argument + * fits into the 6th argument integer register, %r9. + * + * Note that the purpose of the 10th argument is to avoid a situation + * in which gcc would accidentally put the longlong at the right + * address, thus causing a success message even though TCC actually + * generated incorrect code. + */ +typedef reg_pack_longlong_test_type (*ret_6plus2longlong_test_function_type) (long long, long long, long long, long long, long long, reg_pack_longlong_test_type, long long, long long); + +static int ret_6plus2longlong_test_callback(void *ptr) { + ret_6plus2longlong_test_function_type f = (ret_6plus2longlong_test_function_type)ptr; + reg_pack_longlong_test_type a = {10, 35}; + reg_pack_longlong_test_type r; + r = f(0, 0, 0, 0, 0, a, 37, 38); + return ((r.x == 37) && (r.y == 37)) ? 0 : -1; +} + +static int ret_6plus2longlong_test(void) { + const char *src = + "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;" + "reg_pack_longlong_test_type f(long long x1, long long x2, long long x3, long long x4, long long x5, reg_pack_longlong_test_type a, long long x8, long long x9) {\n" + " reg_pack_longlong_test_type r = { x8, x8 };\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_6plus2longlong_test_callback); +} + +/* + * sret_test: Create a struct large enough to be returned via sret + * (hidden pointer as first function argument) + */ +typedef struct sret_test_type_s {long long a, b, c;} sret_test_type; +typedef sret_test_type (*sret_test_function_type) (sret_test_type); + +static int sret_test_callback(void *ptr) { + sret_test_function_type f = (sret_test_function_type)(ptr); + sret_test_type x = {5436LL, 658277698LL, 43878957LL}; + sret_test_type r = f(x); + return ((r.a==x.a*35)&&(r.b==x.b*19)&&(r.c==x.c*21)) ? 0 : -1; +} + +static int sret_test(void) { + const char *src = + "typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;\n" + "sret_test_type f(sret_test_type x) {\n" + " sret_test_type r = {x.a*35, x.b*19, x.c*21};\n" + " return r;\n" + "}\n"; + + return run_callback(src, sret_test_callback); +} + +/* + * one_member_union_test: + * + * In the x86-64 ABI a union should always be passed on the stack. However + * it appears that a single member union is treated by GCC as its member. + */ +typedef union one_member_union_test_type_u {int x;} one_member_union_test_type; +typedef one_member_union_test_type (*one_member_union_test_function_type) (one_member_union_test_type); + +static int one_member_union_test_callback(void *ptr) { + one_member_union_test_function_type f = (one_member_union_test_function_type)ptr; + one_member_union_test_type a, b; + a.x = 34; + b = f(a); + return (b.x == a.x*2) ? 0 : -1; +} + +static int one_member_union_test(void) { + const char *src = + "typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;\n" + "one_member_union_test_type f(one_member_union_test_type a) {\n" + " one_member_union_test_type b;\n" + " b.x = a.x * 2;\n" + " return b;\n" + "}\n"; + return run_callback(src, one_member_union_test_callback); +} + +/* + * two_member_union_test: + * + * In the x86-64 ABI a union should always be passed on the stack. + */ +typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type; +typedef two_member_union_test_type (*two_member_union_test_function_type) (two_member_union_test_type); + +static int two_member_union_test_callback(void *ptr) { + two_member_union_test_function_type f = (two_member_union_test_function_type)ptr; + two_member_union_test_type a, b; + a.x = 34; + b = f(a); + return (b.x == a.x*2) ? 0 : -1; +} + +static int two_member_union_test(void) { + const char *src = + "typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;\n" + "two_member_union_test_type f(two_member_union_test_type a) {\n" + " two_member_union_test_type b;\n" + " b.x = a.x * 2;\n" + " return b;\n" + "}\n"; + return run_callback(src, two_member_union_test_callback); +} + +/* + * Win64 calling convention test. + */ + +typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type; +typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type); + +static int many_struct_test_callback(void *ptr) { + many_struct_test_function_type f = (many_struct_test_function_type)ptr; + many_struct_test_type v = {1, 2, 3}; + many_struct_test_type r = f(v,v,v,v,v,v); + return ((r.a == 6) && (r.b == 12) && (r.c == 18))?0:-1; +} + +static int many_struct_test(void) { + const char *src = + "typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;\n" + "many_struct_test_type f(many_struct_test_type x1, many_struct_test_type x2, many_struct_test_type x3, many_struct_test_type x4, many_struct_test_type x5, many_struct_test_type x6) {\n" + " many_struct_test_type y;\n" + " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n" + " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n" + " y.c = x1.c + x2.c + x3.c + x4.c + x5.c + x6.c;\n" + " return y;\n" + "}\n"; + return run_callback(src, many_struct_test_callback); +} + +/* + * Win64 calling convention test. + */ + +typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type; +typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type); + +static int many_struct_test_2_callback(void *ptr) { + many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr; + many_struct_test_2_type v = {1,2}; + many_struct_test_2_type r = f(v,v,v,v,v,v); + return ((r.a == 6) && (r.b == 12))?0:-1; +} + +static int many_struct_test_2(void) { + const char *src = + "typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;\n" + "many_struct_test_2_type f(many_struct_test_2_type x1, many_struct_test_2_type x2, many_struct_test_2_type x3, many_struct_test_2_type x4, many_struct_test_2_type x5, many_struct_test_2_type x6) {\n" + " many_struct_test_2_type y;\n" + " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n" + " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n" + " return y;\n" + "}\n"; + return run_callback(src, many_struct_test_2_callback); +} + +/* + * Win64 calling convention test. + */ + +typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type; +typedef many_struct_test_3_type (*many_struct_test_3_function_type) (many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type, ...); +typedef struct many_struct_test_3_struct_type { many_struct_test_3_function_type f; many_struct_test_3_function_type *f2; } many_struct_test_3_struct_type; + +static void many_struct_test_3_dummy(double d, ...) +{ + volatile double x = d; +} + +static int many_struct_test_3_callback(void *ptr) { + many_struct_test_3_struct_type s = { ptr, }; + many_struct_test_3_struct_type *s2 = &s; + s2->f2 = &s2->f; + many_struct_test_3_dummy(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, &s2); + many_struct_test_3_function_type f = *(s2->f2); + many_struct_test_3_type v = {1,2}; + many_struct_test_3_type r = (*((s2->f2=&f)+0))(v,v,v,v,v,v,1.0); + return ((r.a == 6) && (r.b == 12))?0:-1; +} + +static int many_struct_test_3(void) { + const char *src = + "typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;\n" + "many_struct_test_3_type f(many_struct_test_3_type x1, many_struct_test_3_type x2, many_struct_test_3_type x3, many_struct_test_3_type x4, many_struct_test_3_type x5, many_struct_test_3_type x6, ...) {\n" + " many_struct_test_3_type y;\n" + " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n" + " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n" + " return y;\n" + "}\n"; + return run_callback(src, many_struct_test_3_callback); +} + +/* + * stdarg_test: Test variable argument list ABI + */ + +typedef struct {long long a, b, c;} stdarg_test_struct_type; +typedef void (*stdarg_test_function_type) (int,int,int,...); + +static int stdarg_test_callback(void *ptr) { + stdarg_test_function_type f = (stdarg_test_function_type)ptr; + int x; + double y; + stdarg_test_struct_type z = {1, 2, 3}, w; + f(10, 10, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &x, + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, &y, + z, z, z, z, z, &w); + return ((x == 55) && (y == 55) && (w.a == 5) && (w.b == 10) && (w.c == 15)) ? 0 : -1; +} + +static int stdarg_test(void) { + const char *src = + "#include <stdarg.h>\n" + "typedef struct {long long a, b, c;} stdarg_test_struct_type;\n" + "void f(int n_int, int n_float, int n_struct, ...) {\n" + " int i, ti = 0;\n" + " double td = 0.0;\n" + " stdarg_test_struct_type ts = {0,0,0}, tmp;\n" + " va_list ap;\n" + " va_start(ap, n_struct);\n" + " for (i = 0, ti = 0; i < n_int; ++i)\n" + " ti += va_arg(ap, int);\n" + " *va_arg(ap, int*) = ti;\n" + " for (i = 0, td = 0; i < n_float; ++i)\n" + " td += va_arg(ap, double);\n" + " *va_arg(ap, double*) = td;\n" + " for (i = 0; i < n_struct; ++i) {\n" + " tmp = va_arg(ap, stdarg_test_struct_type);\n" + " ts.a += tmp.a; ts.b += tmp.b; ts.c += tmp.c;" + " }\n" + " *va_arg(ap, stdarg_test_struct_type*) = ts;\n" + " va_end(ap);" + "}\n"; + return run_callback(src, stdarg_test_callback); +} + +typedef struct {long long a, b;} stdarg_many_test_struct_type; +typedef void (*stdarg_many_test_function_type) (int, int, int, int, int, + stdarg_many_test_struct_type, + int, int, ...); + +static int stdarg_many_test_callback(void *ptr) +{ + stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr; + int x; + stdarg_many_test_struct_type l = {10, 11}; + f(1, 2, 3, 4, 5, l, 6, 7, &x, 44); + return x == 44 ? 0 : -1; +} + +static int stdarg_many_test(void) +{ + const char *src = + "#include <stdarg.h>\n" + "typedef struct {long long a, b;} stdarg_many_test_struct_type;\n" + "void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n" + " va_list ap;\n" + " int *p;\n" + " va_start (ap, g);\n" + " p = va_arg(ap, int*);\n" + " *p = va_arg(ap, int);\n" + " va_end (ap);\n" + "}\n"; + return run_callback(src, stdarg_many_test_callback); +} + +/* + * Test Win32 stdarg handling, since the calling convention will pass a pointer + * to the struct and the stdarg pointer must point to that pointer initially. + */ + +typedef struct {long long a, b, c;} stdarg_struct_test_struct_type; +typedef int (*stdarg_struct_test_function_type) (stdarg_struct_test_struct_type a, ...); + +static int stdarg_struct_test_callback(void *ptr) { + stdarg_struct_test_function_type f = (stdarg_struct_test_function_type)ptr; + stdarg_struct_test_struct_type v = {10, 35, 99}; + int x = f(v, 234); + return (x == 378) ? 0 : -1; +} + +static int stdarg_struct_test(void) { + const char *src = + "#include <stdarg.h>\n" + "typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;\n" + "int f(stdarg_struct_test_struct_type a, ...) {\n" + " va_list ap;\n" + " va_start(ap, a);\n" + " int z = va_arg(ap, int);\n" + " va_end(ap);\n" + " return z + a.a + a.b + a.c;\n" + "}\n"; + return run_callback(src, stdarg_struct_test_callback); +} + +/* Test that x86-64 arranges the stack correctly for arguments with alignment >8 bytes */ + +typedef LONG_DOUBLE (*arg_align_test_callback_type) (LONG_DOUBLE,int,LONG_DOUBLE,int,LONG_DOUBLE); + +static int arg_align_test_callback(void *ptr) { + arg_align_test_callback_type f = (arg_align_test_callback_type)ptr; + long double x = f(12, 0, 25, 0, 37); + return (x == 74) ? 0 : -1; +} + +static int arg_align_test(void) { + const char *src = + "long double f(long double a, int b, long double c, int d, long double e) {\n" + " return a + c + e;\n" + "}\n"; + return run_callback(src, arg_align_test_callback); +} + +#define RUN_TEST(t) \ + if (!testname || (strcmp(#t, testname) == 0)) { \ + fputs(#t "... ", stdout); \ + fflush(stdout); \ + if (t() == 0) { \ + fputs("success\n", stdout); \ + } else { \ + fputs("failure\n", stdout); \ + retval = EXIT_FAILURE; \ + } \ + } + +int main(int argc, char **argv) { + int i; + const char *testname = NULL; + int retval = EXIT_SUCCESS; + + /* if tcclib.h and libtcc1.a are not installed, where can we find them */ + for (i = 1; i < argc; ++i) { + if (!memcmp(argv[i], "run_test=", 9)) + testname = argv[i] + 9; + } + + g_argv = argv, g_argc = argc; + + RUN_TEST(ret_int_test); + RUN_TEST(ret_longlong_test); + RUN_TEST(ret_float_test); + RUN_TEST(ret_double_test); + RUN_TEST(ret_longdouble_test); + RUN_TEST(ret_2float_test); + RUN_TEST(ret_2double_test); + RUN_TEST(ret_8plus2double_test); + RUN_TEST(ret_6plus2longlong_test); +#if !defined __x86_64__ || defined _WIN32 + /* currently broken on x86_64 linux */ + RUN_TEST(ret_mixed_test); + RUN_TEST(ret_mixed2_test); +#endif + RUN_TEST(ret_mixed3_test); + RUN_TEST(reg_pack_test); + RUN_TEST(reg_pack_longlong_test); + RUN_TEST(sret_test); + RUN_TEST(one_member_union_test); + RUN_TEST(two_member_union_test); + RUN_TEST(many_struct_test); + RUN_TEST(many_struct_test_2); + RUN_TEST(many_struct_test_3); + RUN_TEST(stdarg_test); + RUN_TEST(stdarg_many_test); + RUN_TEST(stdarg_struct_test); + RUN_TEST(arg_align_test); + return retval; +} diff --git a/tinyc/tests/asmtest.S b/tinyc/tests/asmtest.S index 358a8239f..55787054a 100644 --- a/tinyc/tests/asmtest.S +++ b/tinyc/tests/asmtest.S @@ -1,3 +1,4 @@ +# gas comment with ``gnu'' style quotes /* some directive tests */ @@ -9,14 +10,23 @@ .int 1, 2, 3 .align 8 .byte 1 - .align 16, 0x90 +/* .align 16, 0x90 gas is too clever for us with 0x90 fill */ + .balign 4, 0x92 + .align 16, 0x91 /* 0x91 tests the non-clever behaviour */ .skip 3 .skip 15, 0x90 .string "hello\0world" - +/* Macro expansion should work like with C, the #n shouldn't be parsed + as asm line comment */ +#define __stringify(n) #n +#define stringify(n) __stringify(n) + .skip 8,0x90 + .asciz stringify(BLA) + .skip 8,0x90 + +# 28 "asmtest.S" # a line directive (and a line comment) + movl %eax, %ebx # some more asm comment /* some label tests */ - - movl %eax, %ebx L1: movl %eax, %ebx mov 0x10000, %eax @@ -36,7 +46,7 @@ mov %al, 0x10000 mov $1, %edx mov $1, %dx -mov $1, %dl +mov $1, %cl movb $2, 0x100(%ebx,%edx,2) movw $2, 0x100(%ebx,%edx,2) movl $2, 0x100(%ebx,%edx,2) @@ -44,17 +54,55 @@ movl %eax, 0x100(%ebx,%edx,2) movl 0x100(%ebx,%edx,2), %edx movw %ax, 0x100(%ebx,%edx,2) +movw $0x1122,%si +movl $0x112233,%edx +movl $0x80000000, %esi +movl $-0x7fffffff, %edi +#ifdef __x86_64__ +mov $0x11223344,%rbx +movq $0x11223344,%rbx +mov $0x1122334455,%rbx +movq $0x1122334455,%rbx +movl $0x11334455,(%rbx) +#endif + mov %eax, 0x12(,%edx,2) +#ifdef __i386__ mov %cr3, %edx mov %ecx, %cr3 movl %cr3, %eax movl %tr3, %eax movl %db3, %ebx movl %dr6, %eax +#else +mov %cr3, %rdx +mov %rcx, %cr3 +movq %cr3, %rax +movq %db3, %rbx +movq %dr6, %rax +mov %cr8, %rsi +mov %rdi, %cr8 +#endif movl %fs, %ecx movl %ebx, %fs +#ifdef __x86_64__ +movq %r8, %r9 +movq %r10, %r11 +movq %r12, %r13 +movq %r14, %r15 +movq %rax, %r9 +movq %r15, %rsi +inc %r9b +dec %r10w +not %r11d +negq %r12 +decb %r13b +incw %r14w +notl %r15d +#endif + movsbl 0x1000, %eax movsbw 0x1000, %ax movswl 0x1000, %eax @@ -66,19 +114,47 @@ movl %ebx, %fs movzb 0x1000, %eax movzb 0x1000, %ax + mov $0x12345678,%eax + +#ifdef __x86_64__ + movzb 0x1000, %rax + movzbq 0x1000, %rbx + movsbq 0x1000, %rdx + movzwq 0x1000, %rdi + movswq 0x1000, %rdx + movslq %eax, %rcx + mov $0x12345678,%rax + mov $0x12345678,%rdx + mov $0x12345678,%r10 + mov $0x123456789abcdef0,%rax + mov $0x123456789abcdef0,%rcx + mov $0x123456789abcdef0,%r11 +#endif +#ifdef __i386__ pushl %eax - pushw %ax push %eax push %cs +#else + pushq %rax + push %rax +#endif + pushw %ax push %gs push $1 push $100 + push 0x42(%eax) + pop 0x43(%esi) +#ifdef __i386__ popl %eax - popw %ax pop %eax pop %ds +#else + popq %rax + pop %rax +#endif + popw %ax pop %fs xchg %eax, %ecx @@ -109,22 +185,61 @@ movl %ebx, %fs leal 0x1000(%ebx), %ecx lea 0x1000(%ebx), %ecx +#ifdef __i386__ les 0x2000, %eax lds 0x2000, %ebx + lss 0x2000, %edx +#endif lfs 0x2000, %ecx lgs 0x2000, %edx - lss 0x2000, %edx addl $0x123, %eax add $0x123, %ebx +add $-16, %ecx +add $-0x123, %esi +add $1, %bx +add $1, %ebx +add $-1, %bx +add $-1, %ebx +add $127, %bx +addl $127, %ebx +addl $-128, %ebx +addl $-128, %ebx +addl $-129, %ebx +addl $128, %ebx +addl $255, %ebx +addl $256, %ebx +andb $0xf, %ah +andb $-15, %cl +xorb $127, %dh +cmpb $42, (%eax) addl $0x123, 0x100 addl $0x123, 0x100(%ebx) addl $0x123, 0x100(%ebx,%edx,2) addl $0x123, 0x100(%esp) +addl $0x123, (3*8)(%esp) addl $0x123, (%ebp) addl $0x123, (%esp) cmpl $0x123, (%esp) +#ifdef __x86_64__ +xor %bl,%ah +xor %bl,%r8b +xor %r9b,%bl +xor %sil,%cl +add %eax,(%r8d) +add %ebx,(%r9) +add %edx,(%r10d,%r11d) +add %ecx,(%r12,%r13) +add %esi,(%r14,%r15,4) +add %edi,0x1000(%rbx,%r12,8) +add %r11,0x1000(%ebp,%r9d,8) +movb $12, %ah +movb $13, %bpl +movb $14, %dil +movb $15, %r12b +#endif + add %eax, (%ebx) add (%ebx), %eax @@ -176,6 +291,8 @@ add (%ebx), %dl div %bl div %ecx, %eax +and $15,%bx +and $-20,%edx shl %edx shl $10, %edx @@ -192,21 +309,53 @@ shrd %eax, %edx L4: call 0x1000 call L4 +#ifdef __i386__ call *%eax +#else +call *%rax +#endif call *0x1000 call func1 +.global L5,L6 + +L5: +L6: + +#ifdef __i386__ lcall $0x100, $0x1000 +#else +lcall *0x100 +lcall *(%rax) +#endif jmp 0x1000 +jmp *(%edi) +#ifdef __i386__ jmp *%eax +#else +jmp *%rax +#endif jmp *0x1000 +#ifdef __i386__ ljmp $0x100, $0x1000 +#else +ljmp *0x100 +ljmp *(%rdi) +ljmpl *(%esi) +ljmpw *(%esi) +#endif ret - ret $10 +#ifdef __i386__ +retl +retl $10 +#else +retq +retq $10 +#endif lret @@ -234,14 +383,20 @@ L3: seto %al + setc %al + setcb %al setnp 0x1000 setl 0xaaaa setg %dl fadd fadd %st(1), %st + fadd %st(0), %st(1) fadd %st(3) + fmul %st(0),%st(0) + fmul %st(0),%st(1) + faddp %st(5) faddp faddp %st(1), %st @@ -341,9 +496,9 @@ L3: fnstcw 0x1002 fstcw 0x1002 fnstsw 0x1004 - fnstsw %eax + fnstsw (%eax) fstsw 0x1004 - fstsw %eax + fstsw (%eax) fnclex fclex fnstenv 0x1000 @@ -387,6 +542,7 @@ L3: fwait bswap %edx +bswapl %ecx xadd %ecx, %edx xaddb %dl, 0x1000 xaddw %ax, 0x1000 @@ -397,6 +553,10 @@ cmpxchgw %ax, 0x1000 cmpxchgl %eax, 0x1000 invlpg 0x1000 cmpxchg8b 0x1002 +#ifdef __x86_64__ +cmpxchg16b (%rax) +cmpxchg16b (%r10,%r11) +#endif fcmovb %st(5), %st fcmove %st(5), %st @@ -416,32 +576,48 @@ fucomip %st(5), %st cmovo 0x1000, %eax cmovs 0x1000, %eax cmovns %edx, %edi + cmovne %ax, %si +#ifdef __x86_64__ + bswapq %rsi + bswapq %r10 + cmovz %rdi,%rbx +#endif int $3 int $0x10 +#ifdef __i386__ pusha popa - clc - cld +#endif + clc # another comment + cld # a comment with embedded ' tick cli clts cmc lahf sahf +#ifdef __i386__ pushfl popfl +#else + pushfq + popfq +#endif pushf popf stc std sti +#ifdef __i386__ aaa aas daa das aad aam + into +#endif cbw cwd cwde @@ -452,7 +628,6 @@ int $0x10 cltd leave int3 - into iret rsm hlt @@ -470,6 +645,24 @@ int $0x10 repz repne repnz + nop + + lock ;negl (%eax) + wait ;pushf + rep ;stosb + repe ;lodsb + repz ;cmpsb + repne;movsb + repnz;outsb + + /* handle one-line prefix + ops */ + lock negl (%eax) + wait pushf + rep stosb + repe lodsb + repz cmpsb + repne movsb + repnz outsb invd wbinvd @@ -479,7 +672,34 @@ int $0x10 rdmsr rdpmc ud2 +#ifdef __x86_64__ + syscall + sysret + sysretq + lfence + mfence + sfence + prefetchnta 0x18(%rdx) + prefetcht0 (%rcx) + prefetcht1 (%rsi) + prefetcht2 (%rdi) + prefetchw (%rdi) + clflush 0x1000(%rax,%rcx) + fxsaveq (%rdx) + fxsaveq (%r11) + fxrstorq (%rcx) + fxrstorq (%r10) +#endif + + lar %ax,%dx + lar %eax,%dx + lar %ax,%edx + lar %eax,%edx +#ifdef __x86_64__ + lar %ax,%rdx + lar %eax,%rdx +#endif emms movd %edx, %mm3 movd 0x1000, %mm2 @@ -524,35 +744,232 @@ int $0x10 +#ifdef __i386__ boundl %edx, 0x10000 boundw %bx, 0x1000 - + arpl %bx, 0x1000 +#endif lar 0x1000, %eax lgdt 0x1000 lidt 0x1000 lldt 0x1000 - lmsw 0x1000 - lsl 0x1000, %ecx - ltr 0x1000 - sgdt 0x1000 sidt 0x1000 sldt 0x1000 +#ifdef __x86_64__ + lgdtq 0x1000 + lidtq 0x1000 + sgdtq 0x1000 + sidtq 0x1000 + + swapgs + + str %rdx + str %r9 +#endif + + lmsw 0x1000 + lsl 0x1000, %ecx + ltr 0x1000 + ltr %si smsw 0x1000 str 0x1000 + str %ecx + str %dx verr 0x1000 verw 0x1000 +#ifdef __i386__ push %ds pushw %ds pushl %ds pop %ds popw %ds popl %ds +#endif fxsave 1(%ebx) fxrstor 1(%ecx) +#ifdef __i386__ pushl $1 +#else + pushq $1 +#endif pushw $1 push $1 + +#ifdef __ASSEMBLER__ // should be defined, for S files + inc %eax +#endif + +#ifndef _WIN32 +ft1: ft2: ft3: ft4: ft5: ft6: ft7: ft8: ft9: + xor %eax, %eax + ret + +.type ft1,STT_FUNC +.type ft2,@STT_FUNC +.type ft3,%STT_FUNC +.type ft4,"STT_FUNC" +.type ft5,function +.type ft6,@function +.type ft7,%function +.type ft8,"function" +#endif + + pause +.rept 6 + nop +.endr +.fill 4,1,0x90 + +.section .text.one,"ax" +nop +.previous +.pushsection .text.one,"ax" +nop +.pushsection .text.two,"ax" +nop +.popsection +.popsection + +1: ud2 +.pushsection __bug_table,"a" +.align 8 +2: .long 1b - 2b + .long 0x600000 - 2b + .long 1b + 42 + .long 43 + 1b + .long 2b + 144 + .long 145 + 2b + .word 164, 0 + .org 2b+32 +#ifdef __x86_64__ + .quad 1b +#else + .long 1b +#endif +.popsection +3: mov %eax,%ecx +4: +.pushsection .text.three, "ax" +nop +.skip (-((4b-3b) > 0) * 2) , 0x90 +.popsection + +.globl overrideme +.weak overrideme + nop +.globl notimplemented +notimplemented: + ret +.set overrideme, notimplemented +overrideme = notimplemented +overrideme: + ret + + movd %esi, %mm1 + movd %edi, %xmm2 + movd (%ebx), %mm3 + movd (%ebx), %xmm3 + movd %mm1, %esi + movd %xmm2, %edi + movd %mm3, (%edx) + movd %xmm3, (%edx) +#ifdef __x86_64__ + movd %rsi, %mm1 + movd %rdi, %xmm2 + movd (%rbx), %mm3 + movd (%rbx), %xmm3 + movd %mm1, %r12 + movd %xmm2, %rdi + movd %mm3, (%r8) + movd %xmm3, (%r13) +#endif + + movq (%ebp), %mm1 + movq %mm2, (%edi) + movq (%edi), %xmm3 + movq %mm4, %mm5 +#ifdef __x86_64__ + movq %rcx, %mm1 + movq %rdx, %xmm2 + movq %r13, %xmm3 + /* movq mem64->xmm is encoded as f30f7e by GAS, but as + 660f6e by tcc (which really is a movd and would need + a REX.W prefix to be movq). */ + movq (%rsi), %xmm3 + movq %mm1, %rdx + movq %xmm3, %rcx + movq %xmm4, (%rsi) +#endif + +#define TEST_MMX_SSE(insn) \ + insn %mm1, %mm2; \ + insn %xmm2, %xmm3; \ + insn (%ebx), %xmm3; +#define TEST_MMX_SSE_I8(insn) \ + TEST_MMX_SSE(insn) \ + insn $0x42, %mm4; \ + insn $0x42, %xmm4; + + TEST_MMX_SSE(packssdw) + TEST_MMX_SSE(packsswb) + TEST_MMX_SSE(packuswb) + TEST_MMX_SSE(paddb) + TEST_MMX_SSE(paddw) + TEST_MMX_SSE(paddd) + TEST_MMX_SSE(paddsb) + TEST_MMX_SSE(paddsw) + TEST_MMX_SSE(paddusb) + TEST_MMX_SSE(paddusw) + TEST_MMX_SSE(pand) + TEST_MMX_SSE(pandn) + TEST_MMX_SSE(pcmpeqb) + TEST_MMX_SSE(pcmpeqw) + TEST_MMX_SSE(pcmpeqd) + TEST_MMX_SSE(pcmpgtb) + TEST_MMX_SSE(pcmpgtw) + TEST_MMX_SSE(pcmpgtd) + TEST_MMX_SSE(pmaddwd) + TEST_MMX_SSE(pmulhw) + TEST_MMX_SSE(pmullw) + TEST_MMX_SSE(por) + TEST_MMX_SSE(psllw) +TEST_MMX_SSE_I8(psllw) + TEST_MMX_SSE(pslld) +TEST_MMX_SSE_I8(pslld) + TEST_MMX_SSE(psllq) +TEST_MMX_SSE_I8(psllq) + TEST_MMX_SSE(psraw) +TEST_MMX_SSE_I8(psraw) + TEST_MMX_SSE(psrad) +TEST_MMX_SSE_I8(psrad) + TEST_MMX_SSE(psrlw) +TEST_MMX_SSE_I8(psrlw) + TEST_MMX_SSE(psrld) +TEST_MMX_SSE_I8(psrld) + TEST_MMX_SSE(psrlq) +TEST_MMX_SSE_I8(psrlq) + TEST_MMX_SSE(psubb) + TEST_MMX_SSE(psubw) + TEST_MMX_SSE(psubd) + TEST_MMX_SSE(psubsb) + TEST_MMX_SSE(psubsw) + TEST_MMX_SSE(psubusb) + TEST_MMX_SSE(psubusw) + TEST_MMX_SSE(punpckhbw) + TEST_MMX_SSE(punpckhwd) + TEST_MMX_SSE(punpckhdq) + TEST_MMX_SSE(punpcklbw) + TEST_MMX_SSE(punpcklwd) + TEST_MMX_SSE(punpckldq) + TEST_MMX_SSE(pxor) + + cvtpi2ps %mm1, %xmm2 + cvtpi2ps (%ebx), %xmm2 + TEST_MMX_SSE(pmaxsw) + TEST_MMX_SSE(pmaxub) + TEST_MMX_SSE(pminsw) + TEST_MMX_SSE(pminub) diff --git a/tinyc/tests/boundtest.c b/tinyc/tests/boundtest.c index 9bc982803..15bffb4ed 100644 --- a/tinyc/tests/boundtest.c +++ b/tinyc/tests/boundtest.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include <stdio.h> +#include <string.h> #define NB_ITS 1000000 //#define NB_ITS 1 @@ -49,12 +50,15 @@ int test4(void) int i, sum = 0; int *tab4; + fprintf(stderr, "%s start\n", __FUNCTION__); + tab4 = malloc(20 * sizeof(int)); for(i=0;i<20;i++) { sum += tab4[i]; } free(tab4); + fprintf(stderr, "%s end\n", __FUNCTION__); return sum; } @@ -64,12 +68,15 @@ int test5(void) int i, sum = 0; int *tab4; + fprintf(stderr, "%s start\n", __FUNCTION__); + tab4 = malloc(20 * sizeof(int)); for(i=0;i<21;i++) { sum += tab4[i]; } free(tab4); + fprintf(stderr, "%s end\n", __FUNCTION__); return sum; } @@ -169,9 +176,61 @@ int test13(void) return strlen(tab); } +int test14(void) +{ + char *p = alloca(TAB_SIZE); + memset(p, 'a', TAB_SIZE); + p[TAB_SIZE-1] = 0; + return strlen(p); +} + +/* error */ +int test15(void) +{ + char *p = alloca(TAB_SIZE-1); + memset(p, 'a', TAB_SIZE); + p[TAB_SIZE-1] = 0; + return strlen(p); +} + +/* ok */ +int test16() +{ + char *demo = "This is only a test."; + char *p; + + fprintf(stderr, "%s start\n", __FUNCTION__); + + p = alloca(16); + strcpy(p,"12345678901234"); + printf("alloca: p is %s\n", p); + + /* Test alloca embedded in a larger expression */ + printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) ); + + fprintf(stderr, "%s end\n", __FUNCTION__); +} + +/* error */ +int test17() +{ + char *demo = "This is only a test."; + char *p; + + fprintf(stderr, "%s start\n", __FUNCTION__); + + p = alloca(16); + strcpy(p,"12345678901234"); + printf("alloca: p is %s\n", p); + + /* Test alloca embedded in a larger expression */ + printf("alloca: %s\n", strcpy(alloca(strlen(demo)),demo) ); + + fprintf(stderr, "%s end\n", __FUNCTION__); +} + int (*table_test[])(void) = { test1, - test1, test2, test3, test4, @@ -184,23 +243,35 @@ int (*table_test[])(void) = { test11, test12, test13, + test14, + test15, + test16, + test17, }; int main(int argc, char **argv) { int index; int (*ftest)(void); + int index_max = sizeof(table_test)/sizeof(table_test[0]); if (argc < 2) { - printf("usage: boundtest n\n" - "test TCC bound checking system\n" - ); + printf( + "test TCC bound checking system\n" + "usage: boundtest N\n" + " 1 <= N <= %d\n", index_max); exit(1); } index = 0; if (argc >= 2) - index = atoi(argv[1]); + index = atoi(argv[1]) - 1; + + if ((index < 0) || (index >= index_max)) { + printf("N is outside of the valid range (%d)\n", index); + exit(2); + } + /* well, we also use bounds on this ! */ ftest = table_test[index]; ftest(); diff --git a/tinyc/tests/gcctestsuite.sh b/tinyc/tests/gcctestsuite.sh index bd9204b2b..f3cc538de 100644 --- a/tinyc/tests/gcctestsuite.sh +++ b/tinyc/tests/gcctestsuite.sh @@ -8,11 +8,11 @@ nb_failed="0" for src in $TESTSUITE_PATH/compile/*.c ; do echo $TCC -o /tmp/test.o -c $src $TCC -o /tmp/test.o -c $src >> tcc.log 2>&1 - if [ "$?" == "0" ] ; then + if [ "$?" = "0" ] ; then result="PASS" else result="FAIL" - nb_failed=$[ $nb_failed + 1 ] + nb_failed=$(( $nb_failed + 1 )) fi echo "$result: $src" >> tcc.sum done @@ -20,11 +20,11 @@ done for src in $TESTSUITE_PATH/execute/*.c ; do echo $TCC $src $TCC $src >> tcc.log 2>&1 - if [ "$?" == "0" ] ; then + if [ "$?" = "0" ] ; then result="PASS" else result="FAIL" - nb_failed=$[ $nb_failed + 1 ] + nb_failed=$(( $nb_failed + 1 )) fi echo "$result: $src" >> tcc.sum done diff --git a/tinyc/tests/libtcc_test.c b/tinyc/tests/libtcc_test.c index a602fb0f4..480d31488 100644 --- a/tinyc/tests/libtcc_test.c +++ b/tinyc/tests/libtcc_test.c @@ -15,7 +15,16 @@ int add(int a, int b) return a + b; } +/* this strinc is referenced by the generated code */ +const char hello[] = "Hello World!"; + char my_program[] = +"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */ +"extern int add(int a, int b);\n" +"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */ +" __attribute__((dllimport))\n" +"#endif\n" +"extern const char hello[];\n" "int fib(int n)\n" "{\n" " if (n <= 2)\n" @@ -26,7 +35,7 @@ char my_program[] = "\n" "int foo(int n)\n" "{\n" -" printf(\"Hello World!\\n\");\n" +" printf(\"%s\\n\", hello);\n" " printf(\"fib(%d) = %d\\n\", n, fib(n));\n" " printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n" " return 0;\n" @@ -35,9 +44,8 @@ char my_program[] = int main(int argc, char **argv) { TCCState *s; + int i; int (*func)(int); - void *mem; - int size; s = tcc_new(); if (!s) { @@ -46,8 +54,17 @@ int main(int argc, char **argv) } /* if tcclib.h and libtcc1.a are not installed, where can we find them */ - if (argc == 2 && !memcmp(argv[1], "lib_path=",9)) - tcc_set_lib_path(s, argv[1]+9); + for (i = 1; i < argc; ++i) { + char *a = argv[i]; + if (a[0] == '-') { + if (a[1] == 'B') + tcc_set_lib_path(s, a+2); + else if (a[1] == 'I') + tcc_add_include_path(s, a+2); + else if (a[1] == 'L') + tcc_add_library_path(s, a+2); + } + } /* MUST BE CALLED before any compilation */ tcc_set_output_type(s, TCC_OUTPUT_MEMORY); @@ -55,30 +72,25 @@ int main(int argc, char **argv) if (tcc_compile_string(s, my_program) == -1) return 1; - /* as a test, we add a symbol that the compiled program can use. + /* as a test, we add symbols that the compiled program can use. You may also open a dll with tcc_add_dll() and use symbols from that */ tcc_add_symbol(s, "add", add); + tcc_add_symbol(s, "hello", hello); - /* get needed size of the code */ - size = tcc_relocate(s, NULL); - if (size == -1) + /* relocate the code */ + if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) return 1; - /* allocate memory and copy the code into it */ - mem = malloc(size); - tcc_relocate(s, mem); - /* get entry symbol */ func = tcc_get_symbol(s, "foo"); if (!func) return 1; - /* delete the state */ - tcc_delete(s); - /* run the code */ func(32); - free(mem); + /* delete the state */ + tcc_delete(s); + return 0; } diff --git a/tinyc/tests/pp/01.c b/tinyc/tests/pp/01.c new file mode 100644 index 000000000..2fc3d7960 --- /dev/null +++ b/tinyc/tests/pp/01.c @@ -0,0 +1,6 @@ +#define hash_hash # ## # +#define mkstr(a) # a +#define in_between(a) mkstr(a) +#define join(c, d) in_between(c hash_hash d) +char p[] = join(x, y); +// char p[] = "x ## y"; diff --git a/tinyc/tests/pp/01.expect b/tinyc/tests/pp/01.expect new file mode 100644 index 000000000..cf5b15340 --- /dev/null +++ b/tinyc/tests/pp/01.expect @@ -0,0 +1 @@ +char p[] = "x ## y"; diff --git a/tinyc/tests/pp/02.c b/tinyc/tests/pp/02.c new file mode 100644 index 000000000..feb1254e3 --- /dev/null +++ b/tinyc/tests/pp/02.c @@ -0,0 +1,28 @@ +#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 +#define p() int +#define q(x) x +#define r(x,y) x ## y +#define str(x) # x +f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); +g(x+(3,4)-w) | h 5) & m +(f)^m(m); +char c[2][6] = { str(hello), str() }; +/* + * 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)) & f(2 * (0,1))^m(0,1); + * char c[2][6] = { "hello", "" }; + */ +#define L21 f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); +#define L22 g(x+(3,4)-w) | h 5) & m\ +(f)^m(m); +L21 +L22 diff --git a/tinyc/tests/pp/02.expect b/tinyc/tests/pp/02.expect new file mode 100644 index 000000000..8ae2eb9ea --- /dev/null +++ b/tinyc/tests/pp/02.expect @@ -0,0 +1,5 @@ +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)) & f(2 * (0,1))^m(0,1); +char c[2][6] = { "hello", "" }; +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)) & f(2 * (0,1))^m(0,1); diff --git a/tinyc/tests/pp/03.c b/tinyc/tests/pp/03.c new file mode 100644 index 000000000..a659245ec --- /dev/null +++ b/tinyc/tests/pp/03.c @@ -0,0 +1,15 @@ +#define str(s) # s +#define xstr(s) str(s) +#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ + x ## s, x ## t) +#define INCFILE(n) vers ## n +#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 + == 0) str(: @\n), s); +\#include xstr(INCFILE(2).h) +glue(HIGH, LOW); +xglue(HIGH, LOW) diff --git a/tinyc/tests/pp/03.expect b/tinyc/tests/pp/03.expect new file mode 100644 index 000000000..44aad0ae1 --- /dev/null +++ b/tinyc/tests/pp/03.expect @@ -0,0 +1,5 @@ +printf("x" "1" "= %d, x" "2" "= %s", x1, x2); +fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s); +\#include "vers2.h" +"hello"; +"hello" ", world" diff --git a/tinyc/tests/pp/04.c b/tinyc/tests/pp/04.c new file mode 100644 index 000000000..0068f3751 --- /dev/null +++ b/tinyc/tests/pp/04.c @@ -0,0 +1,4 @@ +#define foobar 1 +#define C(x,y) x##y +#define D(x) (C(x,bar)) +D(foo) diff --git a/tinyc/tests/pp/04.expect b/tinyc/tests/pp/04.expect new file mode 100644 index 000000000..7c67b0104 --- /dev/null +++ b/tinyc/tests/pp/04.expect @@ -0,0 +1 @@ +(1) diff --git a/tinyc/tests/pp/05.c b/tinyc/tests/pp/05.c new file mode 100644 index 000000000..72749416c --- /dev/null +++ b/tinyc/tests/pp/05.c @@ -0,0 +1,7 @@ +#define t(x,y,z) x ## y ## z +#define xxx(s) int s[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), \ + t(10,,), t(,11,), t(,,12), t(,,) }; + +int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), + t(10,,), t(,11,), t(,,12), t(,,) }; +xxx(j) diff --git a/tinyc/tests/pp/05.expect b/tinyc/tests/pp/05.expect new file mode 100644 index 000000000..9f9be378f --- /dev/null +++ b/tinyc/tests/pp/05.expect @@ -0,0 +1,3 @@ +int j[] = { 123, 45, 67, 89, + 10, 11, 12, }; +int j[] = { 123, 45, 67, 89, 10, 11, 12, }; diff --git a/tinyc/tests/pp/06.c b/tinyc/tests/pp/06.c new file mode 100644 index 000000000..28cfddece --- /dev/null +++ b/tinyc/tests/pp/06.c @@ -0,0 +1,5 @@ +#define X(a,b, \ + c,d) \ + foo + +X(1,2,3,4) diff --git a/tinyc/tests/pp/06.expect b/tinyc/tests/pp/06.expect new file mode 100644 index 000000000..257cc5642 --- /dev/null +++ b/tinyc/tests/pp/06.expect @@ -0,0 +1 @@ +foo diff --git a/tinyc/tests/pp/07.c b/tinyc/tests/pp/07.c new file mode 100644 index 000000000..b22b22bbc --- /dev/null +++ b/tinyc/tests/pp/07.c @@ -0,0 +1,4 @@ +#define a() YES +#define b() a +b() +b()() diff --git a/tinyc/tests/pp/07.expect b/tinyc/tests/pp/07.expect new file mode 100644 index 000000000..ad0e20a66 --- /dev/null +++ b/tinyc/tests/pp/07.expect @@ -0,0 +1,2 @@ +a +YES diff --git a/tinyc/tests/pp/08.c b/tinyc/tests/pp/08.c new file mode 100644 index 000000000..93018e11f --- /dev/null +++ b/tinyc/tests/pp/08.c @@ -0,0 +1,4 @@ +// test macro expansion in arguments +#define s_pos s_s.s_pos +#define foo(x) (x) +foo(hej.s_pos) diff --git a/tinyc/tests/pp/08.expect b/tinyc/tests/pp/08.expect new file mode 100644 index 000000000..2b2e3eebd --- /dev/null +++ b/tinyc/tests/pp/08.expect @@ -0,0 +1 @@ +(hej.s_s.s_pos) diff --git a/tinyc/tests/pp/09.c b/tinyc/tests/pp/09.c new file mode 100644 index 000000000..315b297cd --- /dev/null +++ b/tinyc/tests/pp/09.c @@ -0,0 +1,4 @@ +#define C(a,b,c) a##b##c +#define N(x,y) C(x,_,y) +#define A_O aaaaoooo +N(A,O) diff --git a/tinyc/tests/pp/09.expect b/tinyc/tests/pp/09.expect new file mode 100644 index 000000000..adce0f95e --- /dev/null +++ b/tinyc/tests/pp/09.expect @@ -0,0 +1 @@ +aaaaoooo diff --git a/tinyc/tests/pp/10.c b/tinyc/tests/pp/10.c new file mode 100644 index 000000000..f180eff1e --- /dev/null +++ b/tinyc/tests/pp/10.c @@ -0,0 +1,10 @@ +#define f(x) x +#define g(x) f(x) f(x +#define i(x) g(x)) g(x +#define h(x) i(x))) i(x +#define k(x) i(x))) i(x)))) +f(x) +g(x)) +i(x))) +h(x)))) +k(x)))) diff --git a/tinyc/tests/pp/10.expect b/tinyc/tests/pp/10.expect new file mode 100644 index 000000000..bd18e18e5 --- /dev/null +++ b/tinyc/tests/pp/10.expect @@ -0,0 +1,5 @@ +x +x x +x x x x +x x x x x x x x +x x x x x x x x)))) diff --git a/tinyc/tests/pp/11.c b/tinyc/tests/pp/11.c new file mode 100644 index 000000000..c0edf629c --- /dev/null +++ b/tinyc/tests/pp/11.c @@ -0,0 +1,31 @@ +#define D1(s, ...) s +#define D2(s, ...) s D1(__VA_ARGS__) +#define D3(s, ...) s D2(__VA_ARGS__) +#define D4(s, ...) s D3(__VA_ARGS__) + +D1(a) +D2(a, b) +D3(a, b, c) +D4(a, b, c, d) + +x D4(a, b, c, d) y +x D4(a, b, c) y +x D4(a, b) y +x D4(a) y +x D4() y + +#define GNU_COMMA(X,Y...) X,## Y + +x GNU_COMMA(A,B,C) y +x GNU_COMMA(A,B) y +x GNU_COMMA(A) y +x GNU_COMMA() y + +#define __sun_attr___noreturn__ __attribute__((__noreturn__)) +#define ___sun_attr_inner(__a) __sun_attr_##__a +#define __sun_attr__(__a) ___sun_attr_inner __a +#define __NORETURN __sun_attr__((__noreturn__)) +__NORETURN +#define X(...) +#define Y(...) 1 __VA_ARGS__ 2 +Y(X X() ()) diff --git a/tinyc/tests/pp/11.expect b/tinyc/tests/pp/11.expect new file mode 100644 index 000000000..6b9806c6c --- /dev/null +++ b/tinyc/tests/pp/11.expect @@ -0,0 +1,15 @@ +a +a b +a b c +a b c d +x a b c d y +x a b c y +x a b y +x a y +x y +x A,B,C y +x A,B y +x A y +x y +__attribute__((__noreturn__)) +1 2 diff --git a/tinyc/tests/pp/12.S b/tinyc/tests/pp/12.S new file mode 100644 index 000000000..597ccb4cb --- /dev/null +++ b/tinyc/tests/pp/12.S @@ -0,0 +1,8 @@ +#define SRC(y...) \ + 9999: y; \ + .section __ex_table, "a"; \ + .long 9999b, 6001f ; \ + // .previous + + SRC(1: movw (%esi), %bx) +6001: diff --git a/tinyc/tests/pp/12.expect b/tinyc/tests/pp/12.expect new file mode 100644 index 000000000..17a861c25 --- /dev/null +++ b/tinyc/tests/pp/12.expect @@ -0,0 +1,2 @@ + 9999: 1: movw (%esi), %bx; .section __ex_table, "a"; .long 9999b, 6001f ; +6001: diff --git a/tinyc/tests/pp/13.S b/tinyc/tests/pp/13.S new file mode 100644 index 000000000..bf0b525f9 --- /dev/null +++ b/tinyc/tests/pp/13.S @@ -0,0 +1,6 @@ +# `modelist' label. Each video mode record looks like: +#ifdef AAA +# modelist' label. Each video mode record looks like: +#endif +.text +endtext: diff --git a/tinyc/tests/pp/13.expect b/tinyc/tests/pp/13.expect new file mode 100644 index 000000000..c7a32305f --- /dev/null +++ b/tinyc/tests/pp/13.expect @@ -0,0 +1,2 @@ +.text +endtext: diff --git a/tinyc/tests/pp/14.c b/tinyc/tests/pp/14.c new file mode 100644 index 000000000..e15468c5f --- /dev/null +++ b/tinyc/tests/pp/14.c @@ -0,0 +1,13 @@ +#define W Z +#define Z(X) W(X,2) +#define Y(X) Z(X) +#define X Y +return X(X(1)); + +#define P Q +#define Q(n) P(n,2) +return P(1); + +#define A (B * B) +#define B (A + A) +return A + B; diff --git a/tinyc/tests/pp/14.expect b/tinyc/tests/pp/14.expect new file mode 100644 index 000000000..37860440c --- /dev/null +++ b/tinyc/tests/pp/14.expect @@ -0,0 +1,3 @@ +return Z(Z(1,2),2); +return Q(1,2); +return ((A + A) * (A + A)) + ((B * B) + (B * B)); diff --git a/tinyc/tests/pp/15.c b/tinyc/tests/pp/15.c new file mode 100644 index 000000000..cf13f9a89 --- /dev/null +++ b/tinyc/tests/pp/15.c @@ -0,0 +1,18 @@ +// insert a space between two tokens if otherwise they +// would form a single token when read back + +#define n(x) x + +return (n(long)n(double))d; +return n(A)n(++)n(+)n(B); +return n(A)n(+)n(++)n(B); +return n(A)n(++)n(+)n(+)n(B); + +// not a hex float +return n(0x1E)n(-1); + +// unlike gcc but correct +// XXX: return n(x)+n(x)-n(1)+n(1)-2; + +// unlike gcc, but cannot appear in valid C +// XXX: return n(x)n(x)n(1)n(2)n(x); diff --git a/tinyc/tests/pp/15.expect b/tinyc/tests/pp/15.expect new file mode 100644 index 000000000..b4f885e95 --- /dev/null +++ b/tinyc/tests/pp/15.expect @@ -0,0 +1,5 @@ +return (long double)d; +return A+++B; +return A+ ++B; +return A+++ +B; +return 0x1E -1; diff --git a/tinyc/tests/pp/16.c b/tinyc/tests/pp/16.c new file mode 100644 index 000000000..8b5b6428c --- /dev/null +++ b/tinyc/tests/pp/16.c @@ -0,0 +1,3 @@ +/* The following should warn */ +#define A ... +#define A <<= diff --git a/tinyc/tests/pp/16.expect b/tinyc/tests/pp/16.expect new file mode 100644 index 000000000..695d6d41c --- /dev/null +++ b/tinyc/tests/pp/16.expect @@ -0,0 +1,2 @@ + +16.c:3: warning: A redefined diff --git a/tinyc/tests/pp/17.c b/tinyc/tests/pp/17.c new file mode 100644 index 000000000..f12196fe8 --- /dev/null +++ b/tinyc/tests/pp/17.c @@ -0,0 +1,14 @@ +#define STR1(u) # u +#define pass(a) a +#define __ASM_REG(reg) STR1(one##reg) +#define _ASM_DX __ASM_REG(tok) +X162 pass(__ASM_REG(tok)) +X161 pass(_ASM_DX) +X163 pass(STR1(one##tok)) + +X170 pass(x ## y) +X171 pass(x pass(##) y) + +#define Y(x) Z(x) +#define X Y +X180 return X(X(1)); diff --git a/tinyc/tests/pp/17.expect b/tinyc/tests/pp/17.expect new file mode 100644 index 000000000..e95aafef8 --- /dev/null +++ b/tinyc/tests/pp/17.expect @@ -0,0 +1,6 @@ +X162 "onetok" +X161 "onetok" +X163 "one##tok" +X170 x ## y +X171 x ## y +X180 return Z(Z(1)); diff --git a/tinyc/tests/pp/18.c b/tinyc/tests/pp/18.c new file mode 100644 index 000000000..0961426ac --- /dev/null +++ b/tinyc/tests/pp/18.c @@ -0,0 +1,15 @@ +#define M_RETI_ARG27(x,y,z,aa, ...) aa +#define M_RET_ARG27(...) M_RETI_ARG27(__VA_ARGS__) +#define M_COMMA_P(...) M_RET_ARG27(__VA_ARGS__, 1, 1, 0, useless) +#define M_EMPTYI_DETECT(...) 0, 1, +#define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ () ) +#define EX +#define empty(x) +#define fnlike(x) yeah x +/* If the following macro is called with empty arg (X183), the use + of 'x' between fnlike and '(' doesn't hinder the recognition of this + being a further fnlike macro invocation. */ +#define usefnlike(x) fnlike x (x) +X181 M_EMPTYI_P_C1() +X182 M_EMPTYI_P_C1(x) +X183 usefnlike() diff --git a/tinyc/tests/pp/18.expect b/tinyc/tests/pp/18.expect new file mode 100644 index 000000000..447a9b2ed --- /dev/null +++ b/tinyc/tests/pp/18.expect @@ -0,0 +1,3 @@ +X181 1 +X182 0 +X183 yeah diff --git a/tinyc/tests/pp/19.c b/tinyc/tests/pp/19.c new file mode 100644 index 000000000..aa91abe0d --- /dev/null +++ b/tinyc/tests/pp/19.c @@ -0,0 +1,101 @@ +#define M_C2I(a, ...) a ## __VA_ARGS__ +#define M_C(a, ...) M_C2I(a, __VA_ARGS__) +#define M_C3I(a, b, ...) a ## b ## __VA_ARGS__ +#define M_C3(a, b, ...) M_C3I(a ,b, __VA_ARGS__) + +#define M_RETI_ARG2(a, b, ...) b +#define M_RET_ARG2(...) M_RETI_ARG2(__VA_ARGS__) +#define M_RETI_ARG27(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,aa, ...) aa +#define M_RET_ARG27(...) M_RETI_ARG27(__VA_ARGS__) + +#define M_TOBOOLI_0 1, 0, +#define M_BOOL(x) M_RET_ARG2(M_C(M_TOBOOLI_, x), 1, useless) + +#define M_IFI_0(true_macro, ...) __VA_ARGS__ +#define M_IFI_1(true_macro, ...) true_macro +#define M_IF(c) M_C(M_IFI_, M_BOOL(c)) + +#define M_FLAT(...) __VA_ARGS__ +#define M_INVI_0 1 +#define M_INVI_1 0 +#define M_INV(x) M_C(M_INVI_, x) + +#define M_ANDI_00 0 +#define M_ANDI_01 0 +#define M_ANDI_10 0 +#define M_ANDI_11 1 +#define M_AND(x,y) M_C3(M_ANDI_, x, y) + +#define M_ORI_00 0 +#define M_ORI_01 1 +#define M_ORI_10 1 +#define M_ORI_11 1 +#define M_OR(x,y) M_C3(M_ORI_, x, y) + +#define M_COMMA_P(...) M_RET_ARG27(__VA_ARGS__, 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, 0, useless) + +#define M_EMPTYI_DETECT(...) 0, 1, +#define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ ()) +#define M_EMPTYI_P_C2(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__) +#define M_EMPTYI_P_C3(...) M_COMMA_P(__VA_ARGS__ () ) +#define M_EMPTY_P(...) M_AND(M_EMPTYI_P_C1(__VA_ARGS__), M_INV(M_OR(M_OR(M_EMPTYI_P_C2(__VA_ARGS__), M_COMMA_P(__VA_ARGS__)),M_EMPTYI_P_C3(__VA_ARGS__)))) +#define M_APPLY_FUNC2B(func, arg1, arg2) \ + M_IF(M_EMPTY_P(arg2))(,func(arg1, arg2)) +#define M_MAP2B_0(func, data, 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,...) \ + M_APPLY_FUNC2B(func, data, a) M_APPLY_FUNC2B(func, data, b) M_APPLY_FUNC2B(func, data, c) \ + M_APPLY_FUNC2B(func, data, d) M_APPLY_FUNC2B(func, data, e) M_APPLY_FUNC2B(func, data, f) \ + M_APPLY_FUNC2B(func, data, g) M_APPLY_FUNC2B(func, data, h) M_APPLY_FUNC2B(func, data, i) \ + M_APPLY_FUNC2B(func, data, j) M_APPLY_FUNC2B(func, data, k) M_APPLY_FUNC2B(func, data, l) \ + M_APPLY_FUNC2B(func, data, m) M_APPLY_FUNC2B(func, data, n) M_APPLY_FUNC2B(func, data, o) \ + M_APPLY_FUNC2B(func, data, p) M_APPLY_FUNC2B(func, data, q) M_APPLY_FUNC2B(func, data, r) \ + M_APPLY_FUNC2B(func, data, s) M_APPLY_FUNC2B(func, data, t) M_APPLY_FUNC2B(func, data, u) \ + M_APPLY_FUNC2B(func, data, v) M_APPLY_FUNC2B(func, data, w) M_APPLY_FUNC2B(func, data, x) \ + M_APPLY_FUNC2B(func, data, y) M_APPLY_FUNC2B(func, data, z) +#define M_MAP2B(f, ...) M_MAP2B_0(f, __VA_ARGS__, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ) +#define M_INIT_INIT(a) ,a, + +#define M_GET_METHOD(method, method_default, ...) \ + M_RET_ARG2 (M_MAP2B(M_C, M_C3(M_, method, _), __VA_ARGS__), method_default,) + +#define M_TEST_METHOD_P(method, oplist) \ + M_BOOL(M_GET_METHOD (method, 0, M_FLAT oplist)) + +#define TRUE 1 +#define TEST1(n) \ + M_IF(n)(ok,nok) +#define TEST2(op) \ + M_TEST_METHOD_P(INIT, op) +#define TEST3(op) \ + M_IF(M_TEST_METHOD_P(INIT, op))(ok, nok) +#define TEST4(op) \ + TEST1(TEST2(op)) +#define KO(a) ((void)1) + +/* This checks that the various expansions that ultimately lead to + something like 'KO(arg,arg)', where 'KO' comes from a macro + expansion reducing from a large macro chain do not are regarded + as funclike macro invocation of KO. E.g. X93 and X94 expand to 'KO', + but X95 must not consume the (a,b) arguments outside the M_IF() + invocation to reduce the 'KO' macro to an invocation. Instead + X95 should reduce via M_IF(KO)(a,b) to 'a'. + + The other lines here are variations on this scheme, with X1 to + X6 coming from the bug report at + http://lists.nongnu.org/archive/html/tinycc-devel/2017-07/msg00017.html */ +X92 M_IF(KO) +X93 M_GET_METHOD(INIT, 0, INIT(KO)) +X94 M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))) +X95 M_IF(M_GET_METHOD(INIT, 0, INIT(KO)))(a,b) +X96 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO)))) +X97 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))(ok,nok) +X98 (M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok) +X99 M_IF(M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok) +// test begins +X1 TEST1(TRUE) // ==> expect ok, get ok +// First test with a token which is not a macro +X2 TEST2((INIT(ok))) // ==> expect 1, get 1 +X3 TEST3((INIT(ok))) // ==> expect ok, get ok +// Then test with a token which is a macro, but should not be expanded. +X4 TEST2((INIT(KO))) // ==> expect 1, get 1 +X5 TEST4(INIT(KO)) +X6 TEST3((INIT(KO))) // ==> expect ok, get "error: macro 'KO' used with too many args" diff --git a/tinyc/tests/pp/19.expect b/tinyc/tests/pp/19.expect new file mode 100644 index 000000000..08c08581e --- /dev/null +++ b/tinyc/tests/pp/19.expect @@ -0,0 +1,14 @@ +X92 M_IFI_1 +X93 KO +X94 KO +X95 a +X96 M_IFI_1 +X97 ok +X98 (1)(ok, nok) +X99 ok +X1 ok +X2 1 +X3 ok +X4 1 +X5 nok +X6 ok diff --git a/tinyc/tests/pp/20.c b/tinyc/tests/pp/20.c new file mode 100644 index 000000000..7944d62bc --- /dev/null +++ b/tinyc/tests/pp/20.c @@ -0,0 +1,13 @@ +/* Various things I encountered while hacking the pre processor */ +#define wrap(x) x +#define pr_warning(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__) +#define pr_warn(x,y) pr_warning(x,y) +#define net_ratelimited_function(function, ...) function(__VA_ARGS__) +X1 net_ratelimited_function(pr_warn, "pipapo", bla); +X2 net_ratelimited_function(wrap(pr_warn), "bla", foo); +#define two m n +#define chain4(a,b,c,d) a ## b ## c ## d +X2 chain4(two,o,p,q) +X3 chain4(o,two,p,q) +X4 chain4(o,p,two,q) +X5 chain4(o,p,q,two) diff --git a/tinyc/tests/pp/20.expect b/tinyc/tests/pp/20.expect new file mode 100644 index 000000000..d19405d74 --- /dev/null +++ b/tinyc/tests/pp/20.expect @@ -0,0 +1,6 @@ +X1 printk(KERN_WARNING "pipapo",bla); +X2 printk(KERN_WARNING "bla",foo); +X2 twoopq +X3 otwopq +X4 optwoq +X5 opqtwo diff --git a/tinyc/tests/pp/21.c b/tinyc/tests/pp/21.c new file mode 100644 index 000000000..1316226a2 --- /dev/null +++ b/tinyc/tests/pp/21.c @@ -0,0 +1,36 @@ +/* accept 'defined' as result of substitution */ + +----- 1 ------ +#define AAA 2 +#define BBB +#define CCC (defined ( AAA ) && AAA > 1 && !defined BBB) +#if !CCC +OK +#else +NOT OK +#endif + +----- 2 ------ +#undef BBB +#if CCC +OK +#else +NOT OK +#endif + +----- 3 ------ +#define DEFINED defined +#define DDD (DEFINED ( AAA ) && AAA > 1 && !DEFINED BBB) +#if (DDD) +OK +#else +NOT OK +#endif + +----- 4 ------ +#undef AAA +#if !(DDD) +OK +#else +NOT OK +#endif diff --git a/tinyc/tests/pp/21.expect b/tinyc/tests/pp/21.expect new file mode 100644 index 000000000..5a1376bb1 --- /dev/null +++ b/tinyc/tests/pp/21.expect @@ -0,0 +1,8 @@ +----- 1 ------ +OK +----- 2 ------ +OK +----- 3 ------ +OK +----- 4 ------ +OK diff --git a/tinyc/tests/pp/pp-counter.c b/tinyc/tests/pp/pp-counter.c new file mode 100644 index 000000000..3978e1a7e --- /dev/null +++ b/tinyc/tests/pp/pp-counter.c @@ -0,0 +1,27 @@ +X1 __COUNTER__ +X2 __COUNTER__ +#if __COUNTER__ +X3 __COUNTER__ +#endif +#define pass(x) x +#define a x __COUNTER__ y +#define a2 pass(__COUNTER__) +#define f(c) c __COUNTER__ +#define apply(d) d d __COUNTER__ x2 f(d) y2 __COUNTER__ +#define _paste(a,b) a ## b +#define paste(a,b) _paste(a,b) +#define _paste3(a,b,c) a ## b ## c +#define doublepaste(a,b) _paste3(a,b,b) +#define str(x) #x +X4 a +X5 f(a) +X6 f(b) +X7 f(__COUNTER__) +X8 apply(a) +X9 apply(f(a)) +X10 apply(__COUNTER__) +X11 apply(a2) +X12 str(__COUNTER__) +X13 paste(x,__COUNTER__) +X14 _paste(x,__COUNTER__) +X15 doublepaste(x,__COUNTER__) diff --git a/tinyc/tests/pp/pp-counter.expect b/tinyc/tests/pp/pp-counter.expect new file mode 100644 index 000000000..02fc535bc --- /dev/null +++ b/tinyc/tests/pp/pp-counter.expect @@ -0,0 +1,15 @@ +X1 0 +X2 1 +X3 3 +X4 x 4 y +X5 x 5 y 6 +X6 b 7 +X7 8 9 +X8 x 10 y x 10 y 11 x2 x 10 y 12 y2 13 +X9 x 14 y 15 x 14 y 15 16 x2 x 14 y 15 17 y2 18 +X10 19 19 20 x2 19 21 y2 22 +X11 23 23 24 x2 23 25 y2 26 +X12 "__COUNTER__" +X13 x27 +X14 x__COUNTER__ +X15 x2828 diff --git a/tinyc/tests/tcctest.c b/tinyc/tests/tcctest.c index a2d481a6a..099fc3544 100644 --- a/tinyc/tests/tcctest.c +++ b/tinyc/tests/tcctest.c @@ -1,7 +1,7 @@ /* * TCC auto test program */ -#include "../config.h" +#include "config.h" #if GCC_MAJOR >= 3 @@ -16,6 +16,23 @@ #endif +#if defined(_WIN32) +#define LONG_LONG_FORMAT "%lld" +#define ULONG_LONG_FORMAT "%llu" +#else +#define LONG_LONG_FORMAT "%Ld" +#define ULONG_LONG_FORMAT "%Lu" +#endif + +// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC +#if defined(_WIN32) && defined(__GNUC__) +#define LONG_DOUBLE double +#define LONG_DOUBLE_LITERAL(x) x +#else +#define LONG_DOUBLE long double +#define LONG_DOUBLE_LITERAL(x) x ## L +#endif + /* deprecated and no longer supported in gcc 3.3 */ //#define ACCEPT_CR_IN_STRINGS @@ -27,7 +44,7 @@ #define TCCLIB_INC <tcclib.h> #define TCCLIB_INC1 <tcclib #define TCCLIB_INC2 h> -#define TCCLIB_INC3 "tcclib" +#define TCCLIB_INC3 "tcclib.h" #include TCCLIB_INC @@ -35,16 +52,30 @@ #include TCCLIB_INC1.h> -/* gcc 3.2 does not accept that (bug ?) */ -//#include TCCLIB_INC3 ".h" +#include TCCLIB_INC3 #include <tcclib.h> #include "tcclib.h" +#include "tcctest.h" + +/* Test two more ways to include a file named like a pp-number */ +#define INC(name) <tests/name.h> +#define funnyname 42test.h +#define incdir tests/ +#define incname < incdir funnyname > +#define __stringify(x) #x +#define stringify(x) __stringify(x) +#include INC(42test) +#include incname +#include stringify(funnyname) + +void intdiv_test(); void string_test(); void expr_test(); void macro_test(); +void recursive_macro_test(); void scope_test(); void forward_test(); void funcptr_test(); @@ -57,6 +88,7 @@ void struct_test(); void array_test(); void expr_ptr_test(); void bool_test(); +void optimize_out(); void expr2_test(); void constant_expr_test(); void expr_cmp_test(); @@ -76,18 +108,33 @@ void whitespace_test(void); void relocation_test(void); void old_style_function(void); void alloca_test(void); +void c99_vla_test(int size1, int size2); void sizeof_test(void); void typeof_test(void); void local_label_test(void); void statement_expr_test(void); void asm_test(void); void builtin_test(void); +void weak_test(void); +void global_data_test(void); +void cmp_comparison_test(void); +void math_cmp_test(void); +void callsave_test(void); +void builtin_frame_address_test(void); +void attrib_test(void); int fib(int n); void num(int n); void forward_ref(void); int isid(int c); +/* Line joining happens before tokenization, so the following + must be parsed as ellipsis. */ +void funny_line_continuation (int, ..\ +. ); + +char via_volatile (char); + #define A 2 #define N 1234 + A #define pf printf @@ -100,6 +147,10 @@ int isid(int c); #define HIGHLOW "hello" #define LOW LOW ", world" +static int onetwothree = 123; +#define onetwothree4 onetwothree +#define onetwothree xglue(onetwothree,4) + #define min(a, b) ((a) < (b) ? (a) : (b)) #ifdef C99_MACROS @@ -125,6 +176,11 @@ int isid(int c); #define B3 4 #endif +#ifdef __TINYC__ +/* We try to handle this syntax. Make at least sure it doesn't segfault. */ +char invalid_function_def()[] {} +#endif + #define __INT64_C(c) c ## LL #define INT64_MIN (-__INT64_C(9223372036854775807)-1) @@ -138,6 +194,71 @@ int qq(int x) #define wq_spin_lock spin_lock #define TEST2() wq_spin_lock(a) +#define UINT_MAX ((unsigned) -1) + +void intdiv_test(void) +{ + printf("18/21=%u\n", 18/21); + printf("18%%21=%u\n", 18%21); + printf("41/21=%u\n", 41/21); + printf("41%%21=%u\n", 41%21); + printf("42/21=%u\n", 42/21); + printf("42%%21=%u\n", 42%21); + printf("43/21=%u\n", 43/21); + printf("43%%21=%u\n", 43%21); + printf("126/21=%u\n", 126/21); + printf("126%%21=%u\n", 126%21); + printf("131/21=%u\n", 131/21); + printf("131%%21=%u\n", 131%21); + printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2); + printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2); + + printf("18/-21=%u\n", 18/-21); + printf("18%%-21=%u\n", 18%-21); + printf("41/-21=%u\n", 41/-21); + printf("41%%-21=%u\n", 41%-21); + printf("42/-21=%u\n", 42/-21); + printf("42%%-21=%u\n", 42%-21); + printf("43/-21=%u\n", 43/-21); + printf("43%%-21=%u\n", 43%-21); + printf("126/-21=%u\n", 126/-21); + printf("126%%-21=%u\n", 126%-21); + printf("131/-21=%u\n", 131/-21); + printf("131%%-21=%u\n", 131%-21); + printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2); + printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2); + + printf("-18/21=%u\n", -18/21); + printf("-18%%21=%u\n", -18%21); + printf("-41/21=%u\n", -41/21); + printf("-41%%21=%u\n", -41%21); + printf("-42/21=%u\n", -42/21); + printf("-42%%21=%u\n", -42%21); + printf("-43/21=%u\n", -43/21); + printf("-43%%21=%u\n", -43%21); + printf("-126/21=%u\n", -126/21); + printf("-126%%21=%u\n", -126%21); + printf("-131/21=%u\n", -131/21); + printf("-131%%21=%u\n", -131%21); + printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2); + printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2); + + printf("-18/-21=%u\n", -18/-21); + printf("-18%%-21=%u\n", -18%-21); + printf("-41/-21=%u\n", -41/-21); + printf("-41%%-21=%u\n", -41%-21); + printf("-42/-21=%u\n", -42/-21); + printf("-42%%-21=%u\n", -42%-21); + printf("-43/-21=%u\n", -43/-21); + printf("-43%%-21=%u\n", -43%-21); + printf("-126/-21=%u\n", -126/-21); + printf("-126%%-21=%u\n", -126%-21); + printf("-131/-21=%u\n", -131/-21); + printf("-131%%-21=%u\n", -131%-21); + printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2); + printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2); +} + void macro_test(void) { printf("macro:\n"); @@ -152,6 +273,8 @@ void macro_test(void) printf("s4=%s\n", str(a1)); printf("B3=%d\n", B3); + printf("onetwothree=%d\n", onetwothree); + #ifdef A printf("A defined\n"); #endif @@ -219,6 +342,7 @@ void macro_test(void) printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); +#if 0 #line 200 printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); @@ -226,6 +350,7 @@ void macro_test(void) printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); #line 227 "tcctest.c" +#endif /* not strictly preprocessor, but we test it there */ #ifdef C99_MACROS @@ -240,7 +365,7 @@ void macro_test(void) printf("func='%s'\n", __FUNCTION__); /* complicated macros in glibc */ - printf("INT64_MIN=%Ld\n", INT64_MIN); + printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN); { int a; a = 1; @@ -259,7 +384,7 @@ void macro_test(void) MF_s("hi"); MF_t("hi"); - /* test macro substituion inside args (should not eat stream) */ + /* test macro substitution inside args (should not eat stream) */ printf("qq=%d\n", qq(qq)(2)); /* test zero argument case. NOTE: gcc 2.95.x does not accept a @@ -278,6 +403,48 @@ comment /* test function macro substitution when the function name is substituted */ TEST2(); + + /* And again when the name and parentheses are separated by a + comment. */ + TEST2 /* the comment */ (); + + printf("%s\n", get_basefile_from_header()); + printf("%s\n", __BASE_FILE__); + printf("%s\n", get_file_from_header()); + printf("%s\n", __FILE__); + + /* Check that funnily named include was in fact included */ + have_included_42test_h = 1; + have_included_42test_h_second = 1; + have_included_42test_h_third = 1; +} + + +static void print_num(char *fn, int line, int num) { + printf("fn %s, line %d, num %d\n", fn, line, num); +} + +void recursive_macro_test(void) +{ + +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) +#define STB_WEAK 2 /* Weak symbol */ +#define ELFW(type) ELF##32##_##type + printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123))); + +#define WRAP(x) x + +#define print_num(x) print_num(__FILE__,__LINE__,x) + print_num(123); + WRAP(print_num(123)); + WRAP(WRAP(print_num(123))); + +static struct recursive_macro { int rm_field; } G; +#define rm_field (G.rm_field) + printf("rm_field = %d\n", rm_field); + printf("rm_field = %d\n", WRAP(rm_field)); + WRAP((printf("rm_field = %d %d\n", rm_field, WRAP(rm_field)))); } int op(a,b) @@ -356,6 +523,12 @@ void loop_test() } while (i < 10); printf("\n"); + char count = 123; + /* c99 for loop init test */ + for (size_t count = 1; count < 3; count++) + printf("count=%d\n", count); + printf("count = %d\n", count); + /* break/continue tests */ i = 0; while (1) { @@ -388,6 +561,7 @@ void loop_test() printf("\n"); } +typedef int typedef_and_label; void goto_test() { @@ -396,6 +570,8 @@ void goto_test() printf("goto:\n"); i = 0; + /* This needs to parse as label, not as start of decl. */ + typedef_and_label: s_loop: if (i >= 10) goto s_end; @@ -432,13 +608,48 @@ enum test { E5 = 1000, }; +struct S_enum { + enum {E6 = 42, E7, E8} e:8; +}; + +enum ELong { + /* This is either 0 on L32 machines, or a large number + on L64 machines. We should be able to store this. */ + EL_large = ((unsigned long)0xf000 << 31) << 1, +}; + +enum { BIASU = -1U<<31 }; +enum { BIASS = -1 << 31 }; + +static int getint(int i) +{ + if (i) + return 0; + else + return (int)(-1U << 31); +} + void enum_test() { enum test b1; + /* The following should give no warning */ + unsigned *p = &b1; + struct S_enum s = {E7}; + printf("enum: %d\n", s.e); printf("enum:\n%d %d %d %d %d %d\n", E0, E1, E2, E3, E4, E5); b1 = 1; printf("b1=%d\n", b1); + printf("enum large: %ld\n", EL_large); + + if (getint(0) == BIASU) + printf("enum unsigned: ok\n"); + else + printf("enum unsigned: wrong\n"); + if (getint(0) == BIASS) + printf("enum unsigned: ok\n"); + else + printf("enum unsigned: wrong\n"); } typedef int *my_ptr; @@ -495,11 +706,17 @@ union union2 { struct struct1 st1, st2; +struct empty_mem { + /* nothing */ ; + int x; +}; + int main(int argc, char **argv) { string_test(); expr_test(); macro_test(); + recursive_macro_test(); scope_test(); forward_test(); funcptr_test(); @@ -512,6 +729,7 @@ int main(int argc, char **argv) array_test(); expr_ptr_test(); bool_test(); + optimize_out(); expr2_test(); constant_expr_test(); expr_cmp_test(); @@ -531,12 +749,25 @@ int main(int argc, char **argv) relocation_test(); old_style_function(); alloca_test(); + c99_vla_test(5, 2); sizeof_test(); typeof_test(); statement_expr_test(); local_label_test(); asm_test(); builtin_test(); +#ifndef _WIN32 + weak_test(); +#endif + global_data_test(); + cmp_comparison_test(); + math_cmp_test(); + callsave_test(); + builtin_frame_address_test(); + intdiv_test(); + if (via_volatile (42) != 42) + printf ("via_volatile broken\n"); + attrib_test(); return 0; } @@ -569,9 +800,9 @@ void scope_test() printf("g5=%d\n", g); } -void array_test(int a[4]) +void array_test() { - int i, j; + int i, j, a[4]; printf("array:\n"); printf("sizeof(a) = %d\n", sizeof(a)); @@ -592,6 +823,8 @@ void array_test(int a[4]) printf(" %3d", ((int *)tab2)[i]); } printf("\n"); + printf("sizeof(size_t)=%d\n", sizeof(size_t)); + printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t)); } void expr_test() @@ -746,6 +979,12 @@ void expr_ptr_test() j = -1; printf("%d\n", sp[j].i); } +#ifdef __LP64__ + i = 1; + p = (int*)0x100000000UL + i; + i = ((long)p) >> 32; + printf("largeptr: %p %d\n", p, i); +#endif } void expr_cmp_test() @@ -792,10 +1031,84 @@ struct aligntest4 { double a[0]; }; +struct __attribute__((aligned(16))) aligntest5 +{ + int i; +}; +struct aligntest6 +{ + int i; +} __attribute__((aligned(16))); +struct aligntest7 +{ + int i; +}; +struct aligntest5 altest5[2]; +struct aligntest6 altest6[2]; +int pad1; +/* altest7 is correctly aligned to 16 bytes also with TCC, + but __alignof__ returns the wrong result (4) because we + can't store the alignment yet when specified on symbols + directly (it's stored in the type so we'd need to make + a copy of it). -- FIXED */ +struct aligntest7 altest7[2] __attribute__((aligned(16))); + +struct aligntest8 +{ + int i; +} __attribute__((aligned(4096))); + +struct Large { + unsigned long flags; + union { + void *u1; + int *u2; + }; + + struct { + union { + unsigned long index; + void *freelist; + }; + union { + unsigned long counters; + struct { + int bla; + }; + }; + }; + + union { + struct { + long u3; + long u4; + }; + void *u5; + struct { + unsigned long compound_head; + unsigned int compound_dtor; + unsigned int compound_order; + }; + }; +} __attribute__((aligned(2 * sizeof(long)))); + +typedef unsigned long long __attribute__((aligned(4))) unaligned_u64; + +struct aligntest9 { + unsigned int buf_nr; + unaligned_u64 start_lba; +}; + +struct aligntest10 { + unsigned int buf_nr; + unsigned long long start_lba; +}; + void struct_test() { struct1 *s; union union2 u; + struct Large ls; printf("struct:\n"); printf("sizes: %d %d %d %d\n", @@ -803,6 +1116,7 @@ void struct_test() sizeof(struct struct2), sizeof(union union1), sizeof(union union2)); + printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1)); st1.f1 = 1; st1.f2 = 2; st1.f3 = 3; @@ -831,10 +1145,33 @@ void struct_test() sizeof(struct aligntest3), __alignof__(struct aligntest3)); printf("aligntest4 sizeof=%d alignof=%d\n", sizeof(struct aligntest4), __alignof__(struct aligntest4)); + printf("aligntest5 sizeof=%d alignof=%d\n", + sizeof(struct aligntest5), __alignof__(struct aligntest5)); + printf("aligntest6 sizeof=%d alignof=%d\n", + sizeof(struct aligntest6), __alignof__(struct aligntest6)); + printf("aligntest7 sizeof=%d alignof=%d\n", + sizeof(struct aligntest7), __alignof__(struct aligntest7)); + printf("aligntest8 sizeof=%d alignof=%d\n", + sizeof(struct aligntest8), __alignof__(struct aligntest8)); + printf("aligntest9 sizeof=%d alignof=%d\n", + sizeof(struct aligntest9), __alignof__(struct aligntest9)); + printf("aligntest10 sizeof=%d alignof=%d\n", + sizeof(struct aligntest10), __alignof__(struct aligntest10)); + printf("altest5 sizeof=%d alignof=%d\n", + sizeof(altest5), __alignof__(altest5)); + printf("altest6 sizeof=%d alignof=%d\n", + sizeof(altest6), __alignof__(altest6)); + printf("altest7 sizeof=%d alignof=%d\n", + sizeof(altest7), __alignof__(altest7)); /* empty structures (GCC extension) */ printf("sizeof(struct empty) = %d\n", sizeof(struct empty)); printf("alignof(struct empty) = %d\n", __alignof__(struct empty)); + + printf("Large: sizeof=%d\n", sizeof(ls)); + memset(&ls, 0, sizeof(ls)); + ls.compound_head = 42; + printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls)); } /* XXX: depend on endianness */ @@ -884,6 +1221,14 @@ static int toupper1(int a) return TOUPPER(a); } +static unsigned int calc_vm_flags(unsigned int prot) +{ + unsigned int prot_bits; + /* This used to segfault in some revisions: */ + prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0); + return prot_bits; +} + void bool_test() { int *s, a, b, t, f, i; @@ -956,6 +1301,132 @@ void bool_test() if (toupper1 (i) != TOUPPER (i)) printf("error %d\n", i); } + printf ("bits = 0x%x\n", calc_vm_flags (0x1)); +} + +extern int undefined_function(void); +extern int defined_function(void); + +static inline void refer_to_undefined(void) +{ + undefined_function(); +} + +void optimize_out(void) +{ + int i = 0 ? undefined_function() : defined_function(); + printf ("oo:%d\n", i); + int j = 1 ? defined_function() : undefined_function(); + printf ("oo:%d\n", j); + if (0) + printf("oo:%d\n", undefined_function()); + else + printf("oo:%d\n", defined_function()); + if (1) + printf("oo:%d\n", defined_function()); + else + printf("oo:%d\n", undefined_function()); + while (1) { + printf("oow:%d\n", defined_function()); + break; + printf("oow:%d\n", undefined_function()); + } + j = 1; + /* Following is a switch without {} block intentionally. */ + switch (j) + case 1: break; + printf ("oos:%d\n", defined_function()); + /* The following break shouldn't lead to disabled code after + the while. */ + while (1) + break; + printf ("ool1:%d\n", defined_function()); + /* Same for the other types of loops. */ + do + break; + while (1); + printf ("ool2:%d\n", defined_function()); + for (;;) + break; + printf ("ool3:%d\n", defined_function()); + /* Normal {} blocks without controlling statements + shouldn't reactivate code emission */ + while (1) { + { + break; + } + printf ("ool4:%d\n", undefined_function()); + } + j = 1; + while (j) { + if (j == 0) + break; /* this break shouldn't disable code outside the if. */ + printf("ool5:%d\n", defined_function()); + j--; + } + + j = 1; + while (j) { + if (1) + j--; + else + breakhere: break; + printf("ool6:%d\n", defined_function()); + goto breakhere; + } + + /* Test that constants in logical && are optimized: */ + i = 0 && undefined_function(); + i = defined_function() && 0 && undefined_function(); + if (0 && undefined_function()) + undefined_function(); + if (defined_function() && 0) + undefined_function(); + if (0 && 0) + undefined_function(); + if (defined_function() && 0 && undefined_function()) + undefined_function(); + /* The same for || : */ + i = 1 || undefined_function(); + i = defined_function() || 1 || undefined_function(); + if (1 || undefined_function()) + ; + else + undefined_function(); + if (defined_function() || 1) + ; + else + undefined_function(); + if (1 || 1) + ; + else + undefined_function(); + if (defined_function() || 1 || undefined_function()) + ; + else + undefined_function(); + + if (defined_function() && 0) + refer_to_undefined(); + + if (0) { + (void)sizeof( ({ + do { } while (0); + 0; + }) ); + undefined_function(); + } + + /* Leave the "if(1)return; printf()" in this order and last in the function */ + if (1) + return; + printf ("oor:%d\n", undefined_function()); +} + +int defined_function(void) +{ + static int i = 40; + return i++; } /* GCC accepts that */ @@ -1049,6 +1520,7 @@ void num(int n) printf("%c", *p); } printf("\n"); + free(tab); } /* structure assignment tests */ @@ -1059,9 +1531,9 @@ struct structa1 { struct structa1 ssta1; -void struct_assign_test1(struct structa1 s1, int t) +void struct_assign_test1(struct structa1 s1, int t, float f) { - printf("%d %d %d\n", s1.f1, s1.f2, t); + printf("%d %d %d %f\n", s1.f1, s1.f2, t, f); } struct structa1 struct_assign_test2(struct structa1 s1, int t) @@ -1073,25 +1545,38 @@ struct structa1 struct_assign_test2(struct structa1 s1, int t) void struct_assign_test(void) { - struct structa1 lsta1, lsta2; + struct S { + struct structa1 lsta1, lsta2; + int i; + } s, *ps; + ps = &s; + ps->i = 4; #if 0 printf("struct_assign_test:\n"); - lsta1.f1 = 1; - lsta1.f2 = 2; - printf("%d %d\n", lsta1.f1, lsta1.f2); - lsta2 = lsta1; - printf("%d %d\n", lsta2.f1, lsta2.f2); + s.lsta1.f1 = 1; + s.lsta1.f2 = 2; + printf("%d %d\n", s.lsta1.f1, s.lsta1.f2); + s.lsta2 = s.lsta1; + printf("%d %d\n", s.lsta2.f1, s.lsta2.f2); #else - lsta2.f1 = 1; - lsta2.f2 = 2; + s.lsta2.f1 = 1; + s.lsta2.f2 = 2; #endif - struct_assign_test1(lsta2, 3); + struct_assign_test1(ps->lsta2, 3, 4.5); - printf("before call: %d %d\n", lsta2.f1, lsta2.f2); - lsta2 = struct_assign_test2(lsta2, 4); - printf("after call: %d %d\n", lsta2.f1, lsta2.f2); + printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2); + ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i); + printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2); + + static struct { + void (*elem)(); + } t[] = { + /* XXX: we should allow this even without braces */ + { struct_assign_test } + }; + printf("%d\n", struct_assign_test == t[0].elem); } /* casts to short/char */ @@ -1218,6 +1703,57 @@ int sinit18[10] = { [8] = 10, }; +struct complexinit0 { + int a; + int b; +}; + +struct complexinit { + int a; + const struct complexinit0 *b; +}; + +const static struct complexinit cix[] = { + [0] = { + .a = 2000, + .b = (const struct complexinit0[]) { + { 2001, 2002 }, + { 2003, 2003 }, + {} + } + } +}; + +struct complexinit2 { + int a; + int b[]; +}; + +struct complexinit2 cix20; + +struct complexinit2 cix21 = { + .a = 3000, + .b = { 3001, 3002, 3003 } +}; + +struct complexinit2 cix22 = { + .a = 4000, + .b = { 4001, 4002, 4003, 4004, 4005, 4006 } +}; + +typedef int arrtype1[]; +arrtype1 sinit19 = {1}; +arrtype1 sinit20 = {2,3}; +typedef int arrtype2[3]; +arrtype2 sinit21 = {4}; +arrtype2 sinit22 = {5,6,7}; + +/* Address comparisons of non-weak symbols with zero can be const-folded */ +int sinit23[2] = { "astring" ? sizeof("astring") : -1, + &sinit23 ? 42 : -1 }; + +extern int external_inited = 42; + void init_test(void) { int linit1 = 2; @@ -1232,6 +1768,9 @@ void init_test(void) int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, }; struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 }; int linit17 = sizeof(linit17); + int zero = 0; + /* Addresses on non-weak symbols are non-zero, but not the access itself */ + int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 }; printf("init_test:\n"); @@ -1310,12 +1849,65 @@ void init_test(void) for(i=0;i<10;i++) printf("%x ", sinit18[i]); printf("\n"); + /* complex init check */ + printf("cix: %d %d %d %d %d %d %d\n", + cix[0].a, + cix[0].b[0].a, cix[0].b[0].b, + cix[0].b[1].a, cix[0].b[1].b, + cix[0].b[2].a, cix[0].b[2].b); + printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]); + printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22); + + printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]); + printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20)); + printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]); + printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]); + printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22)); + printf("arrtype6: %d\n", sizeof(arrtype2)); + + printf("sinit23= %d %d\n", sinit23[0], sinit23[1]); + printf("linit18= %d %d\n", linit18[0], linit18[1]); +} + +void switch_uc(unsigned char uc) +{ + switch (uc) { + case 0xfb ... 0xfe: + printf("ucsw:1\n"); + break; + case 0xff: + printf("ucsw:2\n"); + break; + case 0 ... 5: + printf("ucsw:3\n"); + break; + default: + printf("ucsw: broken!\n"); + } +} + +void switch_sc(signed char sc) +{ + switch (sc) { + case -5 ... -2: + printf("scsw:1\n"); + break; + case -1: + printf("scsw:2\n"); + break; + case 0 ... 5: + printf("scsw:3\n"); + break; + default: + printf("scsw: broken!\n"); + } } - void switch_test() { int i; + unsigned long long ull; + long long ll; for(i=0;i<15;i++) { switch(i) { @@ -1332,9 +1924,66 @@ void switch_test() case 3: printf("b"); break; + case 0xc33c6b9fU: + case 0x7c9eeeb9U: + break; } } printf("\n"); + + for (i = 1; i <= 5; i++) { + ull = (unsigned long long)i << 61; + switch (ull) { + case 1ULL << 61: + printf("ullsw:1\n"); + break; + case 2ULL << 61: + printf("ullsw:2\n"); + break; + case 3ULL << 61: + printf("ullsw:3\n"); + break; + case 4ULL << 61: + printf("ullsw:4\n"); + break; + case 5ULL << 61: + printf("ullsw:5\n"); + break; + default: + printf("ullsw: broken!\n"); + } + } + + for (i = 1; i <= 5; i++) { + ll = (long long)i << 61; + switch (ll) { + case 1LL << 61: + printf("llsw:1\n"); + break; + case 2LL << 61: + printf("llsw:2\n"); + break; + case 3LL << 61: + printf("llsw:3\n"); + break; + case 4LL << 61: + printf("llsw:4\n"); + break; + case 5LL << 61: + printf("llsw:5\n"); + break; + default: + printf("llsw: broken!\n"); + } + } + + for (i = -5; i <= 5; i++) { + switch_uc((unsigned char)i); + } + + for (i = -5; i <= 5; i++) { + switch_sc ((signed char)i); + } } /* ISOC99 _Bool type */ @@ -1358,6 +2007,8 @@ void c99_bool_test(void) void bitfield_test(void) { int a; + short sa; + unsigned char ca; struct sbf1 { int f1 : 3; int : 2; @@ -1379,6 +2030,9 @@ void bitfield_test(void) st1.f5++; printf("%d %d %d %d %d\n", st1.f1, st1.f2, st1.f3, st1.f4, st1.f5); + sa = st1.f5; + ca = st1.f5; + printf("%d %d\n", sa, ca); st1.f1 = 7; if (st1.f1 == -1) @@ -1390,8 +2044,6 @@ void bitfield_test(void) else printf("st1.f2 != -1\n"); - /* bit sizes below must be bigger than 32 since GCC doesn't allow - long-long bitfields whose size is not bigger than int */ struct sbf2 { long long f1 : 45; long long : 2; @@ -1404,6 +2056,39 @@ void bitfield_test(void) st2.f3 = a; st2.f2++; printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3); + +#if 0 + Disabled for now until further clarification re GCC compatibility + struct sbf3 { + int f1 : 7; + int f2 : 1; + char f3; + int f4 : 8; + int f5 : 1; + int f6 : 16; + } st3; + printf("sizeof(st3) = %d\n", sizeof(st3)); +#endif + + struct sbf4 { + int x : 31; + char y : 2; + } st4; + st4.y = 1; + printf("st4.y == %d\n", st4.y); + struct sbf5 { + int a; + char b; + int x : 12, y : 4, : 0, : 4, z : 3; + char c; + } st5 = { 1, 2, 3, 4, -3, 6 }; + printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c); + struct sbf6 { + short x : 12; + unsigned char y : 2; + } st6; + st6.y = 1; + printf("st6.y == %d\n", st6.y); } #ifdef __x86_64__ @@ -1415,10 +2100,16 @@ void bitfield_test(void) /* declare strto* functions as they are C99 */ double strtod(const char *nptr, char **endptr); + +#if defined(_WIN32) +float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);} +LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);} +#else float strtof(const char *nptr, char **endptr); -long double strtold(const char *nptr, char **endptr); +LONG_DOUBLE strtold(const char *nptr, char **endptr); +#endif -#define FTEST(prefix, type, fmt)\ +#define FTEST(prefix, typename, type, fmt)\ void prefix ## cmp(type a, type b)\ {\ printf("%d %d %d %d %d %d\n",\ @@ -1446,28 +2137,39 @@ void prefix ## fcast(type a)\ {\ float fa;\ double da;\ - long double la;\ + LONG_DOUBLE la;\ int ia;\ + long long llia;\ unsigned int ua;\ + unsigned long long llua;\ type b;\ fa = a;\ da = a;\ la = a;\ printf("ftof: %f %f %Lf\n", fa, da, la);\ ia = (int)a;\ + llia = (long long)a;\ + a = (a >= 0) ? a : -a;\ ua = (unsigned int)a;\ - printf("ftoi: %d %u\n", ia, ua);\ + llua = (unsigned long long)a;\ + printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\ ia = -1234;\ ua = 0x81234500;\ + llia = -0x123456789012345LL;\ + llua = 0xf123456789012345LLU;\ b = ia;\ printf("itof: " fmt "\n", b);\ b = ua;\ printf("utof: " fmt "\n", b);\ + b = llia;\ + printf("lltof: " fmt "\n", b);\ + b = llua;\ + printf("ulltof: " fmt "\n", b);\ }\ \ float prefix ## retf(type a) { return a; }\ double prefix ## retd(type a) { return a; }\ -long double prefix ## retld(type a) { return a; }\ +LONG_DOUBLE prefix ## retld(type a) { return a; }\ \ void prefix ## call(void)\ {\ @@ -1477,26 +2179,57 @@ void prefix ## call(void)\ printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\ }\ \ +void prefix ## signed_zeros(void) \ +{\ + type x = 0.0, y = -0.0, n, p;\ + if (x == y)\ + printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\ + 1.0 / x != 1.0 / y);\ + else\ + printf ("x != y; this is wrong!\n");\ +\ + n = -x;\ + if (x == n)\ + printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\ + 1.0 / x != 1.0 / n);\ + else\ + printf ("x != -x; this is wrong!\n");\ +\ + p = +y;\ + if (x == p)\ + printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\ + 1.0 / x != 1.0 / p);\ + else\ + printf ("x != +y; this is wrong!\n");\ + p = -y;\ + if (x == p)\ + printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\ + 1.0 / x != 1.0 / p);\ + else\ + printf ("x != -y; this is wrong!\n");\ +}\ void prefix ## test(void)\ {\ - printf("testing '%s'\n", #type);\ + printf("testing '%s'\n", #typename);\ prefix ## cmp(1, 2.5);\ prefix ## cmp(2, 1.5);\ prefix ## cmp(1, 1);\ prefix ## fcast(234.6);\ prefix ## fcast(-2334.6);\ prefix ## call();\ + prefix ## signed_zeros();\ } -FTEST(f, float, "%f") -FTEST(d, double, "%f") -FTEST(ld, long double, "%Lf") +FTEST(f, float, float, "%f") +FTEST(d, double, double, "%f") +FTEST(ld, long double, LONG_DOUBLE, "%Lf") double ftab1[3] = { 1.2, 3.4, -5.6 }; void float_test(void) { +#if !defined(__arm__) || defined(__ARM_PCS_VFP) float fa, fb; double da, db; int a; @@ -1505,7 +2238,7 @@ void float_test(void) printf("float_test:\n"); printf("sizeof(float) = %d\n", sizeof(float)); printf("sizeof(double) = %d\n", sizeof(double)); - printf("sizeof(long double) = %d\n", sizeof(long double)); + printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE)); ftest(); dtest(); ldtest(); @@ -1522,6 +2255,7 @@ void float_test(void) b = 4000000000; db = b; printf("db = %f\n", db); +#endif } int fib(int n) @@ -1540,6 +2274,7 @@ void funcptr_test() int dummy; void (*func)(int); } st1; + long diff; printf("funcptr:\n"); func = # @@ -1555,6 +2290,12 @@ void funcptr_test() printf("sizeof2 = %d\n", sizeof funcptr_test); printf("sizeof3 = %d\n", sizeof(&funcptr_test)); printf("sizeof4 = %d\n", sizeof &funcptr_test); + a = 0; + func = num + a; + diff = func - num; + func(42); + (func + diff)(42); + (num + a)(43); } void lloptest(long long a, long long b) @@ -1564,19 +2305,19 @@ void lloptest(long long a, long long b) ua = a; ub = b; /* arith */ - printf("arith: %Ld %Ld %Ld\n", + printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a + b, a - b, a * b); if (b != 0) { - printf("arith1: %Ld %Ld\n", + printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a / b, a % b); } /* binary */ - printf("bin: %Ld %Ld %Ld\n", + printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a & b, a | b, a ^ b); @@ -1601,25 +2342,25 @@ void lloptest(long long a, long long b) /* arith2 */ a++; b++; - printf("arith2: %Ld %Ld\n", a, b); - printf("arith2: %Ld %Ld\n", a++, b++); - printf("arith2: %Ld %Ld\n", --a, --b); - printf("arith2: %Ld %Ld\n", a, b); + printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); + printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++); + printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b); + printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); b = ub = 0; printf("not: %d %d %d %d\n", !a, !ua, !b, !ub); } void llshift(long long a, int b) { - printf("shift: %Ld %Ld %Ld\n", + printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", (unsigned long long)a >> b, a >> b, a << b); - printf("shiftc: %Ld %Ld %Ld\n", + printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", (unsigned long long)a >> 3, a >> 3, a << 3); - printf("shiftc: %Ld %Ld %Ld\n", + printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", (unsigned long long)a >> 35, a >> 35, a << 35); @@ -1629,14 +2370,14 @@ void llfloat(void) { float fa; double da; - long double lda; + LONG_DOUBLE lda; long long la, lb, lc; unsigned long long ula, ulb, ulc; la = 0x12345678; ula = 0x72345678; la = (la << 20) | 0x12345; ula = ula << 33; - printf("la=%Ld ula=%Lu\n", la, ula); + printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula); fa = la; da = la; @@ -1646,7 +2387,7 @@ void llfloat(void) la = fa; lb = da; lc = lda; - printf("ftoll: %Ld %Ld %Ld\n", la, lb, lc); + printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc); fa = ula; da = ula; @@ -1656,7 +2397,7 @@ void llfloat(void) ula = fa; ulb = da; ulc = lda; - printf("ftoull: %Lu %Lu %Lu\n", ula, ulb, ulc); + printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc); } long long llfunc1(int a) @@ -1674,6 +2415,11 @@ long long int value(struct S *v) return ((long long int)v->item); } +long long llfunc2(long long x, long long y, int z) +{ + return x * y * z; +} + void longlong_test(void) { long long a, b, c; @@ -1685,14 +2431,14 @@ void longlong_test(void) ua = -2; a = ia; b = ua; - printf("%Ld %Ld\n", a, b); - printf("%Ld %Ld %Ld %Lx\n", + printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); + printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n", (long long)1, (long long)-2, 1LL, 0x1234567812345679); a = llfunc1(-3); - printf("%Ld\n", a); + printf(LONG_LONG_FORMAT "\n", a); lloptest(1000, 23); lloptest(0xff, 0x1234); @@ -1720,70 +2466,75 @@ void longlong_test(void) } lloptest(0x80000000, 0); - /* another long long spill test */ { - long long *p, v; + long long *p, v, **pp; v = 1; p = &v; p[0]++; - printf("%lld\n", *p); - } + printf("another long long spill test : %lld\n", *p); + pp = &p; + v = llfunc2(**pp, **pp, ia); + printf("a long long function (arm-)reg-args test : %lld\n", v); + } a = 68719476720LL; b = 4294967295LL; printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b); - printf("%Ld\n", 0x123456789LLU); + printf(LONG_LONG_FORMAT "\n", 0x123456789LLU); + + /* long long pointer deref in argument passing test */ + a = 0x123; + long long *p = &a; + llshift(*p, 5); } void manyarg_test(void) { - long double ld = 1234567891234LL; + LONG_DOUBLE ld = 1234567891234LL; printf("manyarg_test:\n"); printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n", 1, 2, 3, 4, 5, 6, 7, 8, 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0); printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " - "%Ld %Ld %f %f\n", + LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n", 1, 2, 3, 4, 5, 6, 7, 8, 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, 1234567891234LL, 987654321986LL, 42.0, 43.0); printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " - "%Ld %Ld %f %f\n", + LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n", ld, 1, 2, 3, 4, 5, 6, 7, 8, 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, 1234567891234LL, 987654321986LL, 42.0, 43.0); - /* XXX: known bug of x86-64 */ -#ifndef __x86_64__ printf("%d %d %d %d %d %d %d %d %Lf\n", 1, 2, 3, 4, 5, 6, 7, 8, ld); printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " - "%Ld %Ld %f %f %Lf\n", + LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n", 1, 2, 3, 4, 5, 6, 7, 8, 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, 1234567891234LL, 987654321986LL, 42.0, 43.0, ld); printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " - "%Lf %Ld %Ld %f %f %Lf\n", + "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n", 1, 2, 3, 4, 5, 6, 7, 8, 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, ld, 1234567891234LL, 987654321986LL, 42.0, 43.0, ld); -#endif } void vprintf1(const char *fmt, ...) { - va_list ap; + va_list ap, aq; const char *p; int c, i; double d; long long ll; - long double ld; + LONG_DOUBLE ld; - va_start(ap, fmt); + va_start(aq, fmt); + va_copy(ap, aq); p = fmt; for(;;) { @@ -1806,10 +2557,10 @@ void vprintf1(const char *fmt, ...) break; case 'l': ll = va_arg(ap, long long); - printf("%Ld", ll); + printf(LONG_LONG_FORMAT, ll); break; case 'F': - ld = va_arg(ap, long double); + ld = va_arg(ap, LONG_DOUBLE); printf("%Lf", ld); break; } @@ -1819,22 +2570,48 @@ void vprintf1(const char *fmt, ...) } } the_end: + va_end(aq); va_end(ap); } +struct myspace { + short int profile; +}; + +void stdarg_for_struct(struct myspace bob, ...) +{ + struct myspace george, bill; + va_list ap; + short int validate; + + va_start(ap, bob); + bill = va_arg(ap, struct myspace); + george = va_arg(ap, struct myspace); + validate = va_arg(ap, int); + printf("stdarg_for_struct: %d %d %d %d\n", + bob.profile, bill.profile, george.profile, validate); + va_end(ap); +} + +void stdarg_for_libc(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} void stdarg_test(void) { - long double ld = 1234567891234LL; + LONG_DOUBLE ld = 1234567891234LL; + struct myspace bob; + vprintf1("%d %d %d\n", 1, 2, 3); vprintf1("%f %d %f\n", 1.0, 2, 3.0); vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0); - vprintf1("%F %F %F\n", 1.2L, 2.3L, 3.4L); -#ifdef __x86_64__ - /* a bug of x86's TCC */ + vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4)); vprintf1("%d %f %l %F %d %f %l %F\n", - 1, 1.2, 3L, 4.5L, 6, 7.8, 9L, 0.1L); -#endif + 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1)); vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n", 1, 2, 3, 4, 5, 6, 7, 8, 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8); @@ -1867,6 +2644,10 @@ void stdarg_test(void) 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, ld, 1234567891234LL, 987654321986LL, 42.0, 43.0, ld); + + bob.profile = 42; + stdarg_for_struct(bob, bob, bob, bob.profile); + stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456); } void whitespace_test(void) @@ -1906,11 +2687,38 @@ int reltab[3] = { 1, 2, 3 }; int *rel1 = &reltab[1]; int *rel2 = &reltab[2]; +#ifdef _WIN64 +void relocation_test(void) {} +#else +void getmyaddress(void) +{ + printf("in getmyaddress\n"); +} + +#ifdef __LP64__ +long __pa_symbol(void) +{ + /* This 64bit constant was handled incorrectly, it was used as addend + (which can hold 64bit just fine) in connection with a symbol, + and TCC generates wrong code for that (displacements are 32bit only). + This effectively is "+ 0x80000000", and if addresses of globals + are below 2GB the result should be a number without high 32 bits set. */ + return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL)); +} +#endif + +unsigned long theaddress = (unsigned long)getmyaddress; void relocation_test(void) { + void (*fptr)(void) = (void (*)(void))theaddress; printf("*rel1=%d\n", *rel1); printf("*rel2=%d\n", *rel2); + fptr(); +#ifdef __LP64__ + printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63); +#endif } +#endif void old_style_f(a,b,c) int a, b; @@ -1939,7 +2747,7 @@ void old_style_function(void) void alloca_test() { -#if defined __i386__ || defined __x86_64__ +#if defined __i386__ || defined __x86_64__ || defined __arm__ char *p = alloca(16); strcpy(p,"123456789012345"); printf("alloca: p is %s\n", p); @@ -1949,6 +2757,69 @@ void alloca_test() #endif } +void *bounds_checking_is_enabled() +{ + char ca[10], *cp = ca-1; + return (ca != cp + 1) ? cp : NULL; +} + +typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1]; + +void c99_vla_test(int size1, int size2) +{ +#if defined __i386__ || defined __x86_64__ + int size = size1 * size2; + int tab1[size][2], tab2[10][2]; + void *tab1_ptr, *tab2_ptr, *bad_ptr; + + /* "size" should have been 'captured' at tab1 declaration, + so modifying it should have no effect on VLA behaviour. */ + size = size-1; + + printf("Test C99 VLA 1 (sizeof): "); + printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED"); + tab1_ptr = tab1; + tab2_ptr = tab2; + printf("Test C99 VLA 2 (ptrs subtract): "); + printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED"); + printf("Test C99 VLA 3 (ptr add): "); + printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED"); + printf("Test C99 VLA 4 (ptr access): "); + tab1[size1][1] = 42; + printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED"); + + printf("Test C99 VLA 5 (bounds checking (might be disabled)): "); + if (bad_ptr = bounds_checking_is_enabled()) { + int *t1 = &tab1[size1 * size2 - 1][3]; + int *t2 = &tab2[9][3]; + printf("%s ", bad_ptr == t1 ? "PASSED" : "FAILED"); + printf("%s ", bad_ptr == t2 ? "PASSED" : "FAILED"); + + char*c1 = 1 + sizeof(tab1) + (char*)tab1; + char*c2 = 1 + sizeof(tab2) + (char*)tab2; + printf("%s ", bad_ptr == c1 ? "PASSED" : "FAILED"); + printf("%s ", bad_ptr == c2 ? "PASSED" : "FAILED"); + + int *i1 = tab1[-1]; + int *i2 = tab2[-1]; + printf("%s ", bad_ptr == i1 ? "PASSED" : "FAILED"); + printf("%s ", bad_ptr == i2 ? "PASSED" : "FAILED"); + + int *x1 = tab1[size1 * size2 + 1]; + int *x2 = tab2[10 + 1]; + printf("%s ", bad_ptr == x1 ? "PASSED" : "FAILED"); + printf("%s ", bad_ptr == x2 ? "PASSED" : "FAILED"); + } else { + printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED "); + } + printf("\n"); +#endif +} + +#ifndef __TINYC__ +typedef __SIZE_TYPE__ uintptr_t; +#endif + void sizeof_test(void) { int a; @@ -1969,6 +2840,20 @@ void sizeof_test(void) ptr = NULL; printf("sizeof(**ptr) = %d\n", sizeof (**ptr)); + /* The type of sizeof should be as large as a pointer, actually + it should be size_t. */ + printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int))); + uintptr_t t = 1; + uintptr_t t2; + /* Effectively <<32, but defined also on 32bit machines. */ + t <<= 16; + t <<= 16; + t++; + /* This checks that sizeof really can be used to manipulate + uintptr_t objects, without truncation. */ + t2 = t & -sizeof(uintptr_t); + printf ("%lu %lu\n", t, t2); + /* some alignof tests */ printf("__alignof__(int) = %d\n", __alignof__(int)); printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int)); @@ -1977,6 +2862,23 @@ void sizeof_test(void) printf("__alignof__(char) = %d\n", __alignof__(char)); printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char)); printf("__alignof__(func) = %d\n", __alignof__ sizeof_test()); + + /* sizes of VLAs need to be evaluated even inside sizeof: */ + a = 2; + printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a])); + /* And checking if sizeof compound literal works. Parenthesized: */ + printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n", + sizeof( (struct {int i; int j;}){4,5} )); + /* And as direct sizeof argument (as unary expression): */ + printf("sizeof (struct {short i; short j;}){4,5} = %d\n", + sizeof (struct {short i; short j;}){4,5} ); + + /* sizeof(x && y) should be sizeof(int), even if constant + evaluating is possible. */ + printf("sizeof(t && 0) = %d\n", sizeof(t && 0)); + printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1)); + printf("sizeof(t || 1) = %d\n", sizeof(t || 1)); + printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0)); } void typeof_test(void) @@ -1991,10 +2893,22 @@ void typeof_test(void) printf("a=%f b=%f c=%f\n", a, b, c); } + +struct hlist_node; +struct hlist_head { + struct hlist_node *first, *last; +}; + +void consume_ulong (unsigned long i) +{ + i = 0; +} + void statement_expr_test(void) { int a, i; + /* Basic stmt expr test */ a = 0; for(i=0;i<10;i++) { a += 1 + @@ -2006,6 +2920,48 @@ void statement_expr_test(void) } printf("a=%d\n", a); + /* Test that symbols aren't freed prematurely. + With SYM_DEBUG valgrind will show a read from a freed + symbol, and tcc will show an (invalid) warning on the initialization + of 'ptr' below, if symbols are popped after the stmt expr. */ + void *v = (void*)39; + typeof(({ + (struct hlist_node *)v; + })) x; + typeof (x) + ptr = (struct hlist_node *)v; + + /* This part used to segfault when symbols were popped prematurely. + The symbols for the static local would be overwritten with + helper symbols from the pre-processor expansions in between. */ +#define some_attr __attribute__((aligned(1))) +#define tps(str) ({ \ + static const char *t some_attr = str; \ + t; \ + }) + printf ("stmtexpr: %s %s\n", + tps("somerandomlongstring"), + tps("anotherlongstring")); + + /* Test that the three decls of 't' don't interact. */ + int t = 40; + int b = ({ int t = 41; t; }); + int c = ({ int t = 42; t; }); + + /* Test that aggregate return values work. */ + struct hlist_head h + = ({ + typedef struct hlist_head T; + long pre = 48; + T t = { (void*)43, (void*)44 }; + long post = 49; + t; + }); + printf ("stmtexpr: %d %d %d\n", t, b, c); + printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last); + + /* Test that we can give out addresses of local labels. */ + consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; })); } void local_label_test(void) @@ -2039,24 +2995,45 @@ void local_label_test(void) } /* inline assembler test */ -#ifdef __i386__ +#if defined(__i386__) || defined(__x86_64__) /* from linux kernel */ static char * strncat1(char * dest,const char * src,size_t count) { -int d0, d1, d2, d3; +long d0, d1, d2, d3; __asm__ __volatile__( "repne\n\t" "scasb\n\t" - "decl %1\n\t" - "movl %8,%3\n" - "1:\tdecl %3\n\t" + "dec %1\n\t" + "mov %8,%3\n" + "1:\tdec %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txor %2,%2\n\t" + "stosb" + : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) + : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) + : "memory"); +return dest; +} + +static char * strncat2(char * dest,const char * src,size_t count) +{ +long d0, d1, d2, d3; +__asm__ __volatile__( + "repne scasb\n\t" /* one-line repne prefix + string op */ + "dec %1\n\t" + "mov %8,%3\n" + "1:\tdec %3\n\t" "js 2f\n\t" "lodsb\n\t" "stosb\n\t" "testb %%al,%%al\n\t" "jne 1b\n" - "2:\txorl %2,%2\n\t" + "2:\txor %2,%2\n\t" "stosb" : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) @@ -2066,7 +3043,7 @@ return dest; static inline void * memcpy1(void * to, const void * from, size_t n) { -int d0, d1, d2; +long d0, d1, d2; __asm__ __volatile__( "rep ; movsl\n\t" "testb $2,%b4\n\t" @@ -2082,6 +3059,24 @@ __asm__ __volatile__( return (to); } +static inline void * memcpy2(void * to, const void * from, size_t n) +{ +long d0, d1, d2; +__asm__ __volatile__( + "rep movsl\n\t" /* one-line rep prefix + string op */ + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); +return (to); +} + static __inline__ void sigaddset1(unsigned int *set, int _sig) { __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); @@ -2089,7 +3084,7 @@ static __inline__ void sigaddset1(unsigned int *set, int _sig) static __inline__ void sigdelset1(unsigned int *set, int _sig) { - asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); + asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags"); } static __inline__ __const__ unsigned int swab32(unsigned int x) @@ -2097,7 +3092,7 @@ static __inline__ __const__ unsigned int swab32(unsigned int x) __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ "rorl $16,%0\n\t" /* swap words */ "xchgb %b0,%h0" /* swap higher bytes */ - :"=q" (x) + :"=" "q" (x) : "0" (x)); return x; } @@ -2105,25 +3100,272 @@ static __inline__ __const__ unsigned int swab32(unsigned int x) static __inline__ unsigned long long mul64(unsigned int a, unsigned int b) { unsigned long long res; +#ifdef __x86_64__ + /* Using the A constraint is wrong (it means rdx:rax, which is too large) + but still test the 32bit->64bit mull. */ + unsigned int resh, resl; + __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b)); + res = ((unsigned long long)resh << 32) | resl; +#else __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b)); +#endif return res; } static __inline__ unsigned long long inc64(unsigned long long a) { unsigned long long res; +#ifdef __x86_64__ + /* Using the A constraint is wrong, and increments are tested + elsewhere. */ + res = a + 1; +#else __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a)); +#endif return res; } +struct struct123 { + int a; + int b; +}; +struct struct1231 { + unsigned long addr; +}; + +unsigned long mconstraint_test(struct struct1231 *r) +{ + unsigned long ret; + unsigned int a[2]; + a[0] = 0; + __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1" + : "=&r" (ret), "=m" (a) + : "m" (*(struct struct123 *)r->addr)); + return ret + a[0]; +} + +#ifdef __x86_64__ +int fls64(unsigned long long x) +{ + int bitpos = -1; + asm("bsrq %1,%q0" + : "+r" (bitpos) + : "rm" (x)); + return bitpos + 1; +} +#endif + +void other_constraints_test(void) +{ + unsigned long ret; + int var; +#ifndef _WIN64 + __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var)); + printf ("oc1: %d\n", ret == (unsigned long)&var); +#endif +} + +#ifndef _WIN32 +/* Test global asm blocks playing with aliases. */ +void base_func(void) +{ + printf ("asmc: base\n"); +} + +extern void override_func1 (void); +extern void override_func2 (void); + +asm(".weak override_func1\n.set override_func1, base_func"); +asm(".set override_func1, base_func"); +asm(".set override_func2, base_func"); + +void override_func2 (void) +{ + printf ("asmc: override2\n"); +} + +/* This checks a construct used by the linux kernel to encode + references to strings by PC relative references. */ +extern int bug_table[] __attribute__((section("__bug_table"))); +char * get_asm_string (void) +{ + extern int some_symbol; + asm volatile (".globl some_symbol\n" + "jmp .+6\n" + "1:\n" + "some_symbol: .long 0\n" + ".pushsection __bug_table, \"a\"\n" + ".globl bug_table\n" + "bug_table:\n" + /* The first entry (1b-2b) is unused in this test, + but we include it to check if cross-section + PC-relative references work. */ + "2:\t.long 1b - 2b, %c0 - 2b\n" + ".popsection\n" : : "i" ("A string")); + char * str = ((char*)bug_table) + bug_table[1]; + return str; +} + +/* This checks another constructs with local labels. */ +extern unsigned char alld_stuff[]; +asm(".data\n" + ".byte 41\n" + "alld_stuff:\n" + "661:\n" + ".byte 42\n" + "662:\n" + ".pushsection .data.ignore\n" + ".long 661b - .\n" /* This reference to 661 generates an external sym + which shouldn't somehow overwrite the offset that's + already determined for it. */ + ".popsection\n" + ".byte 662b - 661b\n" /* So that this value is undeniably 1. */); + +void asm_local_label_diff (void) +{ + printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); +} + +/* This checks that static local variables are available from assembler. */ +void asm_local_statics (void) +{ + static int localint = 41; + asm("incl %0" : "+m" (localint)); + printf ("asm_local_statics: %d\n", localint); +} +#endif + +static unsigned int set; +void fancy_copy (unsigned *in, unsigned *out) +{ + asm volatile ("" : "=r" (*out) : "0" (*in)); +} + +void fancy_copy2 (unsigned *in, unsigned *out) +{ + asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); +} + +#if defined __x86_64__ && !defined _WIN64 +void clobber_r12(void) +{ + asm volatile("mov $1, %%r12" ::: "r12"); +} +#endif + +void test_high_clobbers(void) +{ +#if defined __x86_64__ && !defined _WIN64 + register long val asm("r12"); + long val2; + /* This tests if asm clobbers correctly save/restore callee saved + registers if they are clobbered and if it's the high 8 x86-64 + registers. This is fragile for GCC as the constraints do not + correctly capture the data flow, but good enough for us. */ + asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory"); + clobber_r12(); + asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory"); + printf("asmhc: 0x%x\n", val2); +#endif +} + +static long cpu_number; +void trace_console(long len, long len2) +{ +#ifdef __x86_64__ + /* This generated invalid code when the emission of the switch + table isn't disabled. The asms are necessary to show the bug, + normal statements don't work (they need to generate some code + even under nocode_wanted, which normal statements don't do, + but asms do). Also at least these number of cases is necessary + to generate enough "random" bytes. They ultimately are enough + to create invalid instruction patterns to which the first + skip-to-decision-table jump jumps. If decision table emission + is disabled all of this is no problem. + + It also is necessary that the switches are in a statement expression + (which has the property of not being enterable from outside. no + matter what). */ + if (0 + && + ({ + long pscr_ret__; + switch(len) { + case 4: + { + long pfo_ret__; + switch (len2) { + case 8: printf("bla"); pfo_ret__ = 42; break; + } + pscr_ret__ = pfo_ret__; + } + break; + case 8: + { + long pfo_ret__; + switch (len2) { + case 1:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; + case 2:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; + case 4:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; + case 8:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; + default: printf("impossible\n"); + } + pscr_ret__ = pfo_ret__; + }; + break; + } + pscr_ret__; + })) + { + printf("huh?\n"); + } +#endif +} + +void test_asm_dead_code(void) +{ + long rdi; + /* Try to make sure that xdi contains a zero, and hence will + lead to a segfault if the next asm is evaluated without + arguments being set up. */ + asm volatile ("" : "=D" (rdi) : "0" (0)); + (void)sizeof (({ + int var; + /* This shouldn't trigger a segfault, either the argument + registers need to be set up and the asm emitted despite + this being in an unevaluated context, or both the argument + setup _and_ the asm emission need to be suppressed. The latter + is better. Disabling asm code gen when suppression is on + also fixes the above trace_console bug, but that came earlier + than asm suppression. */ + asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory"); + var; + })); +} + void asm_test(void) { char buf[128]; - unsigned int val; + unsigned int val, val2; + struct struct123 s1; + struct struct1231 s2 = { (unsigned long)&s1 }; + /* Hide the outer base_func, but check later that the inline + asm block gets the outer one. */ + int base_func = 42; + void override_func3 (void); + unsigned long asmret; +#ifdef BOOL_ISOC99 + _Bool somebool; +#endif + register int regvar asm("%esi"); printf("inline asm:\n"); + + // parse 0x1E-1 as 3 tokens in asm mode + asm volatile ("mov $0x1E-1,%eax"); + /* test the no operand case */ asm volatile ("xorl %eax, %eax"); @@ -2131,10 +3373,19 @@ void asm_test(void) strncat1(buf, " worldXXXXX", 3); printf("%s\n", buf); + memcpy2(buf, "hello", 6); + strncat2(buf, " worldXXXXX", 3); + printf("%s\n", buf); + /* 'A' constraint test */ printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234)); printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff)); + s1.a = 42; + s1.b = 43; + printf("mconstraint: %d", mconstraint_test(&s2)); + printf(" %d %d\n", s1.a, s1.b); + other_constraints_test(); set = 0xff; sigdelset1(&set, 2); sigaddset1(&set, 16); @@ -2143,12 +3394,43 @@ void asm_test(void) goto label1; label2: __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc"); -#ifdef __GNUC__ // works strange with GCC 4.3 - set=0x1080fd; -#endif printf("set=0x%x\n", set); val = 0x01020304; printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val)); +#ifndef _WIN32 + override_func1(); + override_func2(); + /* The base_func ref from the following inline asm should find + the global one, not the local decl from this function. */ + asm volatile(".weak override_func3\n.set override_func3, base_func"); + override_func3(); + printf("asmstr: %s\n", get_asm_string()); + asm_local_label_diff(); + asm_local_statics(); +#endif + /* Check that we can also load structs of appropriate layout + into registers. */ + asm volatile("" : "=r" (asmret) : "0"(s2)); + if (asmret != s2.addr) + printf("asmstr: failed\n"); +#ifdef BOOL_ISOC99 + /* Check that the typesize correctly sets the register size to + 8 bit. */ + asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2)); + if (!somebool) + printf("asmbool: failed\n"); +#endif + val = 43; + fancy_copy (&val, &val2); + printf ("fancycpy(%d)=%d\n", val, val2); + val = 44; + fancy_copy2 (&val, &val2); + printf ("fancycpy2(%d)=%d\n", val, val2); + asm volatile ("mov $0x4243, %%esi" : "=r" (regvar)); + printf ("regvar=%x\n", regvar); + test_high_clobbers(); + trace_console(8, 8); + test_asm_dead_code(); return; label1: goto label2; @@ -2172,6 +3454,9 @@ int constant_p_var; void builtin_test(void) { + short s; + int i; + long long ll; #if GCC_MAJOR >= 3 COMPAT_TYPE(int, int); COMPAT_TYPE(int, unsigned int); @@ -2182,6 +3467,8 @@ void builtin_test(void) COMPAT_TYPE(int *, void *); COMPAT_TYPE(int *, const int *); COMPAT_TYPE(char *, unsigned char *); + COMPAT_TYPE(char *, signed char *); + COMPAT_TYPE(char *, char *); /* space is needed because tcc preprocessor introduces a space between each token */ COMPAT_TYPE(char * *, void *); #endif @@ -2189,8 +3476,79 @@ void builtin_test(void) printf("res = %d\n", __builtin_constant_p(1 + 2)); printf("res = %d\n", __builtin_constant_p(&constant_p_var)); printf("res = %d\n", __builtin_constant_p(constant_p_var)); -} - + printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var)); + s = 1; + ll = 2; + i = __builtin_choose_expr (1 != 0, ll, s); + printf("bce: %d\n", i); + i = __builtin_choose_expr (1 != 1, ll, s); + printf("bce: %d\n", i); + i = sizeof (__builtin_choose_expr (1, ll, s)); + printf("bce: %d\n", i); + i = sizeof (__builtin_choose_expr (0, ll, s)); + printf("bce: %d\n", i); + + //printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); +} + +#ifndef _WIN32 +extern int __attribute__((weak)) weak_f1(void); +extern int __attribute__((weak)) weak_f2(void); +extern int weak_f3(void); +extern int __attribute__((weak)) weak_v1; +extern int __attribute__((weak)) weak_v2; +extern int weak_v3; + +extern int (*weak_fpa)() __attribute__((weak)); +extern int __attribute__((weak)) (*weak_fpb)(); +extern __attribute__((weak)) int (*weak_fpc)(); + +extern int weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak)); +extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x") ; +extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak)); +extern int weak_asm_v1 asm("weak_asm_v1x") __attribute((weak)); +extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ; +extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak)); + +static const size_t dummy = 0; +extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy"))); +extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2; +extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3; + +int some_lib_func(void); +int dummy_impl_of_slf(void) { return 444; } +int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf"))); + +int weak_toolate() __attribute__((weak)); +int weak_toolate() { return 0; } + +void __attribute__((weak)) weak_test(void) +{ + printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123); + printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123); + printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123); + printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123); + printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123); + printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123); + + printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123); + printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123); + printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123); + + printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL); + printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL); + printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL); + printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL); + printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL); + printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL); + printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0); +} + +int __attribute__((weak)) weak_f2() { return 222; } +int __attribute__((weak)) weak_f3() { return 333; } +int __attribute__((weak)) weak_v2 = 222; +int __attribute__((weak)) weak_v3 = 333; +#endif void const_func(const int a) { @@ -2200,3 +3558,256 @@ void const_warn_test(void) { const_func(1); } + +struct condstruct { + int i; +}; + +int getme (struct condstruct *s, int i) +{ + int i1 = (i == 0 ? 0 : s)->i; + int i2 = (i == 0 ? s : 0)->i; + int i3 = (i == 0 ? (void*)0 : s)->i; + int i4 = (i == 0 ? s : (void*)0)->i; + return i1 + i2 + i3 + i4; +} + +struct global_data +{ + int a[40]; + int *b[40]; +}; + +struct global_data global_data; + +int global_data_getstuff (int *, int); + +void global_data_callit (int i) +{ + *global_data.b[i] = global_data_getstuff (global_data.b[i], 1); +} + +int global_data_getstuff (int *p, int i) +{ + return *p + i; +} + +void global_data_test (void) +{ + global_data.a[0] = 42; + global_data.b[0] = &global_data.a[0]; + global_data_callit (0); + printf ("%d\n", global_data.a[0]); +} + +struct cmpcmpS +{ + unsigned char fill : 3; + unsigned char b1 : 1; + unsigned char b2 : 1; + unsigned char fill2 : 3; +}; + +int glob1, glob2, glob3; + +void compare_comparisons (struct cmpcmpS *s) +{ + if (s->b1 != (glob1 == glob2) + || (s->b2 != (glob1 == glob3))) + printf ("comparing comparisons broken\n"); +} + +void cmp_comparison_test(void) +{ + struct cmpcmpS s; + s.b1 = 1; + glob1 = 42; glob2 = 42; + s.b2 = 0; + glob3 = 43; + compare_comparisons (&s); +} + +int fcompare (double a, double b, int code) +{ + switch (code) { + case 0: return a == b; + case 1: return a != b; + case 2: return a < b; + case 3: return a >= b; + case 4: return a > b; + case 5: return a <= b; + } +} + +void math_cmp_test(void) +{ + double nan = 0.0/0.0; + double one = 1.0; + double two = 2.0; + int comp = 0; +#define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part) + + /* This asserts that "a op b" is _not_ true, but "a iop b" is true. + And it does this in various ways so that all code generation paths + are checked (generating inverted tests, or non-inverted tests, or + producing a 0/1 value without jumps (that's done in the fcompare + function). */ +#define FCMP(a,b,op,iop,code) \ + if (fcompare (a,b,code)) \ + bug (a,b,op,iop,1); \ + if (a op b) \ + bug (a,b,op,iop,2); \ + if (a iop b) \ + ; \ + else \ + bug (a,b,op,iop,3); \ + if ((a op b) || comp) \ + bug (a,b,op,iop,4); \ + if ((a iop b) || comp) \ + ; \ + else \ + bug (a,b,op,iop,5); + + /* Equality tests. */ + FCMP(nan, nan, ==, !=, 0); + FCMP(one, two, ==, !=, 0); + FCMP(one, one, !=, ==, 1); + /* Non-equality is a bit special. */ + if (!fcompare (nan, nan, 1)) + bug (nan, nan, !=, ==, 6); + + /* Relational tests on numbers. */ + FCMP(two, one, <, >=, 2); + FCMP(one, two, >=, <, 3); + FCMP(one, two, >, <=, 4); + FCMP(two, one, <=, >, 5); + + /* Relational tests on NaNs. Note that the inverse op here is + always !=, there's no operator in C that is equivalent to !(a < b), + when NaNs are involved, same for the other relational ops. */ + FCMP(nan, nan, <, !=, 2); + FCMP(nan, nan, >=, !=, 3); + FCMP(nan, nan, >, !=, 4); + FCMP(nan, nan, <=, !=, 5); +} + +double get100 () { return 100.0; } + +void callsave_test(void) +{ +#if defined __i386__ || defined __x86_64__ || defined __arm__ + int i, s; double *d; double t; + s = sizeof (double); + printf ("callsavetest: %d\n", s); + d = alloca (sizeof(double)); + d[0] = 10.0; + /* x86-64 had a bug were the next call to get100 would evict + the lvalue &d[0] as VT_LLOCAL, and the reload would be done + in int type, not pointer type. When alloca returns a pointer + with the high 32 bit set (which is likely on x86-64) the access + generates a segfault. */ + i = d[0] > get100 (); + printf ("%d\n", i); +#endif +} + + +void bfa3(ptrdiff_t str_offset) +{ + printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset); +} +void bfa2(ptrdiff_t str_offset) +{ + printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset); + bfa3(str_offset); +} +void bfa1(ptrdiff_t str_offset) +{ + printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset); + bfa2(str_offset); +} + +void builtin_frame_address_test(void) +{ +/* builtin_frame_address fails on ARM with gcc which make test3 fail */ +#ifndef __arm__ + char str[] = "__builtin_frame_address"; + char *fp0 = __builtin_frame_address(0); + + printf("str: %s\n", str); + bfa1(str-fp0); +#endif +} + +char via_volatile (char i) +{ + char volatile vi; + vi = i; + return vi; +} + +struct __attribute__((__packed__)) Spacked { + char a; + short b; + int c; +}; +struct Spacked spacked; +typedef struct __attribute__((__packed__)) { + char a; + short b; + int c; +} Spacked2; +Spacked2 spacked2; +typedef struct Spacked3_s { + char a; + short b; + int c; +} __attribute__((__packed__)) Spacked3; +Spacked3 spacked3; +struct gate_struct64 { + unsigned short offset_low; + unsigned short segment; + unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; + unsigned short offset_middle; + unsigned offset_high; + unsigned zero1; +} __attribute__((packed)); +typedef struct gate_struct64 gate_desc; +gate_desc a_gate_desc; +void attrib_test(void) +{ +#ifndef _WIN32 + printf("attr: %d %d %d %d\n", sizeof(struct Spacked), + sizeof(spacked), sizeof(Spacked2), sizeof(spacked2)); + printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3)); + printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc)); +#endif +} +extern __attribute__((__unused__)) char * __attribute__((__unused__)) * +strange_attrib_placement (void); + +void * __attribute__((__unused__)) get_void_ptr (void *a) +{ + return a; +} + +/* This part checks for a bug in TOK_GET (used for inline expansion), + where the large long long constant left the the high bits set for + the integer constant token. */ +static inline +int __get_order(unsigned long long size) +{ + int order; + size -= 0xffff880000000000ULL; // this const left high bits set in the token + { + struct S { int i : 1; } s; // constructed for this '1' + } + order = size; + return order; +} + +/* This just forces the above inline function to be actually emitted. */ +int force_get_order(unsigned long s) +{ + return __get_order(s); +} diff --git a/tinyc/tests/tcctest.h b/tinyc/tests/tcctest.h new file mode 100644 index 000000000..b301c7c16 --- /dev/null +++ b/tinyc/tests/tcctest.h @@ -0,0 +1,9 @@ +static inline const char *get_basefile_from_header(void) +{ + return __BASE_FILE__; +} + +static inline const char *get_file_from_header(void) +{ + return __FILE__; +} diff --git a/tinyc/tests/testfp.c b/tinyc/tests/testfp.c new file mode 100644 index 000000000..63342b422 --- /dev/null +++ b/tinyc/tests/testfp.c @@ -0,0 +1,510 @@ +/* + * Test 128-bit floating-point arithmetic on arm64: + * build with two different compilers and compare the output. + * + * Copyright (c) 2015 Edmund Grimley Evans + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define check(x) ((x) ? (void)0 : check_fail(#x, __FILE__, __LINE__)) + +void check_fail(const char *assertion, const char *file, unsigned int line) +{ + printf("%s:%d: Check (%s) failed.", file, line, assertion); + exit(1); +} + +typedef struct { + unsigned long long x0, x1; +} u128_t; + +float copy_fi(uint32_t x) +{ + float f; + memcpy(&f, &x, 4); + return f; +} + +double copy_di(uint64_t x) +{ + double f; + memcpy(&f, &x, 8); + return f; +} + +long double copy_ldi(u128_t x) +{ + long double f; + memcpy(&f, &x, 16); + return f; +} + +uint32_t copy_if(float f) +{ + uint32_t x; + memcpy(&x, &f, 4); + return x; +} + +uint64_t copy_id(double f) +{ + uint64_t x; + memcpy(&x, &f, 8); + return x; +} + +u128_t copy_ild(long double f) +{ + u128_t x; + memcpy(&x, &f, 16); + return x; +} + +long double make(int sgn, int exp, uint64_t high, uint64_t low) +{ + u128_t x = { low, + (0x0000ffffffffffff & high) | + (0x7fff000000000000 & (uint64_t)exp << 48) | + (0x8000000000000000 & (uint64_t)sgn << 63) }; + return copy_ldi(x); +} + +void cmp(long double a, long double b) +{ + u128_t ax = copy_ild(a); + u128_t bx = copy_ild(b); + int eq = (a == b); + int ne = (a != b); + int lt = (a < b); + int le = (a <= b); + int gt = (a > b); + int ge = (a >= b); + + check(eq == 0 || eq == 1); + check(lt == 0 || lt == 1); + check(gt == 0 || gt == 1); + check(ne == !eq && le == (lt | eq) && ge == (gt | eq)); + check(eq + lt + gt < 2); + + printf("cmp %016llx%016llx %016llx%016llx %d %d %d\n", + ax.x1, ax.x0, bx.x1, bx.x0, lt, eq, gt); +} + +void cmps(void) +{ + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + cmp(make(i, 0, 0, 0), make(j, 0, 0, 0)); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 64; j++) { + long double f1 = make(i, 32767, (uint64_t)1 << j, 0); + long double f2 = make(i, 32767, 0, (uint64_t)1 << j); + cmp(f1, 0); + cmp(f2, 0); + cmp(0, f1); + cmp(0, f2); + } + } + + for (i = 0; i < 6; i++) + for (j = 0; j < 6; j++) + cmp(make(i & 1, i >> 1, 0, 0), + make(j & 1, j >> 1, 0, 0)); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + int a, b; + for (a = 0; a < 2; a++) { + for (b = 0; b < 2; b++) { + cmp(make(i, j, a, b), make(i, j, 0, 0)); + cmp(make(i, j, 0, 0), make(i, j, a, b)); + } + } + } + } +} + +void xop(const char *name, long double a, long double b, long double c) +{ + u128_t ax = copy_ild(a); + u128_t bx = copy_ild(b); + u128_t cx = copy_ild(c); + printf("%s %016llx%016llx %016llx%016llx %016llx%016llx\n", + name, ax.x1, ax.x0, bx.x1, bx.x0, cx.x1, cx.x0); +} + +void fadd(long double a, long double b) +{ + xop("add", a, b, a + b); +} + +void fsub(long double a, long double b) +{ + xop("sub", a, b, a - b); +} + +void fmul(long double a, long double b) +{ + xop("mul", a, b, a * b); +} + +void fdiv(long double a, long double b) +{ + xop("div", a, b, a / b); +} + +void nanz(void) +{ + // Check NaNs: + { + long double x[7]; + int i, j, n = 0; + x[n++] = make(0, 32000, 0x95132b76effc, 0xd79035214b4f8d53); + x[n++] = make(1, 32001, 0xbe71d7a51587, 0x30601c6815d6c3ac); + x[n++] = make(0, 32767, 0, 1); + x[n++] = make(0, 32767, (uint64_t)1 << 46, 0); + x[n++] = make(1, 32767, (uint64_t)1 << 47, 0); + x[n++] = make(1, 32767, 0x7596c7099ad5, 0xe25fed2c58f73fc9); + x[n++] = make(0, 32767, 0x835d143360f9, 0x5e315efb35630666); + check(n == sizeof(x) / sizeof(*x)); + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + fadd(x[i], x[j]); + fsub(x[i], x[j]); + fmul(x[i], x[j]); + fdiv(x[i], x[j]); + } + } + } + + // Check infinities and zeroes: + { + long double x[6]; + int i, j, n = 0; + x[n++] = make(1, 32000, 0x62acda85f700, 0x47b6c9f35edc4044); + x[n++] = make(0, 32001, 0x94b7abf55af7, 0x9f425fe354428e19); + x[n++] = make(0, 32767, 0, 0); + x[n++] = make(1, 32767, 0, 0); + x[n++] = make(0, 0, 0, 0); + x[n++] = make(1, 0, 0, 0); + check(n == sizeof(x) / sizeof(*x)); + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + fadd(x[i], x[j]); + fsub(x[i], x[j]); + fmul(x[i], x[j]); + fdiv(x[i], x[j]); + } + } + } +} + +void adds(void) +{ + // Check shifting and add/sub: + { + int i; + for (i = -130; i <= 130; i++) { + int s1 = (uint32_t)i % 3 < 1; + int s2 = (uint32_t)i % 5 < 2; + fadd(make(s1, 16384 , 0x502c065e4f71a65d, 0xd2f9bdb031f4f031), + make(s2, 16384 + i, 0xae267395a9bc1033, 0xb56b5800da1ba448)); + } + } + + // Check normalisation: + { + uint64_t a0 = 0xc6bab0a6afbef5ed; + uint64_t a1 = 0x4f84136c4a2e9b52; + int ee[] = { 0, 1, 10000 }; + int e, i; + for (e = 0; e < sizeof(ee) / sizeof(*ee); e++) { + int exp = ee[e]; + fsub(make(0, exp, a1, a0), make(0, 0, 0, 0)); + for (i = 63; i >= 0; i--) + fsub(make(0, exp, a1 | (uint64_t)1 << i >> 1, a0), + make(0, exp, a1 >> i << i, 0)); + for (i = 63; i >=0; i--) + fsub(make(0, exp, a1, a0 | (uint64_t)1 << i >> 1), + make(0, exp, a1, a0 >> i << i)); + } + } + + // Carry/overflow from rounding: + { + fadd(make(0, 114, -1, -1), make(0, 1, 0, 0)); + fadd(make(0, 32766, -1, -1), make(0, 32653, 0, 0)); + fsub(make(1, 32766, -1, -1), make(0, 32653, 0, 0)); + } +} + +void muls(void) +{ + int i, j; + + { + long double max = make(0, 32766, -1, -1); + long double min = make(0, 0, 0, 1); + fmul(max, max); + fmul(max, min); + fmul(min, min); + } + + for (i = 117; i > 0; i--) + fmul(make(0, 16268, 0x643dcea76edc, 0xe0877a598403627a), + make(i & 1, i, 0, 0)); + + fmul(make(0, 16383, -1, -3), make(0, 16383, 0, 1)); + // Round to next exponent: + fmul(make(0, 16383, -1, -2), make(0, 16383, 0, 1)); + // Round from subnormal to normal: + fmul(make(0, 1, -1, -1), make(0, 16382, 0, 0)); + + for (i = 0; i < 2; i++) + for (j = 0; j < 112; j++) + fmul(make(0, 16383, (uint64_t)1 << i, 0), + make(0, 16383, + j < 64 ? 0 : (uint64_t)1 << (j - 64), + j < 64 ? (uint64_t)1 << j : 0)); +} + +void divs(void) +{ + int i; + + { + long double max = make(0, 32766, -1, -1); + long double min = make(0, 0, 0, 1); + fdiv(max, max); + fdiv(max, min); + fdiv(min, max); + fdiv(min, min); + } + + for (i = 0; i < 64; i++) + fdiv(make(0, 16383, -1, -1), make(0, 16383, -1, -(uint64_t)1 << i)); + for (i = 0; i < 48; i++) + fdiv(make(0, 16383, -1, -1), make(0, 16383, -(uint64_t)1 << i, 0)); +} + +void cvtlsw(int32_t a) +{ + long double f = a; + u128_t x = copy_ild(f); + printf("cvtlsw %08lx %016llx%016llx\n", (long)(uint32_t)a, x.x1, x.x0); +} + +void cvtlsx(int64_t a) +{ + long double f = a; + u128_t x = copy_ild(f); + printf("cvtlsx %016llx %016llx%016llx\n", + (long long)(uint64_t)a, x.x1, x.x0); +} + +void cvtluw(uint32_t a) +{ + long double f = a; + u128_t x = copy_ild(f); + printf("cvtluw %08lx %016llx%016llx\n", (long)a, x.x1, x.x0); +} + +void cvtlux(uint64_t a) +{ + long double f = a; + u128_t x = copy_ild(f); + printf("cvtlux %016llx %016llx%016llx\n", (long long)a, x.x1, x.x0); +} + +void cvtil(long double a) +{ + u128_t x = copy_ild(a); + int32_t b1 = a; + int64_t b2 = a; + uint32_t b3 = a; + uint64_t b4 = a; + printf("cvtswl %016llx%016llx %08lx\n", + x.x1, x.x0, (long)(uint32_t)b1); + printf("cvtsxl %016llx%016llx %016llx\n", + x.x1, x.x0, (long long)(uint64_t)b2); + printf("cvtuwl %016llx%016llx %08lx\n", + x.x1, x.x0, (long)b3); + printf("cvtuxl %016llx%016llx %016llx\n", + x.x1, x.x0, (long long)b4); +} + +void cvtlf(float a) +{ + uint32_t ax = copy_if(a); + long double b = a; + u128_t bx = copy_ild(b); + printf("cvtlf %08lx %016llx%016llx\n", (long)ax, bx.x1, bx.x0); +} + +void cvtld(double a) +{ + uint64_t ax = copy_id(a); + long double b = a; + u128_t bx = copy_ild(b); + printf("cvtld %016llx %016llx%016llx\n", (long long)ax, bx.x1, bx.x0); +} + +void cvtfl(long double a) +{ + u128_t ax = copy_ild(a); + float b = a; + uint32_t bx = copy_if(b); + printf("cvtfl %016llx%016llx %08lx\n", ax.x1, ax.x0, (long)bx); +} + +void cvtdl(long double a) +{ + u128_t ax = copy_ild(a); + double b = a; + uint64_t bx = copy_id(b); + printf("cvtdl %016llx%016llx %016llx\n", ax.x1, ax.x0, (long long)bx); +} + +void cvts(void) +{ + int i, j; + + { + uint32_t x = 0xad040c5b; + cvtlsw(0); + for (i = 0; i < 31; i++) + cvtlsw(x >> (31 - i)); + for (i = 0; i < 31; i++) + cvtlsw(-(x >> (31 - i))); + cvtlsw(0x80000000); + } + { + uint64_t x = 0xb630a248cad9afd2; + cvtlsx(0); + for (i = 0; i < 63; i++) + cvtlsx(x >> (63 - i)); + for (i = 0; i < 63; i++) + cvtlsx(-(x >> (63 - i))); + cvtlsx(0x8000000000000000); + } + { + uint32_t x = 0xad040c5b; + cvtluw(0); + for (i = 0; i < 32; i++) + cvtluw(x >> (31 - i)); + } + { + uint64_t x = 0xb630a248cad9afd2; + cvtlux(0); + for (i = 0; i < 64; i++) + cvtlux(x >> (63 - i)); + } + + for (i = 0; i < 2; i++) { + cvtil(make(i, 32767, 0, 1)); + cvtil(make(i, 32767, (uint64_t)1 << 47, 0)); + cvtil(make(i, 32767, 123, 456)); + cvtil(make(i, 32767, 0, 0)); + cvtil(make(i, 16382, -1, -1)); + cvtil(make(i, 16383, -1, -1)); + cvtil(make(i, 16384, 0x7fffffffffff, -1)); + cvtil(make(i, 16384, 0x800000000000, 0)); + for (j = 0; j < 68; j++) + cvtil(make(i, 16381 + j, 0xd4822c0a10ec, 0x1fe2f8b2669f5c9d)); + } + + cvtlf(copy_fi(0x00000000)); + cvtlf(copy_fi(0x456789ab)); + cvtlf(copy_fi(0x7f800000)); + cvtlf(copy_fi(0x7f923456)); + cvtlf(copy_fi(0x7fdbcdef)); + cvtlf(copy_fi(0x80000000)); + cvtlf(copy_fi(0xabcdef12)); + cvtlf(copy_fi(0xff800000)); + cvtlf(copy_fi(0xff923456)); + cvtlf(copy_fi(0xffdbcdef)); + + cvtld(copy_di(0x0000000000000000)); + cvtld(copy_di(0x456789abcdef0123)); + cvtld(copy_di(0x7ff0000000000000)); + cvtld(copy_di(0x7ff123456789abcd)); + cvtld(copy_di(0x7ffabcdef1234567)); + cvtld(copy_di(0x8000000000000000)); + cvtld(copy_di(0xcdef123456789abc)); + cvtld(copy_di(0xfff0000000000000)); + cvtld(copy_di(0xfff123456789abcd)); + cvtld(copy_di(0xfffabcdef1234567)); + + for (i = 0; i < 2; i++) { \ + cvtfl(make(i, 0, 0, 0)); + cvtfl(make(i, 16232, -1, -1)); + cvtfl(make(i, 16233, 0, 0)); + cvtfl(make(i, 16233, 0, 1)); + cvtfl(make(i, 16383, 0xab0ffd000000, 0)); + cvtfl(make(i, 16383, 0xab0ffd000001, 0)); + cvtfl(make(i, 16383, 0xab0ffeffffff, 0)); + cvtfl(make(i, 16383, 0xab0fff000000, 0)); + cvtfl(make(i, 16383, 0xab0fff000001, 0)); + cvtfl(make(i, 16510, 0xfffffeffffff, -1)); + cvtfl(make(i, 16510, 0xffffff000000, 0)); + cvtfl(make(i, 16511, 0, 0)); + cvtfl(make(i, 32767, 0, 0)); + cvtfl(make(i, 32767, 0, 1)); + cvtfl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5)); + cvtfl(make(i, 32767, 0x800000000000, 1)); + cvtfl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099)); + } + + for (i = 0; i < 2; i++) { + cvtdl(make(i, 0, 0, 0)); + cvtdl(make(i, 15307, -1, -1)); + cvtdl(make(i, 15308, 0, 0)); + cvtdl(make(i, 15308, 0, 1)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000000)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000001)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf7ffffffffffffff)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000000)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000001)); + cvtdl(make(i, 17406, 0xffffffffffff, 0xf7ffffffffffffff)); + cvtdl(make(i, 17406, 0xffffffffffff, 0xf800000000000000)); + cvtdl(make(i, 17407, 0, 0)); + cvtdl(make(i, 32767, 0, 0)); + cvtdl(make(i, 32767, 0, 1)); + cvtdl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5)); + cvtdl(make(i, 32767, 0x800000000000, 1)); + cvtdl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099)); + } +} + +void tests(void) +{ + cmps(); + nanz(); + adds(); + muls(); + divs(); + cvts(); +} + +int main() +{ +#ifdef __aarch64__ + tests(); +#else + printf("This test program is intended for a little-endian architecture\n" + "with an IEEE-standard 128-bit long double.\n"); +#endif + return 0; +} diff --git a/tinyc/tests/tests2/00_assignment.c b/tinyc/tests/tests2/00_assignment.c new file mode 100644 index 000000000..c96109fdc --- /dev/null +++ b/tinyc/tests/tests2/00_assignment.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + int a; + a = 42; + printf("%d\n", a); + + int b = 64; + printf("%d\n", b); + + int c = 12, d = 34; + printf("%d, %d\n", c, d); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/00_assignment.expect b/tinyc/tests/tests2/00_assignment.expect new file mode 100644 index 000000000..d4407f3fe --- /dev/null +++ b/tinyc/tests/tests2/00_assignment.expect @@ -0,0 +1,3 @@ +42 +64 +12, 34 diff --git a/tinyc/tests/tests2/01_comment.c b/tinyc/tests/tests2/01_comment.c new file mode 100644 index 000000000..a2e6bc63d --- /dev/null +++ b/tinyc/tests/tests2/01_comment.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main() +{ + printf("Hello\n"); + printf("Hello\n"); /* this is a comment */ printf("Hello\n"); + printf("Hello\n"); + // this is also a comment sayhello(); + printf("Hello\n"); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/01_comment.expect b/tinyc/tests/tests2/01_comment.expect new file mode 100644 index 000000000..b1387ad09 --- /dev/null +++ b/tinyc/tests/tests2/01_comment.expect @@ -0,0 +1,5 @@ +Hello +Hello +Hello +Hello +Hello diff --git a/tinyc/tests/tests2/02_printf.c b/tinyc/tests/tests2/02_printf.c new file mode 100644 index 000000000..4c34dd874 --- /dev/null +++ b/tinyc/tests/tests2/02_printf.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + printf("Hello world\n"); + + int Count; + for (Count = -5; Count <= 5; Count++) + printf("Count = %d\n", Count); + + printf("String 'hello', 'there' is '%s', '%s'\n", "hello", "there"); + printf("Character 'A' is '%c'\n", 65); + printf("Character 'a' is '%c'\n", 'a'); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/02_printf.expect b/tinyc/tests/tests2/02_printf.expect new file mode 100644 index 000000000..f67a0f6e3 --- /dev/null +++ b/tinyc/tests/tests2/02_printf.expect @@ -0,0 +1,15 @@ +Hello world +Count = -5 +Count = -4 +Count = -3 +Count = -2 +Count = -1 +Count = 0 +Count = 1 +Count = 2 +Count = 3 +Count = 4 +Count = 5 +String 'hello', 'there' is 'hello', 'there' +Character 'A' is 'A' +Character 'a' is 'a' diff --git a/tinyc/tests/tests2/03_struct.c b/tinyc/tests/tests2/03_struct.c new file mode 100644 index 000000000..c5d48c5ab --- /dev/null +++ b/tinyc/tests/tests2/03_struct.c @@ -0,0 +1,31 @@ +#include <stdio.h> + +struct fred +{ + int boris; + int natasha; +}; + +int main() +{ + struct fred bloggs; + + bloggs.boris = 12; + bloggs.natasha = 34; + + printf("%d\n", bloggs.boris); + printf("%d\n", bloggs.natasha); + + struct fred jones[2]; + jones[0].boris = 12; + jones[0].natasha = 34; + jones[1].boris = 56; + jones[1].natasha = 78; + + printf("%d\n", jones[0].boris); + printf("%d\n", jones[0].natasha); + printf("%d\n", jones[1].boris); + printf("%d\n", jones[1].natasha); + + return 0; +} diff --git a/tinyc/tests/tests2/03_struct.expect b/tinyc/tests/tests2/03_struct.expect new file mode 100644 index 000000000..ecbf58937 --- /dev/null +++ b/tinyc/tests/tests2/03_struct.expect @@ -0,0 +1,6 @@ +12 +34 +12 +34 +56 +78 diff --git a/tinyc/tests/tests2/04_for.c b/tinyc/tests/tests2/04_for.c new file mode 100644 index 000000000..312fed855 --- /dev/null +++ b/tinyc/tests/tests2/04_for.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +int main() +{ + int Count; + + for (Count = 1; Count <= 10; Count++) + { + printf("%d\n", Count); + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/04_for.expect b/tinyc/tests/tests2/04_for.expect new file mode 100644 index 000000000..f00c965d8 --- /dev/null +++ b/tinyc/tests/tests2/04_for.expect @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/tinyc/tests/tests2/05_array.c b/tinyc/tests/tests2/05_array.c new file mode 100644 index 000000000..c218f3163 --- /dev/null +++ b/tinyc/tests/tests2/05_array.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int Count; + int Array[10]; + + for (Count = 1; Count <= 10; Count++) + { + Array[Count-1] = Count * Count; + } + + for (Count = 0; Count < 10; Count++) + { + printf("%d\n", Array[Count]); + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/05_array.expect b/tinyc/tests/tests2/05_array.expect new file mode 100644 index 000000000..bc7257c0f --- /dev/null +++ b/tinyc/tests/tests2/05_array.expect @@ -0,0 +1,10 @@ +1 +4 +9 +16 +25 +36 +49 +64 +81 +100 diff --git a/tinyc/tests/tests2/06_case.c b/tinyc/tests/tests2/06_case.c new file mode 100644 index 000000000..c0191e2b0 --- /dev/null +++ b/tinyc/tests/tests2/06_case.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +int main() +{ + int Count; + + for (Count = 0; Count < 4; Count++) + { + printf("%d\n", Count); + switch (Count) + { + case 1: + printf("%d\n", 1); + break; + + case 2: + printf("%d\n", 2); + break; + + default: + printf("%d\n", 0); + break; + } + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/06_case.expect b/tinyc/tests/tests2/06_case.expect new file mode 100644 index 000000000..fab2c201a --- /dev/null +++ b/tinyc/tests/tests2/06_case.expect @@ -0,0 +1,8 @@ +0 +0 +1 +1 +2 +2 +3 +0 diff --git a/tinyc/tests/tests2/07_function.c b/tinyc/tests/tests2/07_function.c new file mode 100644 index 000000000..0477ce14e --- /dev/null +++ b/tinyc/tests/tests2/07_function.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +int myfunc(int x) +{ + return x * x; +} + +void vfunc(int a) +{ + printf("a=%d\n", a); +} + +void qfunc() +{ + printf("qfunc()\n"); +} + +int main() +{ + printf("%d\n", myfunc(3)); + printf("%d\n", myfunc(4)); + + vfunc(1234); + + qfunc(); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/07_function.expect b/tinyc/tests/tests2/07_function.expect new file mode 100644 index 000000000..8ffb0a702 --- /dev/null +++ b/tinyc/tests/tests2/07_function.expect @@ -0,0 +1,4 @@ +9 +16 +a=1234 +qfunc() diff --git a/tinyc/tests/tests2/08_while.c b/tinyc/tests/tests2/08_while.c new file mode 100644 index 000000000..602ffc737 --- /dev/null +++ b/tinyc/tests/tests2/08_while.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int p; + int t; + + a = 1; + p = 0; + t = 0; + + while (a < 100) + { + printf("%d\n", a); + t = a; + a = t + p; + p = t; + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/08_while.expect b/tinyc/tests/tests2/08_while.expect new file mode 100644 index 000000000..702d4c0fc --- /dev/null +++ b/tinyc/tests/tests2/08_while.expect @@ -0,0 +1,11 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 diff --git a/tinyc/tests/tests2/09_do_while.c b/tinyc/tests/tests2/09_do_while.c new file mode 100644 index 000000000..1d3315d3a --- /dev/null +++ b/tinyc/tests/tests2/09_do_while.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int p; + int t; + + a = 1; + p = 0; + t = 0; + + do + { + printf("%d\n", a); + t = a; + a = t + p; + p = t; + } while (a < 100); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/09_do_while.expect b/tinyc/tests/tests2/09_do_while.expect new file mode 100644 index 000000000..702d4c0fc --- /dev/null +++ b/tinyc/tests/tests2/09_do_while.expect @@ -0,0 +1,11 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 diff --git a/tinyc/tests/tests2/10_pointer.c b/tinyc/tests/tests2/10_pointer.c new file mode 100644 index 000000000..0177f4d81 --- /dev/null +++ b/tinyc/tests/tests2/10_pointer.c @@ -0,0 +1,40 @@ +#include <stdio.h> + +struct ziggy +{ + int a; + int b; + int c; +} bolshevic; + +int main() +{ + int a; + int *b; + int c; + + a = 42; + b = &a; + printf("a = %d\n", *b); + + bolshevic.a = 12; + bolshevic.b = 34; + bolshevic.c = 56; + + printf("bolshevic.a = %d\n", bolshevic.a); + printf("bolshevic.b = %d\n", bolshevic.b); + printf("bolshevic.c = %d\n", bolshevic.c); + + struct ziggy *tsar = &bolshevic; + + printf("tsar->a = %d\n", tsar->a); + printf("tsar->b = %d\n", tsar->b); + printf("tsar->c = %d\n", tsar->c); + + b = &(bolshevic.b); + printf("bolshevic.b = %d\n", *b); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/10_pointer.expect b/tinyc/tests/tests2/10_pointer.expect new file mode 100644 index 000000000..1e3c473f0 --- /dev/null +++ b/tinyc/tests/tests2/10_pointer.expect @@ -0,0 +1,8 @@ +a = 42 +bolshevic.a = 12 +bolshevic.b = 34 +bolshevic.c = 56 +tsar->a = 12 +tsar->b = 34 +tsar->c = 56 +bolshevic.b = 34 diff --git a/tinyc/tests/tests2/11_precedence.c b/tinyc/tests/tests2/11_precedence.c new file mode 100644 index 000000000..db2049dfe --- /dev/null +++ b/tinyc/tests/tests2/11_precedence.c @@ -0,0 +1,40 @@ +#include <stdio.h> + +int main() +{ + int a; + int b; + int c; + int d; + int e; + int f; + int x; + int y; + + a = 12; + b = 34; + c = 56; + d = 78; + e = 0; + f = 1; + + printf("%d\n", c + d); + printf("%d\n", (y = c + d)); + printf("%d\n", e || e && f); + printf("%d\n", e || f && f); + printf("%d\n", e && e || f); + printf("%d\n", e && f || f); + printf("%d\n", a && f | f); + printf("%d\n", a | b ^ c & d); + printf("%d, %d\n", a == a, a == b); + printf("%d, %d\n", a != a, a != b); + printf("%d\n", a != b && c != d); + printf("%d\n", a + b * c / f); + printf("%d\n", a + b * c / f); + printf("%d\n", (4 << 4)); + printf("%d\n", (64 >> 4)); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/11_precedence.expect b/tinyc/tests/tests2/11_precedence.expect new file mode 100644 index 000000000..b6923966e --- /dev/null +++ b/tinyc/tests/tests2/11_precedence.expect @@ -0,0 +1,15 @@ +134 +134 +0 +1 +1 +1 +1 +46 +1, 0 +0, 1 +1 +1916 +1916 +64 +4 diff --git a/tinyc/tests/tests2/12_hashdefine.c b/tinyc/tests/tests2/12_hashdefine.c new file mode 100644 index 000000000..5c521e02b --- /dev/null +++ b/tinyc/tests/tests2/12_hashdefine.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +#define FRED 12 +#define BLOGGS(x) (12*(x)) + +int main() +{ + printf("%d\n", FRED); + printf("%d, %d, %d\n", BLOGGS(1), BLOGGS(2), BLOGGS(3)); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/12_hashdefine.expect b/tinyc/tests/tests2/12_hashdefine.expect new file mode 100644 index 000000000..99f2ed5d9 --- /dev/null +++ b/tinyc/tests/tests2/12_hashdefine.expect @@ -0,0 +1,2 @@ +12 +12, 24, 36 diff --git a/tinyc/tests/tests2/13_integer_literals.c b/tinyc/tests/tests2/13_integer_literals.c new file mode 100644 index 000000000..7cee98b1f --- /dev/null +++ b/tinyc/tests/tests2/13_integer_literals.c @@ -0,0 +1,20 @@ +#include <stdio.h> + +int main() +{ + int a = 24680; + int b = 01234567; + int c = 0x2468ac; + int d = 0x2468AC; + int e = 0b010101010101; + + printf("%d\n", a); + printf("%d\n", b); + printf("%d\n", c); + printf("%d\n", d); + printf("%d\n", e); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/13_integer_literals.expect b/tinyc/tests/tests2/13_integer_literals.expect new file mode 100644 index 000000000..f5aca06f7 --- /dev/null +++ b/tinyc/tests/tests2/13_integer_literals.expect @@ -0,0 +1,5 @@ +24680 +342391 +2386092 +2386092 +1365 diff --git a/tinyc/tests/tests2/14_if.c b/tinyc/tests/tests2/14_if.c new file mode 100644 index 000000000..2bd255051 --- /dev/null +++ b/tinyc/tests/tests2/14_if.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int a = 1; + + if (a) + printf("a is true\n"); + else + printf("a is false\n"); + + int b = 0; + if (b) + printf("b is true\n"); + else + printf("b is false\n"); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinyc/tests/tests2/14_if.expect b/tinyc/tests/tests2/14_if.expect new file mode 100644 index 000000000..c32c4159c --- /dev/null +++ b/tinyc/tests/tests2/14_if.expect @@ -0,0 +1,2 @@ +a is true +b is false diff --git a/tinyc/tests/tests2/15_recursion.c b/tinyc/tests/tests2/15_recursion.c new file mode 100644 index 000000000..f79a00df5 --- /dev/null +++ b/tinyc/tests/tests2/15_recursion.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int factorial(int i) +{ + if (i < 2) + return i; + else + return i * factorial(i - 1); +} + +int main() +{ + int Count; + + for (Count = 1; Count <= 10; Count++) + printf("%d\n", factorial(Count)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/15_recursion.expect b/tinyc/tests/tests2/15_recursion.expect new file mode 100644 index 000000000..db47b283d --- /dev/null +++ b/tinyc/tests/tests2/15_recursion.expect @@ -0,0 +1,10 @@ +1 +2 +6 +24 +120 +720 +5040 +40320 +362880 +3628800 diff --git a/tinyc/tests/tests2/16_nesting.c b/tinyc/tests/tests2/16_nesting.c new file mode 100644 index 000000000..2b72cc028 --- /dev/null +++ b/tinyc/tests/tests2/16_nesting.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int x, y, z; + + for (x = 0; x < 2; x++) + { + for (y = 0; y < 3; y++) + { + for (z = 0; z < 3; z++) + { + printf("%d %d %d\n", x, y, z); + } + } + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/16_nesting.expect b/tinyc/tests/tests2/16_nesting.expect new file mode 100644 index 000000000..5a3431ee0 --- /dev/null +++ b/tinyc/tests/tests2/16_nesting.expect @@ -0,0 +1,18 @@ +0 0 0 +0 0 1 +0 0 2 +0 1 0 +0 1 1 +0 1 2 +0 2 0 +0 2 1 +0 2 2 +1 0 0 +1 0 1 +1 0 2 +1 1 0 +1 1 1 +1 1 2 +1 2 0 +1 2 1 +1 2 2 diff --git a/tinyc/tests/tests2/17_enum.c b/tinyc/tests/tests2/17_enum.c new file mode 100644 index 000000000..e2bc73629 --- /dev/null +++ b/tinyc/tests/tests2/17_enum.c @@ -0,0 +1,72 @@ +#include <stdio.h> + +enum fred +{ + a, + b, + c, + d, + e = 54, + f = 73, + g, + h +}; + +/* All following uses of enum efoo should compile + without warning. While forward enums aren't ISO C, + it's accepted by GCC also in strict mode, and only warned + about with -pedantic. This happens in the real world. */ +/* Strict ISO C doesn't allow this kind of forward declaration of + enums, but GCC accepts it (and gives only pedantic warning), and + it occurs in the wild. */ +enum efoo; +struct Sforward_use { + int (*fmember) (enum efoo x); +}; + +extern enum efoo it_real_fn(void); +enum efoo { + ONE, + TWO, +}; +struct S2 { + enum efoo (*f2) (void); +}; +void should_compile(struct S2 *s) +{ + s->f2 = it_real_fn; +} + +enum efoo it_real_fn(void) +{ + return TWO; +} + +static unsigned int deref_uintptr(unsigned int *p) +{ + return *p; +} + +enum Epositive { + epos_one, epos_two +}; + +int main() +{ + enum fred frod; + enum Epositive epos = epos_two; + + printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h); + /* printf("%d\n", frod); */ + frod = 12; + printf("%d\n", frod); + frod = e; + printf("%d\n", frod); + + /* Following should compile without warning. */ + printf ("enum to int: %u\n", deref_uintptr(&epos)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/17_enum.expect b/tinyc/tests/tests2/17_enum.expect new file mode 100644 index 000000000..d453a617b --- /dev/null +++ b/tinyc/tests/tests2/17_enum.expect @@ -0,0 +1,4 @@ +0 1 2 3 54 73 74 75 +12 +54 +enum to int: 1 diff --git a/tinyc/tests/tests2/18_include.c b/tinyc/tests/tests2/18_include.c new file mode 100644 index 000000000..dbae3aa2e --- /dev/null +++ b/tinyc/tests/tests2/18_include.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +int main() +{ + printf("including\n"); +#include "18_include.h" + printf("done\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/18_include.expect b/tinyc/tests/tests2/18_include.expect new file mode 100644 index 000000000..58c6d29a0 --- /dev/null +++ b/tinyc/tests/tests2/18_include.expect @@ -0,0 +1,3 @@ +including +included +done diff --git a/tinyc/tests/tests2/18_include.h b/tinyc/tests/tests2/18_include.h new file mode 100644 index 000000000..dc8608025 --- /dev/null +++ b/tinyc/tests/tests2/18_include.h @@ -0,0 +1 @@ +printf("included\n"); diff --git a/tinyc/tests/tests2/19_pointer_arithmetic.c b/tinyc/tests/tests2/19_pointer_arithmetic.c new file mode 100644 index 000000000..aff65e5b5 --- /dev/null +++ b/tinyc/tests/tests2/19_pointer_arithmetic.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +int main() +{ + int a; + int *b; + int *c; + + a = 42; + b = &a; + c = NULL; + + printf("%d\n", *b); + + if (b == NULL) + printf("b is NULL\n"); + else + printf("b is not NULL\n"); + + if (c == NULL) + printf("c is NULL\n"); + else + printf("c is not NULL\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/19_pointer_arithmetic.expect b/tinyc/tests/tests2/19_pointer_arithmetic.expect new file mode 100644 index 000000000..0cf781b9e --- /dev/null +++ b/tinyc/tests/tests2/19_pointer_arithmetic.expect @@ -0,0 +1,3 @@ +42 +b is not NULL +c is NULL diff --git a/tinyc/tests/tests2/20_pointer_comparison.c b/tinyc/tests/tests2/20_pointer_comparison.c new file mode 100644 index 000000000..825f7787d --- /dev/null +++ b/tinyc/tests/tests2/20_pointer_comparison.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int b; + int *d; + int *e; + d = &a; + e = &b; + a = 12; + b = 34; + printf("%d\n", *d); + printf("%d\n", *e); + printf("%d\n", d == e); + printf("%d\n", d != e); + d = e; + printf("%d\n", d == e); + printf("%d\n", d != e); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/20_pointer_comparison.expect b/tinyc/tests/tests2/20_pointer_comparison.expect new file mode 100644 index 000000000..5d1e5f5c7 --- /dev/null +++ b/tinyc/tests/tests2/20_pointer_comparison.expect @@ -0,0 +1,6 @@ +12 +34 +0 +1 +1 +0 diff --git a/tinyc/tests/tests2/21_char_array.c b/tinyc/tests/tests2/21_char_array.c new file mode 100644 index 000000000..f22f5275c --- /dev/null +++ b/tinyc/tests/tests2/21_char_array.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +int main() +{ + int x = 'a'; + char y = x; + + char *a = "hello"; + + printf("%s\n", a); + + int c; + c = *a; + + char *b; + for (b = a; *b != 0; b++) + printf("%c: %d\n", *b, *b); + + char destarray[10]; + char *dest = &destarray[0]; + char *src = a; + + while (*src != 0) + *dest++ = *src++; + + *dest = 0; + + printf("copied string is %s\n", destarray); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/21_char_array.expect b/tinyc/tests/tests2/21_char_array.expect new file mode 100644 index 000000000..dbc60683c --- /dev/null +++ b/tinyc/tests/tests2/21_char_array.expect @@ -0,0 +1,7 @@ +hello +h: 104 +e: 101 +l: 108 +l: 108 +o: 111 +copied string is hello diff --git a/tinyc/tests/tests2/22_floating_point.c b/tinyc/tests/tests2/22_floating_point.c new file mode 100644 index 000000000..e3491f5c6 --- /dev/null +++ b/tinyc/tests/tests2/22_floating_point.c @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <math.h> + +int main() +{ + // variables + float a = 12.34 + 56.78; + printf("%f\n", a); + + // infix operators + printf("%f\n", 12.34 + 56.78); + printf("%f\n", 12.34 - 56.78); + printf("%f\n", 12.34 * 56.78); + printf("%f\n", 12.34 / 56.78); + + // comparison operators + printf("%d %d %d %d %d %d\n", 12.34 < 56.78, 12.34 <= 56.78, 12.34 == 56.78, 12.34 >= 56.78, 12.34 > 56.78, 12.34 != 56.78); + printf("%d %d %d %d %d %d\n", 12.34 < 12.34, 12.34 <= 12.34, 12.34 == 12.34, 12.34 >= 12.34, 12.34 > 12.34, 12.34 != 12.34); + printf("%d %d %d %d %d %d\n", 56.78 < 12.34, 56.78 <= 12.34, 56.78 == 12.34, 56.78 >= 12.34, 56.78 > 12.34, 56.78 != 12.34); + + // assignment operators + a = 12.34; + a += 56.78; + printf("%f\n", a); + + a = 12.34; + a -= 56.78; + printf("%f\n", a); + + a = 12.34; + a *= 56.78; + printf("%f\n", a); + + a = 12.34; + a /= 56.78; + printf("%f\n", a); + + // prefix operators + printf("%f\n", +12.34); + printf("%f\n", -12.34); + + // type coercion + a = 2; + printf("%f\n", a); + printf("%f\n", sin(2)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/22_floating_point.expect b/tinyc/tests/tests2/22_floating_point.expect new file mode 100644 index 000000000..75ea3a7e2 --- /dev/null +++ b/tinyc/tests/tests2/22_floating_point.expect @@ -0,0 +1,16 @@ +69.120003 +69.120000 +-44.440000 +700.665200 +0.217330 +1 1 0 0 0 1 +0 1 1 1 0 0 +0 0 0 1 1 1 +69.120003 +-44.439999 +700.665222 +0.217330 +12.340000 +-12.340000 +2.000000 +0.909297 diff --git a/tinyc/tests/tests2/23_type_coercion.c b/tinyc/tests/tests2/23_type_coercion.c new file mode 100644 index 000000000..1fcc33519 --- /dev/null +++ b/tinyc/tests/tests2/23_type_coercion.c @@ -0,0 +1,54 @@ +#include <stdio.h> + +void charfunc(char a) +{ + printf("char: %c\n", a); +} + +void intfunc(int a) +{ + printf("int: %d\n", a); +} + +void floatfunc(float a) +{ + printf("float: %f\n", a); +} + +int main() +{ + charfunc('a'); + charfunc(98); + charfunc(99.0); + + intfunc('a'); + intfunc(98); + intfunc(99.0); + + floatfunc('a'); + floatfunc(98); + floatfunc(99.0); + + /* printf("%c %d %f\n", 'a', 'b', 'c'); */ + /* printf("%c %d %f\n", 97, 98, 99); */ + /* printf("%c %d %f\n", 97.0, 98.0, 99.0); */ + + char b = 97; + char c = 97.0; + + printf("%d %d\n", b, c); + + int d = 'a'; + int e = 97.0; + + printf("%d %d\n", d, e); + + float f = 'a'; + float g = 97; + + printf("%f %f\n", f, g); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/23_type_coercion.expect b/tinyc/tests/tests2/23_type_coercion.expect new file mode 100644 index 000000000..d9076f018 --- /dev/null +++ b/tinyc/tests/tests2/23_type_coercion.expect @@ -0,0 +1,12 @@ +char: a +char: b +char: c +int: 97 +int: 98 +int: 99 +float: 97.000000 +float: 98.000000 +float: 99.000000 +97 97 +97 97 +97.000000 97.000000 diff --git a/tinyc/tests/tests2/24_math_library.c b/tinyc/tests/tests2/24_math_library.c new file mode 100644 index 000000000..514a25f63 --- /dev/null +++ b/tinyc/tests/tests2/24_math_library.c @@ -0,0 +1,30 @@ +#define _ISOC99_SOURCE 1 + +#include <stdio.h> +#include <math.h> + +int main() +{ + printf("%f\n", sin(0.12)); + printf("%f\n", cos(0.12)); + printf("%f\n", tan(0.12)); + printf("%f\n", asin(0.12)); + printf("%f\n", acos(0.12)); + printf("%f\n", atan(0.12)); + printf("%f\n", sinh(0.12)); + printf("%f\n", cosh(0.12)); + printf("%f\n", tanh(0.12)); + printf("%f\n", exp(0.12)); + printf("%f\n", fabs(-0.12)); + printf("%f\n", log(0.12)); + printf("%f\n", log10(0.12)); + printf("%f\n", pow(0.12, 0.12)); + printf("%f\n", sqrt(0.12)); + printf("%f\n", round(12.34)); + printf("%f\n", ceil(12.34)); + printf("%f\n", floor(12.34)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/24_math_library.expect b/tinyc/tests/tests2/24_math_library.expect new file mode 100644 index 000000000..99f7299cc --- /dev/null +++ b/tinyc/tests/tests2/24_math_library.expect @@ -0,0 +1,18 @@ +0.119712 +0.992809 +0.120579 +0.120290 +1.450506 +0.119429 +0.120288 +1.007209 +0.119427 +1.127497 +0.120000 +-2.120264 +-0.920819 +0.775357 +0.346410 +12.000000 +13.000000 +12.000000 diff --git a/tinyc/tests/tests2/25_quicksort.c b/tinyc/tests/tests2/25_quicksort.c new file mode 100644 index 000000000..5cc08bd9d --- /dev/null +++ b/tinyc/tests/tests2/25_quicksort.c @@ -0,0 +1,83 @@ +#include <stdio.h> + +int array[16]; + +//Swap integer values by array indexes +void swap(int a, int b) +{ + int tmp = array[a]; + array[a] = array[b]; + array[b] = tmp; +} + +//Partition the array into two halves and return the +//index about which the array is partitioned +int partition(int left, int right) +{ + int pivotIndex = left; + int pivotValue = array[pivotIndex]; + int index = left; + int i; + + swap(pivotIndex, right); + for(i = left; i < right; i++) + { + if(array[i] < pivotValue) + { + swap(i, index); + index += 1; + } + } + swap(right, index); + + return index; +} + +//Quicksort the array +void quicksort(int left, int right) +{ + if(left >= right) + return; + + int index = partition(left, right); + quicksort(left, index - 1); + quicksort(index + 1, right); +} + +int main() +{ + int i; + + array[0] = 62; + array[1] = 83; + array[2] = 4; + array[3] = 89; + array[4] = 36; + array[5] = 21; + array[6] = 74; + array[7] = 37; + array[8] = 65; + array[9] = 33; + array[10] = 96; + array[11] = 38; + array[12] = 53; + array[13] = 16; + array[14] = 74; + array[15] = 55; + + for (i = 0; i < 16; i++) + printf("%d ", array[i]); + + printf("\n"); + + quicksort(0, 15); + + for (i = 0; i < 16; i++) + printf("%d ", array[i]); + + printf("\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/25_quicksort.expect b/tinyc/tests/tests2/25_quicksort.expect new file mode 100644 index 000000000..2d39cd327 --- /dev/null +++ b/tinyc/tests/tests2/25_quicksort.expect @@ -0,0 +1,2 @@ +62 83 4 89 36 21 74 37 65 33 96 38 53 16 74 55 +4 16 21 33 36 37 38 53 55 62 65 74 74 83 89 96 diff --git a/tinyc/tests/tests2/26_character_constants.c b/tinyc/tests/tests2/26_character_constants.c new file mode 100644 index 000000000..95c442371 --- /dev/null +++ b/tinyc/tests/tests2/26_character_constants.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + printf("%d\n", '\1'); + printf("%d\n", '\10'); + printf("%d\n", '\100'); + printf("%d\n", '\x01'); + printf("%d\n", '\x0e'); + printf("%d\n", '\x10'); + printf("%d\n", '\x40'); + printf("test \x40\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/26_character_constants.expect b/tinyc/tests/tests2/26_character_constants.expect new file mode 100644 index 000000000..8f8bfa48c --- /dev/null +++ b/tinyc/tests/tests2/26_character_constants.expect @@ -0,0 +1,8 @@ +1 +8 +64 +1 +14 +16 +64 +test @ diff --git a/tinyc/tests/tests2/27_sizeof.c b/tinyc/tests/tests2/27_sizeof.c new file mode 100644 index 000000000..5ae0ede54 --- /dev/null +++ b/tinyc/tests/tests2/27_sizeof.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + char a; + int b; + double c; + + printf("%d\n", sizeof(a)); + printf("%d\n", sizeof(b)); + printf("%d\n", sizeof(c)); + + printf("%d\n", sizeof(!a)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/27_sizeof.expect b/tinyc/tests/tests2/27_sizeof.expect new file mode 100644 index 000000000..a47ea3a40 --- /dev/null +++ b/tinyc/tests/tests2/27_sizeof.expect @@ -0,0 +1,4 @@ +1 +4 +8 +4 diff --git a/tinyc/tests/tests2/28_strings.c b/tinyc/tests/tests2/28_strings.c new file mode 100644 index 000000000..2db22986e --- /dev/null +++ b/tinyc/tests/tests2/28_strings.c @@ -0,0 +1,45 @@ +#include <stdio.h> +#include <string.h> + +int main() +{ + char a[10]; + + strcpy(a, "hello"); + printf("%s\n", a); + + strncpy(a, "gosh", 2); + printf("%s\n", a); + + printf("%d\n", strcmp(a, "apple") > 0); + printf("%d\n", strcmp(a, "goere") > 0); + printf("%d\n", strcmp(a, "zebra") < 0); + + printf("%d\n", strlen(a)); + + strcat(a, "!"); + printf("%s\n", a); + + printf("%d\n", strncmp(a, "apple", 2) > 0); + printf("%d\n", strncmp(a, "goere", 2) == 0); + printf("%d\n", strncmp(a, "goerg", 2) == 0); + printf("%d\n", strncmp(a, "zebra", 2) < 0); + + printf("%s\n", strchr(a, 'o')); + printf("%s\n", strrchr(a, 'l')); + printf("%d\n", strrchr(a, 'x') == NULL); + + memset(&a[1], 'r', 4); + printf("%s\n", a); + + memcpy(&a[2], a, 2); + printf("%s\n", a); + + printf("%d\n", memcmp(a, "apple", 4) > 0); + printf("%d\n", memcmp(a, "grgr", 4) == 0); + printf("%d\n", memcmp(a, "zebra", 4) < 0); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/28_strings.expect b/tinyc/tests/tests2/28_strings.expect new file mode 100644 index 000000000..fd9217a22 --- /dev/null +++ b/tinyc/tests/tests2/28_strings.expect @@ -0,0 +1,19 @@ +hello +gollo +1 +1 +1 +5 +gollo! +1 +1 +1 +1 +ollo! +lo! +1 +grrrr! +grgrr! +1 +1 +1 diff --git a/tinyc/tests/tests2/29_array_address.c b/tinyc/tests/tests2/29_array_address.c new file mode 100644 index 000000000..bda5ddde2 --- /dev/null +++ b/tinyc/tests/tests2/29_array_address.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <string.h> + +int main() +{ + char a[10]; + strcpy(a, "abcdef"); + printf("%s\n", &a[1]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/29_array_address.expect b/tinyc/tests/tests2/29_array_address.expect new file mode 100644 index 000000000..9bc868324 --- /dev/null +++ b/tinyc/tests/tests2/29_array_address.expect @@ -0,0 +1 @@ +bcdef diff --git a/tinyc/tests/tests2/30_hanoi.c b/tinyc/tests/tests2/30_hanoi.c new file mode 100644 index 000000000..7c0893b1a --- /dev/null +++ b/tinyc/tests/tests2/30_hanoi.c @@ -0,0 +1,122 @@ +/* example from http://barnyard.syr.edu/quickies/hanoi.c */ + +/* hanoi.c: solves the tower of hanoi problem. (Programming exercise.) */ +/* By Terry R. McConnell (12/2/97) */ +/* Compile: cc -o hanoi hanoi.c */ + +/* This program does no error checking. But then, if it's right, + it's right ... right ? */ + + +/* The original towers of hanoi problem seems to have been originally posed + by one M. Claus in 1883. There is a popular legend that goes along with + it that has been often repeated and paraphrased. It goes something like this: + In the great temple at Benares there are 3 golden spikes. On one of them, + God placed 64 disks increasing in size from bottom to top, at the beginning + of time. Since then, and to this day, the priest on duty constantly transfers + disks, one at a time, in such a way that no larger disk is ever put on top + of a smaller one. When the disks have been transferred entirely to another + spike the Universe will come to an end in a large thunderclap. + + This paraphrases the original legend due to DeParville, La Nature, Paris 1884, + Part I, 285-286. For this and further information see: Mathematical + Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967, + 303-305. + * + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#define TRUE 1 +#define FALSE 0 + +/* This is the number of "disks" on tower A initially. Taken to be 64 in the + * legend. The number of moves required, in general, is 2^N - 1. For N = 64, + * this is 18,446,744,073,709,551,615 */ +#define N 4 + +/* These are the three towers. For example if the state of A is 0,1,3,4, that + * means that there are three discs on A of sizes 1, 3, and 4. (Think of right + * as being the "down" direction.) */ +int A[N], B[N], C[N]; + +void Hanoi(int,int*,int*,int*); + +/* Print the current configuration of A, B, and C to the screen */ +void PrintAll() +{ + int i; + + printf("A: "); + for(i=0;i<N;i++)printf(" %d ",A[i]); + printf("\n"); + + printf("B: "); + for(i=0;i<N;i++)printf(" %d ",B[i]); + printf("\n"); + + printf("C: "); + for(i=0;i<N;i++)printf(" %d ",C[i]); + printf("\n"); + printf("------------------------------------------\n"); + return; +} + +/* Move the leftmost nonzero element of source to dest, leave behind 0. */ +/* Returns the value moved (not used.) */ +int Move(int *source, int *dest) +{ + int i = 0, j = 0; + + while (i<N && (source[i])==0) i++; + while (j<N && (dest[j])==0) j++; + + dest[j-1] = source[i]; + source[i] = 0; + PrintAll(); /* Print configuration after each move. */ + return dest[j-1]; +} + + +/* Moves first n nonzero numbers from source to dest using the rules of Hanoi. + Calls itself recursively. + */ +void Hanoi(int n,int *source, int *dest, int *spare) +{ + int i; + if(n==1){ + Move(source,dest); + return; + } + + Hanoi(n-1,source,spare,dest); + Move(source,dest); + Hanoi(n-1,spare,dest,source); + return; +} + +int main() +{ + int i; + + /* initialize the towers */ + for(i=0;i<N;i++)A[i]=i+1; + for(i=0;i<N;i++)B[i]=0; + for(i=0;i<N;i++)C[i]=0; + + printf("Solution of Tower of Hanoi Problem with %d Disks\n\n",N); + + /* Print the starting state */ + printf("Starting state:\n"); + PrintAll(); + printf("\n\nSubsequent states:\n\n"); + + /* Do it! Use A = Source, B = Destination, C = Spare */ + Hanoi(N,A,B,C); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/30_hanoi.expect b/tinyc/tests/tests2/30_hanoi.expect new file mode 100644 index 000000000..7798ee051 --- /dev/null +++ b/tinyc/tests/tests2/30_hanoi.expect @@ -0,0 +1,71 @@ +Solution of Tower of Hanoi Problem with 4 Disks + +Starting state: +A: 1 2 3 4 +B: 0 0 0 0 +C: 0 0 0 0 +------------------------------------------ + + +Subsequent states: + +A: 0 2 3 4 +B: 0 0 0 0 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 3 4 +B: 0 0 0 2 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 3 4 +B: 0 0 1 2 +C: 0 0 0 0 +------------------------------------------ +A: 0 0 0 4 +B: 0 0 1 2 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 4 +B: 0 0 0 2 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 4 +B: 0 0 0 0 +C: 0 0 2 3 +------------------------------------------ +A: 0 0 0 4 +B: 0 0 0 0 +C: 0 1 2 3 +------------------------------------------ +A: 0 0 0 0 +B: 0 0 0 4 +C: 0 1 2 3 +------------------------------------------ +A: 0 0 0 0 +B: 0 0 1 4 +C: 0 0 2 3 +------------------------------------------ +A: 0 0 0 2 +B: 0 0 1 4 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 2 +B: 0 0 0 4 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 2 +B: 0 0 3 4 +C: 0 0 0 0 +------------------------------------------ +A: 0 0 0 2 +B: 0 0 3 4 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 0 0 +B: 0 2 3 4 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 0 0 +B: 1 2 3 4 +C: 0 0 0 0 +------------------------------------------ diff --git a/tinyc/tests/tests2/31_args.c b/tinyc/tests/tests2/31_args.c new file mode 100644 index 000000000..dcafed52b --- /dev/null +++ b/tinyc/tests/tests2/31_args.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main(int argc, char **argv) +{ + int Count; + + printf("hello world %d\n", argc); + for (Count = 1; Count < argc; Count++) + printf("arg %d: %s\n", Count, argv[Count]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/31_args.expect b/tinyc/tests/tests2/31_args.expect new file mode 100644 index 000000000..8c60bfc5b --- /dev/null +++ b/tinyc/tests/tests2/31_args.expect @@ -0,0 +1,6 @@ +hello world 6 +arg 1: arg1 +arg 2: arg2 +arg 3: arg3 +arg 4: arg4 +arg 5: arg5 diff --git a/tinyc/tests/tests2/32_led.c b/tinyc/tests/tests2/32_led.c new file mode 100644 index 000000000..5596cbfd3 --- /dev/null +++ b/tinyc/tests/tests2/32_led.c @@ -0,0 +1,266 @@ +/* example from http://barnyard.syr.edu/quickies/led.c */ + +/* led.c: print out number as if on 7 line led display. I.e., write integer + given on command line like this: + _ _ _ + | _| _| |_| |_ + | |_ _| | _| etc. + + We assume the terminal behaves like a classical teletype. So the top + lines of all digits have to be printed first, then the middle lines of + all digits, etc. + + By Terry R. McConnell + +compile: cc -o led led.c + +If you just want to link in the subroutine print_led that does all the +work, compile with -DNO_MAIN, and declare the following in any source file +that uses the call: + +extern void print_led(unsigned long x, char *buf); + +Bug: you cannot call repeatedly to print more than one number to a line. +That would require curses or some other terminal API that allows moving the +cursor to a previous line. + +*/ + + + +#include <stdlib.h> +#include <stdio.h> + +#define MAX_DIGITS 32 +#define NO_MAIN + + +/* Print the top line of the digit d into buffer. + Does not null terminate buffer. */ + +void topline(int d, char *p){ + + *p++ = ' '; + switch(d){ + + /* all these have _ on top line */ + + case 0: + case 2: + case 3: + case 5: + case 7: + case 8: + case 9: + *p++ = '_'; + break; + default: + *p++=' '; + + } + *p++=' '; +} + +/* Print the middle line of the digit d into the buffer. + Does not null terminate. */ + +void midline(int d, char *p){ + + switch(d){ + + /* those that have leading | on middle line */ + + case 0: + case 4: + case 5: + case 6: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + } + switch(d){ + + /* those that have _ on middle line */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + *p++='_'; + break; + default: + *p++=' '; + + } + switch(d){ + + /* those that have closing | on middle line */ + + case 0: + case 1: + case 2: + case 3: + case 4: + case 7: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + + } +} + +/* Print the bottom line of the digit d. Does not null terminate. */ + +void botline(int d, char *p){ + + + switch(d){ + + /* those that have leading | on bottom line */ + + case 0: + case 2: + case 6: + case 8: + *p++='|'; + break; + default: + *p++=' '; + } + switch(d){ + + /* those that have _ on bottom line */ + + case 0: + case 2: + case 3: + case 5: + case 6: + case 8: + *p++='_'; + break; + default: + *p++=' '; + + } + switch(d){ + + /* those that have closing | on bottom line */ + + case 0: + case 1: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + + } +} + +/* Write the led representation of integer to string buffer. */ + +void print_led(unsigned long x, char *buf) +{ + + int i=0,n; + static int d[MAX_DIGITS]; + + + /* extract digits from x */ + + n = ( x == 0L ? 1 : 0 ); /* 0 is a digit, hence a special case */ + + while(x){ + d[n++] = (int)(x%10L); + if(n >= MAX_DIGITS)break; + x = x/10L; + } + + /* print top lines of all digits */ + + for(i=n-1;i>=0;i--){ + topline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; /* move teletype to next line */ + + /* print middle lines of all digits */ + + for(i=n-1;i>=0;i--){ + midline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; + + /* print bottom lines of all digits */ + + for(i=n-1;i>=0;i--){ + botline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; + *buf='\0'; +} + +int main() +{ + char buf[5*MAX_DIGITS]; + print_led(1234567, buf); + printf("%s\n",buf); + + return 0; +} + +#ifndef NO_MAIN +int main(int argc, char **argv) +{ + + int i=0,n; + long x; + static int d[MAX_DIGITS]; + char buf[5*MAX_DIGITS]; + + if(argc != 2){ + fprintf(stderr,"led: usage: led integer\n"); + return 1; + } + + /* fetch argument from command line */ + + x = atol(argv[1]); + + /* sanity check */ + + if(x<0){ + fprintf(stderr,"led: %d must be non-negative\n",x); + return 1; + } + + print_led(x,buf); + printf("%s\n",buf); + + return 0; + +} +#endif + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/32_led.expect b/tinyc/tests/tests2/32_led.expect new file mode 100644 index 000000000..c53b58ae0 --- /dev/null +++ b/tinyc/tests/tests2/32_led.expect @@ -0,0 +1,4 @@ + _ _ _ _ + | _| _| |_| |_ |_ | + | |_ _| | _| |_| | + diff --git a/tinyc/tests/tests2/33_ternary_op.c b/tinyc/tests/tests2/33_ternary_op.c new file mode 100644 index 000000000..8579b5029 --- /dev/null +++ b/tinyc/tests/tests2/33_ternary_op.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +int main() +{ + int Count; + + for (Count = 0; Count < 10; Count++) + { + printf("%d\n", (Count < 5) ? (Count*Count) : (Count * 3)); + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/33_ternary_op.expect b/tinyc/tests/tests2/33_ternary_op.expect new file mode 100644 index 000000000..45ea507a5 --- /dev/null +++ b/tinyc/tests/tests2/33_ternary_op.expect @@ -0,0 +1,10 @@ +0 +1 +4 +9 +16 +15 +18 +21 +24 +27 diff --git a/tinyc/tests/tests2/34_array_assignment.c b/tinyc/tests/tests2/34_array_assignment.c new file mode 100644 index 000000000..5885c9732 --- /dev/null +++ b/tinyc/tests/tests2/34_array_assignment.c @@ -0,0 +1,23 @@ +#include <stdio.h> + +int main() +{ + int a[4]; + + a[0] = 12; + a[1] = 23; + a[2] = 34; + a[3] = 45; + + printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]); + + int b[4]; + + b = a; + + printf("%d %d %d %d\n", b[0], b[1], b[2], b[3]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/34_array_assignment.expect b/tinyc/tests/tests2/34_array_assignment.expect new file mode 100644 index 000000000..9736bf508 --- /dev/null +++ b/tinyc/tests/tests2/34_array_assignment.expect @@ -0,0 +1,2 @@ +12 23 34 45 +12 23 34 45 diff --git a/tinyc/tests/tests2/35_sizeof.c b/tinyc/tests/tests2/35_sizeof.c new file mode 100644 index 000000000..672e87e7f --- /dev/null +++ b/tinyc/tests/tests2/35_sizeof.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main() +{ + char a; + short b; + + printf("%d %d\n", sizeof(char), sizeof(a)); + printf("%d %d\n", sizeof(short), sizeof(b)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/35_sizeof.expect b/tinyc/tests/tests2/35_sizeof.expect new file mode 100644 index 000000000..534fb831b --- /dev/null +++ b/tinyc/tests/tests2/35_sizeof.expect @@ -0,0 +1,2 @@ +1 1 +2 2 diff --git a/tinyc/tests/tests2/36_array_initialisers.c b/tinyc/tests/tests2/36_array_initialisers.c new file mode 100644 index 000000000..1bc8ee088 --- /dev/null +++ b/tinyc/tests/tests2/36_array_initialisers.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int Count; + + int Array[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753 }; + + for (Count = 0; Count < 10; Count++) + printf("%d: %d\n", Count, Array[Count]); + + int Array2[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753, }; + + for (Count = 0; Count < 10; Count++) + printf("%d: %d\n", Count, Array2[Count]); + + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/36_array_initialisers.expect b/tinyc/tests/tests2/36_array_initialisers.expect new file mode 100644 index 000000000..3ac6c7729 --- /dev/null +++ b/tinyc/tests/tests2/36_array_initialisers.expect @@ -0,0 +1,20 @@ +0: 12 +1: 34 +2: 56 +3: 78 +4: 90 +5: 123 +6: 456 +7: 789 +8: 8642 +9: 9753 +0: 12 +1: 34 +2: 56 +3: 78 +4: 90 +5: 123 +6: 456 +7: 789 +8: 8642 +9: 9753 diff --git a/tinyc/tests/tests2/37_sprintf.c b/tinyc/tests/tests2/37_sprintf.c new file mode 100644 index 000000000..1dd1dce28 --- /dev/null +++ b/tinyc/tests/tests2/37_sprintf.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + char Buf[100]; + int Count; + + for (Count = 1; Count <= 20; Count++) + { + sprintf(Buf, "->%02d<-\n", Count); + printf("%s", Buf); + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/37_sprintf.expect b/tinyc/tests/tests2/37_sprintf.expect new file mode 100644 index 000000000..a643da842 --- /dev/null +++ b/tinyc/tests/tests2/37_sprintf.expect @@ -0,0 +1,20 @@ +->01<- +->02<- +->03<- +->04<- +->05<- +->06<- +->07<- +->08<- +->09<- +->10<- +->11<- +->12<- +->13<- +->14<- +->15<- +->16<- +->17<- +->18<- +->19<- +->20<- diff --git a/tinyc/tests/tests2/38_multiple_array_index.c b/tinyc/tests/tests2/38_multiple_array_index.c new file mode 100644 index 000000000..4e1868efe --- /dev/null +++ b/tinyc/tests/tests2/38_multiple_array_index.c @@ -0,0 +1,32 @@ +#include <stdio.h> + +int main() +{ + int a[4][4]; + int b = 0; + int x; + int y; + + for (x = 0; x < 4; x++) + { + for (y = 0; y < 4; y++) + { + b++; + a[x][y] = b; + } + } + + for (x = 0; x < 4; x++) + { + printf("x=%d: ", x); + for (y = 0; y < 4; y++) + { + printf("%d ", a[x][y]); + } + printf("\n"); + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/38_multiple_array_index.expect b/tinyc/tests/tests2/38_multiple_array_index.expect new file mode 100644 index 000000000..747ad751d --- /dev/null +++ b/tinyc/tests/tests2/38_multiple_array_index.expect @@ -0,0 +1,4 @@ +x=0: 1 2 3 4 +x=1: 5 6 7 8 +x=2: 9 10 11 12 +x=3: 13 14 15 16 diff --git a/tinyc/tests/tests2/39_typedef.c b/tinyc/tests/tests2/39_typedef.c new file mode 100644 index 000000000..da73f71e6 --- /dev/null +++ b/tinyc/tests/tests2/39_typedef.c @@ -0,0 +1,65 @@ +#include <stdio.h> + +typedef int MyInt; + +struct FunStruct +{ + int i; + int j; +}; + +typedef struct FunStruct MyFunStruct; + +typedef MyFunStruct *MoreFunThanEver; + +int main() +{ + MyInt a = 1; + printf("%d\n", a); + + MyFunStruct b; + b.i = 12; + b.j = 34; + printf("%d,%d\n", b.i, b.j); + + MoreFunThanEver c = &b; + printf("%d,%d\n", c->i, c->j); + + return 0; +} + +/* "If the specification of an array type includes any type qualifiers, + the element type is so-qualified, not the array type." */ + +typedef int A[3]; +extern A const ca; +extern const A ca; +extern const int ca[3]; + +typedef A B[1][2]; +extern B const cb; +extern const B cb; +extern const int cb[1][2][3]; + +extern B b; +extern int b[1][2][3]; + +/* Funny but valid function declaration. */ +typedef int functype (int); +extern functype func; +int func(int i) +{ + return i + 1; +} + +/* Even funnier function decl and definition using typeof. */ +int set_anon_super(void); +int set_anon_super(void) +{ + return 42; +} +typedef int sas_type (void); +extern typeof(set_anon_super) set_anon_super; +extern sas_type set_anon_super; + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/39_typedef.expect b/tinyc/tests/tests2/39_typedef.expect new file mode 100644 index 000000000..b9050a9b6 --- /dev/null +++ b/tinyc/tests/tests2/39_typedef.expect @@ -0,0 +1,3 @@ +1 +12,34 +12,34 diff --git a/tinyc/tests/tests2/40_stdio.c b/tinyc/tests/tests2/40_stdio.c new file mode 100644 index 000000000..b98609302 --- /dev/null +++ b/tinyc/tests/tests2/40_stdio.c @@ -0,0 +1,52 @@ +#include <stdio.h> + +int main() +{ + FILE *f = fopen("fred.txt", "w"); + fwrite("hello\nhello\n", 1, 12, f); + fclose(f); + + char freddy[7]; + f = fopen("fred.txt", "r"); + if (fread(freddy, 1, 6, f) != 6) + printf("couldn't read fred.txt\n"); + + freddy[6] = '\0'; + fclose(f); + + printf("%s", freddy); + + int InChar; + char ShowChar; + f = fopen("fred.txt", "r"); + while ( (InChar = fgetc(f)) != EOF) + { + ShowChar = InChar; + if (ShowChar < ' ') + ShowChar = '.'; + + printf("ch: %d '%c'\n", InChar, ShowChar); + } + fclose(f); + + f = fopen("fred.txt", "r"); + while ( (InChar = getc(f)) != EOF) + { + ShowChar = InChar; + if (ShowChar < ' ') + ShowChar = '.'; + + printf("ch: %d '%c'\n", InChar, ShowChar); + } + fclose(f); + + f = fopen("fred.txt", "r"); + while (fgets(freddy, sizeof(freddy), f) != NULL) + printf("x: %s", freddy); + + fclose(f); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/40_stdio.expect b/tinyc/tests/tests2/40_stdio.expect new file mode 100644 index 000000000..e08167a6e --- /dev/null +++ b/tinyc/tests/tests2/40_stdio.expect @@ -0,0 +1,27 @@ +hello +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +x: hello +x: hello diff --git a/tinyc/tests/tests2/41_hashif.c b/tinyc/tests/tests2/41_hashif.c new file mode 100644 index 000000000..cb37b9eb0 --- /dev/null +++ b/tinyc/tests/tests2/41_hashif.c @@ -0,0 +1,85 @@ +#include <stdio.h> + +int main() +{ + printf("#include test\n"); + +#if 1 +#if 0 + printf("a\n"); +#else + printf("b\n"); +#endif +#else +#if 0 + printf("c\n"); +#else + printf("d\n"); +#endif +#endif + +#if 0 +#if 1 + printf("e\n"); +#else + printf("f\n"); +#endif +#else +#if 1 + printf("g\n"); +#else + printf("h\n"); +#endif +#endif + +#define DEF + +#ifdef DEF +#ifdef DEF + printf("i\n"); +#else + printf("j\n"); +#endif +#else +#ifdef DEF + printf("k\n"); +#else + printf("l\n"); +#endif +#endif + +#ifndef DEF +#ifndef DEF + printf("m\n"); +#else + printf("n\n"); +#endif +#else +#ifndef DEF + printf("o\n"); +#else + printf("p\n"); +#endif +#endif + +#define ONE 1 +#define ZERO 0 + +#if ONE +#if ZERO + printf("q\n"); +#else + printf("r\n"); +#endif +#else +#if ZERO + printf("s\n"); +#else + printf("t\n"); +#endif +#endif + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/41_hashif.expect b/tinyc/tests/tests2/41_hashif.expect new file mode 100644 index 000000000..5fd414bd0 --- /dev/null +++ b/tinyc/tests/tests2/41_hashif.expect @@ -0,0 +1,6 @@ +#include test +b +g +i +p +r diff --git a/tinyc/tests/tests2/42_function_pointer.c b/tinyc/tests/tests2/42_function_pointer.c new file mode 100644 index 000000000..697bd79a6 --- /dev/null +++ b/tinyc/tests/tests2/42_function_pointer.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +int fred(int p) +{ + printf("yo %d\n", p); + return 42; +} + +int (*f)(int) = &fred; + +/* To test what this is supposed to test the destination function + (fprint here) must not be called directly anywhere in the test. */ +int (*fprintfptr)(FILE *, const char *, ...) = &fprintf; + +int main() +{ + fprintfptr(stdout, "%d\n", (*f)(24)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/42_function_pointer.expect b/tinyc/tests/tests2/42_function_pointer.expect new file mode 100644 index 000000000..6c8b6ce45 --- /dev/null +++ b/tinyc/tests/tests2/42_function_pointer.expect @@ -0,0 +1,2 @@ +yo 24 +42 diff --git a/tinyc/tests/tests2/43_void_param.c b/tinyc/tests/tests2/43_void_param.c new file mode 100644 index 000000000..de17098b2 --- /dev/null +++ b/tinyc/tests/tests2/43_void_param.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +void fred(void) +{ + printf("yo\n"); +} + +int main() +{ + fred(); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/43_void_param.expect b/tinyc/tests/tests2/43_void_param.expect new file mode 100644 index 000000000..092bfb9bd --- /dev/null +++ b/tinyc/tests/tests2/43_void_param.expect @@ -0,0 +1 @@ +yo diff --git a/tinyc/tests/tests2/44_scoped_declarations.c b/tinyc/tests/tests2/44_scoped_declarations.c new file mode 100644 index 000000000..f38664fc5 --- /dev/null +++ b/tinyc/tests/tests2/44_scoped_declarations.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + int a; + + for (a = 0; a < 2; a++) + { + int b = a; + } + + printf("it's all good\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/44_scoped_declarations.expect b/tinyc/tests/tests2/44_scoped_declarations.expect new file mode 100644 index 000000000..231ccc0c5 --- /dev/null +++ b/tinyc/tests/tests2/44_scoped_declarations.expect @@ -0,0 +1 @@ +it's all good diff --git a/tinyc/tests/tests2/45_empty_for.c b/tinyc/tests/tests2/45_empty_for.c new file mode 100644 index 000000000..7cef513f8 --- /dev/null +++ b/tinyc/tests/tests2/45_empty_for.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + int Count = 0; + + for (;;) + { + Count++; + printf("%d\n", Count); + if (Count >= 10) + break; + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/45_empty_for.expect b/tinyc/tests/tests2/45_empty_for.expect new file mode 100644 index 000000000..f00c965d8 --- /dev/null +++ b/tinyc/tests/tests2/45_empty_for.expect @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/tinyc/tests/tests2/46_grep.c b/tinyc/tests/tests2/46_grep.c new file mode 100644 index 000000000..049dfb15e --- /dev/null +++ b/tinyc/tests/tests2/46_grep.c @@ -0,0 +1,568 @@ +/* + * The information in this document is subject to change + * without notice and should not be construed as a commitment + * by Digital Equipment Corporation or by DECUS. + * + * Neither Digital Equipment Corporation, DECUS, nor the authors + * assume any responsibility for the use or reliability of this + * document or the described software. + * + * Copyright (C) 1980, DECUS + * + * General permission to copy or modify, but not for profit, is + * hereby granted, provided that the above copyright notice is + * included and reference made to the fact that reproduction + * privileges were granted by DECUS. + */ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> // tolower() + +/* + * grep + * + * Runs on the Decus compiler or on vms, On vms, define as: + * grep :== "$disk:[account]grep" (native) + * grep :== "$disk:[account]grep grep" (Decus) + * See below for more information. + */ + +char *documentation[] = { + "grep searches a file for a given pattern. Execute by", + " grep [flags] regular_expression file_list\n", + "Flags are single characters preceded by '-':", + " -c Only a count of matching lines is printed", + " -f Print file name for matching lines switch, see below", + " -n Each line is preceded by its line number", + " -v Only print non-matching lines\n", + "The file_list is a list of files (wildcards are acceptable on RSX modes).", + "\nThe file name is normally printed if there is a file given.", + "The -f flag reverses this action (print name no file, not if more).\n", + 0 }; + +char *patdoc[] = { + "The regular_expression defines the pattern to search for. Upper- and", + "lower-case are always ignored. Blank lines never match. The expression", + "should be quoted to prevent file-name translation.", + "x An ordinary character (not mentioned below) matches that character.", + "'\\' The backslash quotes any character. \"\\$\" matches a dollar-sign.", + "'^' A circumflex at the beginning of an expression matches the", + " beginning of a line.", + "'$' A dollar-sign at the end of an expression matches the end of a line.", + "'.' A period matches any character except \"new-line\".", + "':a' A colon matches a class of characters described by the following", + "':d' character. \":a\" matches any alphabetic, \":d\" matches digits,", + "':n' \":n\" matches alphanumerics, \": \" matches spaces, tabs, and", + "': ' other control characters, such as new-line.", + "'*' An expression followed by an asterisk matches zero or more", + " occurrences of that expression: \"fo*\" matches \"f\", \"fo\"", + " \"foo\", etc.", + "'+' An expression followed by a plus sign matches one or more", + " occurrences of that expression: \"fo+\" matches \"fo\", etc.", + "'-' An expression followed by a minus sign optionally matches", + " the expression.", + "'[]' A string enclosed in square brackets matches any character in", + " that string, but no others. If the first character in the", + " string is a circumflex, the expression matches any character", + " except \"new-line\" and the characters in the string. For", + " example, \"[xyz]\" matches \"xx\" and \"zyx\", while \"[^xyz]\"", + " matches \"abc\" but not \"axb\". A range of characters may be", + " specified by two characters separated by \"-\". Note that,", + " [a-z] matches alphabetics, while [z-a] never matches.", + "The concatenation of regular expressions is a regular expression.", + 0}; + +#define LMAX 512 +#define PMAX 256 + +#define CHAR 1 +#define BOL 2 +#define EOL 3 +#define ANY 4 +#define CLASS 5 +#define NCLASS 6 +#define STAR 7 +#define PLUS 8 +#define MINUS 9 +#define ALPHA 10 +#define DIGIT 11 +#define NALPHA 12 +#define PUNCT 13 +#define RANGE 14 +#define ENDPAT 15 + +int cflag=0, fflag=0, nflag=0, vflag=0, nfile=0, debug=0; + +char *pp, lbuf[LMAX], pbuf[PMAX]; + +char *cclass(); +char *pmatch(); +void store(int); +void error(char *); +void badpat(char *, char *, char *); +int match(void); + + +/*** Display a file name *******************************/ +void file(char *s) +{ + printf("File %s:\n", s); +} + +/*** Report unopenable file ****************************/ +void cant(char *s) +{ + fprintf(stderr, "%s: cannot open\n", s); +} + +/*** Give good help ************************************/ +void help(char **hp) +{ + char **dp; + + for (dp = hp; *dp; ++dp) + printf("%s\n", *dp); +} + +/*** Display usage summary *****************************/ +void usage(char *s) +{ + fprintf(stderr, "?GREP-E-%s\n", s); + fprintf(stderr, + "Usage: grep [-cfnv] pattern [file ...]. grep ? for help\n"); + exit(1); +} + +/*** Compile the pattern into global pbuf[] ************/ +void compile(char *source) +{ + char *s; /* Source string pointer */ + char *lp; /* Last pattern pointer */ + int c; /* Current character */ + int o; /* Temp */ + char *spp; /* Save beginning of pattern */ + + s = source; + if (debug) + printf("Pattern = \"%s\"\n", s); + pp = pbuf; + while (c = *s++) { + /* + * STAR, PLUS and MINUS are special. + */ + if (c == '*' || c == '+' || c == '-') { + if (pp == pbuf || + (o=pp[-1]) == BOL || + o == EOL || + o == STAR || + o == PLUS || + o == MINUS) + badpat("Illegal occurrence op.", source, s); + store(ENDPAT); + store(ENDPAT); + spp = pp; /* Save pattern end */ + while (--pp > lp) /* Move pattern down */ + *pp = pp[-1]; /* one byte */ + *pp = (c == '*') ? STAR : + (c == '-') ? MINUS : PLUS; + pp = spp; /* Restore pattern end */ + continue; + } + /* + * All the rest. + */ + lp = pp; /* Remember start */ + switch(c) { + + case '^': + store(BOL); + break; + + case '$': + store(EOL); + break; + + case '.': + store(ANY); + break; + + case '[': + s = cclass(source, s); + break; + + case ':': + if (*s) { + switch(tolower(c = *s++)) { + + case 'a': + case 'A': + store(ALPHA); + break; + + case 'd': + case 'D': + store(DIGIT); + break; + + case 'n': + case 'N': + store(NALPHA); + break; + + case ' ': + store(PUNCT); + break; + + default: + badpat("Unknown : type", source, s); + + } + break; + } + else badpat("No : type", source, s); + + case '\\': + if (*s) + c = *s++; + + default: + store(CHAR); + store(tolower(c)); + } + } + store(ENDPAT); + store(0); /* Terminate string */ + if (debug) { + for (lp = pbuf; lp < pp;) { + if ((c = (*lp++ & 0377)) < ' ') + printf("\\%o ", c); + else printf("%c ", c); + } + printf("\n"); + } +} + +/*** Compile a class (within []) ***********************/ +char *cclass(char *source, char *src) + /* char *source; // Pattern start -- for error msg. */ + /* char *src; // Class start */ +{ + char *s; /* Source pointer */ + char *cp; /* Pattern start */ + int c; /* Current character */ + int o; /* Temp */ + + s = src; + o = CLASS; + if (*s == '^') { + ++s; + o = NCLASS; + } + store(o); + cp = pp; + store(0); /* Byte count */ + while ((c = *s++) && c!=']') { + if (c == '\\') { /* Store quoted char */ + if ((c = *s++) == '\0') /* Gotta get something */ + badpat("Class terminates badly", source, s); + else store(tolower(c)); + } + else if (c == '-' && + (pp - cp) > 1 && *s != ']' && *s != '\0') { + c = pp[-1]; /* Range start */ + pp[-1] = RANGE; /* Range signal */ + store(c); /* Re-store start */ + c = *s++; /* Get end char and*/ + store(tolower(c)); /* Store it */ + } + else { + store(tolower(c)); /* Store normal char */ + } + } + if (c != ']') + badpat("Unterminated class", source, s); + if ((c = (pp - cp)) >= 256) + badpat("Class too large", source, s); + if (c == 0) + badpat("Empty class", source, s); + *cp = c; + return(s); +} + +/*** Store an entry in the pattern buffer **************/ +void store(int op) +{ + if (pp >= &pbuf[PMAX]) + error("Pattern too complex\n"); + *pp++ = op; +} + +/*** Report a bad pattern specification ****************/ +void badpat(char *message, char *source, char *stop) + /* char *message; // Error message */ + /* char *source; // Pattern start */ + /* char *stop; // Pattern end */ +{ + fprintf(stderr, "-GREP-E-%s, pattern is\"%s\"\n", message, source); + fprintf(stderr, "-GREP-E-Stopped at byte %ld, '%c'\n", + stop-source, stop[-1]); + error("?GREP-E-Bad pattern\n"); +} + +/*** Scan the file for the pattern in pbuf[] ***********/ +void grep(FILE *fp, char *fn) + /* FILE *fp; // File to process */ + /* char *fn; // File name (for -f option) */ +{ + int lno, count, m; + + lno = 0; + count = 0; + while (fgets(lbuf, LMAX, fp)) { + ++lno; + m = match(); + if ((m && !vflag) || (!m && vflag)) { + ++count; + if (!cflag) { + if (fflag && fn) { + file(fn); + fn = 0; + } + if (nflag) + printf("%d\t", lno); + printf("%s\n", lbuf); + } + } + } + if (cflag) { + if (fflag && fn) + file(fn); + printf("%d\n", count); + } +} + +/*** Match line (lbuf) with pattern (pbuf) return 1 if match ***/ +int match() +{ + char *l; /* Line pointer */ + + for (l = lbuf; *l; ++l) { + if (pmatch(l, pbuf)) + return(1); + } + return(0); +} + +/*** Match partial line with pattern *******************/ +char *pmatch(char *line, char *pattern) + /* char *line; // (partial) line to match */ + /* char *pattern; // (partial) pattern to match */ +{ + char *l; /* Current line pointer */ + char *p; /* Current pattern pointer */ + char c; /* Current character */ + char *e; /* End for STAR and PLUS match */ + int op; /* Pattern operation */ + int n; /* Class counter */ + char *are; /* Start of STAR match */ + + l = line; + if (debug > 1) + printf("pmatch(\"%s\")\n", line); + p = pattern; + while ((op = *p++) != ENDPAT) { + if (debug > 1) + printf("byte[%ld] = 0%o, '%c', op = 0%o\n", + l-line, *l, *l, op); + switch(op) { + + case CHAR: + if (tolower(*l++) != *p++) + return(0); + break; + + case BOL: + if (l != lbuf) + return(0); + break; + + case EOL: + if (*l != '\0') + return(0); + break; + + case ANY: + if (*l++ == '\0') + return(0); + break; + + case DIGIT: + if ((c = *l++) < '0' || (c > '9')) + return(0); + break; + + case ALPHA: + c = tolower(*l++); + if (c < 'a' || c > 'z') + return(0); + break; + + case NALPHA: + c = tolower(*l++); + if (c >= 'a' && c <= 'z') + break; + else if (c < '0' || c > '9') + return(0); + break; + + case PUNCT: + c = *l++; + if (c == 0 || c > ' ') + return(0); + break; + + case CLASS: + case NCLASS: + c = tolower(*l++); + n = *p++ & 0377; + do { + if (*p == RANGE) { + p += 3; + n -= 2; + if (c >= p[-2] && c <= p[-1]) + break; + } + else if (c == *p++) + break; + } while (--n > 1); + if ((op == CLASS) == (n <= 1)) + return(0); + if (op == CLASS) + p += n - 2; + break; + + case MINUS: + e = pmatch(l, p); /* Look for a match */ + while (*p++ != ENDPAT); /* Skip over pattern */ + if (e) /* Got a match? */ + l = e; /* Yes, update string */ + break; /* Always succeeds */ + + case PLUS: /* One or more ... */ + if ((l = pmatch(l, p)) == 0) + return(0); /* Gotta have a match */ + case STAR: /* Zero or more ... */ + are = l; /* Remember line start */ + while (*l && (e = pmatch(l, p))) + l = e; /* Get longest match */ + while (*p++ != ENDPAT); /* Skip over pattern */ + while (l >= are) { /* Try to match rest */ + if (e = pmatch(l, p)) + return(e); + --l; /* Nope, try earlier */ + } + return(0); /* Nothing else worked */ + + default: + printf("Bad op code %d\n", op); + error("Cannot happen -- match\n"); + } + } + return(l); +} + +/*** Report an error ***********************************/ +void error(char *s) +{ + fprintf(stderr, "%s", s); + exit(1); +} + +/*** Main program - parse arguments & grep *************/ +int main(int argc, char **argv) +{ + char *p; + int c, i; + int gotpattern; + + FILE *f; + + if (argc <= 1) + usage("No arguments"); + if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) { + help(documentation); + help(patdoc); + return 0; + } + nfile = argc-1; + gotpattern = 0; + for (i=1; i < argc; ++i) { + p = argv[i]; + if (*p == '-') { + ++p; + while (c = *p++) { + switch(tolower(c)) { + + case '?': + help(documentation); + break; + + case 'C': + case 'c': + ++cflag; + break; + + case 'D': + case 'd': + ++debug; + break; + + case 'F': + case 'f': + ++fflag; + break; + + case 'n': + case 'N': + ++nflag; + break; + + case 'v': + case 'V': + ++vflag; + break; + + default: + usage("Unknown flag"); + } + } + argv[i] = 0; + --nfile; + } else if (!gotpattern) { + compile(p); + argv[i] = 0; + ++gotpattern; + --nfile; + } + } + if (!gotpattern) + usage("No pattern"); + if (nfile == 0) + grep(stdin, 0); + else { + fflag = fflag ^ (nfile > 0); + for (i=1; i < argc; ++i) { + if (p = argv[i]) { + if ((f=fopen(p, "r")) == NULL) + cant(p); + else { + grep(f, p); + fclose(f); + } + } + } + } + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/46_grep.expect b/tinyc/tests/tests2/46_grep.expect new file mode 100644 index 000000000..e8a67916b --- /dev/null +++ b/tinyc/tests/tests2/46_grep.expect @@ -0,0 +1,3 @@ +File 46_grep.c: +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ + diff --git a/tinyc/tests/tests2/47_switch_return.c b/tinyc/tests/tests2/47_switch_return.c new file mode 100644 index 000000000..1ec7924c4 --- /dev/null +++ b/tinyc/tests/tests2/47_switch_return.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +void fred(int x) +{ + switch (x) + { + case 1: printf("1\n"); return; + case 2: printf("2\n"); break; + case 3: printf("3\n"); return; + } + + printf("out\n"); +} + +int main() +{ + fred(1); + fred(2); + fred(3); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/47_switch_return.expect b/tinyc/tests/tests2/47_switch_return.expect new file mode 100644 index 000000000..b6deb7e9e --- /dev/null +++ b/tinyc/tests/tests2/47_switch_return.expect @@ -0,0 +1,4 @@ +1 +2 +out +3 diff --git a/tinyc/tests/tests2/48_nested_break.c b/tinyc/tests/tests2/48_nested_break.c new file mode 100644 index 000000000..5bc5ba47f --- /dev/null +++ b/tinyc/tests/tests2/48_nested_break.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +int main() +{ + int a; + char b; + + a = 0; + while (a < 2) + { + printf("%d", a++); + break; + + b = 'A'; + while (b < 'C') + { + printf("%c", b++); + } + printf("e"); + } + printf("\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/48_nested_break.expect b/tinyc/tests/tests2/48_nested_break.expect new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/tinyc/tests/tests2/48_nested_break.expect @@ -0,0 +1 @@ +0 diff --git a/tinyc/tests/tests2/49_bracket_evaluation.c b/tinyc/tests/tests2/49_bracket_evaluation.c new file mode 100644 index 000000000..0cbe57d62 --- /dev/null +++ b/tinyc/tests/tests2/49_bracket_evaluation.c @@ -0,0 +1,23 @@ +#include <stdio.h> + +struct point +{ + double x; + double y; +}; + +struct point point_array[100]; + +int main() +{ + int my_point = 10; + + point_array[my_point].x = 12.34; + point_array[my_point].y = 56.78; + + printf("%f, %f\n", point_array[my_point].x, point_array[my_point].y); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/49_bracket_evaluation.expect b/tinyc/tests/tests2/49_bracket_evaluation.expect new file mode 100644 index 000000000..1da66dbeb --- /dev/null +++ b/tinyc/tests/tests2/49_bracket_evaluation.expect @@ -0,0 +1 @@ +12.340000, 56.780000 diff --git a/tinyc/tests/tests2/50_logical_second_arg.c b/tinyc/tests/tests2/50_logical_second_arg.c new file mode 100644 index 000000000..ddec08c87 --- /dev/null +++ b/tinyc/tests/tests2/50_logical_second_arg.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +int fred() +{ + printf("fred\n"); + return 0; +} + +int joe() +{ + printf("joe\n"); + return 1; +} + +int main() +{ + printf("%d\n", fred() && joe()); + printf("%d\n", fred() || joe()); + printf("%d\n", joe() && fred()); + printf("%d\n", joe() || fred()); + printf("%d\n", fred() && (1 + joe())); + printf("%d\n", fred() || (0 + joe())); + printf("%d\n", joe() && (0 + fred())); + printf("%d\n", joe() || (1 + fred())); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/50_logical_second_arg.expect b/tinyc/tests/tests2/50_logical_second_arg.expect new file mode 100644 index 000000000..d6174ae7d --- /dev/null +++ b/tinyc/tests/tests2/50_logical_second_arg.expect @@ -0,0 +1,20 @@ +fred +0 +fred +joe +1 +joe +fred +0 +joe +1 +fred +0 +fred +joe +1 +joe +fred +0 +joe +1 diff --git a/tinyc/tests/tests2/51_static.c b/tinyc/tests/tests2/51_static.c new file mode 100644 index 000000000..d6c0917cf --- /dev/null +++ b/tinyc/tests/tests2/51_static.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +static int fred = 1234; +static int joe; + +void henry() +{ + static int fred = 4567; + + printf("%d\n", fred); + fred++; +} + +int main() +{ + printf("%d\n", fred); + henry(); + henry(); + henry(); + henry(); + printf("%d\n", fred); + fred = 8901; + joe = 2345; + printf("%d\n", fred); + printf("%d\n", joe); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/51_static.expect b/tinyc/tests/tests2/51_static.expect new file mode 100644 index 000000000..18224fa3e --- /dev/null +++ b/tinyc/tests/tests2/51_static.expect @@ -0,0 +1,8 @@ +1234 +4567 +4568 +4569 +4570 +1234 +8901 +2345 diff --git a/tinyc/tests/tests2/52_unnamed_enum.c b/tinyc/tests/tests2/52_unnamed_enum.c new file mode 100644 index 000000000..d0395b202 --- /dev/null +++ b/tinyc/tests/tests2/52_unnamed_enum.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +enum fred { a, b, c }; + +int main() +{ + printf("a=%d\n", a); + printf("b=%d\n", b); + printf("c=%d\n", c); + + enum fred d; + + typedef enum { e, f, g } h; + typedef enum { i, j, k } m; + + printf("e=%d\n", e); + printf("f=%d\n", f); + printf("g=%d\n", g); + + printf("i=%d\n", i); + printf("j=%d\n", j); + printf("k=%d\n", k); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/52_unnamed_enum.expect b/tinyc/tests/tests2/52_unnamed_enum.expect new file mode 100644 index 000000000..84f2ac846 --- /dev/null +++ b/tinyc/tests/tests2/52_unnamed_enum.expect @@ -0,0 +1,9 @@ +a=0 +b=1 +c=2 +e=0 +f=1 +g=2 +i=0 +j=1 +k=2 diff --git a/tinyc/tests/tests2/54_goto.c b/tinyc/tests/tests2/54_goto.c new file mode 100644 index 000000000..2e151bb76 --- /dev/null +++ b/tinyc/tests/tests2/54_goto.c @@ -0,0 +1,56 @@ +#include <stdio.h> + +void fred() +{ + printf("In fred()\n"); + goto done; + printf("In middle\n"); +done: + printf("At end\n"); +} + +void joe() +{ + int b = 5678; + + printf("In joe()\n"); + + { + int c = 1234; + printf("c = %d\n", c); + goto outer; + printf("uh-oh\n"); + } + +outer: + + printf("done\n"); +} + +void henry() +{ + int a; + + printf("In henry()\n"); + goto inner; + + { + int b; +inner: + b = 1234; + printf("b = %d\n", b); + } + + printf("done\n"); +} + +int main() +{ + fred(); + joe(); + henry(); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/54_goto.expect b/tinyc/tests/tests2/54_goto.expect new file mode 100644 index 000000000..8e553fa62 --- /dev/null +++ b/tinyc/tests/tests2/54_goto.expect @@ -0,0 +1,8 @@ +In fred() +At end +In joe() +c = 1234 +done +In henry() +b = 1234 +done diff --git a/tinyc/tests/tests2/55_lshift_type.c b/tinyc/tests/tests2/55_lshift_type.c new file mode 100644 index 000000000..aa3e51a16 --- /dev/null +++ b/tinyc/tests/tests2/55_lshift_type.c @@ -0,0 +1,52 @@ +/* $Id: lshift-type.c 53089 2012-07-06 11:18:26Z vinc17/ypig $ + +Tests on left-shift type, written by Vincent Lefevre <vincent@vinc17.net>. + +ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on +each of the operands. The type of the result is that of the promoted +left operand." +*/ + +#include <stdio.h> + +#define PTYPE(M) ((M) < 0 || -(M) < 0 ? -1 : 1) * (int) sizeof((M)+0) +#define CHECK(X,T) check(#X, PTYPE(X), PTYPE((X) << (T) 1)) +#define TEST1(X,T) do { CHECK(X,T); CHECK(X,unsigned T); } while (0) +#define TEST2(X) \ + do \ + { \ + TEST1((X),short); \ + TEST1((X),int); \ + TEST1((X),long); \ + TEST1((X),long long); \ + } \ + while (0) +#define TEST3(X,T) do { TEST2((T)(X)); TEST2((unsigned T)(X)); } while (0) +#define TEST4(X) \ + do \ + { \ + TEST3((X),short); \ + TEST3((X),int); \ + TEST3((X),long); \ + TEST3((X),long long); \ + } \ + while (0) + +static int debug, nfailed = 0; + +static void check (const char *s, int arg1, int shift) +{ + int failed = arg1 != shift; + if (debug || failed) + printf ("%s %d %d\n", s, arg1, shift); + nfailed += failed; +} + +int main (int argc, char **argv) +{ + debug = argc > 1; + TEST4(1); + TEST4(-1); + printf ("%d test(s) failed\n", nfailed); + return nfailed != 0; +} diff --git a/tinyc/tests/tests2/55_lshift_type.expect b/tinyc/tests/tests2/55_lshift_type.expect new file mode 100644 index 000000000..8523767af --- /dev/null +++ b/tinyc/tests/tests2/55_lshift_type.expect @@ -0,0 +1 @@ +0 test(s) failed diff --git a/tinyc/tests/tests2/60_errors_and_warnings.c b/tinyc/tests/tests2/60_errors_and_warnings.c new file mode 100644 index 000000000..0028caffb --- /dev/null +++ b/tinyc/tests/tests2/60_errors_and_warnings.c @@ -0,0 +1,51 @@ +#if defined test_56_btype_excess_1 +struct A {} int i; + +#elif defined test_57_btype_excess_2 +char int i; + +#elif defined test_58_function_redefinition +int f(void) { return 0; } +int f(void) { return 1; } + +#elif defined test_global_redefinition +int xxx = 1; +int xxx; +int xxx = 2; + +#elif defined test_59_function_array +int (*fct)[42](int x); + +#elif defined test_60_enum_redefinition +enum color { RED, GREEN, BLUE }; +enum color { R, G, B }; +enum color c; + +#elif defined test_62_enumerator_redefinition +enum color { RED, GREEN, BLUE }; +enum rgb { RED, G, B}; +enum color c = RED; + +#elif defined test_63_local_enumerator_redefinition +enum { + FOO, + BAR +}; + +int main(void) +{ + enum { + FOO = 2, + BAR + }; + + return BAR - FOO; +} + +#elif defined test_61_undefined_enum +enum rgb3 c = 42; + +#elif defined test_74_non_const_init +int i = i++; + +#endif diff --git a/tinyc/tests/tests2/60_errors_and_warnings.expect b/tinyc/tests/tests2/60_errors_and_warnings.expect new file mode 100644 index 000000000..ed6a69019 --- /dev/null +++ b/tinyc/tests/tests2/60_errors_and_warnings.expect @@ -0,0 +1,28 @@ +[test_56_btype_excess_1] +60_errors_and_warnings.c:2: error: too many basic types + +[test_57_btype_excess_2] +60_errors_and_warnings.c:5: error: too many basic types + +[test_58_function_redefinition] +60_errors_and_warnings.c:9: error: redefinition of 'f' + +[test_global_redefinition] +60_errors_and_warnings.c:14: error: redefinition of 'xxx' + +[test_59_function_array] +60_errors_and_warnings.c:17: error: declaration of an array of functions + +[test_60_enum_redefinition] +60_errors_and_warnings.c:21: error: struct/union/enum already defined + +[test_62_enumerator_redefinition] +60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED' + +[test_63_local_enumerator_redefinition] + +[test_61_undefined_enum] +60_errors_and_warnings.c:46: error: unknown type size + +[test_74_non_const_init] +60_errors_and_warnings.c:49: error: initializer element is not constant diff --git a/tinyc/tests/tests2/64_macro_nesting.c b/tinyc/tests/tests2/64_macro_nesting.c new file mode 100644 index 000000000..676e5d3ef --- /dev/null +++ b/tinyc/tests/tests2/64_macro_nesting.c @@ -0,0 +1,12 @@ +#include <stdio.h> // printf() + +#define CAT2(a,b) a##b +#define CAT(a,b) CAT2(a,b) +#define AB(x) CAT(x,y) + +int main(void) +{ + int xy = 42; + printf("%d\n", CAT(A,B)(x)); + return 0; +} diff --git a/tinyc/tests/tests2/64_macro_nesting.expect b/tinyc/tests/tests2/64_macro_nesting.expect new file mode 100644 index 000000000..d81cc0710 --- /dev/null +++ b/tinyc/tests/tests2/64_macro_nesting.expect @@ -0,0 +1 @@ +42 diff --git a/tinyc/tests/tests2/67_macro_concat.c b/tinyc/tests/tests2/67_macro_concat.c new file mode 100644 index 000000000..c580d3a64 --- /dev/null +++ b/tinyc/tests/tests2/67_macro_concat.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +#define P(A,B) A ## B ; bob +#define Q(A,B) A ## B+ + +int main(void) +{ + int bob, jim = 21; + bob = P(jim,) *= 2; + printf("jim: %d, bob: %d\n", jim, bob); + jim = 60 Q(+,)3; + printf("jim: %d\n", jim); + return 0; +} diff --git a/tinyc/tests/tests2/67_macro_concat.expect b/tinyc/tests/tests2/67_macro_concat.expect new file mode 100644 index 000000000..8386c2d6c --- /dev/null +++ b/tinyc/tests/tests2/67_macro_concat.expect @@ -0,0 +1,2 @@ +jim: 21, bob: 42 +jim: 63 diff --git a/tinyc/tests/tests2/70_floating_point_literals.c b/tinyc/tests/tests2/70_floating_point_literals.c new file mode 100644 index 000000000..012fb4fab --- /dev/null +++ b/tinyc/tests/tests2/70_floating_point_literals.c @@ -0,0 +1,77 @@ +#include <stdio.h> + +int main() +{ + /* decimal floating constant */ + float fa0 = .123f; + float fa1 = .123E12F; + float fa2 = .123e-12f; + float fa3 = .123e+12f; + printf("%f\n%f\n%f\n%f\n\n", fa0, fa1, fa2, fa3); + + float fb0 = 123.123f; + float fb1 = 123.123E12F; + float fb2 = 123.123e-12f; + float fb3 = 123.123e+12f; + printf("%f\n%f\n%f\n%f\n\n", fb0, fb1, fb2, fb3); + + float fc0 = 123.f; + float fc1 = 123.E12F; + float fc2 = 123.e-12f; + float fc3 = 123.e+12f; + printf("%f\n%f\n%f\n%f\n\n", fc0, fc1, fc2, fc3); + + float fd0 = 123E12F; + float fd1 = 123e-12f; + float fd2 = 123e+12f; + printf("%f\n%f\n%f\n\n", fd0, fd1, fd2); + printf("\n"); + + /* hexadecimal floating constant */ + double da0 = 0X.1ACP12; + double da1 = 0x.1acp-12; + double da2 = 0x.1acp+12; + printf("%f\n%f\n%f\n\n", da0, da1, da2); + + double db0 = 0X1AC.BDP12; + double db1 = 0x1ac.bdp-12; + double db2 = 0x1ac.dbp+12; + printf("%f\n%f\n%f\n\n", db0, db1, db2); + + double dc0 = 0X1AC.P12; + double dc1 = 0x1ac.p-12; + double dc2 = 0x1ac.p+12; + printf("%f\n%f\n%f\n\n", dc0, dc1, dc2); + + double dd0 = 0X1ACP12; + double dd1 = 0x1acp-12; + double dd2 = 0x1acp+12; + printf("%f\n%f\n%f\n\n", dd0, dd1, dd2); + printf("\n"); + +#ifdef __TINYC__ + /* TCC extension + binary floating constant */ + long double la0 = 0B.110101100P12L; + long double la1 = 0b.110101100p-12l; + long double la2 = 0b.110101100p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", la0, la1, la2); + + long double lb0 = 0B110101100.10111101P12L; + long double lb1 = 0b110101100.10111101p-12l; + long double lb2 = 0b110101100.10111101p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", lb0, lb1, lb2); + + long double lc0 = 0B110101100.P12L; + long double lc1 = 0b110101100.p-12l; + long double lc2 = 0b110101100.p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", lc0, lc1, lc2); + + long double ld0 = 0B110101100P12L; + long double ld1 = 0b110101100p-12l; + long double ld2 = 0b110101100p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", ld0, ld1, ld2); +#endif + + return 0; +} diff --git a/tinyc/tests/tests2/70_floating_point_literals.expect b/tinyc/tests/tests2/70_floating_point_literals.expect new file mode 100644 index 000000000..7eb1efb9e --- /dev/null +++ b/tinyc/tests/tests2/70_floating_point_literals.expect @@ -0,0 +1,53 @@ +0.123000 +122999996416.000000 +0.000000 +122999996416.000000 + +123.123001 +123122997002240.000000 +0.000000 +123122997002240.000000 + +123.000000 +123000003231744.000000 +0.000000 +123000003231744.000000 + +123000003231744.000000 +0.000000 +123000003231744.000000 + + +428.000000 +0.000026 +428.000000 + +1756112.000000 +0.104672 +1756592.000000 + +1753088.000000 +0.104492 +1753088.000000 + +1753088.000000 +0.104492 +1753088.000000 + + +3424.000000 +0.000204 +3424.000000 + +1756112.000000 +0.104672 +1756112.000000 + +1753088.000000 +0.104492 +1753088.000000 + +1753088.000000 +0.104492 +1753088.000000 + diff --git a/tinyc/tests/tests2/71_macro_empty_arg.c b/tinyc/tests/tests2/71_macro_empty_arg.c new file mode 100644 index 000000000..f0d3511b9 --- /dev/null +++ b/tinyc/tests/tests2/71_macro_empty_arg.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +#define T(a,b,c) a b c + +int main(void) +{ + printf("%d", T(1,+,2) T(+,,) T(,2,*) T(,7,) T(,,)); + return 0; +} diff --git a/tinyc/tests/tests2/71_macro_empty_arg.expect b/tinyc/tests/tests2/71_macro_empty_arg.expect new file mode 100644 index 000000000..98d9bcb75 --- /dev/null +++ b/tinyc/tests/tests2/71_macro_empty_arg.expect @@ -0,0 +1 @@ +17 diff --git a/tinyc/tests/tests2/72_long_long_constant.c b/tinyc/tests/tests2/72_long_long_constant.c new file mode 100644 index 000000000..66082133d --- /dev/null +++ b/tinyc/tests/tests2/72_long_long_constant.c @@ -0,0 +1,19 @@ +#include <stdio.h> + +int main() +{ + long long int res = 0; + + if (res < -2147483648LL) { + printf("Error: 0 < -2147483648\n"); + return 1; + } + else + if (2147483647LL < res) { + printf("Error: 2147483647 < 0\n"); + return 2; + } + else + printf("long long constant test ok.\n"); + return 0; +} diff --git a/tinyc/tests/tests2/72_long_long_constant.expect b/tinyc/tests/tests2/72_long_long_constant.expect new file mode 100644 index 000000000..dda9e660d --- /dev/null +++ b/tinyc/tests/tests2/72_long_long_constant.expect @@ -0,0 +1 @@ +long long constant test ok. diff --git a/tinyc/tests/tests2/73_arm64.c b/tinyc/tests/tests2/73_arm64.c new file mode 100644 index 000000000..8de61b388 --- /dev/null +++ b/tinyc/tests/tests2/73_arm64.c @@ -0,0 +1,527 @@ +// This program is designed to test some arm64-specific things, such as the +// calling convention, but should give the same results on any architecture. + +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> + +struct s1 { char x[1]; } s1 = { "0" }; +struct s2 { char x[2]; } s2 = { "12" }; +struct s3 { char x[3]; } s3 = { "345" }; +struct s4 { char x[4]; } s4 = { "6789" }; +struct s5 { char x[5]; } s5 = { "abcde" }; +struct s6 { char x[6]; } s6 = { "fghijk" }; +struct s7 { char x[7]; } s7 = { "lmnopqr" }; +struct s8 { char x[8]; } s8 = { "stuvwxyz" }; +struct s9 { char x[9]; } s9 = { "ABCDEFGHI" }; +struct s10 { char x[10]; } s10 = { "JKLMNOPQRS" }; +struct s11 { char x[11]; } s11 = { "TUVWXYZ0123" }; +struct s12 { char x[12]; } s12 = { "456789abcdef" }; +struct s13 { char x[13]; } s13 = { "ghijklmnopqrs" }; +struct s14 { char x[14]; } s14 = { "tuvwxyzABCDEFG" }; +struct s15 { char x[15]; } s15 = { "HIJKLMNOPQRSTUV" }; +struct s16 { char x[16]; } s16 = { "WXYZ0123456789ab" }; +struct s17 { char x[17]; } s17 = { "cdefghijklmnopqrs" }; + +struct hfa11 { float a; } hfa11 = { 11.1 }; +struct hfa12 { float a, b; } hfa12 = { 12.1, 12.2 }; +struct hfa13 { float a, b, c; } hfa13 = { 13.1, 13.2, 13.3 }; +struct hfa14 { float a, b, c, d; } hfa14 = { 14.1, 14.2, 14.3, 14.4 }; + +struct hfa21 { double a; } hfa21 = { 21.1 }; +struct hfa22 { double a, b; } hfa22 = { 22.1, 22.2 }; +struct hfa23 { double a, b, c; } hfa23 = { 23.1, 23.2, 23.3 }; +struct hfa24 { double a, b, c, d; } hfa24 = { 24.1, 24.2, 24.3, 24.4 }; + +struct hfa31 { long double a; } hfa31 = { 31.1 }; +struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 }; +struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 }; +struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 }; + +void fa_s1(struct s1 a) { printf("%.1s\n", a.x); } +void fa_s2(struct s2 a) { printf("%.2s\n", a.x); } +void fa_s3(struct s3 a) { printf("%.3s\n", a.x); } +void fa_s4(struct s4 a) { printf("%.4s\n", a.x); } +void fa_s5(struct s5 a) { printf("%.5s\n", a.x); } +void fa_s6(struct s6 a) { printf("%.6s\n", a.x); } +void fa_s7(struct s7 a) { printf("%.7s\n", a.x); } +void fa_s8(struct s8 a) { printf("%.8s\n", a.x); } +void fa_s9(struct s9 a) { printf("%.9s\n", a.x); } +void fa_s10(struct s10 a) { printf("%.10s\n", a.x); } +void fa_s11(struct s11 a) { printf("%.11s\n", a.x); } +void fa_s12(struct s12 a) { printf("%.12s\n", a.x); } +void fa_s13(struct s13 a) { printf("%.13s\n", a.x); } +void fa_s14(struct s14 a) { printf("%.14s\n", a.x); } +void fa_s15(struct s15 a) { printf("%.15s\n", a.x); } +void fa_s16(struct s16 a) { printf("%.16s\n", a.x); } +void fa_s17(struct s17 a) { printf("%.17s\n", a.x); } + +void fa_hfa11(struct hfa11 a) +{ printf("%.1f\n", a.a); } +void fa_hfa12(struct hfa12 a) +{ printf("%.1f %.1f\n", a.a, a.a); } +void fa_hfa13(struct hfa13 a) +{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); } +void fa_hfa14(struct hfa14 a) +{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); } + +void fa_hfa21(struct hfa21 a) +{ printf("%.1f\n", a.a); } +void fa_hfa22(struct hfa22 a) +{ printf("%.1f %.1f\n", a.a, a.a); } +void fa_hfa23(struct hfa23 a) +{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); } +void fa_hfa24(struct hfa24 a) +{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); } + +void fa_hfa31(struct hfa31 a) +{ printf("%.1Lf\n", a.a); } +void fa_hfa32(struct hfa32 a) +{ printf("%.1Lf %.1Lf\n", a.a, a.a); } +void fa_hfa33(struct hfa33 a) +{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); } +void fa_hfa34(struct hfa34 a) +{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); } + +void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d, + struct s12 e, struct s13 f) +{ + printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x); +} + +void fa2(struct s9 a, struct s10 b, struct s11 c, struct s12 d, + struct s13 e, struct s14 f) +{ + printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x); +} + +void fa3(struct hfa14 a, struct hfa23 b, struct hfa32 c) +{ + printf("%.1f %.1f %.1f %.1f %.1Lf %.1Lf\n", + a.a, a.d, b.a, b.c, c.a, c.b); +} + +void fa4(struct s1 a, struct hfa14 b, struct s2 c, struct hfa24 d, + struct s3 e, struct hfa34 f) +{ + printf("%.1s %.1f %.1f %.2s %.1f %.1f %.3s %.1Lf %.1Lf\n", + a.x, b.a, b.d, c.x, d.a, d.d, e.x, f.a, f.d); +} + +void arg(void) +{ + printf("Arguments:\n"); + fa_s1(s1); + fa_s2(s2); + fa_s3(s3); + fa_s4(s4); + fa_s5(s5); + fa_s6(s6); + fa_s7(s7); + fa_s8(s8); + fa_s9(s9); + fa_s10(s10); + fa_s11(s11); + fa_s12(s12); + fa_s13(s13); + fa_s14(s14); + fa_s15(s15); + fa_s16(s16); + fa_s17(s17); + fa_hfa11(hfa11); + fa_hfa12(hfa12); + fa_hfa13(hfa13); + fa_hfa14(hfa14); + fa_hfa21(hfa21); + fa_hfa22(hfa22); + fa_hfa23(hfa23); + fa_hfa24(hfa24); + fa_hfa31(hfa31); + fa_hfa32(hfa32); + fa_hfa33(hfa33); + fa_hfa34(hfa34); + fa1(s8, s9, s10, s11, s12, s13); + fa2(s9, s10, s11, s12, s13, s14); + fa3(hfa14, hfa23, hfa32); + fa4(s1, hfa14, s2, hfa24, s3, hfa34); +} + +struct s1 fr_s1(void) { return s1; } +struct s2 fr_s2(void) { return s2; } +struct s3 fr_s3(void) { return s3; } +struct s4 fr_s4(void) { return s4; } +struct s5 fr_s5(void) { return s5; } +struct s6 fr_s6(void) { return s6; } +struct s7 fr_s7(void) { return s7; } +struct s8 fr_s8(void) { return s8; } +struct s9 fr_s9(void) { return s9; } +struct s10 fr_s10(void) { return s10; } +struct s11 fr_s11(void) { return s11; } +struct s12 fr_s12(void) { return s12; } +struct s13 fr_s13(void) { return s13; } +struct s14 fr_s14(void) { return s14; } +struct s15 fr_s15(void) { return s15; } +struct s16 fr_s16(void) { return s16; } +struct s17 fr_s17(void) { return s17; } + +struct hfa11 fr_hfa11(void) { return hfa11; } +struct hfa12 fr_hfa12(void) { return hfa12; } +struct hfa13 fr_hfa13(void) { return hfa13; } +struct hfa14 fr_hfa14(void) { return hfa14; } + +struct hfa21 fr_hfa21(void) { return hfa21; } +struct hfa22 fr_hfa22(void) { return hfa22; } +struct hfa23 fr_hfa23(void) { return hfa23; } +struct hfa24 fr_hfa24(void) { return hfa24; } + +struct hfa31 fr_hfa31(void) { return hfa31; } +struct hfa32 fr_hfa32(void) { return hfa32; } +struct hfa33 fr_hfa33(void) { return hfa33; } +struct hfa34 fr_hfa34(void) { return hfa34; } + +void ret(void) +{ + struct s1 t1 = fr_s1(); + struct s2 t2 = fr_s2(); + struct s3 t3 = fr_s3(); + struct s4 t4 = fr_s4(); + struct s5 t5 = fr_s5(); + struct s6 t6 = fr_s6(); + struct s7 t7 = fr_s7(); + struct s8 t8 = fr_s8(); + struct s9 t9 = fr_s9(); + struct s10 t10 = fr_s10(); + struct s11 t11 = fr_s11(); + struct s12 t12 = fr_s12(); + struct s13 t13 = fr_s13(); + struct s14 t14 = fr_s14(); + struct s15 t15 = fr_s15(); + struct s16 t16 = fr_s16(); + struct s17 t17 = fr_s17(); + printf("Return values:\n"); + printf("%.1s\n", t1.x); + printf("%.2s\n", t2.x); + printf("%.3s\n", t3.x); + printf("%.4s\n", t4.x); + printf("%.5s\n", t5.x); + printf("%.6s\n", t6.x); + printf("%.7s\n", t7.x); + printf("%.8s\n", t8.x); + printf("%.9s\n", t9.x); + printf("%.10s\n", t10.x); + printf("%.11s\n", t11.x); + printf("%.12s\n", t12.x); + printf("%.13s\n", t13.x); + printf("%.14s\n", t14.x); + printf("%.15s\n", t15.x); + printf("%.16s\n", t16.x); + printf("%.17s\n", t17.x); + printf("%.1f\n", fr_hfa11().a); + printf("%.1f %.1f\n", fr_hfa12().a, fr_hfa12().b); + printf("%.1f %.1f\n", fr_hfa13().a, fr_hfa13().c); + printf("%.1f %.1f\n", fr_hfa14().a, fr_hfa14().d); + printf("%.1f\n", fr_hfa21().a); + printf("%.1f %.1f\n", fr_hfa22().a, fr_hfa22().b); + printf("%.1f %.1f\n", fr_hfa23().a, fr_hfa23().c); + printf("%.1f %.1f\n", fr_hfa24().a, fr_hfa24().d); + printf("%.1Lf\n", fr_hfa31().a); + printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b); + printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c); + printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d); +} + +int match(const char **s, const char *f) +{ + const char *p = *s; + for (p = *s; *f && *f == *p; f++, p++) + ; + if (!*f) { + *s = p - 1; + return 1; + } + return 0; +} + +void myprintf(const char *format, ...) +{ + const char *s; + va_list ap; + va_start(ap, format); + for (s = format; *s; s++) { + if (match(&s, "%7s")) { + struct s7 t7 = va_arg(ap, struct s7); + printf("%.7s", t7.x); + } + else if (match(&s, "%9s")) { + struct s9 t9 = va_arg(ap, struct s9); + printf("%.9s", t9.x); + } + else if (match(&s, "%hfa11")) { + struct hfa11 x = va_arg(ap, struct hfa11); + printf("%.1f,%.1f", x.a, x.a); + } + else if (match(&s, "%hfa12")) { + struct hfa12 x = va_arg(ap, struct hfa12); + printf("%.1f,%.1f", x.a, x.b); + } + else if (match(&s, "%hfa13")) { + struct hfa13 x = va_arg(ap, struct hfa13); + printf("%.1f,%.1f", x.a, x.c); + } + else if (match(&s, "%hfa14")) { + struct hfa14 x = va_arg(ap, struct hfa14); + printf("%.1f,%.1f", x.a, x.d); + } + else if (match(&s, "%hfa21")) { + struct hfa21 x = va_arg(ap, struct hfa21); + printf("%.1f,%.1f", x.a, x.a); + } + else if (match(&s, "%hfa22")) { + struct hfa22 x = va_arg(ap, struct hfa22); + printf("%.1f,%.1f", x.a, x.b); + } + else if (match(&s, "%hfa23")) { + struct hfa23 x = va_arg(ap, struct hfa23); + printf("%.1f,%.1f", x.a, x.c); + } + else if (match(&s, "%hfa24")) { + struct hfa24 x = va_arg(ap, struct hfa24); + printf("%.1f,%.1f", x.a, x.d); + } + else if (match(&s, "%hfa31")) { + struct hfa31 x = va_arg(ap, struct hfa31); + printf("%.1Lf,%.1Lf", x.a, x.a); + } + else if (match(&s, "%hfa32")) { + struct hfa32 x = va_arg(ap, struct hfa32); + printf("%.1Lf,%.1Lf", x.a, x.b); + } + else if (match(&s, "%hfa33")) { + struct hfa33 x = va_arg(ap, struct hfa33); + printf("%.1Lf,%.1Lf", x.a, x.c); + } + else if (match(&s, "%hfa34")) { + struct hfa34 x = va_arg(ap, struct hfa34); + printf("%.1Lf,%.1Lf", x.a, x.d); + } + else + putchar(*s); + } + putchar('\n'); +} + +void stdarg(void) +{ + printf("stdarg:\n"); + myprintf("%9s %9s %9s %9s %9s %9s", s9, s9, s9, s9, s9, s9); + myprintf("%7s %9s %9s %9s %9s %9s", s7, s9, s9, s9, s9, s9); + + myprintf("HFA long double:"); + myprintf("%hfa34 %hfa34 %hfa34 %hfa34", hfa34, hfa34, hfa34, hfa34); + myprintf("%hfa33 %hfa34 %hfa34 %hfa34", hfa33, hfa34, hfa34, hfa34); + myprintf("%hfa32 %hfa34 %hfa34 %hfa34", hfa32, hfa34, hfa34, hfa34); + myprintf("%hfa31 %hfa34 %hfa34 %hfa34", hfa31, hfa34, hfa34, hfa34); + + myprintf("%hfa32 %hfa33 %hfa33 %hfa33 %hfa33", + hfa32, hfa33, hfa33, hfa33, hfa33); + myprintf("%hfa31 %hfa33 %hfa33 %hfa33 %hfa33", + hfa31, hfa33, hfa33, hfa33, hfa33); + myprintf("%hfa33 %hfa33 %hfa33 %hfa33", + hfa33, hfa33, hfa33, hfa33); + + myprintf("%hfa34 %hfa32 %hfa32 %hfa32 %hfa32", + hfa34, hfa32, hfa32, hfa32, hfa32); + myprintf("%hfa33 %hfa32 %hfa32 %hfa32 %hfa32", + hfa33, hfa32, hfa32, hfa32, hfa32); + + myprintf("%hfa34 %hfa32 %hfa31 %hfa31 %hfa31 %hfa31", + hfa34, hfa32, hfa31, hfa31, hfa31, hfa31); + + myprintf("HFA double:"); + myprintf("%hfa24 %hfa24 %hfa24 %hfa24", hfa24, hfa24, hfa24, hfa24); + myprintf("%hfa23 %hfa24 %hfa24 %hfa24", hfa23, hfa24, hfa24, hfa24); + myprintf("%hfa22 %hfa24 %hfa24 %hfa24", hfa22, hfa24, hfa24, hfa24); + myprintf("%hfa21 %hfa24 %hfa24 %hfa24", hfa21, hfa24, hfa24, hfa24); + + myprintf("%hfa22 %hfa23 %hfa23 %hfa23 %hfa23", + hfa22, hfa23, hfa23, hfa23, hfa23); + myprintf("%hfa21 %hfa23 %hfa23 %hfa23 %hfa23", + hfa21, hfa23, hfa23, hfa23, hfa23); + myprintf("%hfa23 %hfa23 %hfa23 %hfa23", + hfa23, hfa23, hfa23, hfa23); + + myprintf("%hfa24 %hfa22 %hfa22 %hfa22 %hfa22", + hfa24, hfa22, hfa22, hfa22, hfa22); + myprintf("%hfa23 %hfa22 %hfa22 %hfa22 %hfa22", + hfa23, hfa22, hfa22, hfa22, hfa22); + + myprintf("%hfa24 %hfa22 %hfa21 %hfa21 %hfa21 %hfa21", + hfa24, hfa22, hfa21, hfa21, hfa21, hfa21); + + myprintf("HFA float:"); + myprintf("%hfa14 %hfa14 %hfa14 %hfa14", hfa14, hfa14, hfa14, hfa14); + myprintf("%hfa13 %hfa14 %hfa14 %hfa14", hfa13, hfa14, hfa14, hfa14); + myprintf("%hfa12 %hfa14 %hfa14 %hfa14", hfa12, hfa14, hfa14, hfa14); + myprintf("%hfa11 %hfa14 %hfa14 %hfa14", hfa11, hfa14, hfa14, hfa14); + + myprintf("%hfa12 %hfa13 %hfa13 %hfa13 %hfa13", + hfa12, hfa13, hfa13, hfa13, hfa13); + myprintf("%hfa11 %hfa13 %hfa13 %hfa13 %hfa13", + hfa11, hfa13, hfa13, hfa13, hfa13); + myprintf("%hfa13 %hfa13 %hfa13 %hfa13", + hfa13, hfa13, hfa13, hfa13); + + myprintf("%hfa14 %hfa12 %hfa12 %hfa12 %hfa12", + hfa14, hfa12, hfa12, hfa12, hfa12); + myprintf("%hfa13 %hfa12 %hfa12 %hfa12 %hfa12", + hfa13, hfa12, hfa12, hfa12, hfa12); + + myprintf("%hfa14 %hfa12 %hfa11 %hfa11 %hfa11 %hfa11", + hfa14, hfa12, hfa11, hfa11, hfa11, hfa11); +} + +void pll(unsigned long long x) +{ + printf("%llx\n", x); +} + +void movi(void) +{ + printf("MOVI:\n"); + pll(0); + pll(0xabcd); + pll(0xabcd0000); + pll(0xabcd00000000); + pll(0xabcd000000000000); + pll(0xffffabcd); + pll(0xabcdffff); + pll(0xffffffffffffabcd); + pll(0xffffffffabcdffff); + pll(0xffffabcdffffffff); + pll(0xabcdffffffffffff); + pll(0xaaaaaaaa); + pll(0x5555555555555555); + pll(0x77777777); + pll(0x3333333333333333); + pll(0xf8f8f8f8); + pll(0x1e1e1e1e1e1e1e1e); + pll(0x3f803f80); + pll(0x01ff01ff01ff01ff); + pll(0x007fffc0); + pll(0x03fff80003fff800); + pll(0x0007fffffffffe00); + + pll(0xabcd1234); + pll(0xabcd00001234); + pll(0xabcd000000001234); + pll(0xabcd12340000); + pll(0xabcd000012340000); + pll(0xabcd123400000000); + pll(0xffffffffabcd1234); + pll(0xffffabcdffff1234); + pll(0xabcdffffffff1234); + pll(0xffffabcd1234ffff); + pll(0xabcdffff1234ffff); + pll(0xabcd1234ffffffff); + + pll(0xffffef0123456789); + pll(0xabcdef012345ffff); + + pll(0xabcdef0123456789); +} + +static uint32_t addip0(uint32_t x) { return x + 0; } +static uint64_t sublp0(uint64_t x) { return x - 0; } +static uint32_t addip123(uint32_t x) { return x + 123; } +static uint64_t addlm123(uint64_t x) { return x + -123; } +static uint64_t sublp4095(uint64_t x) { return x - 4095; } +static uint32_t subim503808(uint32_t x) { return x - -503808; } +static uint64_t addp12345(uint64_t x) { return x + 12345; } +static uint32_t subp12345(uint32_t x) { return x - 12345; } + +static uint32_t mvni(uint32_t x) { return 0xffffffff - x; } +static uint64_t negl(uint64_t x) { return 0 - x; } +static uint32_t rsbi123(uint32_t x) { return 123 - x; } +static uint64_t rsbl123(uint64_t x) { return 123 - x; } + +static uint32_t andi0(uint32_t x) { return x & 0; } +static uint64_t andlm1(uint64_t x) { return x & -1; } +static uint64_t orrl0(uint64_t x) { return x | 0; } +static uint32_t orrim1(uint32_t x) { return x | -1; } +static uint32_t eori0(uint32_t x) { return x ^ 0; } +static uint64_t eorlm1(uint64_t x) { return x ^ -1; } +static uint32_t and0xf0(uint32_t x) { return x & 0xf0; } +static uint64_t orr0xf0(uint64_t x) { return x | 0xf0; } +static uint64_t eor0xf0(uint64_t x) { return x ^ 0xf0; } + +static uint32_t lsli0(uint32_t x) { return x << 0; } +static uint32_t lsri0(uint32_t x) { return x >> 0; } +static int64_t asrl0(int64_t x) { return x >> 0; } +static uint32_t lsli1(uint32_t x) { return x << 1; } +static uint32_t lsli31(uint32_t x) { return x << 31; } +static uint64_t lsll1(uint64_t x) { return x << 1; } +static uint64_t lsll63(uint64_t x) { return x << 63; } +static uint32_t lsri1(uint32_t x) { return x >> 1; } +static uint32_t lsri31(uint32_t x) { return x >> 31; } +static uint64_t lsrl1(uint64_t x) { return x >> 1; } +static uint64_t lsrl63(uint64_t x) { return x >> 63; } +static int32_t asri1(int32_t x) { return x >> 1; } +static int32_t asri31(int32_t x) { return x >> 31; } +static int64_t asrl1(int64_t x) { return x >> 1; } +static int64_t asrl63(int64_t x) { return x >> 63; } + +void opi(void) +{ + int x = 1000; + pll(addip0(x)); + pll(sublp0(x)); + pll(addip123(x)); + pll(addlm123(x)); + pll(sublp4095(x)); + pll(subim503808(x)); + pll(addp12345(x)); + pll(subp12345(x)); + pll(mvni(x)); + pll(negl(x)); + pll(rsbi123(x)); + pll(rsbl123(x)); + pll(andi0(x)); + pll(andlm1(x)); + pll(orrl0(x)); + pll(orrim1(x)); + pll(eori0(x)); + pll(eorlm1(x)); + pll(and0xf0(x)); + pll(orr0xf0(x)); + pll(eor0xf0(x)); + pll(lsli0(x)); + pll(lsri0(x)); + pll(asrl0(x)); + pll(lsli1(x)); + pll(lsli31(x)); + pll(lsll1(x)); + pll(lsll63(x)); + pll(lsri1(x)); + pll(lsri31(x)); + pll(lsrl1(x)); + pll(lsrl63(x)); + pll(asri1(x)); + pll(asri31(x)); + pll(asrl1(x)); + pll(asrl63(x)); +} + +void pcs(void) +{ + arg(); + ret(); + stdarg(); + movi(); + opi(); +} + +int main() +{ + pcs(); + return 0; +} diff --git a/tinyc/tests/tests2/73_arm64.expect b/tinyc/tests/tests2/73_arm64.expect new file mode 100644 index 000000000..7bdebd307 --- /dev/null +++ b/tinyc/tests/tests2/73_arm64.expect @@ -0,0 +1,174 @@ +Arguments: +0 +12 +345 +6789 +abcde +fghijk +lmnopqr +stuvwxyz +ABCDEFGHI +JKLMNOPQRS +TUVWXYZ0123 +456789abcdef +ghijklmnopqrs +tuvwxyzABCDEFG +HIJKLMNOPQRSTUV +WXYZ0123456789ab +cdefghijklmnopqrs +11.1 +12.1 12.1 +13.1 13.2 13.3 +14.1 14.2 14.3 14.4 +21.1 +22.1 22.1 +23.1 23.2 23.3 +24.1 24.2 24.3 24.4 +31.1 +32.1 32.1 +33.1 33.2 33.3 +34.1 34.2 34.3 34.4 +stu ABC JKL TUV 456 ghi +ABC JKL TUV 456 ghi tuv +14.1 14.4 23.1 23.3 32.1 32.2 +0 14.1 14.4 12 24.1 24.4 345 34.1 34.4 +Return values: +0 +12 +345 +6789 +abcde +fghijk +lmnopqr +stuvwxyz +ABCDEFGHI +JKLMNOPQRS +TUVWXYZ0123 +456789abcdef +ghijklmnopqrs +tuvwxyzABCDEFG +HIJKLMNOPQRSTUV +WXYZ0123456789ab +cdefghijklmnopqrs +11.1 +12.1 12.2 +13.1 13.3 +14.1 14.4 +21.1 +22.1 22.2 +23.1 23.3 +24.1 24.4 +31.1 +32.1 32.2 +33.1 33.3 +34.1 34.4 +stdarg: +ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI +lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI +HFA long double: +34.1,34.4 34.1,34.4 34.1,34.4 34.1,34.4 +33.1,33.3 34.1,34.4 34.1,34.4 34.1,34.4 +32.1,32.2 34.1,34.4 34.1,34.4 34.1,34.4 +31.1,31.1 34.1,34.4 34.1,34.4 34.1,34.4 +32.1,32.2 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +31.1,31.1 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +34.1,34.4 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2 +33.1,33.3 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2 +34.1,34.4 32.1,32.2 31.1,31.1 31.1,31.1 31.1,31.1 31.1,31.1 +HFA double: +24.1,24.4 24.1,24.4 24.1,24.4 24.1,24.4 +23.1,23.3 24.1,24.4 24.1,24.4 24.1,24.4 +22.1,22.2 24.1,24.4 24.1,24.4 24.1,24.4 +21.1,21.1 24.1,24.4 24.1,24.4 24.1,24.4 +22.1,22.2 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +21.1,21.1 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +24.1,24.4 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2 +23.1,23.3 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2 +24.1,24.4 22.1,22.2 21.1,21.1 21.1,21.1 21.1,21.1 21.1,21.1 +HFA float: +14.1,14.4 14.1,14.4 14.1,14.4 14.1,14.4 +13.1,13.3 14.1,14.4 14.1,14.4 14.1,14.4 +12.1,12.2 14.1,14.4 14.1,14.4 14.1,14.4 +11.1,11.1 14.1,14.4 14.1,14.4 14.1,14.4 +12.1,12.2 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +11.1,11.1 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +14.1,14.4 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2 +13.1,13.3 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2 +14.1,14.4 12.1,12.2 11.1,11.1 11.1,11.1 11.1,11.1 11.1,11.1 +MOVI: +0 +abcd +abcd0000 +abcd00000000 +abcd000000000000 +ffffabcd +abcdffff +ffffffffffffabcd +ffffffffabcdffff +ffffabcdffffffff +abcdffffffffffff +aaaaaaaa +5555555555555555 +77777777 +3333333333333333 +f8f8f8f8 +1e1e1e1e1e1e1e1e +3f803f80 +1ff01ff01ff01ff +7fffc0 +3fff80003fff800 +7fffffffffe00 +abcd1234 +abcd00001234 +abcd000000001234 +abcd12340000 +abcd000012340000 +abcd123400000000 +ffffffffabcd1234 +ffffabcdffff1234 +abcdffffffff1234 +ffffabcd1234ffff +abcdffff1234ffff +abcd1234ffffffff +ffffef0123456789 +abcdef012345ffff +abcdef0123456789 +3e8 +3e8 +463 +36d +fffffffffffff3e9 +7b3e8 +3421 +ffffd3af +fffffc17 +fffffffffffffc18 +fffffc93 +fffffffffffffc93 +0 +3e8 +3e8 +ffffffff +3e8 +fffffffffffffc17 +e0 +3f8 +318 +3e8 +3e8 +3e8 +7d0 +0 +7d0 +0 +1f4 +0 +1f4 +0 +1f4 +0 +1f4 +0 diff --git a/tinyc/tests/tests2/75_array_in_struct_init.c b/tinyc/tests/tests2/75_array_in_struct_init.c new file mode 100644 index 000000000..234e3c4fa --- /dev/null +++ b/tinyc/tests/tests2/75_array_in_struct_init.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +/* This test is a snippet from the J interpreter */ + +typedef long I; +typedef struct{I c[4];I b,e,k;} PT; + +PT cases[] = { + ((I)4194304L +(I)2097152L +(I)67108864L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), -1L, 1,2,1, + ((I)+4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L, (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 2,3,2, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,2, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)524288L, -1L, 1,2,1, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)1048576L, (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,1, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (I)262144L, 1,3,1, + ((I)4194304L +(I)2097152L +(I)67108864L), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 1,2,1, + (I)33554432L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)2097152L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 0,2,1, + (I)67108864L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)134217728L, -1L, 0,2,0, +}; + +int main() { + int i, j; + + for(j=0; j < sizeof(cases)/sizeof(cases[0]); j++) { + for(i=0; i < sizeof(cases->c)/sizeof(cases->c[0]); i++) + printf("cases[%d].c[%d]=%ld\n", j, i, cases[j].c[i]); + + printf("cases[%d].b=%ld\n", j, cases[j].b); + printf("cases[%d].e=%ld\n", j, cases[j].e); + printf("cases[%d].k=%ld\n", j, cases[j].k); + printf("\n"); + } + return 0; +} diff --git a/tinyc/tests/tests2/75_array_in_struct_init.expect b/tinyc/tests/tests2/75_array_in_struct_init.expect new file mode 100644 index 000000000..2b75aa59d --- /dev/null +++ b/tinyc/tests/tests2/75_array_in_struct_init.expect @@ -0,0 +1,72 @@ +cases[0].c[0]=73400320 +cases[0].c[1]=262144 +cases[0].c[2]=805567999 +cases[0].c[3]=-1 +cases[0].b=1 +cases[0].e=2 +cases[0].k=1 + +cases[1].c[0]=879754751 +cases[1].c[1]=262144 +cases[1].c[2]=262144 +cases[1].c[3]=805567999 +cases[1].b=2 +cases[1].e=3 +cases[1].k=2 + +cases[2].c[0]=879754751 +cases[2].c[1]=805567999 +cases[2].c[2]=262144 +cases[2].c[3]=805567999 +cases[2].b=1 +cases[2].e=3 +cases[2].k=2 + +cases[3].c[0]=879754751 +cases[3].c[1]=805830143 +cases[3].c[2]=524288 +cases[3].c[3]=-1 +cases[3].b=1 +cases[3].e=2 +cases[3].k=1 + +cases[4].c[0]=879754751 +cases[4].c[1]=805830143 +cases[4].c[2]=1048576 +cases[4].c[3]=805830143 +cases[4].b=1 +cases[4].e=3 +cases[4].k=1 + +cases[5].c[0]=879754751 +cases[5].c[1]=805830143 +cases[5].c[2]=262144 +cases[5].c[3]=262144 +cases[5].b=1 +cases[5].e=3 +cases[5].k=1 + +cases[6].c[0]=73400320 +cases[6].c[1]=807403007 +cases[6].c[2]=807403007 +cases[6].c[3]=-1 +cases[6].b=1 +cases[6].e=2 +cases[6].k=1 + +cases[7].c[0]=839122431 +cases[7].c[1]=2097152 +cases[7].c[2]=807403007 +cases[7].c[3]=-1 +cases[7].b=0 +cases[7].e=2 +cases[7].k=1 + +cases[8].c[0]=67108864 +cases[8].c[1]=807403007 +cases[8].c[2]=134217728 +cases[8].c[3]=-1 +cases[8].b=0 +cases[8].e=2 +cases[8].k=0 + diff --git a/tinyc/tests/tests2/76_dollars_in_identifiers.c b/tinyc/tests/tests2/76_dollars_in_identifiers.c new file mode 100644 index 000000000..c5fcf99e0 --- /dev/null +++ b/tinyc/tests/tests2/76_dollars_in_identifiers.c @@ -0,0 +1,41 @@ +#include <stdio.h> + +#define $(x) x +#define $fred 10 +#define joe$ 20 +#define hen$y 30 + +#define $10(x) x*10 +#define _$10(x) x/10 + +int main() +{ + printf("fred=%d\n", $fred); + printf("joe=%d\n", joe$); + printf("henry=%d\n", hen$y); + + printf("fred2=%d\n", $($fred)); + printf("joe2=%d\n", $(joe$)); + printf("henry2=%d\n", $(hen$y)); + + printf("fred10=%d\n", $10($fred)); + printf("joe_10=%d\n", _$10(joe$)); + + int $ = 10; + int a100$ = 100; + int a$$ = 1000; + int a$c$b = 2121; + int $100 = 10000; + const char *$$$ = "money"; + + printf("local=%d\n", $); + printf("a100$=%d\n", a100$); + printf("a$$=%d\n", a$$); + printf("a$c$b=%d\n", a$c$b); + printf("$100=%d\n", $100); + printf("$$$=%s", $$$); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinyc/tests/tests2/76_dollars_in_identifiers.expect b/tinyc/tests/tests2/76_dollars_in_identifiers.expect new file mode 100644 index 000000000..4a20a52e6 --- /dev/null +++ b/tinyc/tests/tests2/76_dollars_in_identifiers.expect @@ -0,0 +1,14 @@ +fred=10 +joe=20 +henry=30 +fred2=10 +joe2=20 +henry2=30 +fred10=100 +joe_10=2 +local=10 +a100$=100 +a$$=1000 +a$c$b=2121 +$100=10000 +$$$=money diff --git a/tinyc/tests/tests2/77_push_pop_macro.c b/tinyc/tests/tests2/77_push_pop_macro.c new file mode 100644 index 000000000..d38e0bfe3 --- /dev/null +++ b/tinyc/tests/tests2/77_push_pop_macro.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +int main() +{ + /* must not affect how #pragma ppop_macro works */ + #define pop_macro foobar1 + + /* must not affect how #pragma push_macro works */ + #define push_macro foobar2 + + #undef abort + #define abort "111" + printf("abort = %s\n", abort); + + #pragma push_macro("abort") + #undef abort + #define abort "222" + printf("abort = %s\n", abort); + + #pragma push_macro("abort") + #undef abort + #define abort "333" + printf("abort = %s\n", abort); + + #pragma pop_macro("abort") + printf("abort = %s\n", abort); + + #pragma pop_macro("abort") + printf("abort = %s\n", abort); +} diff --git a/tinyc/tests/tests2/77_push_pop_macro.expect b/tinyc/tests/tests2/77_push_pop_macro.expect new file mode 100644 index 000000000..d8a55305a --- /dev/null +++ b/tinyc/tests/tests2/77_push_pop_macro.expect @@ -0,0 +1,5 @@ +abort = 111 +abort = 222 +abort = 333 +abort = 222 +abort = 111 diff --git a/tinyc/tests/tests2/78_vla_label.c b/tinyc/tests/tests2/78_vla_label.c new file mode 100644 index 000000000..4096495d9 --- /dev/null +++ b/tinyc/tests/tests2/78_vla_label.c @@ -0,0 +1,45 @@ +#include <stdio.h> + +/* This test segfaults as of April 27, 2015. */ +void f1(int argc) +{ + char test[argc]; + if(0) + label: + printf("boom!\n"); + if(argc-- == 0) + return; + goto label; +} + +/* This segfaulted on 2015-11-19. */ +void f2(void) +{ + goto start; + { + int a[1 && 1]; /* not a variable-length array */ + int b[1 || 1]; /* not a variable-length array */ + int c[1 ? 1 : 1]; /* not a variable-length array */ + start: + a[0] = 0; + b[0] = 0; + c[0] = 0; + } +} + +void f3(void) +{ + printf("%d\n", 0 ? printf("x1\n") : 11); + printf("%d\n", 1 ? 12 : printf("x2\n")); + printf("%d\n", 0 && printf("x3\n")); + printf("%d\n", 1 || printf("x4\n")); +} + +int main() +{ + f1(2); + f2(); + f3(); + + return 0; +} diff --git a/tinyc/tests/tests2/78_vla_label.expect b/tinyc/tests/tests2/78_vla_label.expect new file mode 100644 index 000000000..3f4063bec --- /dev/null +++ b/tinyc/tests/tests2/78_vla_label.expect @@ -0,0 +1,6 @@ +boom! +boom! +11 +12 +0 +1 diff --git a/tinyc/tests/tests2/79_vla_continue.c b/tinyc/tests/tests2/79_vla_continue.c new file mode 100644 index 000000000..91215c99e --- /dev/null +++ b/tinyc/tests/tests2/79_vla_continue.c @@ -0,0 +1,116 @@ +#include <stdio.h> + +int f(void) +{ + return 5; +} + +void test1() +{ + int count = 10; + void *addr[10]; + for(;count--;) { + int a[f()]; + + addr[count] = a; + + continue; + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test2() +{ + int count = 10; + void *addr[count]; + for(;count--;) { + int a[f()]; + + addr[count] = a; + + continue; + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test3() +{ + int count = 10; + void *addr[count]; + while(count--) { + int a[f()]; + + addr[count] = a; + + continue; + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test4() +{ + int count = 10; + void *addr[count]; + do { + int a[f()]; + + addr[--count] = a; + + continue; + } while (count); + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test5() +{ + int count = 10; + int a[f()]; + int c[f()]; + + c[0] = 42; + + for(;count--;) { + int b[f()]; + int i; + for (i=0; i<f(); i++) { + b[i] = count; + } + } + + if (c[0] == 42) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +int main(void) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + + return 0; +} diff --git a/tinyc/tests/tests2/79_vla_continue.expect b/tinyc/tests/tests2/79_vla_continue.expect new file mode 100644 index 000000000..21da4d2be --- /dev/null +++ b/tinyc/tests/tests2/79_vla_continue.expect @@ -0,0 +1,5 @@ +OK +OK +OK +OK +OK diff --git a/tinyc/tests/tests2/80_flexarray.c b/tinyc/tests/tests2/80_flexarray.c new file mode 100644 index 000000000..1fc1a60a7 --- /dev/null +++ b/tinyc/tests/tests2/80_flexarray.c @@ -0,0 +1,25 @@ +#include <stdio.h> +struct wchar { + char *data; char mem[]; +}; +struct wint { + char *data; int mem[]; +}; +int f1char (void) { + char s[9]="nonono"; + struct wchar q = {"bugs"}; + return !s[0]; +} +int f1int (void) { + char s[9]="nonono"; + struct wint q = {"bugs"}; + return !s[0]; +} +int main (void) { + char s[9]="nonono"; + static struct wchar q = {"bugs", {'c'}}; + //printf ("tcc has %s %s\n", s, q.data); + if (f1char() || f1int()) + printf ("bla\n"); + return !s[0]; +} diff --git a/tinyc/tests/tests2/80_flexarray.expect b/tinyc/tests/tests2/80_flexarray.expect new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tinyc/tests/tests2/80_flexarray.expect diff --git a/tinyc/tests/tests2/81_types.c b/tinyc/tests/tests2/81_types.c new file mode 100644 index 000000000..fd6d71b0c --- /dev/null +++ b/tinyc/tests/tests2/81_types.c @@ -0,0 +1,43 @@ +/* The following are all valid decls, even though some subtypes + are incomplete. */ +enum E *e; +const enum E *e1; +enum E const *e2; +struct S *s; +const struct S *s1; +struct S const *s2; + +/* Various strangely looking declarators, which are all valid + and have to map to the same numbered typedefs. */ +typedef int (*fptr1)(); +int f1 (int (), int); +typedef int (*fptr2)(int x); +int f2 (int (int x), int); +typedef int (*fptr3)(int); +int f3 (int (int), int); +typedef int (*fptr4[4])(int); +int f4 (int (*[4])(int), int); +typedef int (*fptr5)(fptr1); +int f5 (int (int()), fptr1); +int f1 (fptr1 fp, int i) +{ + return (*fp)(i); +} +int f2 (fptr2 fp, int i) +{ + return (*fp)(i); +} +int f3 (fptr3 fp, int i) +{ + return (*fp)(i); +} +int f4 (fptr4 fp, int i) +{ + return (*fp[i])(i); +} +int f5 (fptr5 fp, fptr1 i) +{ + return fp(i); +} +int f8 (int ([4]), int); +int main () { return 0; } diff --git a/tinyc/tests/tests2/81_types.expect b/tinyc/tests/tests2/81_types.expect new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tinyc/tests/tests2/81_types.expect diff --git a/tinyc/tests/tests2/82_attribs_position.c b/tinyc/tests/tests2/82_attribs_position.c new file mode 100644 index 000000000..7c9f98726 --- /dev/null +++ b/tinyc/tests/tests2/82_attribs_position.c @@ -0,0 +1,19 @@ +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +typedef union Unaligned16a { + uint16_t u; + uint8_t b[2]; +} __attribute__((packed)) Unaligned16a; + +typedef union __attribute__((packed)) Unaligned16b { + uint16_t u; + uint8_t b[2]; +} Unaligned16b; + +extern void foo (void) __attribute__((stdcall)); +void __attribute__((stdcall)) foo (void) +{ +} + +int main () { return 0; } diff --git a/tinyc/tests/tests2/82_attribs_position.expect b/tinyc/tests/tests2/82_attribs_position.expect new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tinyc/tests/tests2/82_attribs_position.expect diff --git a/tinyc/tests/tests2/83_utf8_in_identifiers.c b/tinyc/tests/tests2/83_utf8_in_identifiers.c new file mode 100644 index 000000000..1f8609525 --- /dev/null +++ b/tinyc/tests/tests2/83_utf8_in_identifiers.c @@ -0,0 +1,9 @@ +#include <stdio.h> +double привет=0.1; +int Lefèvre=2; +int main(){ + printf("привет=%g\n",привет); + printf("Lefèvre=%d\n",Lefèvre); + return 0; +} +// pcc & tcc only diff --git a/tinyc/tests/tests2/83_utf8_in_identifiers.expect b/tinyc/tests/tests2/83_utf8_in_identifiers.expect new file mode 100644 index 000000000..1553f5f6f --- /dev/null +++ b/tinyc/tests/tests2/83_utf8_in_identifiers.expect @@ -0,0 +1,2 @@ +привет=0.1 +Lefèvre=2 diff --git a/tinyc/tests/tests2/84_hex-float.c b/tinyc/tests/tests2/84_hex-float.c new file mode 100644 index 000000000..0ef09bfc2 --- /dev/null +++ b/tinyc/tests/tests2/84_hex-float.c @@ -0,0 +1,12 @@ +extern int printf(const char *format, ...); + +#define ACPI_TYPE_INVALID 0x1E +#define NUM_NS_TYPES ACPI_TYPE_INVALID+1 +int array[NUM_NS_TYPES]; + +#define n 0xe +int main() +{ + printf("n+1 = %d\n", n+1); +// printf("n+1 = %d\n", 0xe+1); +} diff --git a/tinyc/tests/tests2/84_hex-float.expect b/tinyc/tests/tests2/84_hex-float.expect new file mode 100644 index 000000000..2175385aa --- /dev/null +++ b/tinyc/tests/tests2/84_hex-float.expect @@ -0,0 +1 @@ +n+1 = 15 diff --git a/tinyc/tests/tests2/85_asm-outside-function.c b/tinyc/tests/tests2/85_asm-outside-function.c new file mode 100644 index 000000000..dc5639a46 --- /dev/null +++ b/tinyc/tests/tests2/85_asm-outside-function.c @@ -0,0 +1,9 @@ +extern int printf (const char *, ...); +extern void vide(void); +__asm__("vide: ret"); + +int main() { + vide(); + printf ("okay\n"); + return 0; +} diff --git a/tinyc/tests/tests2/85_asm-outside-function.expect b/tinyc/tests/tests2/85_asm-outside-function.expect new file mode 100644 index 000000000..dcf02b2fb --- /dev/null +++ b/tinyc/tests/tests2/85_asm-outside-function.expect @@ -0,0 +1 @@ +okay diff --git a/tinyc/tests/tests2/86_memory-model.c b/tinyc/tests/tests2/86_memory-model.c new file mode 100644 index 000000000..744c3e207 --- /dev/null +++ b/tinyc/tests/tests2/86_memory-model.c @@ -0,0 +1,38 @@ +#include <stdio.h> + +int +main() +{ +#if defined(__LLP64__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 4 + && sizeof(long long int) == 8 + && sizeof(void*) == 8) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __LLP64__\n"); + } +#elif defined(__LP64__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 8 + && sizeof(long long int) == 8 + && sizeof(void*) == 8) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __LP64__\n"); + } +#elif defined(__ILP32__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 4 + && sizeof(void*) == 4) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __ILP32__\n"); + } +#else + (void)printf("KO no __*LP*__ defined.\n"); +#endif +} diff --git a/tinyc/tests/tests2/86_memory-model.expect b/tinyc/tests/tests2/86_memory-model.expect new file mode 100644 index 000000000..7326d9603 --- /dev/null +++ b/tinyc/tests/tests2/86_memory-model.expect @@ -0,0 +1 @@ +Ok diff --git a/tinyc/tests/tests2/87_dead_code.c b/tinyc/tests/tests2/87_dead_code.c new file mode 100644 index 000000000..98d4566c5 --- /dev/null +++ b/tinyc/tests/tests2/87_dead_code.c @@ -0,0 +1,122 @@ +/* This checks various ways of dead code inside if statements + where there are non-obvious ways of how the code is actually + not dead due to reachable by labels. */ +extern int printf (const char *, ...); +static void kb_wait_1(void) +{ + unsigned long timeout = 2; + do { + /* Here the else arm is a statement expression that's supposed + to be suppressed. The label inside the while would unsuppress + code generation again if not handled correctly. And that + would wreak havoc to the cond-expression because there's no + jump-around emitted, the whole statement expression really + needs to not generate code (perhaps except useless forward jumps). */ + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + int i = 1; + while (1) + while (i--) + some_label: + printf("error\n"); + goto some_label; + }) + ); + timeout--; + } while (timeout); +} +int main (void) +{ + int i = 1; + kb_wait_1(); + + /* Simple test of dead code at first sight which isn't actually dead. */ + if (0) { +yeah: + printf ("yeah\n"); + } else { + printf ("boo\n"); + } + if (i--) + goto yeah; + + /* Some more non-obvious uses where the problems are loops, so that even + the first loop statements aren't actually dead. */ + i = 1; + if (0) { + while (i--) { + printf ("once\n"); +enterloop: + printf ("twice\n"); + } + } + if (i >= 0) + goto enterloop; + + /* The same with statement expressions. One might be tempted to + handle them specially by counting if inside statement exprs and + not unsuppressing code at loops at all then. + See kb_wait_1 for the other side of the medal where that wouldn't work. */ + i = ({ + int j = 1; + if (0) { + while (j--) { + printf ("SEonce\n"); + enterexprloop: + printf ("SEtwice\n"); + } + } + if (j >= 0) + goto enterexprloop; + j; }); + + /* The other two loop forms: */ + i = 1; + if (0) { + for (i = 1; i--;) { + printf ("once2\n"); +enterloop2: + printf ("twice2\n"); + } + } + if (i > 0) + goto enterloop2; + + i = 1; + if (0) { + do { + printf ("once3\n"); +enterloop3: + printf ("twice3\n"); + } while (i--); + } + if (i > 0) + goto enterloop3; + + /* And check that case and default labels have the same effect + of disabling code suppression. */ + i = 41; + switch (i) { + if (0) { + printf ("error\n"); + case 42: + printf ("error2\n"); + case 41: + printf ("caseok\n"); + } + } + + i = 41; + switch (i) { + if (0) { + printf ("error3\n"); + default: + printf ("caseok2\n"); + break; + case 42: + printf ("error4\n"); + } + } + return 0; +} diff --git a/tinyc/tests/tests2/87_dead_code.expect b/tinyc/tests/tests2/87_dead_code.expect new file mode 100644 index 000000000..0b3ec1d9d --- /dev/null +++ b/tinyc/tests/tests2/87_dead_code.expect @@ -0,0 +1,18 @@ +timeout=2 +timeout=1 +boo +yeah +twice +once +twice +SEtwice +SEonce +SEtwice +twice2 +once2 +twice2 +twice3 +once3 +twice3 +caseok +caseok2 diff --git a/tinyc/tests/tests2/88_codeopt.c b/tinyc/tests/tests2/88_codeopt.c new file mode 100644 index 000000000..647626f9e --- /dev/null +++ b/tinyc/tests/tests2/88_codeopt.c @@ -0,0 +1,68 @@ +/* Check some way in where code suppression caused various + miscompilations. */ +extern int printf (const char *, ...); +typedef unsigned long size_t; + +size_t _brk_start, _brk_end; +void * extend_brk(size_t size, size_t align) +{ + size_t mask = align - 1; + void *ret = 0; + + do { + if (__builtin_expect(!!(_brk_start == 0), 0)) + do { + printf("wrong1\n"); + } while (0); + } while (0); + _brk_end = (_brk_end + mask) & ~mask; + ret = (void *)_brk_end; + _brk_end += size; + + return ret; +} + +static void get_args (int a, int b) +{ + if (a != 1) + printf("wrong2\n"); + else + printf("okay\n"); +} + +void bla(void) +{ + int __ret = 42; + ({ + if (__builtin_expect(!!(0), 0)) { + if (__builtin_expect(!!__ret, 0)) + printf("wrong3\n"); + int x = !!(__ret); + } + __ret; + }); + get_args(!!__ret, sizeof(__ret)); +} + +_Bool chk(unsigned long addr, unsigned long limit, unsigned long size) +{ + _Bool ret; + /* This just needs to compile, no runtime test. (And it doesn't compile + only with certain internal checking added that's not committed). */ + if (0) + ret = 0 != (!!(addr > limit - size)); +} + +int main() +{ + void *r; + _brk_start = 1024; + _brk_end = 1024; + r = extend_brk (4096, 16); + if (!r) + printf("wrong4\n"); + else + printf("okay\n"); + bla(); + return 0; +} diff --git a/tinyc/tests/tests2/88_codeopt.expect b/tinyc/tests/tests2/88_codeopt.expect new file mode 100644 index 000000000..439edfd8f --- /dev/null +++ b/tinyc/tests/tests2/88_codeopt.expect @@ -0,0 +1,2 @@ +okay +okay diff --git a/tinyc/tests/tests2/89_nocode_wanted.c b/tinyc/tests/tests2/89_nocode_wanted.c new file mode 100644 index 000000000..73e0a4bc8 --- /dev/null +++ b/tinyc/tests/tests2/89_nocode_wanted.c @@ -0,0 +1,112 @@ +extern int printf(const char *format, ...); +static void kb_wait_1(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + while (1) + printf("error\n"); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + for (;;) + printf("error\n"); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2_1(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + do { + printf("error\n"); + } while (1); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2_2(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + label: + printf("error\n"); + goto label; + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_3(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + int i = 1; + goto label; + i = i + 2; + label: + i = i + 3; + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_4(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + switch(timeout) { + case 2: + printf("timeout is 2"); + break; + case 1: + printf("timeout is 1"); + break; + default: + printf("timeout is 0?"); + break; + }; + // return; + }) + ); + timeout--; + } while (timeout); +} +int main() +{ + printf("begin\n"); + kb_wait_1(); + kb_wait_2(); + kb_wait_2_1(); + kb_wait_2_2(); + kb_wait_3(); + kb_wait_4(); + printf("end\n"); + return 0; +} diff --git a/tinyc/tests/tests2/89_nocode_wanted.expect b/tinyc/tests/tests2/89_nocode_wanted.expect new file mode 100644 index 000000000..c44d4ea6c --- /dev/null +++ b/tinyc/tests/tests2/89_nocode_wanted.expect @@ -0,0 +1,14 @@ +begin +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +end diff --git a/tinyc/tests/tests2/90_struct-init.c b/tinyc/tests/tests2/90_struct-init.c new file mode 100644 index 000000000..d931e2378 --- /dev/null +++ b/tinyc/tests/tests2/90_struct-init.c @@ -0,0 +1,282 @@ +typedef unsigned char u8; +typedef struct {} empty_s; +struct contains_empty { + u8 a; + empty_s empty; + u8 b; +}; +struct contains_empty ce = { { (1) }, (empty_s){}, 022, }; +/* The following decl of 'q' would demonstrate the TCC bug in init_putv when + handling copying compound literals. (Compound literals + aren't acceptable constant initializers in isoc99, but + we accept them like gcc, except for this case) +//char *q = (char *){ "trara" }; */ +struct SS {u8 a[3], b; }; +struct SS sinit16[] = { { 1 }, 2 }; +struct S +{ + u8 a,b; + u8 c[2]; +}; + +struct T +{ + u8 s[16]; + u8 a; +}; + +struct U +{ + u8 a; + struct S s; + u8 b; + struct T t; +}; + +struct V +{ + struct S s; + struct T t; + u8 a; +}; + +struct W +{ + struct V t; + struct S s[]; +}; + +struct S gs = ((struct S){1, 2, 3, 4}); +struct S gs2 = {1, 2, {3, 4}}; +struct T gt = {"hello", 42}; +struct U gu = {3, 5,6,7,8, 4, "huhu", 43}; +struct U gu2 = {3, {5,6,7,8}, 4, {"huhu", 43}}; +/* Optional braces around scalar initializers. Accepted, but with + a warning. */ +struct U gu3 = { {3}, {5,6,7,8,}, 4, {"huhu", 43}}; +/* Many superfluous braces and leaving out one initializer for U.s.c[1] */ +struct U gu4 = { 3, {5,6,7,}, 5, { "bla", {44}} }; +/* Superfluous braces and useless parens around values */ +struct S gs3 = { (1), {(2)}, {(((3))), {4}}}; +/* Superfluous braces, and leaving out braces for V.t, plus cast */ +struct V gv = {{{3},4,{5,6}}, "haha", (u8)45, 46}; +/* Compound literal */ +struct V gv2 = {(struct S){7,8,{9,10}}, {"hihi", 47}, 48}; +/* Parens around compound literal */ +struct V gv3 = {((struct S){7,8,{9,10}}), {"hoho", 49}, 50}; +/* Initialization of a flex array member (warns in GCC) */ +struct W gw = {{1,2,3,4}, {1,2,3,4,5}}; + +union UU { + u8 a; + u8 b; +}; +struct SU { + union UU u; + u8 c; +}; +struct SU gsu = {5,6}; + +/* Unnamed struct/union members aren't ISO C, but it's a widely accepted + extension. See below for further extensions to that under -fms-extension.*/ +union UV { + struct {u8 a,b;}; + struct S s; +}; +union UV guv = {{6,5}}; +union UV guv2 = {{.b = 7, .a = 8}}; +union UV guv3 = {.b = 8, .a = 7}; + +/* Under -fms-extensions also the following is valid: +union UV2 { + struct Anon {u8 a,b;}; // unnamed member, but tagged struct, ... + struct S s; +}; +struct Anon gan = { 10, 11 }; // ... which makes it available here. +union UV2 guv4 = {{4,3}}; // and the other inits from above as well +*/ + +struct in6_addr { + union { + u8 u6_addr8[16]; + unsigned short u6_addr16[8]; + } u; +}; +struct flowi6 { + struct in6_addr saddr, daddr; +}; +struct pkthdr { + struct in6_addr daddr, saddr; +}; +struct pkthdr phdr = { { { 6,5,4,3 } }, { { 9,8,7,6 } } }; + +struct Wrap { + void *func; +}; +int global; +void inc_global (void) +{ + global++; +} + +struct Wrap global_wrap[] = { + ((struct Wrap) {inc_global}), + inc_global, +}; + +#include <stdio.h> +void print_ (const char *name, const u8 *p, long size) +{ + printf ("%s:", name); + while (size--) { + printf (" %x", *p++); + } + printf ("\n"); +} +#define print(x) print_(#x, (u8*)&x, sizeof (x)) +#if 1 +void foo (struct W *w, struct pkthdr *phdr_) +{ + struct S ls = {1, 2, 3, 4}; + struct S ls2 = {1, 2, {3, 4}}; + struct T lt = {"hello", 42}; + struct U lu = {3, 5,6,7,8, 4, "huhu", 43}; + struct U lu1 = {3, ls, 4, {"huhu", 43}}; + struct U lu2 = {3, (ls), 4, {"huhu", 43}}; + const struct S *pls = &ls; + struct S ls21 = *pls; + struct U lu22 = {3, *pls, 4, {"huhu", 43}}; + /* Incomplete bracing. */ + struct U lu21 = {3, ls, 4, "huhu", 43}; + /* Optional braces around scalar initializers. Accepted, but with + a warning. */ + struct U lu3 = { 3, {5,6,7,8,}, 4, {"huhu", 43}}; + /* Many superfluous braces and leaving out one initializer for U.s.c[1] */ + struct U lu4 = { 3, {5,6,7,}, 5, { "bla", 44} }; + /* Superfluous braces and useless parens around values */ + struct S ls3 = { (1), (2), {(((3))), 4}}; + /* Superfluous braces, and leaving out braces for V.t, plus cast */ + struct V lv = {{3,4,{5,6}}, "haha", (u8)45, 46}; + /* Compound literal */ + struct V lv2 = {(struct S)w->t.s, {"hihi", 47}, 48}; + /* Parens around compound literal */ + struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50}; + const struct pkthdr *phdr = phdr_; + struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr }; + int elt = 0x42; + /* Range init, overlapping */ + struct T lt2 = { { [1 ... 5] = 9, [6 ... 10] = elt, [4 ... 7] = elt+1 }, 1 }; + print(ls); + print(ls2); + print(lt); + print(lu); + print(lu1); + print(lu2); + print(ls21); + print(lu21); + print(lu22); + print(lu3); + print(lu4); + print(ls3); + print(lv); + print(lv2); + print(lv3); + print(lt2); + print(flow); +} +#endif + +void test_compound_with_relocs (void) +{ + struct Wrap local_wrap[] = { + ((struct Wrap) {inc_global}), + inc_global, + }; + void (*p)(void); + p = global_wrap[0].func; p(); + p = global_wrap[1].func; p(); + p = local_wrap[0].func; p(); + p = local_wrap[1].func; p(); +} + +void sys_ni(void) { printf("ni\n"); } +void sys_one(void) { printf("one\n"); } +void sys_two(void) { printf("two\n"); } +void sys_three(void) { printf("three\n"); } +typedef void (*fptr)(void); +const fptr table[3] = { + [0 ... 2] = &sys_ni, + [0] = sys_one, + [1] = sys_two, + [2] = sys_three, +}; + +void test_multi_relocs(void) +{ + int i; + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) + table[i](); +} + +/* Following is from GCC gcc.c-torture/execute/20050613-1.c. */ + +struct SEA { int i; int j; int k; int l; }; +struct SEB { struct SEA a; int r[1]; }; +struct SEC { struct SEA a; int r[0]; }; +struct SED { struct SEA a; int r[]; }; + +static void +test_correct_filling (struct SEA *x) +{ + static int i; + if (x->i != 0 || x->j != 5 || x->k != 0 || x->l != 0) + printf("sea_fill%d: wrong\n", i); + else + printf("sea_fill%d: okay\n", i); + i++; +} + +int +test_zero_init (void) +{ + /* The peculiarity here is that only a.j is initialized. That + means that all other members must be zero initialized. TCC + once didn't do that for sub-level designators. */ + struct SEB b = { .a.j = 5 }; + struct SEC c = { .a.j = 5 }; + struct SED d = { .a.j = 5 }; + test_correct_filling (&b.a); + test_correct_filling (&c.a); + test_correct_filling (&d.a); + return 0; +} + +int main() +{ + print(ce); + print(gs); + print(gs2); + print(gt); + print(gu); + print(gu2); + print(gu3); + print(gu4); + print(gs3); + print(gv); + print(gv2); + print(gv3); + print(sinit16); + print(gw); + print(gsu); + print(guv); + print(guv.b); + print(guv2); + print(guv3); + print(phdr); + foo(&gw, &phdr); + //printf("q: %s\n", q); + test_compound_with_relocs(); + test_multi_relocs(); + test_zero_init(); + return 0; +} diff --git a/tinyc/tests/tests2/90_struct-init.expect b/tinyc/tests/tests2/90_struct-init.expect new file mode 100644 index 000000000..e366121a5 --- /dev/null +++ b/tinyc/tests/tests2/90_struct-init.expect @@ -0,0 +1,43 @@ +ce: 1 12 +gs: 1 2 3 4 +gs2: 1 2 3 4 +gt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a +gu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu2: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c +gs3: 1 2 3 4 +gv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e +gv2: 7 8 9 a 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30 +gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32 +sinit16: 1 0 0 0 2 0 0 0 +gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +gsu: 5 6 +guv: 6 5 0 0 +guv.b: 5 +guv2: 8 7 0 0 +guv3: 7 8 0 0 +phdr: 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 +ls: 1 2 3 4 +ls2: 1 2 3 4 +lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a +lu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu1: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu2: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +ls21: 1 2 3 4 +lu21: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu22: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c +ls3: 1 2 3 4 +lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e +lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30 +lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 +lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1 +flow: 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 +one +two +three +sea_fill0: okay +sea_fill1: okay +sea_fill2: okay diff --git a/tinyc/tests/tests2/91_ptr_longlong_arith32.c b/tinyc/tests/tests2/91_ptr_longlong_arith32.c new file mode 100644 index 000000000..bf07915ab --- /dev/null +++ b/tinyc/tests/tests2/91_ptr_longlong_arith32.c @@ -0,0 +1,15 @@ +int printf(const char *, ...); +char t[] = "012345678"; + +int main(void) +{ + char *data = t; + unsigned long long r = 4; + unsigned a = 5; + unsigned long long b = 12; + + *(unsigned*)(data + r) += a - b; + + printf("data = \"%s\"\n", data); + return 0; +} diff --git a/tinyc/tests/tests2/91_ptr_longlong_arith32.expect b/tinyc/tests/tests2/91_ptr_longlong_arith32.expect new file mode 100644 index 000000000..f91e4b420 --- /dev/null +++ b/tinyc/tests/tests2/91_ptr_longlong_arith32.expect @@ -0,0 +1 @@ +data = "0123-5678" diff --git a/tinyc/tests/tests2/92_enum_bitfield.c b/tinyc/tests/tests2/92_enum_bitfield.c new file mode 100644 index 000000000..bb6dc35d2 --- /dev/null +++ b/tinyc/tests/tests2/92_enum_bitfield.c @@ -0,0 +1,57 @@ +/* This checks if enums needing 8 bit but only having positive + values are correctly zero extended (instead of sign extended) + when stored into/loaded from a 8 bit bit-field of enum type (which + itself is implementation defined, so isn't necessarily supported by all + other compilers). */ +enum tree_code { + SOME_CODE = 148, /* has bit 7 set, and hence all further enum values as well */ + LAST_AND_UNUSED_TREE_CODE +}; +typedef union tree_node *tree; +struct tree_common +{ + union tree_node *chain; + union tree_node *type; + enum tree_code code : 8; + unsigned side_effects_flag : 1; +}; +union tree_node +{ + struct tree_common common; + }; +enum c_tree_code { + C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE, + STMT_EXPR, + LAST_C_TREE_CODE +}; +enum cplus_tree_code { + CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE, + AMBIG_CONV, + LAST_CPLUS_TREE_CODE +}; + +extern int printf(const char *, ...); +int blah(){return 0;} + +int convert_like_real (tree convs) +{ + switch (((enum tree_code) (convs)->common.code)) + { + case AMBIG_CONV: /* This has bit 7 set, which must not be the sign + bit in tree_common.code, i.e. the bitfield must + be somehow marked unsigned. */ + return blah(); + default: + break; + }; + printf("unsigned enum bit-fields broken\n"); +} + +int main() +{ + union tree_node convs; + + convs.common.code = AMBIG_CONV; + convert_like_real (&convs); + return 0; +} diff --git a/tinyc/tests/tests2/92_enum_bitfield.expect b/tinyc/tests/tests2/92_enum_bitfield.expect new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tinyc/tests/tests2/92_enum_bitfield.expect diff --git a/tinyc/tests/tests2/93_integer_promotion.c b/tinyc/tests/tests2/93_integer_promotion.c new file mode 100644 index 000000000..a1176fc6b --- /dev/null +++ b/tinyc/tests/tests2/93_integer_promotion.c @@ -0,0 +1,71 @@ +/* integer promotion */ + +int printf(const char*, ...); +#define promote(s) printf(" %ssigned : %s\n", (s) - 100 < 0 ? " " : "un", #s); + +int main (void) +{ + struct { + unsigned ub:3; + unsigned u:32; + unsigned long long ullb:35; + unsigned long long ull:64; + unsigned char c; + } s = { 1, 1, 1 }; + + promote(s.ub); + promote(s.u); + promote(s.ullb); + promote(s.ull); + promote(s.c); + printf("\n"); + + promote((1 ? s.ub : 1)); + promote((1 ? s.u : 1)); + promote((1 ? s.ullb : 1)); + promote((1 ? s.ull : 1)); + promote((1 ? s.c : 1)); + printf("\n"); + + promote(s.ub << 1); + promote(s.u << 1); + promote(s.ullb << 1); + promote(s.ull << 1); + promote(s.c << 1); + printf("\n"); + + promote(+s.ub); + promote(+s.u); + promote(+s.ullb); + promote(+s.ull); + promote(+s.c); + printf("\n"); + + promote(-s.ub); + promote(-s.u); + promote(-s.ullb); + promote(-s.ull); + promote(-s.c); + printf("\n"); + + promote(~s.ub); + promote(~s.u); + promote(~s.ullb); + promote(~s.ull); + promote(~s.c); + printf("\n"); + + promote(!s.ub); + promote(!s.u); + promote(!s.ullb); + promote(!s.ull); + promote(!s.c); + printf("\n"); + + promote(+(unsigned)s.ub); + promote(-(unsigned)s.ub); + promote(~(unsigned)s.ub); + promote(!(unsigned)s.ub); + + return 0; +} diff --git a/tinyc/tests/tests2/93_integer_promotion.expect b/tinyc/tests/tests2/93_integer_promotion.expect new file mode 100644 index 000000000..34b9c145c --- /dev/null +++ b/tinyc/tests/tests2/93_integer_promotion.expect @@ -0,0 +1,46 @@ + signed : s.ub + unsigned : s.u + signed : s.ullb + unsigned : s.ull + signed : s.c + + signed : (1 ? s.ub : 1) + unsigned : (1 ? s.u : 1) + signed : (1 ? s.ullb : 1) + unsigned : (1 ? s.ull : 1) + signed : (1 ? s.c : 1) + + signed : s.ub << 1 + unsigned : s.u << 1 + signed : s.ullb << 1 + unsigned : s.ull << 1 + signed : s.c << 1 + + signed : +s.ub + unsigned : +s.u + signed : +s.ullb + unsigned : +s.ull + signed : +s.c + + signed : -s.ub + unsigned : -s.u + signed : -s.ullb + unsigned : -s.ull + signed : -s.c + + signed : ~s.ub + unsigned : ~s.u + signed : ~s.ullb + unsigned : ~s.ull + signed : ~s.c + + signed : !s.ub + signed : !s.u + signed : !s.ullb + signed : !s.ull + signed : !s.c + + unsigned : +(unsigned)s.ub + unsigned : -(unsigned)s.ub + unsigned : ~(unsigned)s.ub + signed : !(unsigned)s.ub diff --git a/tinyc/tests/tests2/94_generic.c b/tinyc/tests/tests2/94_generic.c new file mode 100644 index 000000000..d7fb5fc3b --- /dev/null +++ b/tinyc/tests/tests2/94_generic.c @@ -0,0 +1,64 @@ +#include <stdio.h> + +const int a = 0; + +struct a { + int a; +}; + +struct b { + int a; +}; + +int a_f() +{ + return 20; +} + +int b_f() +{ + return 10; +} + +typedef int int_type1; + +#define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123); + +int main() +{ + int i = 0; + signed long int l = 2; + struct b titi; + const int * const ptr; + const char *ti; + int_type1 i2; + + i = _Generic(a, int: a_f, const int: b_f)(); + printf("%d\n", i); + i = _Generic(a, int: a_f() / 2, const int: b_f() / 2); + printf("%d\n", i); + i = _Generic(ptr, int *:1, int * const:2, default:20); + printf("%d\n", i); + i = gen_sw(a); + printf("%d\n", i); + i = _Generic(titi, struct a:1, struct b:2, default:20); + printf("%d\n", i); + i = _Generic(i2, char: 1, int : 0); + printf("%d\n", i); + i = _Generic(a, char:1, int[4]:2, default:5); + printf("%d\n", i); + i = _Generic(17, int :1, int **:2); + printf("%d\n", i); + i = _Generic(17L, int :1, long :2, long long : 3); + printf("%d\n", i); + i = _Generic("17, io", char *: 3, const char *: 1); + printf("%d\n", i); + i = _Generic(ti, const unsigned char *:1, const char *:4, char *:3, + const signed char *:2); + printf("%d\n", i); + printf("%s\n", _Generic(i + 2L, long: "long", int: "int", + long long: "long long")); + i = _Generic(l, long: 1, int: 2); + printf("%d\n", i); + return 0; +} diff --git a/tinyc/tests/tests2/94_generic.expect b/tinyc/tests/tests2/94_generic.expect new file mode 100644 index 000000000..9aa927530 --- /dev/null +++ b/tinyc/tests/tests2/94_generic.expect @@ -0,0 +1,13 @@ +20 +10 +20 +123 +2 +0 +5 +1 +2 +3 +4 +long +1 \ No newline at end of file diff --git a/tinyc/tests/tests2/95_bitfields.c b/tinyc/tests/tests2/95_bitfields.c new file mode 100644 index 000000000..f025c575d --- /dev/null +++ b/tinyc/tests/tests2/95_bitfields.c @@ -0,0 +1,218 @@ +/* ----------------------------------------------------------------------- */ +#if TEST == 1 +{ + struct M P A __s + { + unsigned x : 12; + unsigned char y : 7; + unsigned z : 28; + unsigned a: 4; + unsigned b: 5; + }; + TEST_STRUCT(0x333,0x44,0x555555,6,7); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 2 +{ + struct M P __s + { + int x: 12; + char y: 6; + long long z:63; + A char a:4; + long long b:2; + + }; + TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 3 +{ + struct M P __s + { + unsigned x:5, y:5, :0, z:5; char a:5; A short b:5; + }; + TEST_STRUCT(21,23,25,6,14); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 4 +{ + struct M P __s { + int x : 3; + int : 2; + int y : 1; + int : 0; + int z : 5; + int a : 7; + unsigned int b : 7; + }; + TEST_STRUCT(3,1,15,120,120); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 5 +{ + struct M P __s { + long long x : 45; + long long : 2; + long long y : 30; + unsigned long long z : 38; + char a; short b; + }; + TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 6 +{ + struct M P __s { + int a; + signed char b; + int x : 12, y : 4, : 0, : 4, z : 3; + char d; + }; + TEST_STRUCT(1,2,3,4,-3); +} + +/* ----------------------------------------------------------------------- */ +#elif defined PACK + +#if PACK +# pragma pack(push,1) +# define P //_P +#else +# define P +#endif + +printf("\n\n" + 2*top); +#define TEST 1 +#include SELF +top = 0; +#define TEST 2 +#include SELF +#define TEST 3 +#include SELF +#define TEST 4 +#include SELF +#define TEST 5 +#include SELF +#define TEST 6 +#include SELF + +#if PACK +# pragma pack(pop) +#endif + +#undef P +#undef PACK + +/* ----------------------------------------------------------------------- */ +#elif defined ALIGN + +#if ALIGN +# define A _A(16) +#else +# define A +#endif + +#define PACK 0 +#include SELF +#define PACK 1 +#include SELF + +#undef A +#undef ALIGN + +/* ----------------------------------------------------------------------- */ +#elif defined MS_BF + +#if MS_BF +# ifdef __TINYC__ +# pragma comment(option, "-mms-bitfields") +# elif defined __GNUC__ +# define M __attribute__((ms_struct)) +# endif +#else +# ifdef __TINYC__ +# pragma comment(option, "-mno-ms-bitfields") +# elif defined __GNUC__ +# define M __attribute__((gcc_struct)) +# endif +#endif +#ifndef M +# define M +#endif + +#define ALIGN 0 +#include SELF +#define ALIGN 1 +#include SELF + +#undef M +#undef MS_BF + +/* ----------------------------------------------------------------------- */ +#else + +#include <stdio.h> +#include <string.h> +/* some gcc headers #define __attribute__ to empty if it's not gcc */ +#undef __attribute__ + +void dump(void *p, int s) +{ + int i; + for (i = s; --i >= 0;) + printf("%02X", ((unsigned char*)p)[i]); + printf("\n"); +} + +#define pv(m) \ + printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m) + +#define TEST_STRUCT(v1,v2,v3,v4,v5) { \ + struct __s _s, *s = & _s; \ + printf("\n---- TEST %d%s%s%s ----\n" + top, \ + TEST, MS_BF?" - MS-BITFIELDS":"", \ + PACK?" - PACKED":"", \ + ALIGN?" - WITH ALIGN":""); \ + memset(s, 0, sizeof *s); \ + s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \ + printf("bits in use : "), dump(s, sizeof *s); \ + s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \ + printf("bits as set : "), dump(s, sizeof *s); \ + printf("values :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \ + printf("align/size : %d %d\n", alignof(struct __s),sizeof(struct __s)); \ + } + +#ifdef _MSC_VER +# define _A(n) __declspec(align(n)) +# define _P +# define alignof(x) __alignof(x) +#else +# define _A(n) __attribute__((aligned(n))) +# define _P __attribute__((packed)) +# define alignof(x) __alignof__(x) +#endif + +#ifndef MS_BITFIELDS +# define MS_BITFIELDS 0 +#endif + +#define SELF "95_bitfields.c" + +int top = 1; + +int main() +{ +#define MS_BF MS_BITFIELDS +#include SELF + return 0; +} + +/* ----------------------------------------------------------------------- */ +#endif +#undef TEST diff --git a/tinyc/tests/tests2/95_bitfields.expect b/tinyc/tests/tests2/95_bitfields.expect new file mode 100644 index 000000000..6a8fd9abd --- /dev/null +++ b/tinyc/tests/tests2/95_bitfields.expect @@ -0,0 +1,149 @@ +---- TEST 1 ---- +bits in use : 0000001FFFFFFFFF007F0FFF +bits as set : 000000076055555500440333 +values : 333 44 555555 06 07 +align/size : 4 12 + +---- TEST 2 ---- +bits in use : 000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF +bits as set : 0000000000000025123456789ABCDEF000000000001E0003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 8 24 + +---- TEST 3 ---- +bits in use : 001F1F1F000003FF +bits as set : 000E0619000002F5 +values : 15 17 19 06 0e +align/size : 4 8 + +---- TEST 4 ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 ---- +bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000007800000000300000000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 8 24 + +---- TEST 6 ---- +bits in use : 0000007000FFFFFFFFFFFFFF +bits as set : 00000030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 12 + + + +---- TEST 1 - PACKED ---- +bits in use : FFFFFFFFFFFFFF +bits as set : 3B02AAAAAC4333 +values : 333 44 555555 06 07 +align/size : 1 7 + +---- TEST 2 - PACKED ---- +bits in use : 7FFFFFFFFFFFFFFFFFFFFF +bits as set : 4A48D159E26AF37BC1E003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 1 11 + +---- TEST 3 - PACKED ---- +bits in use : 7FFF000003FF +bits as set : 38D9000002F5 +values : 15 17 19 06 0e +align/size : 1 6 + +---- TEST 4 - PACKED ---- +bits in use : 07FFFF00000027 +bits as set : 078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 7 + +---- TEST 5 - PACKED ---- +bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF +bits as set : 007744000000000F18000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 1 18 + +---- TEST 6 - PACKED ---- +bits in use : 007000FFFFFFFFFFFFFF +bits as set : 0030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 10 + + + +---- TEST 1 - WITH ALIGN ---- +bits in use : 000000000000001FFFFFFFFF007F0FFF +bits as set : 00000000000000076055555500440333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - WITH ALIGN ---- +bits in use : 0000000000000000000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF +bits as set : 00000000000000000000000000000025123456789ABCDEF000000000001E0003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 16 32 + +---- TEST 3 - WITH ALIGN ---- +bits in use : 0000000000000000000000000000001F000000000000000000001F1F000003FF +bits as set : 0000000000000000000000000000000E000000000000000000000619000002F5 +values : 15 17 19 06 0e +align/size : 16 32 + +---- TEST 4 - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - WITH ALIGN ---- +bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000007800000000300000000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 8 24 + +---- TEST 6 - WITH ALIGN ---- +bits in use : 0000007000FFFFFFFFFFFFFF +bits as set : 00000030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 12 + + + +---- TEST 1 - PACKED - WITH ALIGN ---- +bits in use : 000000000000000000FFFFFFFFFFFFFF +bits as set : 0000000000000000003B02AAAAAC4333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - PACKED - WITH ALIGN ---- +bits in use : 3F01FFFFFFFFFFFFFFFFFFFF +bits as set : 250048D159E26AF37BC1E003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 1 12 + +---- TEST 3 - PACKED - WITH ALIGN ---- +bits in use : 1F03FF000003FF +bits as set : 0E00D9000002F5 +values : 15 17 19 06 0e +align/size : 1 7 + +---- TEST 4 - PACKED - WITH ALIGN ---- +bits in use : 07FFFF00000027 +bits as set : 078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 7 + +---- TEST 5 - PACKED - WITH ALIGN ---- +bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF +bits as set : 007744000000000F18000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 1 18 + +---- TEST 6 - PACKED - WITH ALIGN ---- +bits in use : 007000FFFFFFFFFFFFFF +bits as set : 0030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 10 diff --git a/tinyc/tests/tests2/95_bitfields_ms.c b/tinyc/tests/tests2/95_bitfields_ms.c new file mode 100644 index 000000000..b196fbd66 --- /dev/null +++ b/tinyc/tests/tests2/95_bitfields_ms.c @@ -0,0 +1,2 @@ +#define MS_BITFIELDS 1 +#include "95_bitfields.c" diff --git a/tinyc/tests/tests2/95_bitfields_ms.expect b/tinyc/tests/tests2/95_bitfields_ms.expect new file mode 100644 index 000000000..8ccafb78d --- /dev/null +++ b/tinyc/tests/tests2/95_bitfields_ms.expect @@ -0,0 +1,149 @@ +---- TEST 1 - MS-BITFIELDS ---- +bits in use : 0000001FFFFFFFFF0000007F00000FFF +bits as set : 00000007605555550000004400000333 +values : 333 44 555555 06 07 +align/size : 4 16 + +---- TEST 2 - MS-BITFIELDS ---- +bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF +bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 8 32 + +---- TEST 3 - MS-BITFIELDS ---- +bits in use : 001F001F0000001F000003FF +bits as set : 000E000600000019000002F5 +values : 15 17 19 06 0e +align/size : 4 12 + +---- TEST 4 - MS-BITFIELDS ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - MS-BITFIELDS ---- +bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 0000000000770044000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 8 32 + +---- TEST 6 - MS-BITFIELDS ---- +bits in use : 00000000000000700000FFFF000000FFFFFFFFFF +bits as set : 000000000000003000002001000000FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 20 + + + +---- TEST 1 - MS-BITFIELDS - PACKED ---- +bits in use : 0000001FFFFFFFFF7F00000FFF +bits as set : 00000007605555554400000333 +values : 333 44 555555 06 07 +align/size : 1 13 + +---- TEST 2 - MS-BITFIELDS - PACKED ---- +bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF +bits as set : 000000000000000205123456789ABCDEF01E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 1 22 + +---- TEST 3 - MS-BITFIELDS - PACKED ---- +bits in use : 001F1F0000001F000003FF +bits as set : 000E0600000019000002F5 +values : 15 17 19 06 0e +align/size : 1 11 + +---- TEST 4 - MS-BITFIELDS - PACKED ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 8 + +---- TEST 5 - MS-BITFIELDS - PACKED ---- +bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 1 27 + +---- TEST 6 - MS-BITFIELDS - PACKED ---- +bits in use : 00000000700000FFFFFFFFFFFFFF +bits as set : 000000003000002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 14 + + + +---- TEST 1 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000001FFFFFFFFF0000007F00000FFF +bits as set : 00000007605555550000004400000333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF +bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 16 32 + +---- TEST 3 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF +bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5 +values : 15 17 19 06 0e +align/size : 16 32 + +---- TEST 4 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 0000000000770044000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 8 32 + +---- TEST 6 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 00000000000000700000FFFF000000FFFFFFFFFF +bits as set : 000000000000003000002001000000FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 20 + + + +---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 0000000000001FFFFFFFFF7F00000FFF +bits as set : 00000000000007605555554400000333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF +bits as set : 000000000000000205000000123456789ABCDEF01E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 16 25 + +---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 001F000000000000001F0000001F000003FF +bits as set : 000E000000000000000600000019000002F5 +values : 15 17 19 06 0e +align/size : 16 18 + +---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 8 + +---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 1 27 + +---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 00000000700000FFFFFFFFFFFFFF +bits as set : 000000003000002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 14 diff --git a/tinyc/tests/tests2/96_nodata_wanted.c b/tinyc/tests/tests2/96_nodata_wanted.c new file mode 100644 index 000000000..cc211d36b --- /dev/null +++ b/tinyc/tests/tests2/96_nodata_wanted.c @@ -0,0 +1,84 @@ +/*****************************************************************************/ +/* test 'nodata_wanted' data output suppression */ + +#if defined test_static_data_error +void foo() { + if (1) { + static short w = (int)&foo; /* initializer not computable */ + } +} + +#elif defined test_static_nodata_error +void foo() { + if (0) { + static short w = (int)&foo; /* initializer not computable */ + } +} + +#elif defined test_global_data_error +void foo(); +static short w = (int)&foo; /* initializer not computable */ + + +#elif defined test_local_data_noerror +void foo() { + short w = &foo; /* 2 cast warnings */ +} + +#elif defined test_data_suppression_off || defined test_data_suppression_on + +#if defined test_data_suppression_on +# define SKIP 1 +#else +# define SKIP 0 +#endif + +#include <stdio.h> +/* some gcc headers #define __attribute__ to empty if it's not gcc */ +#undef __attribute__ + +int main() +{ + __label__ ts0, te0, ts1, te1; + int tl, dl; + + static char ds0 = 0; + static char de0 = 0; + /* get reference size of empty jmp */ +ts0:; + if (!SKIP) {} +te0:; + dl = -(&de0 - &ds0); + tl = -(&&te0 - &&ts0); + + /* test data and code suppression */ + static char ds1 = 0; +ts1:; + if (!SKIP) { + static void *p = (void*)&main; + static char cc[] = "static string"; + static double d = 8.0; + + static struct __attribute__((packed)) { + unsigned x : 12; + unsigned char y : 7; + unsigned z : 28, a: 4, b: 5; + } s = { 0x333,0x44,0x555555,6,7 }; + + printf("data:\n"); + printf(" %d - %.1f - %.1f - %s - %s\n", + sizeof 8.0, 8.0, d, __FUNCTION__, cc); + printf(" %x %x %x %x %x\n", + s.x, s.y, s.z, s.a, s.b); + } +te1:; + static char de1 = 0; + + dl += &de1 - &ds1; + tl += &&te1 - &&ts1; + printf("size of data/text:\n %s/%s\n", + dl ? "non-zero":"zero", tl ? "non-zero":"zero"); + /*printf("# %d/%d\n", dl, tl);*/ +} + +#endif diff --git a/tinyc/tests/tests2/96_nodata_wanted.expect b/tinyc/tests/tests2/96_nodata_wanted.expect new file mode 100644 index 000000000..2749109a0 --- /dev/null +++ b/tinyc/tests/tests2/96_nodata_wanted.expect @@ -0,0 +1,23 @@ +[test_static_data_error] +96_nodata_wanted.c:7: error: initializer element is not computable at load time + +[test_static_nodata_error] +96_nodata_wanted.c:14: error: initializer element is not computable at load time + +[test_global_data_error] +96_nodata_wanted.c:20: error: initializer element is not computable at load time + +[test_local_data_noerror] +96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast +96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short + +[test_data_suppression_off] +data: + 8 - 8.0 - 8.0 - main - static string + 333 44 555555 6 7 +size of data/text: + non-zero/non-zero + +[test_data_suppression_on] +size of data/text: + zero/zero diff --git a/tinyc/tests/tests2/97_utf8_string_literal.c b/tinyc/tests/tests2/97_utf8_string_literal.c new file mode 100644 index 000000000..96fbab0d1 --- /dev/null +++ b/tinyc/tests/tests2/97_utf8_string_literal.c @@ -0,0 +1,12 @@ +// this file contains BMP chars encoded in UTF-8 +#include <stdio.h> +#include <wchar.h> + +int main() +{ + wchar_t s[] = L"hello$$ä½ å¥½Â¢Â¢ä¸–ç•Œâ‚¬â‚¬world"; + wchar_t *p; + for (p = s; *p; p++) printf("%04X ", (unsigned) *p); + printf("\n"); + return 0; +} diff --git a/tinyc/tests/tests2/97_utf8_string_literal.expect b/tinyc/tests/tests2/97_utf8_string_literal.expect new file mode 100644 index 000000000..9a1593cdd --- /dev/null +++ b/tinyc/tests/tests2/97_utf8_string_literal.expect @@ -0,0 +1 @@ +0068 0065 006C 006C 006F 0024 0024 4F60 597D 00A2 00A2 4E16 754C 20AC 20AC 0077 006F 0072 006C 0064 diff --git a/tinyc/tests/tests2/98_al_ax_extend.c b/tinyc/tests/tests2/98_al_ax_extend.c new file mode 100644 index 000000000..9b4e02fe7 --- /dev/null +++ b/tinyc/tests/tests2/98_al_ax_extend.c @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> +asm ( + ".text;" + ".globl _us;.globl _ss;.globl _uc;.globl _sc;" + "_us:;_ss:;_uc:;_sc:;" + "movl $0x1234ABCD, %eax;" + "ret;" +); + +#if 1 +#define us _us +#define ss _ss +#define uc _uc +#define sc _sc +#endif + +int main() +{ + unsigned short us(void); + short ss(void); + unsigned char uc(void); + signed char sc(void); + + unsigned short (*fpus)(void) = us; + short (*fpss)(void) = ss; + unsigned char (*fpuc)(void) = uc; + signed char (*fpsc)(void) = sc; + + printf("%08X %08X\n", us() + 1, fpus() + 1); + printf("%08X %08X\n", ss() + 1, fpss() + 1); + printf("%08X %08X\n", uc() + 1, fpuc() + 1); + printf("%08X %08X\n", sc() + 1, fpsc() + 1); + printf("\n"); + printf("%08X %08X\n", fpus() + 1, us() + 1); + printf("%08X %08X\n", fpss() + 1, ss() + 1); + printf("%08X %08X\n", fpuc() + 1, uc() + 1); + printf("%08X %08X\n", fpsc() + 1, sc() + 1); + + return 0; +} diff --git a/tinyc/tests/tests2/98_al_ax_extend.expect b/tinyc/tests/tests2/98_al_ax_extend.expect new file mode 100644 index 000000000..c5752e843 --- /dev/null +++ b/tinyc/tests/tests2/98_al_ax_extend.expect @@ -0,0 +1,9 @@ +0000ABCE 0000ABCE +FFFFABCE FFFFABCE +000000CE 000000CE +FFFFFFCE FFFFFFCE + +0000ABCE 0000ABCE +FFFFABCE FFFFABCE +000000CE 000000CE +FFFFFFCE FFFFFFCE diff --git a/tinyc/tests/tests2/99_fastcall.c b/tinyc/tests/tests2/99_fastcall.c new file mode 100644 index 000000000..ee4b67d20 --- /dev/null +++ b/tinyc/tests/tests2/99_fastcall.c @@ -0,0 +1,276 @@ +#include <stdio.h> +#include <assert.h> + +#ifndef _WIN32 +#define __fastcall __attribute((fastcall)) +#endif + +#if 1 +#define SYMBOL(x) _##x +#else +#define SYMBOL(x) x +#endif + +///////////////////////////////////////////////////////////////////////// +////////// TRAP FRAMEWORK +///////////////////////////////////////////////////////////////////////// +// if you cast 'TRAP' to a function pointer and call it, +// it will save all 8 registers, +// and jump into C-code (previously set using 'SET_TRAP_HANDLER(x)'), +// in C-code you can pop DWORDs from stack and modify registers +// + +void *SYMBOL(trap_handler); + +extern unsigned char SYMBOL(trap)[]; +asm ( + ".text;" + "_trap:;" + "pushl %esp;" + "pusha;" + "addl $0x4, 0xc(%esp);" + "pushl %esp;" + "call *_trap_handler;" + "addl $0x4, %esp;" + "movl 0xc(%esp), %eax;" + "movl %eax, 0x20(%esp);" + "popa;" + "popl %esp;" + "ret;" +); + +struct trapframe { + unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax; +}; + + +#define M_FLOAT(addr) (*(float *)(addr)) +#define M_DWORD(addr) (*(unsigned *)(addr)) +#define M_WORD(addr) (*(unsigned short *)(addr)) +#define M_BYTE(addr) (*(unsigned char *)(addr)) +#define R_EAX ((tf)->eax) +#define R_ECX ((tf)->ecx) +#define R_EDX ((tf)->edx) +#define R_EBX ((tf)->ebx) +#define R_ESP ((tf)->esp) +#define R_EBP ((tf)->ebp) +#define R_ESI ((tf)->esi) +#define R_EDI ((tf)->edi) + +#define ARG(x) (M_DWORD(R_ESP + (x) * 4)) + +#define RETN(x) do { \ + M_DWORD(R_ESP + (x)) = M_DWORD(R_ESP); \ + R_ESP += (x); \ +} while (0) + +#define DUMP() do { \ + unsigned i; \ + printf("EAX: %08X\n", R_EAX); \ + printf("ECX: %08X\n", R_ECX); \ + printf("EDX: %08X\n", R_EDX); \ + printf("EBX: %08X\n", R_EBX); \ + printf("ESP: %08X\n", R_ESP); \ + printf("EBP: %08X\n", R_EBP); \ + printf("ESI: %08X\n", R_ESI); \ + printf("EDI: %08X\n", R_EDI); \ + printf("\n"); \ + printf("[RETADDR]: %08X\n", M_DWORD(R_ESP)); \ + for (i = 1; i <= 8; i++) { \ + printf("[ARG%4d]: %08X\n", i, ARG(i)); \ + } \ +} while (0) + +#define SET_TRAP_HANDLER(x) ((SYMBOL(trap_handler)) = (x)) +#define TRAP ((void *) &SYMBOL(trap)) + + + +///////////////////////////////////////////////////////////////////////// +////////// SAFECALL FRAMEWORK +///////////////////////////////////////////////////////////////////////// +// this framework will convert any calling convention to cdecl +// usage: first set call target with 'SET_SAFECALL_TARGET(x)' +// then cast 'SAFECALL' to target function pointer type and invoke it +// after calling, 'ESPDIFF' is the difference of old and new esp + +void *SYMBOL(sc_call_target); +unsigned SYMBOL(sc_retn_addr); +unsigned SYMBOL(sc_old_esp); +unsigned SYMBOL(sc_new_esp); + +extern unsigned char SYMBOL(safecall)[]; +asm ( + ".text;" + "_safecall:;" + "popl _sc_retn_addr;" + "movl %esp, _sc_old_esp;" + "call *_sc_call_target;" + "movl %esp, _sc_new_esp;" + "movl _sc_old_esp, %esp;" + "jmp *_sc_retn_addr;" +); + +#define SET_SAFECALL_TARGET(x) ((SYMBOL(sc_call_target)) = (x)) +#define SAFECALL ((void *) &SYMBOL(safecall)) +#define ESPDIFF (SYMBOL(sc_new_esp) - SYMBOL(sc_old_esp)) + + +///////////////////////////////////////////////////////////////////////// +////////// TEST FASTCALL INVOKE +///////////////////////////////////////////////////////////////////////// + +void check_fastcall_invoke_0(struct trapframe *tf) +{ + //DUMP(); + RETN(0); +} + +void check_fastcall_invoke_1(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + RETN(0); +} +void check_fastcall_invoke_2(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + RETN(0); +} +void check_fastcall_invoke_3(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + RETN(1*4); +} +void check_fastcall_invoke_4(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + assert(ARG(2) == 0x44444444); + RETN(2*4); +} + +void check_fastcall_invoke_5(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + assert(ARG(2) == 0x44444444); + assert(ARG(3) == 0x55555555); + RETN(3*4); +} + +void test_fastcall_invoke() +{ + SET_TRAP_HANDLER(check_fastcall_invoke_0); + ((void __fastcall (*)(void)) TRAP)(); + + SET_TRAP_HANDLER(check_fastcall_invoke_1); + ((void __fastcall (*)(unsigned)) TRAP)(0x11111111); + + SET_TRAP_HANDLER(check_fastcall_invoke_2); + ((void __fastcall (*)(unsigned, unsigned)) TRAP)(0x11111111, 0x22222222); + + SET_TRAP_HANDLER(check_fastcall_invoke_3); + ((void __fastcall (*)(unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333); + + SET_TRAP_HANDLER(check_fastcall_invoke_4); + ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444); + + SET_TRAP_HANDLER(check_fastcall_invoke_5); + ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555); +} + + +///////////////////////////////////////////////////////////////////////// +////////// TEST FUNCTION CODE GENERATION +///////////////////////////////////////////////////////////////////////// + +int __fastcall check_fastcall_espdiff_0(void) +{ + return 0; +} + +int __fastcall check_fastcall_espdiff_1(int a) +{ + return a; +} + +int __fastcall check_fastcall_espdiff_2(int a, int b) +{ + return a + b; +} + +int __fastcall check_fastcall_espdiff_3(int a, int b, int c) +{ + return a + b + c; +} + +int __fastcall check_fastcall_espdiff_4(int a, int b, int c, int d) +{ + return a + b + c + d; +} + +int __fastcall check_fastcall_espdiff_5(int a, int b, int c, int d, int e) +{ + return a + b + c + d + e; +} + +void test_fastcall_espdiff() +{ + int x; + SET_SAFECALL_TARGET(check_fastcall_espdiff_0); + x = ((typeof(&check_fastcall_espdiff_0))SAFECALL)(); + assert(x == 0); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_1); + x = ((typeof(&check_fastcall_espdiff_1))SAFECALL)(1); + assert(x == 1); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_2); + x = ((typeof(&check_fastcall_espdiff_2))SAFECALL)(1, 2); + assert(x == 1 + 2); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_3); + x = ((typeof(&check_fastcall_espdiff_3))SAFECALL)(1, 2, 3); + assert(x == 1 + 2 + 3); + assert(ESPDIFF == 1*4); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_4); + x = ((typeof(&check_fastcall_espdiff_4))SAFECALL)(1, 2, 3, 4); + assert(x == 1 + 2 + 3 + 4); + assert(ESPDIFF == 2*4); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_5); + x = ((typeof(&check_fastcall_espdiff_5))SAFECALL)(1, 2, 3, 4, 5); + assert(x == 1 + 2 + 3 + 4 + 5); + assert(ESPDIFF == 3*4); +} + +int main() +{ +#define N 10000 + int i; + + for (i = 1; i <= N; i++) { + test_fastcall_espdiff(); + } + + for (i = 1; i <= N; i++) { + test_fastcall_invoke(); + } + + puts("TEST OK"); + return 0; +} diff --git a/tinyc/tests/tests2/99_fastcall.expect b/tinyc/tests/tests2/99_fastcall.expect new file mode 100644 index 000000000..3835d63df --- /dev/null +++ b/tinyc/tests/tests2/99_fastcall.expect @@ -0,0 +1 @@ +TEST OK diff --git a/tinyc/tests/vla_test.c b/tinyc/tests/vla_test.c new file mode 100644 index 000000000..3616c46d4 --- /dev/null +++ b/tinyc/tests/vla_test.c @@ -0,0 +1,84 @@ +/* + * Test that allocating a variable length array in a loop + * does not use up a linear amount of memory + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define LOOP_COUNT 1000 +#define ARRAY_SIZE 100 + +/* Overwrite a VLA. This will overwrite the return address if SP is incorrect */ +void smash(char *p, int n) { + memset(p, 0, n); +} + +int test1(int n) { + int i; + char *array_ptrs[LOOP_COUNT]; + + for (i = 0; i < LOOP_COUNT; ++i) { + char test[n]; + smash(test, n); + array_ptrs[i] = test; + } + + return (array_ptrs[0]-array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1; +} + +/* ensure goto does not circumvent array free */ +int test2(int n) { + char *array_ptrs[LOOP_COUNT]; + + int i = 0; +loop:; + char test[n]; + smash(test, n); + if (i >= LOOP_COUNT) + goto end; + array_ptrs[i] = test; + ++i; + goto loop; + +end: + smash(test, n); + char test2[n]; + smash(test2, n); + return (array_ptrs[0] - array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1; +} + +int test3(int n) { + char test[n]; + smash(test, n); + goto label; +label: + smash(test, n); + char test2[n]; + smash(test2, n); + return (test-test2 >= n) ? 0 : 1; +} + +#define RUN_TEST(t) \ + if (!testname || (strcmp(#t, testname) == 0)) { \ + fputs(#t "... ", stdout); \ + fflush(stdout); \ + if (t(ARRAY_SIZE) == 0) { \ + fputs("success\n", stdout); \ + } else { \ + fputs("failure\n", stdout); \ + retval = EXIT_FAILURE; \ + } \ + } + +int main(int argc, char **argv) { + const char *testname = NULL; + int retval = EXIT_SUCCESS; + if (argc > 1) + testname = argv[1]; + RUN_TEST(test1) + RUN_TEST(test2) + RUN_TEST(test3) + return retval; +} diff --git a/tinyc/win32/build-tcc.bat b/tinyc/win32/build-tcc.bat index 9d3866c16..ceb4411ff 100644 --- a/tinyc/win32/build-tcc.bat +++ b/tinyc/win32/build-tcc.bat @@ -1,28 +1,189 @@ -@rem ---------------------------------------------------- -@rem batch file to build tcc using gcc and ar from mingw -@rem ---------------------------------------------------- -: -@echo>..\config.h #define TCC_VERSION "0.9.25" -@echo>>..\config.h #define TCC_TARGET_PE 1 -@echo>>..\config.h #define CONFIG_TCCDIR "." -@echo>>..\config.h #define CONFIG_SYSROOT "" -: -gcc -Os -fno-strict-aliasing ../tcc.c -o tcc.exe -s -gcc -Os -fno-strict-aliasing ../libtcc.c -c -o libtcc.o -gcc -Os tools/tiny_impdef.c -o tiny_impdef.exe -s -gcc -Os tools/tiny_libmaker.c -o tiny_libmaker.exe -s -mkdir libtcc -ar rcs libtcc/libtcc.a libtcc.o -del libtcc.o -copy ..\libtcc.h libtcc -: -.\tcc -c lib/crt1.c -.\tcc -c lib/wincrt1.c -.\tcc -c lib/dllcrt1.c -.\tcc -c lib/dllmain.c -.\tcc -c lib/chkstk.S -.\tcc -c ../lib/libtcc1.c -.\tcc -c ../lib/alloca86.S -.\tcc -c ../lib/alloca86-bt.S -ar rcs lib/libtcc1.a crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o libtcc1.o alloca86.o alloca86-bt.o -rem del *.o +@rem ------------------------------------------------------ +@rem batch file to build tcc using mingw, msvc or tcc itself +@rem ------------------------------------------------------ + +@echo off +setlocal +if (%1)==(-clean) goto :cleanup +set CC=gcc +set /p VERSION= < ..\VERSION +set INST= +set BIN= +set DOC=no +set EXES_ONLY=no +goto :a0 +:a2 +shift +:a3 +shift +:a0 +if not (%1)==(-c) goto :a1 +set CC=%~2 +if (%2)==(cl) set CC=@call :cl +goto :a2 +:a1 +if (%1)==(-t) set T=%2&& goto :a2 +if (%1)==(-v) set VERSION=%~2&& goto :a2 +if (%1)==(-i) set INST=%2&& goto :a2 +if (%1)==(-b) set BIN=%2&& goto :a2 +if (%1)==(-d) set DOC=yes&& goto :a3 +if (%1)==(-x) set EXES_ONLY=yes&& goto :a3 +if (%1)==() goto :p1 +:usage +echo usage: build-tcc.bat [ options ... ] +echo options: +echo -c prog use prog (gcc/tcc/cl) to compile tcc +echo -c "prog options" use prog with options to compile tcc +echo -t 32/64 force 32/64 bit default target +echo -v "version" set tcc version +echo -i tccdir install tcc into tccdir +echo -b bindir optionally install binaries into bindir elsewhere +echo -d create tcc-doc.html too (needs makeinfo) +echo -x just create the executables +echo -clean delete all previously produced files and directories +exit /B 1 + +@rem ------------------------------------------------------ +@rem sub-routines + +:cleanup +set LOG=echo +%LOG% removing files: +for %%f in (*tcc.exe libtcc.dll lib\*.a) do call :del_file %%f +for %%f in (..\config.h ..\config.texi) do call :del_file %%f +for %%f in (include\*.h) do @if exist ..\%%f call :del_file %%f +for %%f in (include\tcclib.h examples\libtcc_test.c) do call :del_file %%f +for %%f in (*.o *.obj *.def *.pdb *.lib *.exp *.ilk) do call :del_file %%f +%LOG% removing directories: +for %%f in (doc libtcc) do call :del_dir %%f +%LOG% done. +exit /B 0 +:del_file +if exist %1 del %1 && %LOG% %1 +exit /B 0 +:del_dir +if exist %1 rmdir /Q/S %1 && %LOG% %1 +exit /B 0 + +:cl +@echo off +set CMD=cl +:c0 +set ARG=%1 +set ARG=%ARG:.dll=.lib% +if (%1)==(-shared) set ARG=-LD +if (%1)==(-o) shift && set ARG=-Fe%2 +set CMD=%CMD% %ARG% +shift +if not (%1)==() goto :c0 +echo on +%CMD% -O1 -W2 -Zi -MT -GS- -nologo -link -opt:ref,icf +@exit /B %ERRORLEVEL% + +@rem ------------------------------------------------------ +@rem main program + +:p1 +if not %T%_==_ goto :p2 +set T=32 +if %PROCESSOR_ARCHITECTURE%_==AMD64_ set T=64 +if %PROCESSOR_ARCHITEW6432%_==AMD64_ set T=64 +:p2 +if "%CC:~-3%"=="gcc" set CC=%CC% -Os -s -static +set D32=-DTCC_TARGET_PE -DTCC_TARGET_I386 +set D64=-DTCC_TARGET_PE -DTCC_TARGET_X86_64 +set P32=i386-win32 +set P64=x86_64-win32 +if %T%==64 goto :t64 +set D=%D32% +set DX=%D64% +set PX=%P64% +goto :p3 +:t64 +set D=%D64% +set DX=%D32% +set PX=%P32% +goto :p3 + +:p3 +@echo on + +:config.h +echo>..\config.h #define TCC_VERSION "%VERSION%" +echo>> ..\config.h #ifdef TCC_TARGET_X86_64 +echo>> ..\config.h #define TCC_LIBTCC1 "libtcc1-64.a" +echo>> ..\config.h #else +echo>> ..\config.h #define TCC_LIBTCC1 "libtcc1-32.a" +echo>> ..\config.h #endif + +for %%f in (*tcc.exe *tcc.dll) do @del %%f + +:compiler +%CC% -o libtcc.dll -shared ..\libtcc.c %D% -DLIBTCC_AS_DLL +@if errorlevel 1 goto :the_end +%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0" +%CC% -o %PX%-tcc.exe ..\tcc.c %DX% + +@if (%EXES_ONLY%)==(yes) goto :files-done + +if not exist libtcc mkdir libtcc +if not exist doc mkdir doc +copy>nul ..\include\*.h include +copy>nul ..\tcclib.h include +copy>nul ..\libtcc.h libtcc +copy>nul ..\tests\libtcc_test.c examples +copy>nul tcc-win32.txt doc + +.\tcc -impdef libtcc.dll -o libtcc\libtcc.def +@if errorlevel 1 goto :the_end + +:libtcc1.a +@set O1=libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o bcheck.o +.\tcc -m32 -c ../lib/libtcc1.c +.\tcc -m32 -c lib/crt1.c +.\tcc -m32 -c lib/crt1w.c +.\tcc -m32 -c lib/wincrt1.c +.\tcc -m32 -c lib/wincrt1w.c +.\tcc -m32 -c lib/dllcrt1.c +.\tcc -m32 -c lib/dllmain.c +.\tcc -m32 -c lib/chkstk.S +.\tcc -m32 -w -c ../lib/bcheck.c +.\tcc -m32 -c ../lib/alloca86.S +.\tcc -m32 -c ../lib/alloca86-bt.S +.\tcc -m32 -ar lib/libtcc1-32.a %O1% alloca86.o alloca86-bt.o +@if errorlevel 1 goto :the_end +.\tcc -m64 -c ../lib/libtcc1.c +.\tcc -m64 -c lib/crt1.c +.\tcc -m64 -c lib/crt1w.c +.\tcc -m64 -c lib/wincrt1.c +.\tcc -m64 -c lib/wincrt1w.c +.\tcc -m64 -c lib/dllcrt1.c +.\tcc -m64 -c lib/dllmain.c +.\tcc -m64 -c lib/chkstk.S +.\tcc -m64 -w -c ../lib/bcheck.c +.\tcc -m64 -c ../lib/alloca86_64.S +.\tcc -m64 -c ../lib/alloca86_64-bt.S +.\tcc -m64 -ar lib/libtcc1-64.a %O1% alloca86_64.o alloca86_64-bt.o +@if errorlevel 1 goto :the_end + +:tcc-doc.html +@if not (%DOC%)==(yes) goto :doc-done +echo>..\config.texi @set VERSION %VERSION% +cmd /c makeinfo --html --no-split ../tcc-doc.texi -o doc/tcc-doc.html +:doc-done + +:files-done +for %%f in (*.o *.def) do @del %%f + +:copy-install +@if (%INST%)==() goto :the_end +if not exist %INST% mkdir %INST% +@if (%BIN%)==() set BIN=%INST% +if not exist %BIN% mkdir %BIN% +for %%f in (*tcc.exe *tcc.dll) do @copy>nul %%f %BIN%\%%f +@if not exist %INST%\lib mkdir %INST%\lib +for %%f in (lib\*.a lib\*.def) do @copy>nul %%f %INST%\%%f +for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %INST%\%%f + +:the_end +exit /B %ERRORLEVEL% diff --git a/tinyc/win32/examples/dll.c b/tinyc/win32/examples/dll.c index 4202e99ca..052a05644 100644 --- a/tinyc/win32/examples/dll.c +++ b/tinyc/win32/examples/dll.c @@ -5,11 +5,9 @@ #include <windows.h> -#define DLL_EXPORT __declspec(dllexport) +__declspec(dllexport) const char *hello_data = "(not set)"; - -DLL_EXPORT void HelloWorld (void) +__declspec(dllexport) void hello_func (void) { - MessageBox (0, "Hello World!", "From DLL", MB_ICONINFORMATION); + MessageBox (0, hello_data, "From DLL", MB_ICONINFORMATION); } - diff --git a/tinyc/win32/examples/fib.c b/tinyc/win32/examples/fib.c index 6a4bdf5c4..8da26bce6 100644 --- a/tinyc/win32/examples/fib.c +++ b/tinyc/win32/examples/fib.c @@ -1,7 +1,7 @@ #include <stdio.h> -#include <math.h> +#include <stdlib.h> // atoi() -int fib(int n) +int fib(n) { if (n <= 2) return 1; diff --git a/tinyc/win32/examples/hello_dll.c b/tinyc/win32/examples/hello_dll.c index 7adba77ec..4813c5b94 100644 --- a/tinyc/win32/examples/hello_dll.c +++ b/tinyc/win32/examples/hello_dll.c @@ -5,15 +5,16 @@ #include <windows.h> -void HelloWorld (void); +void hello_func (void); +__declspec(dllimport) extern const char *hello_data; int WINAPI WinMain( - HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) { - HelloWorld(); - return 0; + hello_data = "Hello World!"; + hello_func(); + return 0; } - diff --git a/tinyc/win32/examples/hello_win.c b/tinyc/win32/examples/hello_win.c index 294b7279a..96546e415 100644 --- a/tinyc/win32/examples/hello_win.c +++ b/tinyc/win32/examples/hello_win.c @@ -10,9 +10,7 @@ char szAppName[] = APPNAME; // The name of this application char szTitle[] = APPNAME; // The title bar text -char *pWindowText; - -HINSTANCE g_hInst; // current instance +const char *pWindowText; void CenterWindow(HWND hWnd); @@ -28,51 +26,49 @@ void CenterWindow(HWND hWnd); LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) - { - // ----------------------- first and last - case WM_CREATE: - CenterWindow(hwnd); - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - - // ----------------------- get out of it... - case WM_RBUTTONUP: - DestroyWindow(hwnd); - break; - - case WM_KEYDOWN: - if (VK_ESCAPE == wParam) - DestroyWindow(hwnd); - break; - - - // ----------------------- display our minimal info - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc; - RECT rc; - hdc = BeginPaint(hwnd, &ps); - - GetClientRect(hwnd, &rc); - SetTextColor(hdc, RGB(240,240,96)); - SetBkMode(hdc, TRANSPARENT); - DrawText(hdc, pWindowText, -1, &rc, DT_CENTER|DT_SINGLELINE|DT_VCENTER); - - EndPaint(hwnd, &ps); - break; - } - - // ----------------------- let windows do all other stuff - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; + switch (message) { + + // ----------------------- first and last + case WM_CREATE: + CenterWindow(hwnd); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + // ----------------------- get out of it... + case WM_RBUTTONUP: + DestroyWindow(hwnd); + break; + + case WM_KEYDOWN: + if (VK_ESCAPE == wParam) + DestroyWindow(hwnd); + break; + + // ----------------------- display our minimal info + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc; + RECT rc; + hdc = BeginPaint(hwnd, &ps); + + GetClientRect(hwnd, &rc); + SetTextColor(hdc, RGB(240,240,96)); + SetBkMode(hdc, TRANSPARENT); + DrawText(hdc, pWindowText, -1, &rc, DT_CENTER|DT_SINGLELINE|DT_VCENTER); + + EndPaint(hwnd, &ps); + break; + } + + // ----------------------- let windows do all other stuff + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; } //+--------------------------------------------------------------------------- @@ -83,57 +79,57 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) // //---------------------------------------------------------------------------- int APIENTRY WinMain( - HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow + ) { - MSG msg; - - WNDCLASS wc; - - HWND hwnd; - - // Fill in window class structure with parameters that describe - // the main window. - - ZeroMemory(&wc, sizeof wc); - wc.hInstance = hInstance; - wc.lpszClassName = szAppName; - wc.lpfnWndProc = (WNDPROC)WndProc; - wc.style = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW; - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - - if (FALSE == RegisterClass(&wc)) return 0; - - // create the browser - hwnd = CreateWindow( - szAppName, - szTitle, - WS_OVERLAPPEDWINDOW|WS_VISIBLE, - CW_USEDEFAULT, - CW_USEDEFAULT, - 360,//CW_USEDEFAULT, - 240,//CW_USEDEFAULT, - 0, - 0, - g_hInst, - 0); - - if (NULL == hwnd) return 0; - - pWindowText = lpCmdLine[0] ? lpCmdLine : "Hello Windows!"; - - // Main message loop: - while (GetMessage(&msg, NULL, 0, 0) > 0) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - return msg.wParam; + MSG msg; + WNDCLASS wc; + HWND hwnd; + + pWindowText = lpCmdLine[0] ? lpCmdLine : "Hello Windows!"; + + // Fill in window class structure with parameters that describe + // the main window. + + ZeroMemory(&wc, sizeof wc); + wc.hInstance = hInstance; + wc.lpszClassName = szAppName; + wc.lpfnWndProc = (WNDPROC)WndProc; + wc.style = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW; + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + + if (FALSE == RegisterClass(&wc)) + return 0; + + // create the browser + hwnd = CreateWindow( + szAppName, + szTitle, + WS_OVERLAPPEDWINDOW|WS_VISIBLE, + CW_USEDEFAULT, + CW_USEDEFAULT, + 360,//CW_USEDEFAULT, + 240,//CW_USEDEFAULT, + 0, + 0, + hInstance, + 0); + + if (NULL == hwnd) + return 0; + + // Main message loop: + while (GetMessage(&msg, NULL, 0, 0) > 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return msg.wParam; } //+--------------------------------------------------------------------------- @@ -142,18 +138,26 @@ int APIENTRY WinMain( void CenterWindow(HWND hwnd_self) { - RECT rw_self, rc_parent, rw_parent; HWND hwnd_parent; - hwnd_parent = GetParent(hwnd_self); - if (NULL==hwnd_parent) hwnd_parent = GetDesktopWindow(); - GetWindowRect(hwnd_parent, &rw_parent); - GetClientRect(hwnd_parent, &rc_parent); - GetWindowRect(hwnd_self, &rw_self); - SetWindowPos(hwnd_self, NULL, - rw_parent.left + (rc_parent.right + rw_self.left - rw_self.right) / 2, - rw_parent.top + (rc_parent.bottom + rw_self.top - rw_self.bottom) / 2, - 0, 0, - SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE - ); + HWND hwnd_parent; + RECT rw_self, rc_parent, rw_parent; + int xpos, ypos; + + hwnd_parent = GetParent(hwnd_self); + if (NULL == hwnd_parent) + hwnd_parent = GetDesktopWindow(); + + GetWindowRect(hwnd_parent, &rw_parent); + GetClientRect(hwnd_parent, &rc_parent); + GetWindowRect(hwnd_self, &rw_self); + + xpos = rw_parent.left + (rc_parent.right + rw_self.left - rw_self.right) / 2; + ypos = rw_parent.top + (rc_parent.bottom + rw_self.top - rw_self.bottom) / 2; + + SetWindowPos( + hwnd_self, NULL, + xpos, ypos, 0, 0, + SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE + ); } //+--------------------------------------------------------------------------- diff --git a/tinyc/win32/include/_mingw.h b/tinyc/win32/include/_mingw.h index 257c52376..2fc979872 100644 --- a/tinyc/win32/include/_mingw.h +++ b/tinyc/win32/include/_mingw.h @@ -1,7 +1,7 @@ /* * _mingw.h * - * This file is for TCC-PE and not part of the Mingw32 package. + * This file is for TinyCC and not part of the Mingw32 package. * * THIS SOFTWARE IS NOT COPYRIGHTED * @@ -18,37 +18,153 @@ #ifndef __MINGW_H #define __MINGW_H +/* some winapi files define these before including _mingw.h --> */ +#undef __cdecl +#undef _X86_ +#undef WIN32 +/* <-- */ + #include <stddef.h> +#include <stdarg.h> -#define __int64 long long -#define __int32 long -#define __int16 short #define __int8 char -#define __cdecl __attribute__((__cdecl__)) -#define __stdcall __attribute__((__stdcall__)) -#define __declspec(x) __attribute__((x)) +#define __int16 short +#define __int32 int +#define __int64 long long +#define _HAVE_INT64 -#define __MINGW32_VERSION 2.0 -#define __MINGW32_MAJOR_VERSION 2 -#define __MINGW32_MINOR_VERSION 0 +#define __cdecl +#define __declspec(x) __attribute__((x)) +#define __unaligned __attribute__((packed)) +#define __fastcall __attribute__((fastcall)) #define __MSVCRT__ 1 -#define __MINGW_IMPORT extern -#define _CRTIMP +#undef _MSVCRT_ +#define __MINGW_IMPORT extern __declspec(dllimport) +#define __MINGW_ATTRIB_NORETURN +#define __MINGW_ATTRIB_CONST +#define __MINGW_ATTRIB_DEPRECATED +#define __MINGW_ATTRIB_MALLOC +#define __MINGW_ATTRIB_PURE +#define __MINGW_ATTRIB_NONNULL(arg) +#define __MINGW_NOTHROW +#define __GNUC_VA_LIST + +#define _CRTIMP extern #define __CRT_INLINE extern __inline__ +#define _CRT_ALIGN(x) __attribute__((aligned(x))) +#define DECLSPEC_ALIGN(x) __attribute__((aligned(x))) +#define _CRT_PACKING 8 +#define __CRT_UNALIGNED +#define _CONST_RETURN + +#ifndef _TRUNCATE +#define _TRUNCATE ((size_t)-1) +#endif + +#define __CRT_STRINGIZE(_Value) #_Value +#define _CRT_STRINGIZE(_Value) __CRT_STRINGIZE(_Value) +#define __CRT_WIDE(_String) L ## _String +#define _CRT_WIDE(_String) __CRT_WIDE(_String) + +#ifdef _WIN64 +#define __stdcall +#define _AMD64_ 1 +#define __x86_64 1 +#define _M_X64 100 /* Visual Studio */ +#define _M_AMD64 100 /* Visual Studio */ +#define USE_MINGW_SETJMP_TWO_ARGS +#define mingw_getsp tinyc_getbp +#define __TRY__ +#else +#define __stdcall __attribute__((__stdcall__)) +#define _X86_ 1 +#define _M_IX86 300 /* Visual Studio */ #define WIN32 1 +#define _USE_32BIT_TIME_T +#ifdef __arm__ +#define __TRY__ +#else +#define __TRY__ void __try__(void**), *_sehrec[6]; __try__(_sehrec); +#endif +#endif + +/* in stddef.h */ +#define _SIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#define _PTRDIFF_T_DEFINED +#define _WCHAR_T_DEFINED +#define _UINTPTR_T_DEFINED +#define _INTPTR_T_DEFINED +#define _INTEGRAL_MAX_BITS 64 + +#ifndef _TIME32_T_DEFINED +#define _TIME32_T_DEFINED +typedef long __time32_t; +#endif + +#ifndef _TIME64_T_DEFINED +#define _TIME64_T_DEFINED +typedef long long __time64_t; +#endif + +#ifndef _TIME_T_DEFINED +#define _TIME_T_DEFINED +#ifdef _USE_32BIT_TIME_T +typedef __time32_t time_t; +#else +typedef __time64_t time_t; +#endif +#endif + +#ifndef _WCTYPE_T_DEFINED +#define _WCTYPE_T_DEFINED +typedef wchar_t wctype_t; +#endif #ifndef _WINT_T #define _WINT_T -typedef unsigned int wint_t; +typedef __WINT_TYPE__ wint_t; #endif +typedef int errno_t; +#define _ERRCODE_DEFINED + +typedef struct threadlocaleinfostruct *pthreadlocinfo; +typedef struct threadmbcinfostruct *pthreadmbcinfo; +typedef struct localeinfo_struct _locale_tstruct,*_locale_t; + /* for winapi */ #define _ANONYMOUS_UNION #define _ANONYMOUS_STRUCT #define DECLSPEC_NORETURN -#define WIN32_LEAN_AND_MEAN #define DECLARE_STDCALL_P(type) __stdcall type +#define NOSERVICE 1 +#define NOMCX 1 +#define NOIME 1 +#define __INTRIN_H_ +#ifndef DUMMYUNIONNAME +# define DUMMYUNIONNAME +# define DUMMYUNIONNAME1 +# define DUMMYUNIONNAME2 +# define DUMMYUNIONNAME3 +# define DUMMYUNIONNAME4 +# define DUMMYUNIONNAME5 +#endif +#ifndef DUMMYSTRUCTNAME +# define DUMMYSTRUCTNAME +#endif +#ifndef WINVER +# define WINVER 0x0502 +#endif +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x502 +#endif + +#define __C89_NAMELESS +#define __MINGW_EXTENSION +#define WINAPI_FAMILY_PARTITION(X) 1 +#define MINGW_HAS_SECURE_API #endif /* __MINGW_H */ diff --git a/tinyc/win32/include/assert.h b/tinyc/win32/include/assert.h index 959c80351..466d4571a 100644 --- a/tinyc/win32/include/assert.h +++ b/tinyc/win32/include/assert.h @@ -1,71 +1,57 @@ -/* - * assert.h - * - * Define the assert macro for debug output. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef __ASSERT_H_ +#define __ASSERT_H_ -#ifndef _ASSERT_H_ -#define _ASSERT_H_ - -/* All the headers include this file. */ #include <_mingw.h> - -#ifndef RC_INVOKED - -#ifdef __cplusplus -extern "C" { +#ifdef __cplusplus +#include <stdlib.h> #endif #ifdef NDEBUG +#ifndef assert +#define assert(_Expression) ((void)0) +#endif +#else + +#ifndef _CRT_TERMINATE_DEFINED +#define _CRT_TERMINATE_DEFINED + void __cdecl __MINGW_NOTHROW exit(int _Code) __MINGW_ATTRIB_NORETURN; + _CRTIMP void __cdecl __MINGW_NOTHROW _exit(int _Code) __MINGW_ATTRIB_NORETURN; +#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */ +/* C99 function name */ +void __cdecl _Exit(int) __MINGW_ATTRIB_NORETURN; +__CRT_INLINE __MINGW_ATTRIB_NORETURN void __cdecl _Exit(int status) +{ _exit(status); } +#endif -/* - * If not debugging, assert does nothing. - */ -#define assert(x) ((void)0) +#pragma push_macro("abort") +#undef abort + void __cdecl __declspec(noreturn) abort(void); +#pragma pop_macro("abort") -#else /* debugging enabled */ +#endif -/* - * CRTDLL nicely supplies a function which does the actual output and - * call to abort. - */ -void _assert (const char*, const char*, int) -#ifdef __GNUC__ - __attribute__ ((noreturn)) +#ifdef __cplusplus +extern "C" { #endif - ; -/* - * Definition of the assert macro. - */ -#define assert(e) ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__)) -#endif /* NDEBUG */ -#ifdef __cplusplus +extern void __cdecl _wassert(const wchar_t *_Message,const wchar_t *_File,unsigned _Line); +extern void __cdecl _assert(const char *, const char *, unsigned); + +#ifdef __cplusplus } #endif -#endif /* Not RC_INVOKED */ +#ifndef assert +//#define assert(_Expression) (void)((!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression),_CRT_WIDE(__FILE__),__LINE__),0)) +#define assert(e) ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__)) +#endif -#endif /* Not _ASSERT_H_ */ +#endif +#endif diff --git a/tinyc/win32/include/conio.h b/tinyc/win32/include/conio.h index c1f4151df..39f779eb0 100644 --- a/tinyc/win32/include/conio.h +++ b/tinyc/win32/include/conio.h @@ -1,159 +1,409 @@ -/* A conio implementation for Mingw/Dev-C++. - * - * Written by: - * Hongli Lai <hongli@telekabel.nl> - * tkorrovi <tkorrovi@altavista.net> on 2002/02/26. - * Andrew Westcott <ajwestco@users.sourceforge.net> - * - * Offered for use in the public domain without any warranty. +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_CONIO +#define _INC_CONIO -#ifndef _CONIO_H_ -#define _CONIO_H_ - - -#include <stdio.h> +#include <_mingw.h> #ifdef __cplusplus extern "C" { #endif -#define BLINK 0 - -typedef enum -{ - BLACK, - BLUE, - GREEN, - CYAN, - RED, - MAGENTA, - BROWN, - LIGHTGRAY, - DARKGRAY, - LIGHTBLUE, - LIGHTGREEN, - LIGHTCYAN, - LIGHTRED, - LIGHTMAGENTA, - YELLOW, - WHITE -} COLORS; - - -#define cgets _cgets -#define cprintf _cprintf -#define cputs _cputs -#define cscanf _cscanf -#define ScreenClear clrscr - -/* blinkvideo */ - -void clreol (void); -void clrscr (void); - -int _conio_gettext (int left, int top, int right, int bottom, - char *str); -/* _conio_kbhit */ - -void delline (void); - -/* gettextinfo */ -void gotoxy(int x, int y); -/* -highvideo -insline -intensevideo -lowvideo -movetext -normvideo -*/ - -void puttext (int left, int top, int right, int bottom, char *str); - -// Screen Variables - -/* ScreenCols -ScreenGetChar -ScreenGetCursor -ScreenMode -ScreenPutChar -ScreenPutString -ScreenRetrieve -ScreenRows -ScreenSetCursor -ScreenUpdate -ScreenUpdateLine -ScreenVisualBell -_set_screen_lines */ - -void _setcursortype (int type); - -void textattr (int _attr); - -void textbackground (int color); - -void textcolor (int color); - -/* textmode */ - -int wherex (void); - -int wherey (void); - -/* window */ - - - -/* The code below was part of Mingw's conio.h */ -/* - * conio.h - * - * Low level console I/O functions. Pretty please try to use the ANSI - * standard ones if you are writing new code. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * - */ + _CRTIMP char *_cgets(char *_Buffer); + _CRTIMP int __cdecl _cprintf(const char *_Format,...); + _CRTIMP int __cdecl _cputs(const char *_Str); + _CRTIMP int __cdecl _cscanf(const char *_Format,...); + _CRTIMP int __cdecl _cscanf_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _getch(void); + _CRTIMP int __cdecl _getche(void); + _CRTIMP int __cdecl _vcprintf(const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _cprintf_p(const char *_Format,...); + _CRTIMP int __cdecl _vcprintf_p(const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _cprintf_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcprintf_l(const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _cprintf_p_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcprintf_p_l(const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _kbhit(void); + +#if defined(_X86_) && !defined(__x86_64) + int __cdecl _inp(unsigned short); + unsigned short __cdecl _inpw(unsigned short); + unsigned long __cdecl _inpd(unsigned short); + int __cdecl _outp(unsigned short,int); + unsigned short __cdecl _outpw(unsigned short,unsigned short); + unsigned long __cdecl _outpd(unsigned short,unsigned long); +#endif + + _CRTIMP int __cdecl _putch(int _Ch); + _CRTIMP int __cdecl _ungetch(int _Ch); + _CRTIMP int __cdecl _getch_nolock(void); + _CRTIMP int __cdecl _getche_nolock(void); + _CRTIMP int __cdecl _putch_nolock(int _Ch); + _CRTIMP int __cdecl _ungetch_nolock(int _Ch); + +#ifndef _WCONIO_DEFINED +#define _WCONIO_DEFINED + +#ifndef WEOF +#define WEOF (wint_t)(0xFFFF) +#endif -char* _cgets (char*); -int _cprintf (const char*, ...); -int _cputs (const char*); -int _cscanf (char*, ...); + _CRTIMP wchar_t *_cgetws(wchar_t *_Buffer); + _CRTIMP wint_t __cdecl _getwch(void); + _CRTIMP wint_t __cdecl _getwche(void); + _CRTIMP wint_t __cdecl _putwch(wchar_t _WCh); + _CRTIMP wint_t __cdecl _ungetwch(wint_t _WCh); + _CRTIMP int __cdecl _cputws(const wchar_t *_String); + _CRTIMP int __cdecl _cwprintf(const wchar_t *_Format,...); + _CRTIMP int __cdecl _cwscanf(const wchar_t *_Format,...); + _CRTIMP int __cdecl _cwscanf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _cwprintf_p(const wchar_t *_Format,...); + _CRTIMP int __cdecl _vcwprintf_p(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _cwprintf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _cwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP wint_t __cdecl _putwch_nolock(wchar_t _WCh); + _CRTIMP wint_t __cdecl _getwch_nolock(void); + _CRTIMP wint_t __cdecl _getwche_nolock(void); + _CRTIMP wint_t __cdecl _ungetwch_nolock(wint_t _WCh); +#endif -int _getch (void); -int _getche (void); -int _kbhit (void); -int _putch (int); -int _ungetch (int); +#ifndef NO_OLDNAMES + char *__cdecl cgets(char *_Buffer); + int __cdecl cprintf(const char *_Format,...); + int __cdecl cputs(const char *_Str); + int __cdecl cscanf(const char *_Format,...); + int __cdecl getch(void); + int __cdecl getche(void); + int __cdecl kbhit(void); + int __cdecl putch(int _Ch); + int __cdecl ungetch(int _Ch); + +#if (defined(_X86_) && !defined(__x86_64)) + int __cdecl inp(unsigned short); + unsigned short __cdecl inpw(unsigned short); + int __cdecl outp(unsigned short,int); + unsigned short __cdecl outpw(unsigned short,unsigned short); +#endif + /* I/O intrin functions. */ + __CRT_INLINE unsigned char __inbyte(unsigned short Port) + { + unsigned char value; + __asm__ __volatile__ ("inb %w1,%b0" + : "=a" (value) + : "Nd" (Port)); + return value; + } + __CRT_INLINE unsigned short __inword(unsigned short Port) + { + unsigned short value; + __asm__ __volatile__ ("inw %w1,%w0" + : "=a" (value) + : "Nd" (Port)); + return value; + } + __CRT_INLINE unsigned long __indword(unsigned short Port) + { + unsigned long value; + __asm__ __volatile__ ("inl %w1,%0" + : "=a" (value) + : "Nd" (Port)); + return value; + } + __CRT_INLINE void __outbyte(unsigned short Port,unsigned char Data) + { + __asm__ __volatile__ ("outb %b0,%w1" + : + : "a" (Data), "Nd" (Port)); + } + __CRT_INLINE void __outword(unsigned short Port,unsigned short Data) + { + __asm__ __volatile__ ("outw %w0,%w1" + : + : "a" (Data), "Nd" (Port)); + } + __CRT_INLINE void __outdword(unsigned short Port,unsigned long Data) + { + __asm__ __volatile__ ("outl %0,%w1" + : + : "a" (Data), "Nd" (Port)); + } + __CRT_INLINE void __inbytestring(unsigned short Port,unsigned char *Buffer,unsigned long Count) + { + __asm__ __volatile__ ( + "cld ; rep ; insb " + : "=D" (Buffer), "=c" (Count) + : "d"(Port), "0"(Buffer), "1" (Count) + ); + } + __CRT_INLINE void __inwordstring(unsigned short Port,unsigned short *Buffer,unsigned long Count) + { + __asm__ __volatile__ ( + "cld ; rep ; insw " + : "=D" (Buffer), "=c" (Count) + : "d"(Port), "0"(Buffer), "1" (Count) + ); + } + __CRT_INLINE void __indwordstring(unsigned short Port,unsigned long *Buffer,unsigned long Count) + { + __asm__ __volatile__ ( + "cld ; rep ; insl " + : "=D" (Buffer), "=c" (Count) + : "d"(Port), "0"(Buffer), "1" (Count) + ); + } + + __CRT_INLINE void __outbytestring(unsigned short Port,unsigned char *Buffer,unsigned long Count) + { + __asm__ __volatile__ ( + "cld ; rep ; outsb " + : "=S" (Buffer), "=c" (Count) + : "d"(Port), "0"(Buffer), "1" (Count) + ); + } + __CRT_INLINE void __outwordstring(unsigned short Port,unsigned short *Buffer,unsigned long Count) + { + __asm__ __volatile__ ( + "cld ; rep ; outsw " + : "=S" (Buffer), "=c" (Count) + : "d"(Port), "0"(Buffer), "1" (Count) + ); + } + __CRT_INLINE void __outdwordstring(unsigned short Port,unsigned long *Buffer,unsigned long Count) + { + __asm__ __volatile__ ( + "cld ; rep ; outsl " + : "=S" (Buffer), "=c" (Count) + : "d"(Port), "0"(Buffer), "1" (Count) + ); + } + + __CRT_INLINE unsigned __int64 __readcr0(void) + { + unsigned __int64 value; + __asm__ __volatile__ ( + "mov %%cr0, %[value]" + : [value] "=q" (value)); + return value; + } + + /* Register sizes are different between 32/64 bit mode. So we have to do this for _WIN64 and _WIN32 + separately. */ + +#ifdef _WIN64 + __CRT_INLINE void __writecr0(unsigned __int64 Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr0" + : + : [Data] "q" (Data) + : "memory"); + } + + __CRT_INLINE unsigned __int64 __readcr2(void) + { + unsigned __int64 value; + __asm__ __volatile__ ( + "mov %%cr2, %[value]" + : [value] "=q" (value)); + return value; + } + + __CRT_INLINE void __writecr2(unsigned __int64 Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr2" + : + : [Data] "q" (Data) + : "memory"); + } + + __CRT_INLINE unsigned __int64 __readcr3(void) + { + unsigned __int64 value; + __asm__ __volatile__ ( + "mov %%cr3, %[value]" + : [value] "=q" (value)); + return value; + } + + __CRT_INLINE void __writecr3(unsigned __int64 Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr3" + : + : [Data] "q" (Data) + : "memory"); + } + + __CRT_INLINE unsigned __int64 __readcr4(void) + { + unsigned __int64 value; + __asm__ __volatile__ ( + "mov %%cr4, %[value]" + : [value] "=q" (value)); + return value; + } + + __CRT_INLINE void __writecr4(unsigned __int64 Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr4" + : + : [Data] "q" (Data) + : "memory"); + } + + __CRT_INLINE unsigned __int64 __readcr8(void) + { + unsigned __int64 value; + __asm__ __volatile__ ( + "mov %%cr8, %[value]" + : [value] "=q" (value)); + return value; + } + + __CRT_INLINE void __writecr8(unsigned __int64 Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr8" + : + : [Data] "q" (Data) + : "memory"); + } + +#elif defined(_WIN32) + + __CRT_INLINE void __writecr0(unsigned Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr0" + : + : [Data] "q" (Data) + : "memory"); + } + + __CRT_INLINE unsigned long __readcr2(void) + { + unsigned long value; + __asm__ __volatile__ ( + "mov %%cr2, %[value]" + : [value] "=q" (value)); + return value; + } + + __CRT_INLINE void __writecr2(unsigned Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr2" + : + : [Data] "q" (Data) + : "memory"); + } + + __CRT_INLINE unsigned long __readcr3(void) + { + unsigned long value; + __asm__ __volatile__ ( + "mov %%cr3, %[value]" + : [value] "=q" (value)); + return value; + } + + __CRT_INLINE void __writecr3(unsigned Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr3" + : + : [Data] "q" (Data) + : "memory"); + } + + __CRT_INLINE unsigned long __readcr4(void) + { + unsigned long value; + __asm__ __volatile__ ( + "mov %%cr4, %[value]" + : [value] "=q" (value)); + return value; + } + + __CRT_INLINE void __writecr4(unsigned Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr4" + : + : [Data] "q" (Data) + : "memory"); + } + + __CRT_INLINE unsigned long __readcr8(void) + { + unsigned long value; __asm__ __volatile__ ( + "mov %%cr8, %[value]" + : [value] "=q" (value)); + return value; + } + + __CRT_INLINE void __writecr8(unsigned Data) + { + __asm__ __volatile__ ( + "mov %[Data], %%cr8" + : + : [Data] "q" (Data) + : "memory"); + } + +#endif -int getch (void); -int getche (void); -int kbhit (void); -int putch (int); -int ungetch (int); + __CRT_INLINE unsigned __int64 __readmsr(unsigned long msr) + { + unsigned __int64 val1, val2; + __asm__ __volatile__( + "rdmsr" + : "=a" (val1), "=d" (val2) + : "c" (msr)); + return val1 | (val2 << 32); + } + + __CRT_INLINE void __writemsr (unsigned long msr, unsigned __int64 Value) + { + unsigned long val1 = Value, val2 = Value >> 32; + __asm__ __volatile__ ( + "wrmsr" + : + : "c" (msr), "a" (val1), "d" (val2)); + } + + __CRT_INLINE unsigned __int64 __rdtsc(void) + { + unsigned __int64 val1, val2; + __asm__ __volatile__ ( + "rdtsc" + : "=a" (val1), "=d" (val2)); + return val1 | (val2 << 32); + } + + __CRT_INLINE void __cpuid(int CPUInfo[4], int InfoType) + { + __asm__ __volatile__ ( + "cpuid" + : "=a" (CPUInfo [0]), "=b" (CPUInfo [1]), "=c" (CPUInfo [2]), "=d" (CPUInfo [3]) + : "a" (InfoType)); + } +#endif #ifdef __cplusplus } #endif -#endif /* _CONIO_H_ */ +#include <sec_api/conio_s.h> + +#endif diff --git a/tinyc/win32/include/ctype.h b/tinyc/win32/include/ctype.h index 0c416a6e1..7e9010026 100644 --- a/tinyc/win32/include/ctype.h +++ b/tinyc/win32/include/ctype.h @@ -1,232 +1,281 @@ -/* - * ctype.h - * - * Functions for testing character types and converting characters. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_CTYPE +#define _INC_CTYPE -#ifndef _CTYPE_H_ -#define _CTYPE_H_ - -/* All the headers include this file. */ #include <_mingw.h> -#define __need_wchar_t -#define __need_wint_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ - - -/* - * The following flags are used to tell iswctype and _isctype what character - * types you are looking for. - */ -#define _UPPER 0x0001 -#define _LOWER 0x0002 -#define _DIGIT 0x0004 -#define _SPACE 0x0008 /* HT LF VT FF CR SP */ -#define _PUNCT 0x0010 -#define _CONTROL 0x0020 -#define _BLANK 0x0040 /* this is SP only, not SP and HT as in C99 */ -#define _HEX 0x0080 -#define _LEADBYTE 0x8000 - -#define _ALPHA 0x0103 - -#ifndef RC_INVOKED - #ifdef __cplusplus extern "C" { #endif -int isalnum(int); -int isalpha(int); -int iscntrl(int); -int isdigit(int); -int isgraph(int); -int islower(int); -int isprint(int); -int ispunct(int); -int isspace(int); -int isupper(int); -int isxdigit(int); - -#ifndef __STRICT_ANSI__ -int _isctype (int, int); +#ifndef WEOF +#define WEOF (wint_t)(0xFFFF) #endif -/* These are the ANSI versions, with correct checking of argument */ -int tolower(int); -int toupper(int); +#ifndef _CRT_CTYPEDATA_DEFINED +#define _CRT_CTYPEDATA_DEFINED +#ifndef _CTYPE_DISABLE_MACROS -/* - * NOTE: The above are not old name type wrappers, but functions exported - * explicitly by MSVCRT/CRTDLL. However, underscored versions are also - * exported. - */ -#ifndef __STRICT_ANSI__ -/* - * These are the cheap non-std versions: The return values are undefined - * if the argument is not ASCII char or is not of appropriate case - */ -int _tolower(int); -int _toupper(int); +#ifndef __PCTYPE_FUNC +#define __PCTYPE_FUNC __pctype_func() +#ifdef _MSVCRT_ +#define __pctype_func() (_pctype) +#else +#define __pctype_func() (*_imp___pctype) +#endif #endif -/* Also defined in stdlib.h */ -#ifndef MB_CUR_MAX -# ifdef __MSVCRT__ -# define MB_CUR_MAX __mb_cur_max - __MINGW_IMPORT int __mb_cur_max; -# else /* not __MSVCRT */ -# define MB_CUR_MAX __mb_cur_max_dll - __MINGW_IMPORT int __mb_cur_max_dll; -# endif /* not __MSVCRT */ -#endif /* MB_CUR_MAX */ - -__MINGW_IMPORT unsigned short _ctype[]; -#ifdef __MSVCRT__ -__MINGW_IMPORT unsigned short* _pctype; -#else /* CRTDLL */ -__MINGW_IMPORT unsigned short* _pctype_dll; -#define _pctype _pctype_dll -#endif - -/* - * Use inlines here rather than macros, because macros will upset - * C++ usage (eg, ::isalnum), and so usually get undefined - * - * According to standard for SB chars, these function are defined only - * for input values representable by unsigned char or EOF. - * Thus, there is no range test. - * This reproduces behaviour of MSVCRT.dll lib implemention for SB chars. - * - * If no MB char support is needed, these can be simplified even - * more by command line define -DMB_CUR_MAX=1. The compiler will then - * optimise away the constant condition. - */ +#ifndef _pctype +#ifdef _MSVCRT_ + extern unsigned short *_pctype; +#else + extern unsigned short **_imp___pctype; +#define _pctype (*_imp___pctype) +#endif +#endif +#endif +#endif -#if ! (defined (__NO_CTYPE_INLINES) || defined (__STRICT_ANSI__ )) -/* use simple lookup if SB locale, else _isctype() */ -#define __ISCTYPE(c, mask) (MB_CUR_MAX == 1 ? (_pctype[c] & mask) : _isctype(c, mask)) -extern __inline__ int isalnum(int c) {return __ISCTYPE(c, (_ALPHA|_DIGIT));} -extern __inline__ int isalpha(int c) {return __ISCTYPE(c, _ALPHA);} -extern __inline__ int iscntrl(int c) {return __ISCTYPE(c, _CONTROL);} -extern __inline__ int isdigit(int c) {return __ISCTYPE(c, _DIGIT);} -extern __inline__ int isgraph(int c) {return __ISCTYPE(c, (_PUNCT|_ALPHA|_DIGIT));} -extern __inline__ int islower(int c) {return __ISCTYPE(c, _LOWER);} -extern __inline__ int isprint(int c) {return __ISCTYPE(c, (_BLANK|_PUNCT|_ALPHA|_DIGIT));} -extern __inline__ int ispunct(int c) {return __ISCTYPE(c, _PUNCT);} -extern __inline__ int isspace(int c) {return __ISCTYPE(c, _SPACE);} -extern __inline__ int isupper(int c) {return __ISCTYPE(c, _UPPER);} -extern __inline__ int isxdigit(int c) {return __ISCTYPE(c, _HEX);} +#ifndef _CRT_WCTYPEDATA_DEFINED +#define _CRT_WCTYPEDATA_DEFINED +#ifndef _CTYPE_DISABLE_MACROS +#ifndef _wctype +#ifdef _MSVCRT_ + extern unsigned short *_wctype; +#else + extern unsigned short **_imp___wctype; +#define _wctype (*_imp___wctype) +#endif +#endif +#ifdef _MSVCRT_ +#define __pwctype_func() (_pwctype) +#ifndef _pwctype + extern unsigned short *_pwctype; +#endif +#else +#define __pwctype_func() (*_imp___pwctype) +#ifndef _pwctype + extern unsigned short **_imp___pwctype; +#define _pwctype (*_imp___pwctype) +#endif +#endif +#endif +#endif -/* these reproduce behaviour of lib underscored versions */ -extern __inline__ int _tolower(int c) {return ( c -'A'+'a');} -extern __inline__ int _toupper(int c) {return ( c -'a'+'A');} + /* CRT stuff */ +#if 1 + extern const unsigned char __newclmap[]; + extern const unsigned char __newcumap[]; + extern pthreadlocinfo __ptlocinfo; + extern pthreadmbcinfo __ptmbcinfo; + extern int __globallocalestatus; + extern int __locale_changed; + extern struct threadlocaleinfostruct __initiallocinfo; + extern _locale_tstruct __initiallocalestructinfo; + pthreadlocinfo __cdecl __updatetlocinfo(void); + pthreadmbcinfo __cdecl __updatetmbcinfo(void); +#endif -/* TODO? Is it worth inlining ANSI tolower, toupper? Probably only - if we only want C-locale. */ +#define _UPPER 0x1 +#define _LOWER 0x2 +#define _DIGIT 0x4 +#define _SPACE 0x8 + +#define _PUNCT 0x10 +#define _CONTROL 0x20 +#define _BLANK 0x40 +#define _HEX 0x80 + +#define _LEADBYTE 0x8000 +#define _ALPHA (0x0100|_UPPER|_LOWER) + +#ifndef _CTYPE_DEFINED +#define _CTYPE_DEFINED + + _CRTIMP int __cdecl _isctype(int _C,int _Type); + _CRTIMP int __cdecl _isctype_l(int _C,int _Type,_locale_t _Locale); + _CRTIMP int __cdecl isalpha(int _C); + _CRTIMP int __cdecl _isalpha_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl isupper(int _C); + _CRTIMP int __cdecl _isupper_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl islower(int _C); + _CRTIMP int __cdecl _islower_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl isdigit(int _C); + _CRTIMP int __cdecl _isdigit_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl isxdigit(int _C); + _CRTIMP int __cdecl _isxdigit_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl isspace(int _C); + _CRTIMP int __cdecl _isspace_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl ispunct(int _C); + _CRTIMP int __cdecl _ispunct_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl isalnum(int _C); + _CRTIMP int __cdecl _isalnum_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl isprint(int _C); + _CRTIMP int __cdecl _isprint_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl isgraph(int _C); + _CRTIMP int __cdecl _isgraph_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl iscntrl(int _C); + _CRTIMP int __cdecl _iscntrl_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl toupper(int _C); + _CRTIMP int __cdecl tolower(int _C); + _CRTIMP int __cdecl _tolower(int _C); + _CRTIMP int __cdecl _tolower_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl _toupper(int _C); + _CRTIMP int __cdecl _toupper_l(int _C,_locale_t _Locale); + _CRTIMP int __cdecl __isascii(int _C); + _CRTIMP int __cdecl __toascii(int _C); + _CRTIMP int __cdecl __iscsymf(int _C); + _CRTIMP int __cdecl __iscsym(int _C); + +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES) +int __cdecl isblank(int _C); +#endif +#endif -#endif /* _NO_CTYPE_INLINES */ +#ifndef _WCTYPE_DEFINED +#define _WCTYPE_DEFINED + + int __cdecl iswalpha(wint_t _C); + _CRTIMP int __cdecl _iswalpha_l(wint_t _C,_locale_t _Locale); + int __cdecl iswupper(wint_t _C); + _CRTIMP int __cdecl _iswupper_l(wint_t _C,_locale_t _Locale); + int __cdecl iswlower(wint_t _C); + _CRTIMP int __cdecl _iswlower_l(wint_t _C,_locale_t _Locale); + int __cdecl iswdigit(wint_t _C); + _CRTIMP int __cdecl _iswdigit_l(wint_t _C,_locale_t _Locale); + int __cdecl iswxdigit(wint_t _C); + _CRTIMP int __cdecl _iswxdigit_l(wint_t _C,_locale_t _Locale); + int __cdecl iswspace(wint_t _C); + _CRTIMP int __cdecl _iswspace_l(wint_t _C,_locale_t _Locale); + int __cdecl iswpunct(wint_t _C); + _CRTIMP int __cdecl _iswpunct_l(wint_t _C,_locale_t _Locale); + int __cdecl iswalnum(wint_t _C); + _CRTIMP int __cdecl _iswalnum_l(wint_t _C,_locale_t _Locale); + int __cdecl iswprint(wint_t _C); + _CRTIMP int __cdecl _iswprint_l(wint_t _C,_locale_t _Locale); + int __cdecl iswgraph(wint_t _C); + _CRTIMP int __cdecl _iswgraph_l(wint_t _C,_locale_t _Locale); + int __cdecl iswcntrl(wint_t _C); + _CRTIMP int __cdecl _iswcntrl_l(wint_t _C,_locale_t _Locale); + int __cdecl iswascii(wint_t _C); + int __cdecl isleadbyte(int _C); + _CRTIMP int __cdecl _isleadbyte_l(int _C,_locale_t _Locale); + wint_t __cdecl towupper(wint_t _C); + _CRTIMP wint_t __cdecl _towupper_l(wint_t _C,_locale_t _Locale); + wint_t __cdecl towlower(wint_t _C); + _CRTIMP wint_t __cdecl _towlower_l(wint_t _C,_locale_t _Locale); + int __cdecl iswctype(wint_t _C,wctype_t _Type); + _CRTIMP int __cdecl _iswctype_l(wint_t _C,wctype_t _Type,_locale_t _Locale); + _CRTIMP int __cdecl __iswcsymf(wint_t _C); + _CRTIMP int __cdecl _iswcsymf_l(wint_t _C,_locale_t _Locale); + _CRTIMP int __cdecl __iswcsym(wint_t _C); + _CRTIMP int __cdecl _iswcsym_l(wint_t _C,_locale_t _Locale); + int __cdecl is_wctype(wint_t _C,wctype_t _Type); + +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES) +int __cdecl iswblank(wint_t _C); +#endif +#endif -/* Wide character equivalents */ +#ifndef _CTYPE_DISABLE_MACROS -#ifndef WEOF -#define WEOF (wchar_t)(0xFFFF) -#endif - -#ifndef _WCTYPE_T_DEFINED -typedef wchar_t wctype_t; -#define _WCTYPE_T_DEFINED -#endif - -int iswalnum(wint_t); -int iswalpha(wint_t); -int iswascii(wint_t); -int iswcntrl(wint_t); -int iswctype(wint_t, wctype_t); -int is_wctype(wint_t, wctype_t); /* Obsolete! */ -int iswdigit(wint_t); -int iswgraph(wint_t); -int iswlower(wint_t); -int iswprint(wint_t); -int iswpunct(wint_t); -int iswspace(wint_t); -int iswupper(wint_t); -int iswxdigit(wint_t); - -wchar_t towlower(wchar_t); -wchar_t towupper(wchar_t); - -int isleadbyte (int); - -/* Also in wctype.h */ -#if ! (defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED)) -#define __WCTYPE_INLINES_DEFINED -extern __inline__ int iswalnum(wint_t wc) {return (iswctype(wc,_ALPHA|_DIGIT));} -extern __inline__ int iswalpha(wint_t wc) {return (iswctype(wc,_ALPHA));} -extern __inline__ int iswascii(wint_t wc) {return (((unsigned)wc & 0x7F) ==0);} -extern __inline__ int iswcntrl(wint_t wc) {return (iswctype(wc,_CONTROL));} -extern __inline__ int iswdigit(wint_t wc) {return (iswctype(wc,_DIGIT));} -extern __inline__ int iswgraph(wint_t wc) {return (iswctype(wc,_PUNCT|_ALPHA|_DIGIT));} -extern __inline__ int iswlower(wint_t wc) {return (iswctype(wc,_LOWER));} -extern __inline__ int iswprint(wint_t wc) {return (iswctype(wc,_BLANK|_PUNCT|_ALPHA|_DIGIT));} -extern __inline__ int iswpunct(wint_t wc) {return (iswctype(wc,_PUNCT));} -extern __inline__ int iswspace(wint_t wc) {return (iswctype(wc,_SPACE));} -extern __inline__ int iswupper(wint_t wc) {return (iswctype(wc,_UPPER));} -extern __inline__ int iswxdigit(wint_t wc) {return (iswctype(wc,_HEX));} -extern __inline__ int isleadbyte(int c) {return (_pctype[(unsigned char)(c)] & _LEADBYTE);} -#endif /* !(defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED)) */ - -#ifndef __STRICT_ANSI__ -int __isascii (int); -int __toascii (int); -int __iscsymf (int); /* Valid first character in C symbol */ -int __iscsym (int); /* Valid character in C symbol (after first) */ - -#ifndef __NO_CTYPE_INLINES -extern __inline__ int __isascii(int c) {return (((unsigned)c & ~0x7F) == 0);} -extern __inline__ int __toascii(int c) {return (c & 0x7F);} -extern __inline__ int __iscsymf(int c) {return (isalpha(c) || (c == '_'));} -extern __inline__ int __iscsym(int c) {return (isalnum(c) || (c == '_'));} -#endif /* __NO_CTYPE_INLINES */ - -#ifndef _NO_OLDNAMES -int isascii (int); -int toascii (int); -int iscsymf (int); -int iscsym (int); -#endif /* Not _NO_OLDNAMES */ - -#endif /* Not __STRICT_ANSI__ */ +#ifndef MB_CUR_MAX +#define MB_CUR_MAX ___mb_cur_max_func() +#ifndef __mb_cur_max +#ifdef _MSVCRT_ + extern int __mb_cur_max; +#else +#define __mb_cur_max (*_imp____mb_cur_max) + extern int *_imp____mb_cur_max; +#endif +#endif +#ifdef _MSVCRT_ +#define ___mb_cur_max_func() (__mb_cur_max) +#else +#define ___mb_cur_max_func() (*_imp____mb_cur_max) +#endif +#endif -#ifdef __cplusplus -} +#define __chvalidchk(a,b) (__PCTYPE_FUNC[(a)] & (b)) +#define _chvalidchk_l(_Char,_Flag,_Locale) (!_Locale ? __chvalidchk(_Char,_Flag) : ((_locale_t)_Locale)->locinfo->pctype[_Char] & (_Flag)) +#define _ischartype_l(_Char,_Flag,_Locale) (((_Locale)!=NULL && (((_locale_t)(_Locale))->locinfo->mb_cur_max) > 1) ? _isctype_l(_Char,(_Flag),_Locale) : _chvalidchk_l(_Char,_Flag,_Locale)) +#define _isalpha_l(_Char,_Locale) _ischartype_l(_Char,_ALPHA,_Locale) +#define _isupper_l(_Char,_Locale) _ischartype_l(_Char,_UPPER,_Locale) +#define _islower_l(_Char,_Locale) _ischartype_l(_Char,_LOWER,_Locale) +#define _isdigit_l(_Char,_Locale) _ischartype_l(_Char,_DIGIT,_Locale) +#define _isxdigit_l(_Char,_Locale) _ischartype_l(_Char,_HEX,_Locale) +#define _isspace_l(_Char,_Locale) _ischartype_l(_Char,_SPACE,_Locale) +#define _ispunct_l(_Char,_Locale) _ischartype_l(_Char,_PUNCT,_Locale) +#define _isalnum_l(_Char,_Locale) _ischartype_l(_Char,_ALPHA|_DIGIT,_Locale) +#define _isprint_l(_Char,_Locale) _ischartype_l(_Char,_BLANK|_PUNCT|_ALPHA|_DIGIT,_Locale) +#define _isgraph_l(_Char,_Locale) _ischartype_l(_Char,_PUNCT|_ALPHA|_DIGIT,_Locale) +#define _iscntrl_l(_Char,_Locale) _ischartype_l(_Char,_CONTROL,_Locale) +#define _tolower(_Char) ((_Char)-'A'+'a') +#define _toupper(_Char) ((_Char)-'a'+'A') +#define __isascii(_Char) ((unsigned)(_Char) < 0x80) +#define __toascii(_Char) ((_Char) & 0x7f) + +#ifndef _WCTYPE_INLINE_DEFINED +#define _WCTYPE_INLINE_DEFINED + +#undef _CRT_WCTYPE_NOINLINE +#ifndef __cplusplus +#define iswalpha(_c) (iswctype(_c,_ALPHA)) +#define iswupper(_c) (iswctype(_c,_UPPER)) +#define iswlower(_c) (iswctype(_c,_LOWER)) +#define iswdigit(_c) (iswctype(_c,_DIGIT)) +#define iswxdigit(_c) (iswctype(_c,_HEX)) +#define iswspace(_c) (iswctype(_c,_SPACE)) +#define iswpunct(_c) (iswctype(_c,_PUNCT)) +#define iswalnum(_c) (iswctype(_c,_ALPHA|_DIGIT)) +#define iswprint(_c) (iswctype(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT)) +#define iswgraph(_c) (iswctype(_c,_PUNCT|_ALPHA|_DIGIT)) +#define iswcntrl(_c) (iswctype(_c,_CONTROL)) +#define iswascii(_c) ((unsigned)(_c) < 0x80) +#define _iswalpha_l(_c,_p) (_iswctype_l(_c,_ALPHA,_p)) +#define _iswupper_l(_c,_p) (_iswctype_l(_c,_UPPER,_p)) +#define _iswlower_l(_c,_p) (_iswctype_l(_c,_LOWER,_p)) +#define _iswdigit_l(_c,_p) (_iswctype_l(_c,_DIGIT,_p)) +#define _iswxdigit_l(_c,_p) (_iswctype_l(_c,_HEX,_p)) +#define _iswspace_l(_c,_p) (_iswctype_l(_c,_SPACE,_p)) +#define _iswpunct_l(_c,_p) (_iswctype_l(_c,_PUNCT,_p)) +#define _iswalnum_l(_c,_p) (_iswctype_l(_c,_ALPHA|_DIGIT,_p)) +#define _iswprint_l(_c,_p) (_iswctype_l(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT,_p)) +#define _iswgraph_l(_c,_p) (_iswctype_l(_c,_PUNCT|_ALPHA|_DIGIT,_p)) +#define _iswcntrl_l(_c,_p) (_iswctype_l(_c,_CONTROL,_p)) +#endif #endif -#endif /* Not RC_INVOKED */ +#define __iscsymf(_c) (isalpha(_c) || ((_c)=='_')) +#define __iscsym(_c) (isalnum(_c) || ((_c)=='_')) +#define __iswcsymf(_c) (iswalpha(_c) || ((_c)=='_')) +#define __iswcsym(_c) (iswalnum(_c) || ((_c)=='_')) +#define _iscsymf_l(_c,_p) (_isalpha_l(_c,_p) || ((_c)=='_')) +#define _iscsym_l(_c,_p) (_isalnum_l(_c,_p) || ((_c)=='_')) +#define _iswcsymf_l(_c,_p) (_iswalpha_l(_c,_p) || ((_c)=='_')) +#define _iswcsym_l(_c,_p) (_iswalnum_l(_c,_p) || ((_c)=='_')) +#endif -#endif /* Not _CTYPE_H_ */ +#ifndef NO_OLDNAMES +#ifndef _CTYPE_DEFINED + int __cdecl isascii(int _C); + int __cdecl toascii(int _C); + int __cdecl iscsymf(int _C); + int __cdecl iscsym(int _C); +#else +#define isascii __isascii +#define toascii __toascii +#define iscsymf __iscsymf +#define iscsym __iscsym +#endif +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/tinyc/win32/include/dir.h b/tinyc/win32/include/dir.h index d759a0a61..f38f750d2 100644 --- a/tinyc/win32/include/dir.h +++ b/tinyc/win32/include/dir.h @@ -1,3 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ /* * dir.h * diff --git a/tinyc/win32/include/direct.h b/tinyc/win32/include/direct.h index 925f4c54c..99ce69db7 100644 --- a/tinyc/win32/include/direct.h +++ b/tinyc/win32/include/direct.h @@ -1,95 +1,68 @@ -/* - * direct.h - * - * Functions for manipulating paths and directories (included from io.h) - * plus functions for setting the current drive. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_DIRECT +#define _INC_DIRECT -#ifndef __STRICT_ANSI__ - -#ifndef _DIRECT_H_ -#define _DIRECT_H_ - -/* All the headers include this file. */ #include <_mingw.h> - -#define __need_wchar_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ - #include <io.h> -#ifndef RC_INVOKED +#pragma pack(push,_CRT_PACKING) -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif #ifndef _DISKFREE_T_DEFINED -/* needed by _getdiskfree (also in dos.h) */ -struct _diskfree_t { - unsigned total_clusters; - unsigned avail_clusters; - unsigned sectors_per_cluster; - unsigned bytes_per_sector; -}; #define _DISKFREE_T_DEFINED -#endif - -/* - * You really shouldn't be using these. Use the Win32 API functions instead. - * However, it does make it easier to port older code. - */ -int _getdrive (void); -unsigned long _getdrives(void); -int _chdrive (int); -char* _getdcwd (int, char*, int); -unsigned _getdiskfree (unsigned, struct _diskfree_t *); + struct _diskfree_t { + unsigned total_clusters; + unsigned avail_clusters; + unsigned sectors_per_cluster; + unsigned bytes_per_sector; + }; +#endif -#ifndef _NO_OLDNAMES -# define diskfree_t _diskfree_t + _CRTIMP char *__cdecl _getcwd(char *_DstBuf,int _SizeInBytes); + _CRTIMP char *__cdecl _getdcwd(int _Drive,char *_DstBuf,int _SizeInBytes); + char *__cdecl _getdcwd_nolock(int _Drive,char *_DstBuf,int _SizeInBytes); + _CRTIMP int __cdecl _chdir(const char *_Path); + _CRTIMP int __cdecl _mkdir(const char *_Path); + _CRTIMP int __cdecl _rmdir(const char *_Path); + _CRTIMP int __cdecl _chdrive(int _Drive); + _CRTIMP int __cdecl _getdrive(void); + _CRTIMP unsigned long __cdecl _getdrives(void); + +#ifndef _GETDISKFREE_DEFINED +#define _GETDISKFREE_DEFINED + _CRTIMP unsigned __cdecl _getdiskfree(unsigned _Drive,struct _diskfree_t *_DiskFree); #endif #ifndef _WDIRECT_DEFINED -/* wide character versions. Also in wchar.h */ -#ifdef __MSVCRT__ -int _wchdir(const wchar_t*); -wchar_t* _wgetcwd(wchar_t*, int); -wchar_t* _wgetdcwd(int, wchar_t*, int); -int _wmkdir(const wchar_t*); -int _wrmdir(const wchar_t*); -#endif /* __MSVCRT__ */ #define _WDIRECT_DEFINED + _CRTIMP wchar_t *__cdecl _wgetcwd(wchar_t *_DstBuf,int _SizeInWords); + _CRTIMP wchar_t *__cdecl _wgetdcwd(int _Drive,wchar_t *_DstBuf,int _SizeInWords); + wchar_t *__cdecl _wgetdcwd_nolock(int _Drive,wchar_t *_DstBuf,int _SizeInWords); + _CRTIMP int __cdecl _wchdir(const wchar_t *_Path); + _CRTIMP int __cdecl _wmkdir(const wchar_t *_Path); + _CRTIMP int __cdecl _wrmdir(const wchar_t *_Path); #endif -#ifdef __cplusplus -} -#endif +#ifndef NO_OLDNAMES -#endif /* Not RC_INVOKED */ +#define diskfree_t _diskfree_t -#endif /* Not _DIRECT_H_ */ + char *__cdecl getcwd(char *_DstBuf,int _SizeInBytes); + int __cdecl chdir(const char *_Path); + int __cdecl mkdir(const char *_Path); + int __cdecl rmdir(const char *_Path); +#endif -#endif /* Not __STRICT_ANSI__ */ +#ifdef __cplusplus +} +#endif +#pragma pack(pop) +#endif diff --git a/tinyc/win32/include/dirent.h b/tinyc/win32/include/dirent.h index 41c3dd715..cd31f59e0 100644 --- a/tinyc/win32/include/dirent.h +++ b/tinyc/win32/include/dirent.h @@ -1,33 +1,18 @@ -/* - * DIRENT.H (formerly DIRLIB.H) - * - * by M. J. Weinstein Released to public domain 1-Jan-89 - * - * Because I have heard that this feature (opendir, readdir, closedir) - * it so useful for programmers coming from UNIX or attempting to port - * UNIX code, and because it is reasonably light weight, I have included - * it in the Mingw32 package. I have also added an implementation of - * rewinddir, seekdir and telldir. - * - Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * This code is distributed in the hope that is will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includeds but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +/* All the headers include this file. */ +#include <_mingw.h> #ifndef __STRICT_ANSI__ #ifndef _DIRENT_H_ #define _DIRENT_H_ -/* All the headers include this file. */ -#include <_mingw.h> + +#pragma pack(push,_CRT_PACKING) #include <io.h> @@ -37,52 +22,103 @@ extern "C" { #endif -struct dirent -{ - long d_ino; /* Always zero. */ - unsigned short d_reclen; /* Always zero. */ - unsigned short d_namlen; /* Length of name in d_name. */ - char* d_name; /* File name. */ - /* NOTE: The name in the dirent structure points to the name in the - * finddata_t structure in the DIR. */ -}; - -/* - * This is an internal data structure. Good programmers will not use it - * except as an argument to one of the functions below. - */ -typedef struct -{ - /* disk transfer area for this dir */ - struct _finddata_t dd_dta; - - /* dirent struct to return from dir (NOTE: this makes this thread - * safe as long as only one thread uses a particular DIR struct at - * a time) */ - struct dirent dd_dir; - - /* _findnext handle */ - long dd_handle; - - /* - * Status of search: - * 0 = not started yet (next entry to read is first entry) - * -1 = off the end - * positive = 0 based index of next entry - */ - short dd_stat; - - /* given path for dir with search pattern (struct is extended) */ - char dd_name[1]; -} DIR; - - -DIR* opendir (const char*); -struct dirent* readdir (DIR*); -int closedir (DIR*); -void rewinddir (DIR*); -long telldir (DIR*); -void seekdir (DIR*, long); + struct dirent + { + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + char* d_name; /* File name. */ + /* NOTE: The name in the dirent structure points to the name in the + * finddata_t structure in the DIR. */ + }; + + /* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + * dd_stat field is now int (was short in older versions). + */ + typedef struct + { + /* disk transfer area for this dir */ + struct _finddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct dirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + char dd_name[1]; + } DIR; + + DIR* __cdecl opendir (const char*); + struct dirent* __cdecl readdir (DIR*); + int __cdecl closedir (DIR*); + void __cdecl rewinddir (DIR*); + long __cdecl telldir (DIR*); + void __cdecl seekdir (DIR*, long); + + + /* wide char versions */ + + struct _wdirent + { + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + wchar_t* d_name; /* File name. */ + /* NOTE: The name in the dirent structure points to the name in the * wfinddata_t structure in the _WDIR. */ + }; + + /* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + */ + typedef struct + { + /* disk transfer area for this dir */ + struct _wfinddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct _wdirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + wchar_t dd_name[1]; + } _WDIR; + + + + _WDIR* __cdecl _wopendir (const wchar_t*); + struct _wdirent* __cdecl _wreaddir (_WDIR*); + int __cdecl _wclosedir (_WDIR*); + void __cdecl _wrewinddir (_WDIR*); + long __cdecl _wtelldir (_WDIR*); + void __cdecl _wseekdir (_WDIR*, long); + #ifdef __cplusplus } @@ -90,7 +126,10 @@ void seekdir (DIR*, long); #endif /* Not RC_INVOKED */ +#pragma pack(pop) + #endif /* Not _DIRENT_H_ */ + #endif /* Not __STRICT_ANSI__ */ diff --git a/tinyc/win32/include/dos.h b/tinyc/win32/include/dos.h index 2cb380fba..294e8fe1b 100644 --- a/tinyc/win32/include/dos.h +++ b/tinyc/win32/include/dos.h @@ -1,110 +1,55 @@ -/* - * dos.h - * - * DOS-specific functions and structures. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by J.J. van der Heijden <J.J.vanderHeijden@student.utwente.nl> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_DOS +#define _INC_DOS -#ifndef __STRICT_ANSI__ - -#ifndef _DOS_H_ -#define _DOS_H_ - -/* All the headers include this file. */ #include <_mingw.h> - -#define __need_wchar_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ - -/* For DOS file attributes */ #include <io.h> -#ifndef RC_INVOKED +#pragma pack(push,_CRT_PACKING) #ifdef __cplusplus extern "C" { #endif -#ifndef __MSVCRT__ /* these are in CRTDLL, but not MSVCRT */ -#ifndef __DECLSPEC_SUPPORTED -extern unsigned int *__imp__basemajor_dll; -extern unsigned int *__imp__baseminor_dll; -extern unsigned int *__imp__baseversion_dll; -extern unsigned int *__imp__osmajor_dll; -extern unsigned int *__imp__osminor_dll; -extern unsigned int *__imp__osmode_dll; - -#define _basemajor (*__imp__basemajor_dll) -#define _baseminor (*__imp__baseminor_dll) -#define _baseversion (*__imp__baseversion_dll) -#define _osmajor (*__imp__osmajor_dll) -#define _osminor (*__imp__osminor_dll) -#define _osmode (*__imp__osmode_dll) - -#else /* __DECLSPEC_SUPPORTED */ - -__MINGW_IMPORT unsigned int _basemajor_dll; -__MINGW_IMPORT unsigned int _baseminor_dll; -__MINGW_IMPORT unsigned int _baseversion_dll; -__MINGW_IMPORT unsigned int _osmajor_dll; -__MINGW_IMPORT unsigned int _osminor_dll; -__MINGW_IMPORT unsigned int _osmode_dll; +#ifndef _DISKFREE_T_DEFINED +#define _DISKFREE_T_DEFINED -#define _basemajor _basemajor_dll -#define _baseminor _baseminor_dll -#define _baseversion _baseversion_dll -#define _osmajor _osmajor_dll -#define _osminor _osminor_dll -#define _osmode _osmode_dll + struct _diskfree_t { + unsigned total_clusters; + unsigned avail_clusters; + unsigned sectors_per_cluster; + unsigned bytes_per_sector; + }; +#endif -#endif /* __DECLSPEC_SUPPORTED */ -#endif /* ! __MSVCRT__ */ +#define _A_NORMAL 0x00 +#define _A_RDONLY 0x01 +#define _A_HIDDEN 0x02 +#define _A_SYSTEM 0x04 +#define _A_SUBDIR 0x10 +#define _A_ARCH 0x20 -#ifndef _DISKFREE_T_DEFINED -/* needed by _getdiskfree (also in direct.h) */ -struct _diskfree_t { - unsigned total_clusters; - unsigned avail_clusters; - unsigned sectors_per_cluster; - unsigned bytes_per_sector; -}; -#define _DISKFREE_T_DEFINED -#endif +#ifndef _GETDISKFREE_DEFINED +#define _GETDISKFREE_DEFINED + _CRTIMP unsigned __cdecl _getdiskfree(unsigned _Drive,struct _diskfree_t *_DiskFree); +#endif -unsigned _getdiskfree (unsigned, struct _diskfree_t *); +#if (defined(_X86_) && !defined(__x86_64)) + void __cdecl _disable(void); + void __cdecl _enable(void); +#endif -#ifndef _NO_OLDNAMES -# define diskfree_t _diskfree_t +#ifndef NO_OLDNAMES +#define diskfree_t _diskfree_t #endif #ifdef __cplusplus } #endif -#endif /* Not RC_INVOKED */ - -#endif /* Not _DOS_H_ */ - -#endif /* Not __STRICT_ANSI__ */ - +#pragma pack(pop) +#endif diff --git a/tinyc/win32/include/errno.h b/tinyc/win32/include/errno.h index b41a70e01..c2df01581 100644 --- a/tinyc/win32/include/errno.h +++ b/tinyc/win32/include/errno.h @@ -1,117 +1,75 @@ -/* - * errno.h - * - * Error numbers and access to error reporting. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_ERRNO +#define _INC_ERRNO -#ifndef _ERRNO_H_ -#define _ERRNO_H_ - -/* All the headers include this file. */ #include <_mingw.h> -/* - * Error numbers. - * TODO: Can't be sure of some of these assignments, I guessed from the - * names given by strerror and the defines in the Cygnus errno.h. A lot - * of the names from the Cygnus errno.h are not represented, and a few - * of the descriptions returned by strerror do not obviously match - * their error naming. - */ -#define EPERM 1 /* Operation not permitted */ -#define ENOFILE 2 /* No such file or directory */ -#define ENOENT 2 -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted function call */ -#define EIO 5 /* Input/output error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file descriptor */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Resource temporarily unavailable */ -#define ENOMEM 12 /* Not enough space */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -/* 15 - Unknown Error */ -#define EBUSY 16 /* strerror reports "Resource device" */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Improper link (cross-device link?) */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* Too many open files in system */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Inappropriate I/O control operation */ -/* 26 - Unknown Error */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Invalid seek (seek on a pipe?) */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Domain error (math functions) */ -#define ERANGE 34 /* Result too large (possibly too small) */ -/* 35 - Unknown Error */ -#define EDEADLOCK 36 /* Resource deadlock avoided (non-Cyg) */ -#define EDEADLK 36 -/* 37 - Unknown Error */ -#define ENAMETOOLONG 38 /* Filename too long (91 in Cyg?) */ -#define ENOLCK 39 /* No locks available (46 in Cyg?) */ -#define ENOSYS 40 /* Function not implemented (88 in Cyg?) */ -#define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */ -#define EILSEQ 42 /* Illegal byte sequence */ - -/* - * NOTE: ENAMETOOLONG and ENOTEMPTY conflict with definitions in the - * sockets.h header provided with windows32api-0.1.2. - * You should go and put an #if 0 ... #endif around the whole block - * of errors (look at the comment above them). - */ - -#ifndef RC_INVOKED - -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif -/* - * Definitions of errno. For _doserrno, sys_nerr and * sys_errlist, see - * stdlib.h. - */ -#ifdef _UWIN -#undef errno -extern int errno; -#else -int* _errno(void); -#define errno (*_errno()) +#ifndef _CRT_ERRNO_DEFINED +#define _CRT_ERRNO_DEFINED + _CRTIMP extern int *__cdecl _errno(void); +#define errno (*_errno()) + + errno_t __cdecl _set_errno(int _Value); + errno_t __cdecl _get_errno(int *_Value); #endif -#ifdef __cplusplus -} +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define EDEADLK 36 +#define ENAMETOOLONG 38 +#define ENOLCK 39 +#define ENOSYS 40 +#define ENOTEMPTY 41 + +#ifndef RC_INVOKED +#if !defined(_SECURECRT_ERRCODE_VALUES_DEFINED) +#define _SECURECRT_ERRCODE_VALUES_DEFINED +#define EINVAL 22 +#define ERANGE 34 +#define EILSEQ 42 +#define STRUNCATE 80 +#endif #endif -#endif /* Not RC_INVOKED */ +#define EDEADLOCK EDEADLK -#endif /* Not _ERRNO_H_ */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/tinyc/win32/include/excpt.h b/tinyc/win32/include/excpt.h index 774612458..26cc9437c 100644 --- a/tinyc/win32/include/excpt.h +++ b/tinyc/win32/include/excpt.h @@ -1,20 +1,123 @@ -#ifndef _EXCPT_H -#define _EXCPT_H -#if __GNUC__ >=3 -#pragma GCC system_header +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_EXCPT +#define _INC_EXCPT + +#include <_mingw.h> + +#pragma pack(push,_CRT_PACKING) + +#ifdef __cplusplus +extern "C" { +#endif + + struct _EXCEPTION_POINTERS; + +#ifndef EXCEPTION_DISPOSITION +#define EXCEPTION_DISPOSITION int +#endif +#define ExceptionContinueExecution 0 +#define ExceptionContinueSearch 1 +#define ExceptionNestedException 2 +#define ExceptionCollidedUnwind 3 + +#if (defined(_X86_) && !defined(__x86_64)) + struct _EXCEPTION_RECORD; + struct _CONTEXT; + + EXCEPTION_DISPOSITION __cdecl _except_handler(struct _EXCEPTION_RECORD *_ExceptionRecord,void *_EstablisherFrame,struct _CONTEXT *_ContextRecord,void *_DispatcherContext); +#elif defined(__ia64__) + + typedef struct _EXCEPTION_POINTERS *Exception_info_ptr; + struct _EXCEPTION_RECORD; + struct _CONTEXT; + struct _DISPATCHER_CONTEXT; + + _CRTIMP EXCEPTION_DISPOSITION __cdecl __C_specific_handler (struct _EXCEPTION_RECORD *_ExceptionRecord,unsigned __int64 _MemoryStackFp,unsigned __int64 _BackingStoreFp,struct _CONTEXT *_ContextRecord,struct _DISPATCHER_CONTEXT *_DispatcherContext,unsigned __int64 _GlobalPointer); +#elif defined(__x86_64) + + struct _EXCEPTION_RECORD; + struct _CONTEXT; +#endif + +#define GetExceptionCode _exception_code +#define exception_code _exception_code +#define GetExceptionInformation (struct _EXCEPTION_POINTERS *)_exception_info +#define exception_info (struct _EXCEPTION_POINTERS *)_exception_info +#define AbnormalTermination _abnormal_termination +#define abnormal_termination _abnormal_termination + + unsigned long __cdecl _exception_code(void); + void *__cdecl _exception_info(void); + int __cdecl _abnormal_termination(void); + +#define EXCEPTION_EXECUTE_HANDLER 1 +#define EXCEPTION_CONTINUE_SEARCH 0 +#define EXCEPTION_CONTINUE_EXECUTION -1 + + /* CRT stuff */ + typedef void (__cdecl * _PHNDLR)(int); + + struct _XCPT_ACTION { + unsigned long XcptNum; + int SigNum; + _PHNDLR XcptAction; + }; + + extern struct _XCPT_ACTION _XcptActTab[]; + extern int _XcptActTabCount; + extern int _XcptActTabSize; + extern int _First_FPE_Indx; + extern int _Num_FPE; + + int __cdecl __CppXcptFilter(unsigned long _ExceptionNum,struct _EXCEPTION_POINTERS * _ExceptionPtr); + int __cdecl _XcptFilter(unsigned long _ExceptionNum,struct _EXCEPTION_POINTERS * _ExceptionPtr); + + /* + * The type of function that is expected as an exception handler to be + * installed with _try1. + */ + typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER)(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); + +#ifndef HAVE_NO_SEH + /* + * This is not entirely necessary, but it is the structure installed by + * the _try1 primitive below. + */ + typedef struct _EXCEPTION_REGISTRATION { + struct _EXCEPTION_REGISTRATION *prev; + EXCEPTION_DISPOSITION (*handler)(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); + } EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION; + + typedef EXCEPTION_REGISTRATION EXCEPTION_REGISTRATION_RECORD; + typedef PEXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION_RECORD; +#endif + +#if (defined(_X86_) && !defined(__x86_64)) +#define __try1(pHandler) \ + __asm__ ("pushl %0;pushl %%fs:0;movl %%esp,%%fs:0;" : : "g" (pHandler)); + +#define __except1 \ + __asm__ ("movl (%%esp),%%eax;movl %%eax,%%fs:0;addl $8,%%esp;" \ + : : : "%eax"); +#elif defined(__x86_64) +#define __try1(pHandler) \ + __asm__ ("pushq %0;pushq %%gs:0;movq %%rsp,%%gs:0;" : : "g" (pHandler)); + +#define __except1 \ + __asm__ ("movq (%%rsp),%%rax;movq %%rax,%%gs:0;addq $16,%%rsp;" \ + : : : "%rax"); +#else +#define __try1(pHandler) +#define __except1 #endif -/* FIXME: This will make some code compile. The programs will most - likely crash when an exception is raised, but at least they will - compile. */ -#ifdef __GNUC__ -#define __try -#define __except(x) if (0) /* don't execute handler */ -#define __finally - -#define _try __try -#define _except __except -#define _finally __finally +#ifdef __cplusplus +} #endif +#pragma pack(pop) #endif diff --git a/tinyc/win32/include/fcntl.h b/tinyc/win32/include/fcntl.h index d31bc84d5..9202b08cc 100644 --- a/tinyc/win32/include/fcntl.h +++ b/tinyc/win32/include/fcntl.h @@ -1,135 +1,52 @@ -/* - * fcntl.h - * - * Access constants for _open. Note that the permissions constants are - * in sys/stat.h (ick). - * - * This code is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ - -#ifndef __STRICT_ANSI__ - -#ifndef _FCNTL_H_ -#define _FCNTL_H_ - -/* All the headers include this file. */ #include <_mingw.h> -/* - * It appears that fcntl.h should include io.h for compatibility... - */ #include <io.h> -/* Specifiy one of these flags to define the access mode. */ -#define _O_RDONLY 0 -#define _O_WRONLY 1 -#define _O_RDWR 2 - -/* Mask for access mode bits in the _open flags. */ -#define _O_ACCMODE (_O_RDONLY|_O_WRONLY|_O_RDWR) - -#define _O_APPEND 0x0008 /* Writes will add to the end of the file. */ - -#define _O_RANDOM 0x0010 -#define _O_SEQUENTIAL 0x0020 -#define _O_TEMPORARY 0x0040 /* Make the file disappear after closing. - * WARNING: Even if not created by _open! */ -#define _O_NOINHERIT 0x0080 - -#define _O_CREAT 0x0100 /* Create the file if it does not exist. */ -#define _O_TRUNC 0x0200 /* Truncate the file if it does exist. */ -#define _O_EXCL 0x0400 /* Open only if the file does not exist. */ - -/* NOTE: Text is the default even if the given _O_TEXT bit is not on. */ -#define _O_TEXT 0x4000 /* CR-LF in file becomes LF in memory. */ -#define _O_BINARY 0x8000 /* Input and output is not translated. */ -#define _O_RAW _O_BINARY - -#ifndef _NO_OLDNAMES - -/* POSIX/Non-ANSI names for increased portability */ -#define O_RDONLY _O_RDONLY -#define O_WRONLY _O_WRONLY -#define O_RDWR _O_RDWR -#define O_ACCMODE _O_ACCMODE -#define O_APPEND _O_APPEND -#define O_CREAT _O_CREAT -#define O_TRUNC _O_TRUNC -#define O_EXCL _O_EXCL -#define O_TEXT _O_TEXT -#define O_BINARY _O_BINARY -#define O_TEMPORARY _O_TEMPORARY -#define O_NOINHERIT _O_NOINHERIT -#define O_SEQENTIAL _O_SEQUENTIAL -#define O_RANDOM _O_RANDOM - -#endif /* Not _NO_OLDNAMES */ - - -#ifndef RC_INVOKED - -/* - * This variable determines the default file mode. - * TODO: Which flags work? - */ -#ifndef __DECLSPEC_SUPPORTED - -#ifdef __MSVCRT__ -extern unsigned int* __imp__fmode; -#define _fmode (*__imp__fmode) -#else -/* CRTDLL */ -extern unsigned int* __imp__fmode_dll; -#define _fmode (*__imp__fmode_dll) +#ifndef _INC_FCNTL +#define _INC_FCNTL + +#define _O_RDONLY 0x0000 +#define _O_WRONLY 0x0001 +#define _O_RDWR 0x0002 +#define _O_APPEND 0x0008 +#define _O_CREAT 0x0100 +#define _O_TRUNC 0x0200 +#define _O_EXCL 0x0400 +#define _O_TEXT 0x4000 +#define _O_BINARY 0x8000 +#define _O_WTEXT 0x10000 +#define _O_U16TEXT 0x20000 +#define _O_U8TEXT 0x40000 +#define _O_ACCMODE (_O_RDONLY|_O_WRONLY|_O_RDWR) + +#define _O_RAW _O_BINARY +#define _O_NOINHERIT 0x0080 +#define _O_TEMPORARY 0x0040 +#define _O_SHORT_LIVED 0x1000 + +#define _O_SEQUENTIAL 0x0020 +#define _O_RANDOM 0x0010 + +#if !defined(NO_OLDNAMES) || defined(_POSIX) +#define O_RDONLY _O_RDONLY +#define O_WRONLY _O_WRONLY +#define O_RDWR _O_RDWR +#define O_APPEND _O_APPEND +#define O_CREAT _O_CREAT +#define O_TRUNC _O_TRUNC +#define O_EXCL _O_EXCL +#define O_TEXT _O_TEXT +#define O_BINARY _O_BINARY +#define O_RAW _O_BINARY +#define O_TEMPORARY _O_TEMPORARY +#define O_NOINHERIT _O_NOINHERIT +#define O_SEQUENTIAL _O_SEQUENTIAL +#define O_RANDOM _O_RANDOM +#define O_ACCMODE _O_ACCMODE #endif - -#else /* __DECLSPEC_SUPPORTED */ - -#ifdef __MSVCRT__ -__MINGW_IMPORT unsigned int _fmode; -#else /* ! __MSVCRT__ */ -__MINGW_IMPORT unsigned int _fmode_dll; -#define _fmode _fmode_dll -#endif /* ! __MSVCRT__ */ - -#endif /* __DECLSPEC_SUPPORTED */ - - -#ifdef __cplusplus -extern "C" { #endif - -int _setmode (int, int); - -#ifndef _NO_OLDNAMES -int setmode (int, int); -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus -} -#endif - -#endif /* Not RC_INVOKED */ - -#endif /* Not _FCNTL_H_ */ - -#endif /* Not __STRICT_ANSI__ */ - diff --git a/tinyc/win32/include/fenv.h b/tinyc/win32/include/fenv.h index ddc43dfc8..258f3a5d9 100644 --- a/tinyc/win32/include/fenv.h +++ b/tinyc/win32/include/fenv.h @@ -1,15 +1,49 @@ -#ifndef _FENV_H -#define _FENV_H +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _FENV_H_ +#define _FENV_H_ +#include <_mingw.h> + +/* FPU status word exception flags */ +#define FE_INVALID 0x01 +#define FE_DENORMAL 0x02 +#define FE_DIVBYZERO 0x04 +#define FE_OVERFLOW 0x08 +#define FE_UNDERFLOW 0x10 +#define FE_INEXACT 0x20 +#define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO \ + | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* FPU control word rounding flags */ +#define FE_TONEAREST 0x0000 +#define FE_DOWNWARD 0x0400 +#define FE_UPWARD 0x0800 +#define FE_TOWARDZERO 0x0c00 + +/* The MXCSR exception flags are the same as the + FE flags. */ +#define __MXCSR_EXCEPT_FLAG_SHIFT 0 + +/* How much to shift FE status word exception flags + to get MXCSR rounding flags, */ +#define __MXCSR_ROUND_FLAG_SHIFT 3 + +#ifndef RC_INVOKED /* For now, support only for the basic abstraction of flags that are - either set or clear. fexcept_t could be structure that holds more info - about the fp environment. + either set or clear. fexcept_t could be structure that holds more + info about the fp environment. */ typedef unsigned short fexcept_t; -/* This 28-byte struct represents the entire floating point - environment as stored by fnstenv or fstenv */ +/* This 32-byte struct represents the entire floating point + environment as stored by fnstenv or fstenv, augmented by + the contents of the MXCSR register, as stored by stmxcsr + (if CPU supports it). */ typedef struct { unsigned short __control_word; @@ -24,58 +58,47 @@ typedef struct unsigned int __data_offset; unsigned short __data_selector; unsigned short __unused3; + unsigned int __mxcsr; /* contents of the MXCSR register */ } fenv_t; -/* FPU status word exception flags */ -#define FE_INVALID 0x01 -#define FE_DENORMAL 0x02 -#define FE_DIVBYZERO 0x04 -#define FE_OVERFLOW 0x08 -#define FE_UNDERFLOW 0x10 -#define FE_INEXACT 0x20 -#define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO \ - | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) - -/* FPU control word rounding flags */ -#define FE_TONEAREST 0x0000 -#define FE_DOWNWARD 0x0400 -#define FE_UPWARD 0x0800 -#define FE_TOWARDZERO 0x0c00 +/*The C99 standard (7.6.9) allows us to define implementation-specific macros for + different fp environments */ + +/* The default Intel x87 floating point environment (64-bit mantissa) */ +#define FE_PC64_ENV ((const fenv_t *)-1) +/* The floating point environment set by MSVCRT _fpreset (53-bit mantissa) */ +#define FE_PC53_ENV ((const fenv_t *)-2) -/* The default floating point environment */ -#define FE_DFL_ENV ((const fenv_t *)-1) +/* The FE_DFL_ENV macro is required by standard. + fesetenv will use the environment set at app startup.*/ +#define FE_DFL_ENV ((const fenv_t *) 0) - -#ifndef RC_INVOKED #ifdef __cplusplus extern "C" { #endif - /*TODO: Some of these could be inlined */ /* 7.6.2 Exception */ -extern int feclearexcept (int); -extern int fegetexceptflag (fexcept_t * flagp, int excepts); -extern int feraiseexcept (int excepts ); -extern int fesetexceptflag (const fexcept_t *, int); -extern int fetestexcept (int excepts); - +extern int __cdecl feclearexcept (int); +extern int __cdecl fegetexceptflag (fexcept_t * flagp, int excepts); +extern int __cdecl feraiseexcept (int excepts ); +extern int __cdecl fesetexceptflag (const fexcept_t *, int); +extern int __cdecl fetestexcept (int excepts); /* 7.6.3 Rounding */ -extern int fegetround (void); -extern int fesetround (int mode); - +extern int __cdecl fegetround (void); +extern int __cdecl fesetround (int mode); /* 7.6.4 Environment */ -extern int fegetenv (fenv_t * envp); -extern int fesetenv (const fenv_t * ); -extern int feupdateenv (const fenv_t *); -extern int feholdexcept (fenv_t *); +extern int __cdecl fegetenv(fenv_t * envp); +extern int __cdecl fesetenv(const fenv_t * ); +extern int __cdecl feupdateenv(const fenv_t *); +extern int __cdecl feholdexcept(fenv_t *); #ifdef __cplusplus } diff --git a/tinyc/win32/include/float.h b/tinyc/win32/include/float.h deleted file mode 100644 index a6fb6dbe0..000000000 --- a/tinyc/win32/include/float.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - * float.h - * - * Constants related to floating point arithmetic. - * - * Also included here are some non-ANSI bits for accessing the floating - * point controller. - * - * NOTE: GCC provides float.h, and it is probably more accurate than this, - * but it doesn't include the non-standard stuff for accessing the - * fp controller. (TODO: Move those bits elsewhere?) Thus it is - * probably not a good idea to use the GCC supplied version instead - * of this header. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * - */ - -#ifndef _FLOAT_H_ -#define _FLOAT_H_ - -/* All the headers include this file. */ -#include <_mingw.h> - -#define FLT_ROUNDS 1 -#define FLT_GUARD 1 -#define FLT_NORMALIZE 1 - -/* - * The characteristics of float. - */ - -/* The radix for floating point representation. */ -#define FLT_RADIX 2 - -/* Decimal digits of precision. */ -#define FLT_DIG 6 - -/* Smallest number such that 1+x != 1 */ -#define FLT_EPSILON 1.19209290e-07F - -/* The number of base FLT_RADIX digits in the mantissa. */ -#define FLT_MANT_DIG 24 - -/* The maximum floating point number. */ -#define FLT_MAX 3.40282347e+38F - -/* Maximum n such that FLT_RADIX^n - 1 is representable. */ -#define FLT_MAX_EXP 128 - -/* Maximum n such that 10^n is representable. */ -#define FLT_MAX_10_EXP 38 - -/* Minimum normalized floating-point number. */ -#define FLT_MIN 1.17549435e-38F - -/* Minimum n such that FLT_RADIX^n is a normalized number. */ -#define FLT_MIN_EXP (-125) - -/* Minimum n such that 10^n is a normalized number. */ -#define FLT_MIN_10_EXP (-37) - - -/* - * The characteristics of double. - */ -#define DBL_DIG 15 -#define DBL_EPSILON 1.1102230246251568e-16 -#define DBL_MANT_DIG 53 -#define DBL_MAX 1.7976931348623157e+308 -#define DBL_MAX_EXP 1024 -#define DBL_MAX_10_EXP 308 -#define DBL_MIN 2.2250738585072014e-308 -#define DBL_MIN_EXP (-1021) -#define DBL_MIN_10_EXP (-307) - - -/* - * The characteristics of long double. - * NOTE: long double is the same as double. - */ -#define LDBL_DIG 15 -#define LDBL_EPSILON 1.1102230246251568e-16L -#define LDBL_MANT_DIG 53 -#define LDBL_MAX 1.7976931348623157e+308L -#define LDBL_MAX_EXP 1024 -#define LDBL_MAX_10_EXP 308 -#define LDBL_MIN 2.2250738585072014e-308L -#define LDBL_MIN_EXP (-1021) -#define LDBL_MIN_10_EXP (-307) - - -/* - * Functions and definitions for controlling the FPU. - */ -#ifndef __STRICT_ANSI__ - -/* TODO: These constants are only valid for x86 machines */ - -/* Control word masks for unMask */ -#define _MCW_EM 0x0008001F /* Error masks */ -#define _MCW_IC 0x00040000 /* Infinity */ -#define _MCW_RC 0x00000300 /* Rounding */ -#define _MCW_PC 0x00030000 /* Precision */ - -/* Control word values for unNew (use with related unMask above) */ -#define _EM_INVALID 0x00000010 -#define _EM_DENORMAL 0x00080000 -#define _EM_ZERODIVIDE 0x00000008 -#define _EM_OVERFLOW 0x00000004 -#define _EM_UNDERFLOW 0x00000002 -#define _EM_INEXACT 0x00000001 -#define _IC_AFFINE 0x00040000 -#define _IC_PROJECTIVE 0x00000000 -#define _RC_CHOP 0x00000300 -#define _RC_UP 0x00000200 -#define _RC_DOWN 0x00000100 -#define _RC_NEAR 0x00000000 -#define _PC_24 0x00020000 -#define _PC_53 0x00010000 -#define _PC_64 0x00000000 - -/* These are also defined in Mingw math.h, needed to work around - GCC build issues. */ -/* Return values for fpclass. */ -#ifndef __MINGW_FPCLASS_DEFINED -#define __MINGW_FPCLASS_DEFINED 1 -#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ -#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ -#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ -#define _FPCLASS_NN 0x0008 /* Negative Normal */ -#define _FPCLASS_ND 0x0010 /* Negative Denormal */ -#define _FPCLASS_NZ 0x0020 /* Negative Zero */ -#define _FPCLASS_PZ 0x0040 /* Positive Zero */ -#define _FPCLASS_PD 0x0080 /* Positive Denormal */ -#define _FPCLASS_PN 0x0100 /* Positive Normal */ -#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ -#endif /* __MINGW_FPCLASS_DEFINED */ - -/* invalid subconditions (_SW_INVALID also set) */ -#define _SW_UNEMULATED 0x0040 /* unemulated instruction */ -#define _SW_SQRTNEG 0x0080 /* square root of a neg number */ -#define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */ -#define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */ - -/* Floating point error signals and return codes */ -#define _FPE_INVALID 0x81 -#define _FPE_DENORMAL 0x82 -#define _FPE_ZERODIVIDE 0x83 -#define _FPE_OVERFLOW 0x84 -#define _FPE_UNDERFLOW 0x85 -#define _FPE_INEXACT 0x86 -#define _FPE_UNEMULATED 0x87 -#define _FPE_SQRTNEG 0x88 -#define _FPE_STACKOVERFLOW 0x8a -#define _FPE_STACKUNDERFLOW 0x8b -#define _FPE_EXPLICITGEN 0x8c /* raise( SIGFPE ); */ - -#ifndef RC_INVOKED - -#ifdef __cplusplus -extern "C" { -#endif - -/* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask), - * i.e. change the bits in unMask to have the values they have in unNew, - * leaving other bits unchanged. */ -unsigned int _controlfp (unsigned int unNew, unsigned int unMask); -unsigned int _control87 (unsigned int unNew, unsigned int unMask); - - -unsigned int _clearfp (void); /* Clear the FPU status word */ -unsigned int _statusfp (void); /* Report the FPU status word */ -#define _clear87 _clearfp -#define _status87 _statusfp - -void _fpreset (void); /* Reset the FPU */ -void fpreset (void); - -/* Global 'variable' for the current floating point error code. */ -int * __fpecode(void); -#define _fpecode (*(__fpecode())) - -/* - * IEEE recommended functions - */ - -double _chgsign (double); -double _copysign (double, double); -double _logb (double); -double _nextafter (double, double); -double _scalb (double, long); - -int _finite (double); -int _fpclass (double); -int _isnan (double); - -#ifdef __cplusplus -} -#endif - -#endif /* Not RC_INVOKED */ - -#endif /* Not __STRICT_ANSI__ */ - -#endif /* _FLOAT_H_ */ - diff --git a/tinyc/win32/include/inttypes.h b/tinyc/win32/include/inttypes.h index 74944f14b..736009195 100644 --- a/tinyc/win32/include/inttypes.h +++ b/tinyc/win32/include/inttypes.h @@ -1,8 +1,14 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ /* 7.8 Format conversion of integer types <inttypes.h> */ -#ifndef _INTTYPES_H -#define _INTTYPES_H +#ifndef _INTTYPES_H_ +#define _INTTYPES_H_ +#include <_mingw.h> #include <stdint.h> #define __need_wchar_t #include <stddef.h> @@ -43,7 +49,6 @@ typedef struct { #define PRIdFAST64 "I64d" #define PRIdMAX "I64d" -#define PRIdPTR "d" #define PRIi8 "i" #define PRIi16 "i" @@ -61,7 +66,6 @@ typedef struct { #define PRIiFAST64 "I64i" #define PRIiMAX "I64i" -#define PRIiPTR "i" #define PRIo8 "o" #define PRIo16 "o" @@ -80,8 +84,6 @@ typedef struct { #define PRIoMAX "I64o" -#define PRIoPTR "o" - /* fprintf macros for unsigned types */ #define PRIu8 "u" #define PRIu16 "u" @@ -100,7 +102,6 @@ typedef struct { #define PRIuFAST64 "I64u" #define PRIuMAX "I64u" -#define PRIuPTR "u" #define PRIx8 "x" #define PRIx16 "x" @@ -118,7 +119,6 @@ typedef struct { #define PRIxFAST64 "I64x" #define PRIxMAX "I64x" -#define PRIxPTR "x" #define PRIX8 "X" #define PRIX16 "X" @@ -136,7 +136,6 @@ typedef struct { #define PRIXFAST64 "I64X" #define PRIXMAX "I64X" -#define PRIXPTR "X" /* * fscanf macros for signed int types @@ -158,7 +157,6 @@ typedef struct { #define SCNdFAST64 "I64d" #define SCNdMAX "I64d" -#define SCNdPTR "d" #define SCNi16 "hi" #define SCNi32 "i" @@ -173,7 +171,6 @@ typedef struct { #define SCNiFAST64 "I64i" #define SCNiMAX "I64i" -#define SCNiPTR "i" #define SCNo16 "ho" #define SCNo32 "o" @@ -188,7 +185,6 @@ typedef struct { #define SCNoFAST64 "I64o" #define SCNoMAX "I64o" -#define SCNoPTR "o" #define SCNx16 "hx" #define SCNx32 "x" @@ -203,8 +199,6 @@ typedef struct { #define SCNxFAST64 "I64x" #define SCNxMAX "I64x" -#define SCNxPTR "x" - /* fscanf macros for unsigned int types */ @@ -221,7 +215,32 @@ typedef struct { #define SCNuFAST64 "I64u" #define SCNuMAX "I64u" + +#ifdef _WIN64 +#define PRIdPTR "I64d" +#define PRIiPTR "I64i" +#define PRIoPTR "I64o" +#define PRIuPTR "I64u" +#define PRIxPTR "I64x" +#define PRIXPTR "I64X" +#define SCNdPTR "I64d" +#define SCNiPTR "I64i" +#define SCNoPTR "I64o" +#define SCNxPTR "I64x" +#define SCNuPTR "I64u" +#else +#define PRIdPTR "d" +#define PRIiPTR "i" +#define PRIoPTR "o" +#define PRIuPTR "u" +#define PRIxPTR "x" +#define PRIXPTR "X" +#define SCNdPTR "d" +#define SCNiPTR "i" +#define SCNoPTR "o" +#define SCNxPTR "x" #define SCNuPTR "u" +#endif #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* @@ -254,19 +273,22 @@ typedef struct { #endif /* !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) */ -extern inline intmax_t imaxabs (intmax_t j) +intmax_t __cdecl imaxabs (intmax_t j); +__CRT_INLINE intmax_t __cdecl imaxabs (intmax_t j) {return (j >= 0 ? j : -j);} -imaxdiv_t imaxdiv (intmax_t numer, intmax_t denom); +imaxdiv_t __cdecl imaxdiv (intmax_t numer, intmax_t denom); /* 7.8.2 Conversion functions for greatest-width integer types */ -intmax_t strtoimax (const char* __restrict__ nptr, char** __restrict__ endptr, int base); -uintmax_t strtoumax (const char* __restrict__ nptr, char** __restrict__ endptr, int base); +intmax_t __cdecl strtoimax (const char* __restrict__ nptr, + char** __restrict__ endptr, int base); +uintmax_t __cdecl strtoumax (const char* __restrict__ nptr, + char** __restrict__ endptr, int base); -intmax_t wcstoimax (const wchar_t* __restrict__ nptr, wchar_t** __restrict__ endptr, - int base); -uintmax_t wcstoumax (const wchar_t* __restrict__ nptr, wchar_t** __restrict__ endptr, - int base); +intmax_t __cdecl wcstoimax (const wchar_t* __restrict__ nptr, + wchar_t** __restrict__ endptr, int base); +uintmax_t __cdecl wcstoumax (const wchar_t* __restrict__ nptr, + wchar_t** __restrict__ endptr, int base); #ifdef __cplusplus } diff --git a/tinyc/win32/include/io.h b/tinyc/win32/include/io.h index 8d5115e6c..e2aeec3db 100644 --- a/tinyc/win32/include/io.h +++ b/tinyc/win32/include/io.h @@ -1,296 +1,418 @@ -/* - * io.h - * - * System level I/O functions and types. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * - */ - -#ifndef __STRICT_ANSI__ -#ifndef _IO_H_ -#define _IO_H_ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _IO_H_ +#define _IO_H_ -/* All the headers include this file. */ #include <_mingw.h> +#include <string.h> -/* We need the definition of FILE anyway... */ -#include <stdio.h> - -/* MSVC's io.h contains the stuff from dir.h, so I will too. - * NOTE: This also defines off_t, the file offset type, through - * an inclusion of sys/types.h */ -#ifndef __STRICT_ANSI__ +#pragma pack(push,_CRT_PACKING) -#include <sys/types.h> /* To get time_t. */ +#ifndef _POSIX_ -/* - * Attributes of files as returned by _findfirst et al. - */ -#define _A_NORMAL 0x00000000 -#define _A_RDONLY 0x00000001 -#define _A_HIDDEN 0x00000002 -#define _A_SYSTEM 0x00000004 -#define _A_VOLID 0x00000008 -#define _A_SUBDIR 0x00000010 -#define _A_ARCH 0x00000020 - - -#ifndef RC_INVOKED +#ifdef __cplusplus +extern "C" { +#endif -#ifndef _FSIZE_T_DEFINED -typedef unsigned long _fsize_t; +_CRTIMP char* __cdecl _getcwd (char*, int); +#ifndef _FSIZE_T_DEFINED + typedef unsigned long _fsize_t; #define _FSIZE_T_DEFINED #endif -/* - * The following structure is filled in by _findfirst or _findnext when - * they succeed in finding a match. - */ -struct _finddata_t -{ - unsigned attrib; /* Attributes, see constants above. */ - time_t time_create; - time_t time_access; /* always midnight local time */ - time_t time_write; - _fsize_t size; - char name[FILENAME_MAX]; /* may include spaces. */ -}; - -struct _finddatai64_t { - unsigned attrib; - time_t time_create; - time_t time_access; - time_t time_write; - __int64 size; - char name[FILENAME_MAX]; -}; +#ifndef _FINDDATA_T_DEFINED + + struct _finddata32_t { + unsigned attrib; + __time32_t time_create; + __time32_t time_access; + __time32_t time_write; + _fsize_t size; + char name[260]; + }; + +/*#if _INTEGRAL_MAX_BITS >= 64*/ + + struct _finddata32i64_t { + unsigned attrib; + __time32_t time_create; + __time32_t time_access; + __time32_t time_write; + __int64 size; + char name[260]; + }; + + struct _finddata64i32_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + _fsize_t size; + char name[260]; + }; + + struct __finddata64_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + __int64 size; + char name[260]; + }; +/* #endif */ + +#ifdef _USE_32BIT_TIME_T +#define _finddata_t _finddata32_t +#define _finddatai64_t _finddata32i64_t + +#ifdef _WIN64 +#define _findfirst _findfirst32 +#define _findnext _findnext32 +#else +#define _findfirst32 _findfirst +#define _findnext32 _findnext +#endif +#define _findfirsti64 _findfirst32i64 +#define _findnexti64 _findnext32i64 +#else +#define _finddata_t _finddata64i32_t +#define _finddatai64_t __finddata64_t + +#define _findfirst _findfirst64i32 +#define _findnext _findnext64i32 +#define _findfirsti64 _findfirst64 +#define _findnexti64 _findnext64 +#endif +#define _FINDDATA_T_DEFINED +#endif #ifndef _WFINDDATA_T_DEFINED -struct _wfinddata_t { - unsigned attrib; - time_t time_create; /* -1 for FAT file systems */ - time_t time_access; /* -1 for FAT file systems */ - time_t time_write; - _fsize_t size; - wchar_t name[FILENAME_MAX]; /* may include spaces. */ -}; -struct _wfinddatai64_t { - unsigned attrib; - time_t time_create; - time_t time_access; - time_t time_write; - __int64 size; - wchar_t name[FILENAME_MAX]; -}; + + struct _wfinddata32_t { + unsigned attrib; + __time32_t time_create; + __time32_t time_access; + __time32_t time_write; + _fsize_t size; + wchar_t name[260]; + }; + +/* #if _INTEGRAL_MAX_BITS >= 64 */ + + struct _wfinddata32i64_t { + unsigned attrib; + __time32_t time_create; + __time32_t time_access; + __time32_t time_write; + __int64 size; + wchar_t name[260]; + }; + + struct _wfinddata64i32_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + _fsize_t size; + wchar_t name[260]; + }; + + struct _wfinddata64_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + __int64 size; + wchar_t name[260]; + }; +/* #endif */ + +#ifdef _USE_32BIT_TIME_T +#define _wfinddata_t _wfinddata32_t +#define _wfinddatai64_t _wfinddata32i64_t + +#define _wfindfirst _wfindfirst32 +#define _wfindnext _wfindnext32 +#define _wfindfirsti64 _wfindfirst32i64 +#define _wfindnexti64 _wfindnext32i64 +#else +#define _wfinddata_t _wfinddata64i32_t +#define _wfinddatai64_t _wfinddata64_t + +#define _wfindfirst _wfindfirst64i32 +#define _wfindnext _wfindnext64i32 +#define _wfindfirsti64 _wfindfirst64 +#define _wfindnexti64 _wfindnext64 +#endif #define _WFINDDATA_T_DEFINED #endif -#ifdef __cplusplus -extern "C" { +#define _A_NORMAL 0x00 +#define _A_RDONLY 0x01 +#define _A_HIDDEN 0x02 +#define _A_SYSTEM 0x04 +#define _A_SUBDIR 0x10 +#define _A_ARCH 0x20 + +#ifndef _SIZE_T_DEFINED +#define _SIZE_T_DEFINED +#undef size_t +#ifdef _WIN64 +#if defined(__GNUC__) && defined(__STRICT_ANSI__) + typedef unsigned int size_t __attribute__ ((mode (DI))); +#else + typedef unsigned __int64 size_t; +#endif +#else + typedef unsigned int size_t; +#endif #endif -/* - * Functions for searching for files. _findfirst returns -1 if no match - * is found. Otherwise it returns a handle to be used in _findnext and - * _findclose calls. _findnext also returns -1 if no match could be found, - * and 0 if a match was found. Call _findclose when you are finished. - */ -int _findfirst (const char*, struct _finddata_t*); -int _findnext (int, struct _finddata_t*); -int _findclose (int); +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 +#if defined(__GNUC__) && defined(__STRICT_ANSI__) + typedef int ssize_t __attribute__ ((mode (DI))); +#else + typedef __int64 ssize_t; +#endif +#else + typedef int ssize_t; +#endif +#endif -int _chdir (const char*); -char* _getcwd (char*, int); -int _mkdir (const char*); -char* _mktemp (char*); -int _rmdir (const char*); +#ifndef _OFF_T_DEFINED +#define _OFF_T_DEFINED +#ifndef _OFF_T_ +#define _OFF_T_ + typedef long _off_t; +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef long off_t; +#endif +#endif +#endif +#ifndef _OFF64_T_DEFINED +#define _OFF64_T_DEFINED +#if defined(__GNUC__) && defined(__STRICT_ANSI__) + typedef int _off64_t __attribute__ ((mode (DI))); +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef int off64_t __attribute__ ((mode (DI))); +#endif +#else + typedef long long _off64_t; +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef long long off64_t; +#endif +#endif +#endif -#ifdef __MSVCRT__ -__int64 _filelengthi64(int); -long _findfirsti64(const char*, struct _finddatai64_t*); -int _findnexti64(long, struct _finddatai64_t*); -__int64 _lseeki64(int, __int64, int); -__int64 _telli64(int); -#endif /* __MSVCRT__ */ + /* Some defines for _access nAccessMode (MS doesn't define them, but + * it doesn't seem to hurt to add them). */ +#define F_OK 0 /* Check for file existence */ +#define X_OK 1 /* Check for execute permission. */ +#define W_OK 2 /* Check for write permission */ +#define R_OK 4 /* Check for read permission */ + _CRTIMP int __cdecl _access(const char *_Filename,int _AccessMode); + _CRTIMP int __cdecl _chmod(const char *_Filename,int _Mode); + _CRTIMP int __cdecl _chsize(int _FileHandle,long _Size); + _CRTIMP int __cdecl _close(int _FileHandle); + _CRTIMP int __cdecl _commit(int _FileHandle); + _CRTIMP int __cdecl _creat(const char *_Filename,int _PermissionMode); + _CRTIMP int __cdecl _dup(int _FileHandle); + _CRTIMP int __cdecl _dup2(int _FileHandleSrc,int _FileHandleDst); + _CRTIMP int __cdecl _eof(int _FileHandle); + _CRTIMP long __cdecl _filelength(int _FileHandle); + _CRTIMP intptr_t __cdecl _findfirst32(const char *_Filename,struct _finddata32_t *_FindData); + _CRTIMP int __cdecl _findnext32(intptr_t _FindHandle,struct _finddata32_t *_FindData); + _CRTIMP int __cdecl _findclose(intptr_t _FindHandle); + _CRTIMP int __cdecl _isatty(int _FileHandle); + _CRTIMP int __cdecl _locking(int _FileHandle,int _LockMode,long _NumOfBytes); + _CRTIMP long __cdecl _lseek(int _FileHandle,long _Offset,int _Origin); + _off64_t lseek64(int fd,_off64_t offset, int whence); + _CRTIMP char *__cdecl _mktemp(char *_TemplateName); + _CRTIMP int __cdecl _pipe(int *_PtHandles,unsigned int _PipeSize,int _TextMode); + _CRTIMP int __cdecl _read(int _FileHandle,void *_DstBuf,unsigned int _MaxCharCount); + +#ifndef _CRT_DIRECTORY_DEFINED +#define _CRT_DIRECTORY_DEFINED + int __cdecl remove(const char *_Filename); + int __cdecl rename(const char *_OldFilename,const char *_NewFilename); + _CRTIMP int __cdecl _unlink(const char *_Filename); +#ifndef NO_OLDNAMES + int __cdecl unlink(const char *_Filename); +#endif +#endif -#ifndef _NO_OLDNAMES + _CRTIMP int __cdecl _setmode(int _FileHandle,int _Mode); + _CRTIMP long __cdecl _tell(int _FileHandle); + _CRTIMP int __cdecl _umask(int _Mode); + _CRTIMP int __cdecl _write(int _FileHandle,const void *_Buf,unsigned int _MaxCharCount); + +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP __int64 __cdecl _filelengthi64(int _FileHandle); + _CRTIMP intptr_t __cdecl _findfirst32i64(const char *_Filename,struct _finddata32i64_t *_FindData); + _CRTIMP intptr_t __cdecl _findfirst64(const char *_Filename,struct __finddata64_t *_FindData); +#ifdef __cplusplus +#include <string.h> +#endif + intptr_t __cdecl _findfirst64i32(const char *_Filename,struct _finddata64i32_t *_FindData); + __CRT_INLINE intptr_t __cdecl _findfirst64i32(const char *_Filename,struct _finddata64i32_t *_FindData) + { + struct __finddata64_t fd; + intptr_t ret = _findfirst64(_Filename,&fd); + _FindData->attrib=fd.attrib; + _FindData->time_create=fd.time_create; + _FindData->time_access=fd.time_access; + _FindData->time_write=fd.time_write; + _FindData->size=(_fsize_t) fd.size; + strncpy(_FindData->name,fd.name,260); + return ret; + } + _CRTIMP int __cdecl _findnext32i64(intptr_t _FindHandle,struct _finddata32i64_t *_FindData); + _CRTIMP int __cdecl _findnext64(intptr_t _FindHandle,struct __finddata64_t *_FindData); + int __cdecl _findnext64i32(intptr_t _FindHandle,struct _finddata64i32_t *_FindData); + __CRT_INLINE int __cdecl _findnext64i32(intptr_t _FindHandle,struct _finddata64i32_t *_FindData) + { + struct __finddata64_t fd; + int ret = _findnext64(_FindHandle,&fd); + _FindData->attrib=fd.attrib; + _FindData->time_create=fd.time_create; + _FindData->time_access=fd.time_access; + _FindData->time_write=fd.time_write; + _FindData->size=(_fsize_t) fd.size; + strncpy(_FindData->name,fd.name,260); + return ret; + } + __int64 __cdecl _lseeki64(int _FileHandle,__int64 _Offset,int _Origin); + __int64 __cdecl _telli64(int _FileHandle); +#endif +#ifndef NO_OLDNAMES #ifndef _UWIN -int chdir (const char*); -char* getcwd (char*, int); -int mkdir (const char*); -char* mktemp (char*); -int rmdir (const char*); + int __cdecl chdir (const char *); + char *__cdecl getcwd (char *, int); + int __cdecl mkdir (const char *); + char *__cdecl mktemp(char *); + int __cdecl rmdir (const char*); + int __cdecl chmod (const char *, int); #endif /* _UWIN */ -#endif /* Not _NO_OLDNAMES */ +#endif /* Not NO_OLDNAMES */ -#ifdef __cplusplus -} + _CRTIMP errno_t __cdecl _sopen_s(int *_FileHandle,const char *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionMode); + +#ifndef __cplusplus + _CRTIMP int __cdecl _open(const char *_Filename,int _OpenFlag,...); + _CRTIMP int __cdecl _sopen(const char *_Filename,int _OpenFlag,int _ShareFlag,...); +#else + extern "C++" _CRTIMP int __cdecl _open(const char *_Filename,int _Openflag,int _PermissionMode = 0); + extern "C++" _CRTIMP int __cdecl _sopen(const char *_Filename,int _Openflag,int _ShareFlag,int _PermissionMode = 0); #endif -#endif /* Not RC_INVOKED */ +#ifndef _WIO_DEFINED +#define _WIO_DEFINED + _CRTIMP int __cdecl _waccess(const wchar_t *_Filename,int _AccessMode); + _CRTIMP int __cdecl _wchmod(const wchar_t *_Filename,int _Mode); + _CRTIMP int __cdecl _wcreat(const wchar_t *_Filename,int _PermissionMode); + _CRTIMP intptr_t __cdecl _wfindfirst32(const wchar_t *_Filename,struct _wfinddata32_t *_FindData); + _CRTIMP int __cdecl _wfindnext32(intptr_t _FindHandle,struct _wfinddata32_t *_FindData); + _CRTIMP int __cdecl _wunlink(const wchar_t *_Filename); + _CRTIMP int __cdecl _wrename(const wchar_t *_NewFilename,const wchar_t *_OldFilename); + _CRTIMP wchar_t *__cdecl _wmktemp(wchar_t *_TemplateName); + +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP intptr_t __cdecl _wfindfirst32i64(const wchar_t *_Filename,struct _wfinddata32i64_t *_FindData); + intptr_t __cdecl _wfindfirst64i32(const wchar_t *_Filename,struct _wfinddata64i32_t *_FindData); + _CRTIMP intptr_t __cdecl _wfindfirst64(const wchar_t *_Filename,struct _wfinddata64_t *_FindData); + _CRTIMP int __cdecl _wfindnext32i64(intptr_t _FindHandle,struct _wfinddata32i64_t *_FindData); + int __cdecl _wfindnext64i32(intptr_t _FindHandle,struct _wfinddata64i32_t *_FindData); + _CRTIMP int __cdecl _wfindnext64(intptr_t _FindHandle,struct _wfinddata64_t *_FindData); +#endif -#endif /* Not __STRICT_ANSI__ */ + _CRTIMP errno_t __cdecl _wsopen_s(int *_FileHandle,const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionFlag); -/* TODO: Maximum number of open handles has not been tested, I just set - * it the same as FOPEN_MAX. */ -#define HANDLE_MAX FOPEN_MAX +#if !defined(__cplusplus) || !(defined(_X86_) && !defined(__x86_64)) + _CRTIMP int __cdecl _wopen(const wchar_t *_Filename,int _OpenFlag,...); + _CRTIMP int __cdecl _wsopen(const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,...); +#else + extern "C++" _CRTIMP int __cdecl _wopen(const wchar_t *_Filename,int _OpenFlag,int _PermissionMode = 0); + extern "C++" _CRTIMP int __cdecl _wsopen(const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionMode = 0); +#endif +#endif -/* Some defines for _access nAccessMode (MS doesn't define them, but - * it doesn't seem to hurt to add them). */ -#define F_OK 0 /* Check for file existence */ -#define X_OK 1 /* Check for execute permission. */ -#define W_OK 2 /* Check for write permission */ -#define R_OK 4 /* Check for read permission */ + int __cdecl __lock_fhandle(int _Filehandle); + void __cdecl _unlock_fhandle(int _Filehandle); + _CRTIMP intptr_t __cdecl _get_osfhandle(int _FileHandle); + _CRTIMP int __cdecl _open_osfhandle(intptr_t _OSFileHandle,int _Flags); + +#ifndef NO_OLDNAMES + int __cdecl access(const char *_Filename,int _AccessMode); + int __cdecl chmod(const char *_Filename,int _AccessMode); + int __cdecl chsize(int _FileHandle,long _Size); + int __cdecl close(int _FileHandle); + int __cdecl creat(const char *_Filename,int _PermissionMode); + int __cdecl dup(int _FileHandle); + int __cdecl dup2(int _FileHandleSrc,int _FileHandleDst); + int __cdecl eof(int _FileHandle); + long __cdecl filelength(int _FileHandle); + int __cdecl isatty(int _FileHandle); + int __cdecl locking(int _FileHandle,int _LockMode,long _NumOfBytes); + long __cdecl lseek(int _FileHandle,long _Offset,int _Origin); + char *__cdecl mktemp(char *_TemplateName); + int __cdecl open(const char *_Filename,int _OpenFlag,...); + int __cdecl read(int _FileHandle,void *_DstBuf,unsigned int _MaxCharCount); + int __cdecl setmode(int _FileHandle,int _Mode); + int __cdecl sopen(const char *_Filename,int _OpenFlag,int _ShareFlag,...); + long __cdecl tell(int _FileHandle); + int __cdecl umask(int _Mode); + int __cdecl write(int _Filehandle,const void *_Buf,unsigned int _MaxCharCount); +#endif -#ifndef RC_INVOKED +#ifdef __cplusplus +} +#endif +#endif -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif -int _access (const char*, int); -int _chsize (int, long); -int _close (int); -int _commit(int); - -/* NOTE: The only significant bit in unPermissions appears to be bit 7 (0x80), - * the "owner write permission" bit (on FAT). */ -int _creat (const char*, unsigned); - -int _dup (int); -int _dup2 (int, int); -long _filelength (int); -int _fileno (FILE*); -long _get_osfhandle (int); -int _isatty (int); - -/* In a very odd turn of events this function is excluded from those - * files which define _STREAM_COMPAT. This is required in order to - * build GNU libio because of a conflict with _eof in streambuf.h - * line 107. Actually I might just be able to change the name of - * the enum member in streambuf.h... we'll see. TODO */ -#ifndef _STREAM_COMPAT -int _eof (int); -#endif - -/* LK_... locking commands defined in sys/locking.h. */ -int _locking (int, int, long); - -long _lseek (int, long, int); - -/* Optional third argument is unsigned unPermissions. */ -int _open (const char*, int, ...); - -int _open_osfhandle (long, int); -int _pipe (int *, unsigned int, int); -int _read (int, void*, unsigned int); - -/* SH_... flags for nShFlags defined in share.h - * Optional fourth argument is unsigned unPermissions */ -int _sopen (const char*, int, int, ...); - -long _tell (int); -/* Should umask be in sys/stat.h and/or sys/types.h instead? */ -int _umask (int); -int _unlink (const char*); -int _write (int, const void*, unsigned int); - -/* Wide character versions. Also declared in wchar.h. */ -/* Not in crtdll.dll */ -#if !defined (_WIO_DEFINED) -#if defined (__MSVCRT__) -int _waccess(const wchar_t*, int); -int _wchmod(const wchar_t*, int); -int _wcreat(const wchar_t*, int); -long _wfindfirst(wchar_t*, struct _wfinddata_t*); -int _wfindnext(long, struct _wfinddata_t *); -int _wunlink(const wchar_t*); -int _wopen(const wchar_t*, int, ...); -int _wsopen(const wchar_t*, int, int, ...); -wchar_t * _wmktemp(wchar_t*); -long _wfindfirsti64(const wchar_t*, struct _wfinddatai64_t*); -int _wfindnexti64(long, struct _wfinddatai64_t*); -#endif /* defined (__MSVCRT__) */ -#define _WIO_DEFINED -#endif /* _WIO_DEFINED */ - -#ifndef _NO_OLDNAMES -/* - * Non-underscored versions of non-ANSI functions to improve portability. - * These functions live in libmoldname.a. - */ +/* Misc stuff */ +char *getlogin(void); +#ifdef __USE_MINGW_ALARM +unsigned int alarm(unsigned int seconds); +#endif -#ifndef _UWIN -int access (const char*, int); -int chsize (int, long ); -int close (int); -int creat (const char*, int); -int dup (int); -int dup2 (int, int); -int eof (int); -long filelength (int); -int fileno (FILE*); -int isatty (int); -long lseek (int, long, int); -int open (const char*, int, ...); -int read (int, void*, unsigned int); -int sopen (const char*, int, int, ...); -long tell (int); -int umask (int); -int unlink (const char*); -int write (int, const void*, unsigned int); -#endif /* _UWIN */ +#ifdef __USE_MINGW_ACCESS +/* Old versions of MSVCRT access() just ignored X_OK, while the version + shipped with Vista, returns an error code. This will restore the + old behaviour */ +static inline int __mingw_access (const char *__fname, int __mode) { + return _access (__fname, __mode & ~X_OK); +} -/* Wide character versions. Also declared in wchar.h. */ -/* Where do these live? Not in libmoldname.a nor in libmsvcrt.a */ -#if 0 -int waccess(const wchar_t *, int); -int wchmod(const wchar_t *, int); -int wcreat(const wchar_t *, int); -long wfindfirst(wchar_t *, struct _wfinddata_t *); -int wfindnext(long, struct _wfinddata_t *); -int wunlink(const wchar_t *); -int wrename(const wchar_t *, const wchar_t *); -int wopen(const wchar_t *, int, ...); -int wsopen(const wchar_t *, int, int, ...); -wchar_t * wmktemp(wchar_t *); +#define access(__f,__m) __mingw_access (__f, __m) #endif -#endif /* Not _NO_OLDNAMES */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not RC_INVOKED */ -#endif /* _IO_H_ not defined */ +#pragma pack(pop) + +#include <sec_api/io_s.h> -#endif /* Not strict ANSI */ +#endif /* End _IO_H_ */ diff --git a/tinyc/win32/include/limits.h b/tinyc/win32/include/limits.h index 5dc6025fd..fafb04a46 100644 --- a/tinyc/win32/include/limits.h +++ b/tinyc/win32/include/limits.h @@ -1,115 +1,111 @@ -/* - * limits.h - * - * Defines constants for the sizes of integral types. - * - * NOTE: GCC should supply a version of this header and it should be safe to - * use that version instead of this one (maybe safer). - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ - -#ifndef _LIMITS_H_ -#define _LIMITS_H_ - -/* All the headers include this file. */ #include <_mingw.h> -/* - * File system limits - * - * TODO: NAME_MAX and OPEN_MAX are file system limits or not? Are they the - * same as FILENAME_MAX and FOPEN_MAX from stdio.h? - * NOTE: Apparently the actual size of PATH_MAX is 260, but a space is - * required for the NUL. TODO: Test? - */ -#define PATH_MAX (259) +#ifndef _INC_LIMITS +#define _INC_LIMITS /* - * Characteristics of the char data type. - * - * TODO: Is MB_LEN_MAX correct? - */ -#define CHAR_BIT 8 -#define MB_LEN_MAX 2 - -#define SCHAR_MIN (-128) -#define SCHAR_MAX 127 - -#define UCHAR_MAX 255 +* File system limits +* +* TODO: NAME_MAX and OPEN_MAX are file system limits or not? Are they the +* same as FILENAME_MAX and FOPEN_MAX from stdio.h? +* NOTE: Apparently the actual size of PATH_MAX is 260, but a space is +* required for the NUL. TODO: Test? +*/ +#define PATH_MAX (259) -/* TODO: Is this safe? I think it might just be testing the preprocessor, - * not the compiler itself... */ -#if ('\x80' < 0) -#define CHAR_MIN SCHAR_MIN -#define CHAR_MAX SCHAR_MAX -#else -#define CHAR_MIN 0 -#define CHAR_MAX UCHAR_MAX +#define CHAR_BIT 8 +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 +#define UCHAR_MAX 0xff + +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX + +#define MB_LEN_MAX 5 +#define SHRT_MIN (-32768) +#define SHRT_MAX 32767 +#define USHRT_MAX 0xffff +#define INT_MIN (-2147483647 - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 0xffffffff +#define LONG_MIN (-2147483647L - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 0xffffffffUL +#define LLONG_MAX 9223372036854775807ll +#define LLONG_MIN (-9223372036854775807ll - 1) +#define ULLONG_MAX 0xffffffffffffffffull + +#if _INTEGRAL_MAX_BITS >= 8 +#define _I8_MIN (-127 - 1) +#define _I8_MAX 127i8 +#define _UI8_MAX 0xffu #endif -/* - * Maximum and minimum values for ints. - */ -#define INT_MAX 2147483647 -#define INT_MIN (-INT_MAX-1) - -#define UINT_MAX 0xffffffff - -/* - * Maximum and minimum values for shorts. - */ -#define SHRT_MAX 32767 -#define SHRT_MIN (-SHRT_MAX-1) - -#define USHRT_MAX 0xffff - -/* - * Maximum and minimum values for longs and unsigned longs. - * - * TODO: This is not correct for Alphas, which have 64 bit longs. - */ -#define LONG_MAX 2147483647L - -#define LONG_MIN (-LONG_MAX-1) - -#define ULONG_MAX 0xffffffffUL - - -/* - * The GNU C compiler also allows 'long long int' - */ -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) - -#define LONG_LONG_MAX 9223372036854775807LL -#define LONG_LONG_MIN (-LONG_LONG_MAX-1) +#if _INTEGRAL_MAX_BITS >= 16 +#define _I16_MIN (-32767 - 1) +#define _I16_MAX 32767i16 +#define _UI16_MAX 0xffffu +#endif -#define ULONG_LONG_MAX (2ULL * LONG_LONG_MAX + 1) +#if _INTEGRAL_MAX_BITS >= 32 +#define _I32_MIN (-2147483647 - 1) +#define _I32_MAX 2147483647 +#define _UI32_MAX 0xffffffffu +#endif -/* ISO C9x macro names */ -#define LLONG_MAX LONG_LONG_MAX -#define LLONG_MIN LONG_LONG_MIN -#define ULLONG_MAX ULONG_LONG_MAX +#if defined(__GNUC__) +#undef LONG_LONG_MAX +#define LONG_LONG_MAX 9223372036854775807ll +#undef LONG_LONG_MIN +#define LONG_LONG_MIN (-LONG_LONG_MAX-1) +#undef ULONG_LONG_MAX +#define ULONG_LONG_MAX (2ull * LONG_LONG_MAX + 1ull) +#endif -#endif /* Not Strict ANSI and GNU C compiler */ +#if _INTEGRAL_MAX_BITS >= 64 +#define _I64_MIN (-9223372036854775807ll - 1) +#define _I64_MAX 9223372036854775807ll +#define _UI64_MAX 0xffffffffffffffffull +#endif +#ifndef SIZE_MAX +#ifdef _WIN64 +#define SIZE_MAX _UI64_MAX +#else +#define SIZE_MAX UINT_MAX +#endif +#endif -#endif /* not _LIMITS_H_ */ +#ifdef _POSIX_ +#define _POSIX_ARG_MAX 4096 +#define _POSIX_CHILD_MAX 6 +#define _POSIX_LINK_MAX 8 +#define _POSIX_MAX_CANON 255 +#define _POSIX_MAX_INPUT 255 +#define _POSIX_NAME_MAX 14 +#define _POSIX_NGROUPS_MAX 0 +#define _POSIX_OPEN_MAX 16 +#define _POSIX_PATH_MAX 255 +#define _POSIX_PIPE_BUF 512 +#define _POSIX_SSIZE_MAX 32767 +#define _POSIX_STREAM_MAX 8 +#define _POSIX_TZNAME_MAX 3 +#define ARG_MAX 14500 +#define LINK_MAX 1024 +#define MAX_CANON _POSIX_MAX_CANON +#define MAX_INPUT _POSIX_MAX_INPUT +#define NAME_MAX 255 +#define NGROUPS_MAX 16 +#define OPEN_MAX 32 +#define PATH_MAX 512 +#define PIPE_BUF _POSIX_PIPE_BUF +#define SSIZE_MAX _POSIX_SSIZE_MAX +#define STREAM_MAX 20 +#define TZNAME_MAX 10 +#endif +#endif diff --git a/tinyc/win32/include/locale.h b/tinyc/win32/include/locale.h index d0da14d6b..686aa9bae 100644 --- a/tinyc/win32/include/locale.h +++ b/tinyc/win32/include/locale.h @@ -1,100 +1,91 @@ -/* - * locale.h - * - * Functions and types for localization (ie. changing the appearance of - * output based on the standards of a certain country). - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_LOCALE +#define _INC_LOCALE -#ifndef _LOCALE_H_ -#define _LOCALE_H_ - -/* All the headers include this file. */ #include <_mingw.h> -/* - * NOTE: I have tried to test this, but I am limited by my knowledge of - * locale issues. The structure does not bomb if you look at the - * values, and 'decimal_point' even seems to be correct. But the - * rest of the values are, by default, not particularly useful - * (read meaningless and not related to the international settings - * of the system). - */ +#pragma pack(push,_CRT_PACKING) -#define LC_ALL 0 -#define LC_COLLATE 1 -#define LC_CTYPE 2 -#define LC_MONETARY 3 -#define LC_NUMERIC 4 -#define LC_TIME 5 -#define LC_MIN LC_ALL -#define LC_MAX LC_TIME +#ifdef __cplusplus +extern "C" { +#endif -#ifndef RC_INVOKED +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif -/* - * The structure returned by 'localeconv'. - */ -struct lconv -{ - 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 frac_digits; - char p_cs_precedes; - char p_sep_by_space; - char n_cs_precedes; - char n_sep_by_space; - char p_sign_posn; - char n_sign_posn; -}; +#define LC_ALL 0 +#define LC_COLLATE 1 +#define LC_CTYPE 2 +#define LC_MONETARY 3 +#define LC_NUMERIC 4 +#define LC_TIME 5 -#ifdef __cplusplus -extern "C" { +#define LC_MIN LC_ALL +#define LC_MAX LC_TIME + +#ifndef _LCONV_DEFINED +#define _LCONV_DEFINED + struct lconv { + 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 frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + }; #endif -char* setlocale (int, const char*); -struct lconv* localeconv (void); +#ifndef _CONFIG_LOCALE_SWT +#define _CONFIG_LOCALE_SWT -#ifndef _WLOCALE_DEFINED /* also declared in wchar.h */ -# define __need_wchar_t -# include <stddef.h> - wchar_t* _wsetlocale(int, const wchar_t*); -# define _WLOCALE_DEFINED -#endif /* ndef _WLOCALE_DEFINED */ +#define _ENABLE_PER_THREAD_LOCALE 0x1 +#define _DISABLE_PER_THREAD_LOCALE 0x2 +#define _ENABLE_PER_THREAD_LOCALE_GLOBAL 0x10 +#define _DISABLE_PER_THREAD_LOCALE_GLOBAL 0x20 +#define _ENABLE_PER_THREAD_LOCALE_NEW 0x100 +#define _DISABLE_PER_THREAD_LOCALE_NEW 0x200 -#ifdef __cplusplus -} #endif -#endif /* Not RC_INVOKED */ + int __cdecl _configthreadlocale(int _Flag); + char *__cdecl setlocale(int _Category,const char *_Locale); + _CRTIMP struct lconv *__cdecl localeconv(void); + _locale_t __cdecl _get_current_locale(void); + _locale_t __cdecl _create_locale(int _Category,const char *_Locale); + void __cdecl _free_locale(_locale_t _Locale); + _locale_t __cdecl __get_current_locale(void); + _locale_t __cdecl __create_locale(int _Category,const char *_Locale); + void __cdecl __free_locale(_locale_t _Locale); -#endif /* Not _LOCALE_H_ */ +#ifndef _WLOCALE_DEFINED +#define _WLOCALE_DEFINED + _CRTIMP wchar_t *__cdecl _wsetlocale(int _Category,const wchar_t *_Locale); +#endif +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) +#endif diff --git a/tinyc/win32/include/malloc.h b/tinyc/win32/include/malloc.h index ca4259689..fc783a8e3 100644 --- a/tinyc/win32/include/malloc.h +++ b/tinyc/win32/include/malloc.h @@ -1,87 +1,181 @@ -/* - * malloc.h - * - * Support for programs which want to use malloc.h to get memory management - * functions. Unless you absolutely need some of these functions and they are - * not in the ANSI headers you should use the ANSI standard header files - * instead. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ - -#ifndef __STRICT_ANSI__ - #ifndef _MALLOC_H_ #define _MALLOC_H_ -/* All the headers include this file. */ #include <_mingw.h> -#include <stdlib.h> +#pragma pack(push,_CRT_PACKING) -#ifndef RC_INVOKED +#ifndef _MM_MALLOC_H_INCLUDED +#define _MM_MALLOC_H_INCLUDED +#endif -/* - * The structure used to walk through the heap with _heapwalk. - */ -typedef struct _heapinfo -{ - int* _pentry; - size_t _size; - int _useflag; -} _HEAPINFO; +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN64 +#define _HEAP_MAXREQ 0xFFFFFFFFFFFFFFE0 +#else +#define _HEAP_MAXREQ 0xFFFFFFE0 +#endif + +#ifndef _STATIC_ASSERT +#define _STATIC_ASSERT(expr) extern void __static_assert_t(int [(expr)?1:-1]) +#endif + +/* Return codes for _heapwalk() */ +#define _HEAPEMPTY (-1) +#define _HEAPOK (-2) +#define _HEAPBADBEGIN (-3) +#define _HEAPBADNODE (-4) +#define _HEAPEND (-5) +#define _HEAPBADPTR (-6) /* Values for _heapinfo.useflag */ -#define _USEDENTRY 0 -#define _FREEENTRY 1 +#define _FREEENTRY 0 +#define _USEDENTRY 1 + +#ifndef _HEAPINFO_DEFINED +#define _HEAPINFO_DEFINED + /* The structure used to walk through the heap with _heapwalk. */ + typedef struct _heapinfo { + int *_pentry; + size_t _size; + int _useflag; + } _HEAPINFO; +#endif -#ifdef __cplusplus -extern "C" { + extern unsigned int _amblksiz; + +#define _mm_free(a) _aligned_free(a) +#define _mm_malloc(a,b) _aligned_malloc(a,b) + +#ifndef _CRT_ALLOCATION_DEFINED +#define _CRT_ALLOCATION_DEFINED + void *__cdecl calloc(size_t _NumOfElements,size_t _SizeOfElements); + void __cdecl free(void *_Memory); + void *__cdecl malloc(size_t _Size); + void *__cdecl realloc(void *_Memory,size_t _NewSize); + _CRTIMP void *__cdecl _recalloc(void *_Memory,size_t _Count,size_t _Size); + /* _CRTIMP void __cdecl _aligned_free(void *_Memory); + _CRTIMP void *__cdecl _aligned_malloc(size_t _Size,size_t _Alignment); */ + _CRTIMP void *__cdecl _aligned_offset_malloc(size_t _Size,size_t _Alignment,size_t _Offset); + _CRTIMP void *__cdecl _aligned_realloc(void *_Memory,size_t _Size,size_t _Alignment); + _CRTIMP void *__cdecl _aligned_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment); + _CRTIMP void *__cdecl _aligned_offset_realloc(void *_Memory,size_t _Size,size_t _Alignment,size_t _Offset); + _CRTIMP void *__cdecl _aligned_offset_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment,size_t _Offset); #endif -/* - The _heap* memory allocation functions are supported on NT - but not W9x. On latter, they always set errno to ENOSYS. -*/ -int _heapwalk (_HEAPINFO*); -#ifndef _NO_OLDNAMES -int heapwalk (_HEAPINFO*); -#endif /* Not _NO_OLDNAMES */ +#define _MAX_WAIT_MALLOC_CRT 60000 + + _CRTIMP int __cdecl _resetstkoflw (void); + _CRTIMP unsigned long __cdecl _set_malloc_crt_max_wait(unsigned long _NewValue); + + _CRTIMP void *__cdecl _expand(void *_Memory,size_t _NewSize); + _CRTIMP size_t __cdecl _msize(void *_Memory); +#ifdef __GNUC__ +#undef _alloca +#define _alloca(x) __builtin_alloca((x)) +#else + /* tcc implements alloca internally and exposes it (since commit d778bde7). + /* alloca is declared at include/stddef.h (which is distributed with tcc). + */ +#ifdef _alloca +#undef _alloca +#endif +#define _alloca(x) alloca((x)) +#endif + _CRTIMP size_t __cdecl _get_sbh_threshold(void); + _CRTIMP int __cdecl _set_sbh_threshold(size_t _NewValue); + _CRTIMP errno_t __cdecl _set_amblksiz(size_t _Value); + _CRTIMP errno_t __cdecl _get_amblksiz(size_t *_Value); + _CRTIMP int __cdecl _heapadd(void *_Memory,size_t _Size); + _CRTIMP int __cdecl _heapchk(void); + _CRTIMP int __cdecl _heapmin(void); + _CRTIMP int __cdecl _heapset(unsigned int _Fill); + _CRTIMP int __cdecl _heapwalk(_HEAPINFO *_EntryInfo); + _CRTIMP size_t __cdecl _heapused(size_t *_Used,size_t *_Commit); + _CRTIMP intptr_t __cdecl _get_heap_handle(void); + +#define _ALLOCA_S_THRESHOLD 1024 +#define _ALLOCA_S_STACK_MARKER 0xCCCC +#define _ALLOCA_S_HEAP_MARKER 0xDDDD + +#if(defined(_X86_) && !defined(__x86_64)) +#define _ALLOCA_S_MARKER_SIZE 8 +#elif defined(__ia64__) || defined(__x86_64) +#define _ALLOCA_S_MARKER_SIZE 16 +#endif -int _heapchk (void); /* Verify heap integrety. */ -int _heapmin (void); /* Return unused heap to the OS. */ -int _heapset (unsigned int); +#if !defined(RC_INVOKED) + static __inline void *_MarkAllocaS(void *_Ptr,unsigned int _Marker) { + if(_Ptr) { + *((unsigned int*)_Ptr) = _Marker; + _Ptr = (char*)_Ptr + _ALLOCA_S_MARKER_SIZE; + } + return _Ptr; + } +#endif -size_t _msize (void*); -size_t _get_sbh_threshold (void); -int _set_sbh_threshold (size_t); -void * _expand (void*, size_t); +#undef _malloca +#define _malloca(size) \ + ((((size) + _ALLOCA_S_MARKER_SIZE) <= _ALLOCA_S_THRESHOLD) ? \ + _MarkAllocaS(_alloca((size) + _ALLOCA_S_MARKER_SIZE),_ALLOCA_S_STACK_MARKER) : \ + _MarkAllocaS(malloc((size) + _ALLOCA_S_MARKER_SIZE),_ALLOCA_S_HEAP_MARKER)) +#undef _FREEA_INLINE +#define _FREEA_INLINE -#ifdef __cplusplus -} +#ifndef RC_INVOKED +#undef _freea + static __inline void __cdecl _freea(void *_Memory) { + unsigned int _Marker; + if(_Memory) { + _Memory = (char*)_Memory - _ALLOCA_S_MARKER_SIZE; + _Marker = *(unsigned int *)_Memory; + if(_Marker==_ALLOCA_S_HEAP_MARKER) { + free(_Memory); + } +#ifdef _ASSERTE + else if(_Marker!=_ALLOCA_S_STACK_MARKER) { + _ASSERTE(("Corrupted pointer passed to _freea",0)); + } +#endif + } + } +#endif /* RC_INVOKED */ + +#ifndef NO_OLDNAMES +#ifdef __GNUC__ +#undef alloca +#define alloca(x) __builtin_alloca((x)) +#endif #endif -#endif /* RC_INVOKED */ +#ifdef HEAPHOOK +#ifndef _HEAPHOOK_DEFINED +#define _HEAPHOOK_DEFINED + typedef int (__cdecl *_HEAPHOOK)(int,size_t,void *,void **); +#endif + + _CRTIMP _HEAPHOOK __cdecl _setheaphook(_HEAPHOOK _NewHook); + +#define _HEAP_MALLOC 1 +#define _HEAP_CALLOC 2 +#define _HEAP_FREE 3 +#define _HEAP_REALLOC 4 +#define _HEAP_MSIZE 5 +#define _HEAP_EXPAND 6 +#endif -#endif /* Not _MALLOC_H_ */ +#ifdef __cplusplus +} +#endif -#endif /* Not __STRICT_ANSI__ */ +#pragma pack(pop) +#endif /* _MALLOC_H_ */ diff --git a/tinyc/win32/include/math.h b/tinyc/win32/include/math.h index ffb133a2f..74add20e9 100644 --- a/tinyc/win32/include/math.h +++ b/tinyc/win32/include/math.h @@ -1,70 +1,59 @@ -/* - * math.h - * - * Mathematical functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ - #ifndef _MATH_H_ #define _MATH_H_ -/* All the headers include this file. */ -#include <_mingw.h> - -/* - * Types for the _exception structure. - */ +#if __GNUC__ >= 3 +#pragma GCC system_header +#endif -#define _DOMAIN 1 /* domain error in argument */ -#define _SING 2 /* singularity */ -#define _OVERFLOW 3 /* range overflow */ -#define _UNDERFLOW 4 /* range underflow */ -#define _TLOSS 5 /* total loss of precision */ -#define _PLOSS 6 /* partial loss of precision */ +#include <_mingw.h> -/* - * Exception types with non-ANSI names for compatibility. - */ +struct exception; -#ifndef __STRICT_ANSI__ -#ifndef _NO_OLDNAMES +#pragma pack(push,_CRT_PACKING) -#define DOMAIN _DOMAIN -#define SING _SING -#define OVERFLOW _OVERFLOW -#define UNDERFLOW _UNDERFLOW -#define TLOSS _TLOSS -#define PLOSS _PLOSS +#define _DOMAIN 1 +#define _SING 2 +#define _OVERFLOW 3 +#define _UNDERFLOW 4 +#define _TLOSS 5 +#define _PLOSS 6 -#endif /* Not _NO_OLDNAMES */ -#endif /* Not __STRICT_ANSI__ */ +#ifndef __STRICT_ANSI__ +#ifndef NO_OLDNAMES +#define DOMAIN _DOMAIN +#define SING _SING +#define OVERFLOW _OVERFLOW +#define UNDERFLOW _UNDERFLOW +#define TLOSS _TLOSS +#define PLOSS _PLOSS +#endif +#endif +#ifndef __STRICT_ANSI__ +#define M_E 2.71828182845904523536 +#define M_LOG2E 1.44269504088896340736 +#define M_LOG10E 0.434294481903251827651 +#define M_LN2 0.693147180559945309417 +#define M_LN10 2.30258509299404568402 +#define M_PI 3.14159265358979323846 +#define M_PI_2 1.57079632679489661923 +#define M_PI_4 0.785398163397448309616 +#define M_1_PI 0.318309886183790671538 +#define M_2_PI 0.636619772367581343076 +#define M_2_SQRTPI 1.12837916709551257390 +#define M_SQRT2 1.41421356237309504880 +#define M_SQRT1_2 0.707106781186547524401 +#endif -/* These are also defined in Mingw float.h; needed here as well to work - around GCC build issues. */ -#ifndef __STRICT_ANSI__ +#ifndef __STRICT_ANSI__ +/* See also float.h */ #ifndef __MINGW_FPCLASS_DEFINED #define __MINGW_FPCLASS_DEFINED 1 -/* IEEE 754 classication */ #define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ #define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ #define _FPCLASS_NINF 0x0004 /* Negative Infinity */ @@ -75,251 +64,606 @@ #define _FPCLASS_PD 0x0080 /* Positive Denormal */ #define _FPCLASS_PN 0x0100 /* Positive Normal */ #define _FPCLASS_PINF 0x0200 /* Positive Infinity */ -#endif /* __MINGW_FPCLASS_DEFINED */ -#endif /* Not __STRICT_ANSI__ */ - -#ifndef RC_INVOKED +#endif +#endif #ifdef __cplusplus extern "C" { #endif -/* - * HUGE_VAL is returned by strtod when the value would overflow the - * representation of 'double'. There are other uses as well. - * - * __imp__HUGE is a pointer to the actual variable _HUGE in - * MSVCRT.DLL. If we used _HUGE directly we would get a pointer - * to a thunk function. - * - * NOTE: The CRTDLL version uses _HUGE_dll instead. - */ - -#ifndef __DECLSPEC_SUPPORTED +#ifndef _EXCEPTION_DEFINED +#define _EXCEPTION_DEFINED + struct _exception { + int type; + char *name; + double arg1; + double arg2; + double retval; + }; +#endif -#ifdef __MSVCRT__ -extern double* __imp__HUGE; -#define HUGE_VAL (*__imp__HUGE) -#else -/* CRTDLL */ -extern double* __imp__HUGE_dll; -#define HUGE_VAL (*__imp__HUGE_dll) +#ifndef _COMPLEX_DEFINED +#define _COMPLEX_DEFINED + struct _complex { + double x,y; + }; #endif -#else /* __DECLSPEC_SUPPORTED */ +#define EDOM 33 +#define ERANGE 34 -#ifdef __MSVCRT__ -__MINGW_IMPORT double _HUGE; -#define HUGE_VAL _HUGE +#ifndef _HUGE +#ifdef _MSVCRT_ + extern double *_HUGE; #else -/* CRTDLL */ -__MINGW_IMPORT double _HUGE_dll; -#define HUGE_VAL _HUGE_dll + extern double *_imp___HUGE; +#define _HUGE (*_imp___HUGE) +#endif #endif -#endif /* __DECLSPEC_SUPPORTED */ - -struct _exception -{ - int type; - char *name; - double arg1; - double arg2; - double retval; -}; - - -double sin (double); -double cos (double); -double tan (double); -double sinh (double); -double cosh (double); -double tanh (double); -double asin (double); -double acos (double); -double atan (double); -double atan2 (double, double); -double exp (double); -double log (double); -double log10 (double); -double pow (double, double); -double sqrt (double); -double ceil (double); -double floor (double); -double fabs (double); -double ldexp (double, int); -double frexp (double, int*); -double modf (double, double*); -double fmod (double, double); - - -#ifndef __STRICT_ANSI__ - -/* Complex number (for cabs) */ -struct _complex -{ - double x; /* Real part */ - double y; /* Imaginary part */ -}; - -double _cabs (struct _complex); -double _hypot (double, double); -double _j0 (double); -double _j1 (double); -double _jn (int, double); -double _y0 (double); -double _y1 (double); -double _yn (int, double); -int _matherr (struct _exception *); - -/* These are also declared in Mingw float.h; needed here as well to work - around GCC build issues. */ -/* BEGIN FLOAT.H COPY */ -/* - * IEEE recommended functions - */ - -double _chgsign (double); -double _copysign (double, double); -double _logb (double); -double _nextafter (double, double); -double _scalb (double, long); - -int _finite (double); -int _fpclass (double); -int _isnan (double); - -/* END FLOAT.H COPY */ - -#if !defined (_NO_OLDNAMES) \ - || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L ) - -/* - * Non-underscored versions of non-ANSI functions. These reside in - * liboldnames.a. They are now also ISO C99 standand names. - * Provided for extra portability. - */ +#define HUGE_VAL _HUGE -double cabs (struct _complex); -double hypot (double, double); -double j0 (double); -double j1 (double); -double jn (int, double); -double y0 (double); -double y1 (double); -double yn (int, double); +#ifndef _CRT_ABS_DEFINED +#define _CRT_ABS_DEFINED + int __cdecl abs(int _X); + long __cdecl labs(long _X); +#endif + double __cdecl acos(double _X); + double __cdecl asin(double _X); + double __cdecl atan(double _X); + double __cdecl atan2(double _Y,double _X); +#ifndef _SIGN_DEFINED +#define _SIGN_DEFINED + _CRTIMP double __cdecl _copysign (double _Number,double _Sign); + _CRTIMP double __cdecl _chgsign (double _X); +#endif + double __cdecl cos(double _X); + double __cdecl cosh(double _X); + double __cdecl exp(double _X); + double __cdecl expm1(double _X); + double __cdecl fabs(double _X); + double __cdecl fmod(double _X,double _Y); + double __cdecl log(double _X); + double __cdecl log10(double _X); + double __cdecl pow(double _X,double _Y); + double __cdecl sin(double _X); + double __cdecl sinh(double _X); + double __cdecl tan(double _X); + double __cdecl tanh(double _X); + double __cdecl sqrt(double _X); +#ifndef _CRT_ATOF_DEFINED +#define _CRT_ATOF_DEFINED + double __cdecl atof(const char *_String); + double __cdecl _atof_l(const char *_String,_locale_t _Locale); +#endif -#endif /* Not _NO_OLDNAMES */ + _CRTIMP double __cdecl _cabs(struct _complex _ComplexA); + double __cdecl ceil(double _X); + double __cdecl floor(double _X); + double __cdecl frexp(double _X,int *_Y); + double __cdecl _hypot(double _X,double _Y); + _CRTIMP double __cdecl _j0(double _X); + _CRTIMP double __cdecl _j1(double _X); + _CRTIMP double __cdecl _jn(int _X,double _Y); + double __cdecl ldexp(double _X,int _Y); +#ifndef _CRT_MATHERR_DEFINED +#define _CRT_MATHERR_DEFINED + int __cdecl _matherr(struct _exception *_Except); +#endif + double __cdecl modf(double _X,double *_Y); + _CRTIMP double __cdecl _y0(double _X); + _CRTIMP double __cdecl _y1(double _X); + _CRTIMP double __cdecl _yn(int _X,double _Y); + +#if(defined(_X86_) && !defined(__x86_64)) + _CRTIMP int __cdecl _set_SSE2_enable(int _Flag); + /* from libmingwex */ + float __cdecl _hypotf(float _X,float _Y); +#endif -#endif /* Not __STRICT_ANSI__ */ + float frexpf(float _X,int *_Y); + float __cdecl ldexpf(float _X,int _Y); + long double __cdecl ldexpl(long double _X,int _Y); + float __cdecl acosf(float _X); + float __cdecl asinf(float _X); + float __cdecl atanf(float _X); + float __cdecl atan2f(float _X,float _Y); + float __cdecl cosf(float _X); + float __cdecl sinf(float _X); + float __cdecl tanf(float _X); + float __cdecl coshf(float _X); + float __cdecl sinhf(float _X); + float __cdecl tanhf(float _X); + float __cdecl expf(float _X); + float __cdecl expm1f(float _X); + float __cdecl logf(float _X); + float __cdecl log10f(float _X); + float __cdecl modff(float _X,float *_Y); + float __cdecl powf(float _X,float _Y); + float __cdecl sqrtf(float _X); + float __cdecl ceilf(float _X); + float __cdecl floorf(float _X); + float __cdecl fmodf(float _X,float _Y); + float __cdecl _hypotf(float _X,float _Y); + float __cdecl fabsf(float _X); +#if !defined(__ia64__) + /* from libmingwex */ + float __cdecl _copysignf (float _Number,float _Sign); + float __cdecl _chgsignf (float _X); + float __cdecl _logbf(float _X); + float __cdecl _nextafterf(float _X,float _Y); + int __cdecl _finitef(float _X); + int __cdecl _isnanf(float _X); + int __cdecl _fpclassf(float _X); +#endif -#ifdef __cplusplus -} +#ifndef __cplusplus + __CRT_INLINE long double __cdecl fabsl (long double x) + { + long double res; + __asm__ ("fabs;" : "=t" (res) : "0" (x)); + return res; + } +#define _hypotl(x,y) ((long double)_hypot((double)(x),(double)(y))) +#define _matherrl _matherr + __CRT_INLINE long double _chgsignl(long double _Number) { return _chgsign((double)(_Number)); } + __CRT_INLINE long double _copysignl(long double _Number,long double _Sign) { return _copysign((double)(_Number),(double)(_Sign)); } + __CRT_INLINE float frexpf(float _X,int *_Y) { return ((float)frexp((double)_X,_Y)); } + +#if !defined (__ia64__) + __CRT_INLINE float __cdecl fabsf (float x) + { + float res; + __asm__ ("fabs;" : "=t" (res) : "0" (x)); + return res; + } + + __CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); } +#endif +#else + // cplusplus + __CRT_INLINE long double __cdecl fabsl (long double x) + { + long double res; + __asm__ ("fabs;" : "=t" (res) : "0" (x)); + return res; + } + __CRT_INLINE long double modfl(long double _X,long double *_Y) { + double _Di,_Df = modf((double)_X,&_Di); + *_Y = (long double)_Di; + return (_Df); + } + __CRT_INLINE long double _chgsignl(long double _Number) { return _chgsign(static_cast<double>(_Number)); } + __CRT_INLINE long double _copysignl(long double _Number,long double _Sign) { return _copysign(static_cast<double>(_Number),static_cast<double>(_Sign)); } + __CRT_INLINE float frexpf(float _X,int *_Y) { return ((float)frexp((double)_X,_Y)); } +#ifndef __ia64__ + __CRT_INLINE float __cdecl fabsf (float x) + { + float res; + __asm__ ("fabs;" : "=t" (res) : "0" (x)); + return res; + } + __CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); } +#ifndef __x86_64 + __CRT_INLINE float acosf(float _X) { return ((float)acos((double)_X)); } + __CRT_INLINE float asinf(float _X) { return ((float)asin((double)_X)); } + __CRT_INLINE float atanf(float _X) { return ((float)atan((double)_X)); } + __CRT_INLINE float atan2f(float _X,float _Y) { return ((float)atan2((double)_X,(double)_Y)); } + __CRT_INLINE float ceilf(float _X) { return ((float)ceil((double)_X)); } + __CRT_INLINE float cosf(float _X) { return ((float)cos((double)_X)); } + __CRT_INLINE float coshf(float _X) { return ((float)cosh((double)_X)); } + __CRT_INLINE float expf(float _X) { return ((float)exp((double)_X)); } + __CRT_INLINE float floorf(float _X) { return ((float)floor((double)_X)); } + __CRT_INLINE float fmodf(float _X,float _Y) { return ((float)fmod((double)_X,(double)_Y)); } + __CRT_INLINE float logf(float _X) { return ((float)log((double)_X)); } + __CRT_INLINE float log10f(float _X) { return ((float)log10((double)_X)); } + __CRT_INLINE float modff(float _X,float *_Y) { + double _Di,_Df = modf((double)_X,&_Di); + *_Y = (float)_Di; + return ((float)_Df); + } + __CRT_INLINE float powf(float _X,float _Y) { return ((float)pow((double)_X,(double)_Y)); } + __CRT_INLINE float sinf(float _X) { return ((float)sin((double)_X)); } + __CRT_INLINE float sinhf(float _X) { return ((float)sinh((double)_X)); } + __CRT_INLINE float sqrtf(float _X) { return ((float)sqrt((double)_X)); } + __CRT_INLINE float tanf(float _X) { return ((float)tan((double)_X)); } + __CRT_INLINE float tanhf(float _X) { return ((float)tanh((double)_X)); } +#endif +#endif #endif -#endif /* Not RC_INVOKED */ +#ifndef NO_OLDNAMES +#define matherr _matherr + +#define HUGE _HUGE + /* double __cdecl cabs(struct _complex _X); */ + double __cdecl hypot(double _X,double _Y); + _CRTIMP double __cdecl j0(double _X); + _CRTIMP double __cdecl j1(double _X); + _CRTIMP double __cdecl jn(int _X,double _Y); + _CRTIMP double __cdecl y0(double _X); + _CRTIMP double __cdecl y1(double _X); + _CRTIMP double __cdecl yn(int _X,double _Y); +#endif #ifndef __NO_ISOCEXT +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \ + || !defined __STRICT_ANSI__ || defined __GLIBCPP__ -#define INFINITY HUGE_VAL #define NAN (0.0F/0.0F) +#define HUGE_VALF (1.0F/0.0F) +#define HUGE_VALL (1.0L/0.0L) +#define INFINITY (1.0F/0.0F) + -/* - Return values for fpclassify. - These are based on Intel x87 fpu condition codes - in the high byte of status word and differ from - the return values for MS IEEE 754 extension _fpclass() -*/ #define FP_NAN 0x0100 #define FP_NORMAL 0x0400 #define FP_INFINITE (FP_NAN | FP_NORMAL) #define FP_ZERO 0x4000 #define FP_SUBNORMAL (FP_NORMAL | FP_ZERO) -/* 0x0200 is signbit mask */ - -#ifndef RC_INVOKED -#ifdef __cplusplus -extern "C" { -#endif + /* 0x0200 is signbit mask */ -double nan(const char *tagp); -float nanf(const char *tagp); -#ifndef __STRICT_ANSI__ -#define nan() nan("") -#define nanf() nanf("") -#endif - - -/* - We can't inline float, because we want to ensure truncation - to semantic type before classification. If we extend to long - double, we will also need to make double extern only. + /* + We can't __CRT_INLINE float or double, because we want to ensure truncation + to semantic type before classification. (A normal long double value might become subnormal when converted to double, and zero when converted to float.) -*/ -extern __inline__ int __fpclassify (double x){ - unsigned short sw; - __asm__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x)); - return sw & (FP_NAN | FP_NORMAL | FP_ZERO ); -} - -extern int __fpclassifyf (float); + */ -#define fpclassify(x) ((sizeof(x) == sizeof(float)) ? __fpclassifyf(x) \ - : __fpclassify(x)) + extern int __cdecl __fpclassifyf (float); + extern int __cdecl __fpclassify (double); + extern int __cdecl __fpclassifyl (long double); -/* We don't need to worry about trucation here: - A NaN stays a NaN. */ +/* Implemented at tcc/tcc_libm.h */ +#define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x) \ + : sizeof (x) == sizeof (double) ? __fpclassify (x) \ + : __fpclassifyl (x)) -extern __inline__ int __isnan (double _x) -{ - unsigned short sw; - __asm__ ("fxam;" - "fstsw %%ax": "=a" (sw) : "t" (_x)); - return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL)) - == FP_NAN; -} - -extern __inline__ int __isnanf (float _x) -{ - unsigned short sw; - __asm__ ("fxam;" - "fstsw %%ax": "=a" (sw) : "t" (_x)); - return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL)) - == FP_NAN; -} + /* 7.12.3.2 */ +#define isfinite(x) ((fpclassify(x) & FP_NAN) == 0) -#define isnan(x) ((sizeof(x) == sizeof(float)) ? __isnanf(x) \ - : __isnan(x)) + /* 7.12.3.3 */ +#define isinf(x) (fpclassify(x) == FP_INFINITE) + /* 7.12.3.4 */ + /* We don't need to worry about truncation here: + A NaN stays a NaN. */ +#define isnan(x) (fpclassify(x) == FP_NAN) -#define isfinite(x) ((fpclassify(x) & FP_NAN) == 0) -#define isinf(x) (fpclassify(x) == FP_INFINITE) + /* 7.12.3.5 */ #define isnormal(x) (fpclassify(x) == FP_NORMAL) + /* 7.12.3.6 The signbit macro */ + + extern int __cdecl __signbitf (float); + extern int __cdecl __signbit (double); + extern int __cdecl __signbitl (long double); + +/* Implemented at tcc/tcc_libm.h */ +#define signbit(x) (sizeof (x) == sizeof (float) ? __signbitf (x) \ + : sizeof (x) == sizeof (double) ? __signbit (x) \ + : __signbitl (x)) + + extern double __cdecl exp2(double); + extern float __cdecl exp2f(float); + extern long double __cdecl exp2l(long double); + +#define FP_ILOGB0 ((int)0x80000000) +#define FP_ILOGBNAN ((int)0x80000000) + extern int __cdecl ilogb (double); + extern int __cdecl ilogbf (float); + extern int __cdecl ilogbl (long double); + + extern double __cdecl log1p(double); + extern float __cdecl log1pf(float); + extern long double __cdecl log1pl(long double); + + extern double __cdecl log2 (double); + extern float __cdecl log2f (float); + extern long double __cdecl log2l (long double); + + extern double __cdecl logb (double); + extern float __cdecl logbf (float); + extern long double __cdecl logbl (long double); + + __CRT_INLINE double __cdecl logb (double x) + { + double res; + __asm__ ("fxtract\n\t" + "fstp %%st" : "=t" (res) : "0" (x)); + return res; + } + + __CRT_INLINE float __cdecl logbf (float x) + { + float res; + __asm__ ("fxtract\n\t" + "fstp %%st" : "=t" (res) : "0" (x)); + return res; + } + + __CRT_INLINE long double __cdecl logbl (long double x) + { + long double res; + __asm__ ("fxtract\n\t" + "fstp %%st" : "=t" (res) : "0" (x)); + return res; + } + + extern long double __cdecl modfl (long double, long double*); + + /* 7.12.6.13 */ + extern double __cdecl scalbn (double, int); + extern float __cdecl scalbnf (float, int); + extern long double __cdecl scalbnl (long double, int); + + extern double __cdecl scalbln (double, long); + extern float __cdecl scalblnf (float, long); + extern long double __cdecl scalblnl (long double, long); + + /* 7.12.7.1 */ + /* Implementations adapted from Cephes versions */ + extern double __cdecl cbrt (double); + extern float __cdecl cbrtf (float); + extern long double __cdecl cbrtl (long double); + + __CRT_INLINE float __cdecl hypotf (float x, float y) + { return (float) hypot (x, y);} + extern long double __cdecl hypotl (long double, long double); + + extern long double __cdecl powl (long double, long double); + extern long double __cdecl expl(long double); + extern long double __cdecl expm1l(long double); + extern long double __cdecl coshl(long double); + extern long double __cdecl fabsl (long double); + extern long double __cdecl acosl(long double); + extern long double __cdecl asinl(long double); + extern long double __cdecl atanl(long double); + extern long double __cdecl atan2l(long double,long double); + extern long double __cdecl sinhl(long double); + extern long double __cdecl tanhl(long double); + + /* 7.12.8.1 The erf functions */ + extern double __cdecl erf (double); + extern float __cdecl erff (float); + /* TODO + extern long double __cdecl erfl (long double); + */ + + /* 7.12.8.2 The erfc functions */ + extern double __cdecl erfc (double); + extern float __cdecl erfcf (float); + /* TODO + extern long double __cdecl erfcl (long double); + */ + + /* 7.12.8.3 The lgamma functions */ + extern double __cdecl lgamma (double); + extern float __cdecl lgammaf (float); + extern long double __cdecl lgammal (long double); + + /* 7.12.8.4 The tgamma functions */ + extern double __cdecl tgamma (double); + extern float __cdecl tgammaf (float); + extern long double __cdecl tgammal (long double); + + extern long double __cdecl ceill (long double); + extern long double __cdecl floorl (long double); + extern long double __cdecl frexpl(long double,int *); + extern long double __cdecl log10l(long double); + extern long double __cdecl logl(long double); + extern long double __cdecl cosl(long double); + extern long double __cdecl sinl(long double); + extern long double __cdecl tanl(long double); + extern long double sqrtl(long double); + + /* 7.12.9.3 */ + extern double __cdecl nearbyint ( double); + extern float __cdecl nearbyintf (float); + extern long double __cdecl nearbyintl (long double); + + /* 7.12.9.4 */ + /* round, using fpu control word settings */ + __CRT_INLINE double __cdecl rint (double x) + { + double retval; + __asm__ ( + "fldl %1\n" + "frndint \n" + "fstl %0\n" : "=m" (retval) : "m" (x)); + return retval; + } + + __CRT_INLINE float __cdecl rintf (float x) + { + float retval; + __asm__ ( + "flds %1\n" + "frndint \n" + "fsts %0\n" : "=m" (retval) : "m" (x)); + return retval; + } + + __CRT_INLINE long double __cdecl rintl (long double x) + { + long double retval; + __asm__ ( + "fldt %1\n" + "frndint \n" + "fstt %0\n" : "=m" (retval) : "m" (x)); + return retval; + } + + /* 7.12.9.5 */ + __CRT_INLINE long __cdecl lrint (double x) + { + long retval; + __asm__ __volatile__ \ + ("fldl %1\n" \ + "fistpl %0" : "=m" (retval) : "m" (x)); \ + return retval; + } + + __CRT_INLINE long __cdecl lrintf (float x) + { + long retval; + __asm__ __volatile__ \ + ("flds %1\n" \ + "fistpl %0" : "=m" (retval) : "m" (x)); \ + return retval; + } + + __CRT_INLINE long __cdecl lrintl (long double x) + { + long retval; + __asm__ __volatile__ \ + ("fldt %1\n" \ + "fistpl %0" : "=m" (retval) : "m" (x)); \ + return retval; + } + + __CRT_INLINE long long __cdecl llrint (double x) + { + long long retval; + __asm__ __volatile__ \ + ("fldl %1\n" \ + "fistpll %0" : "=m" (retval) : "m" (x)); \ + return retval; + } + + __CRT_INLINE long long __cdecl llrintf (float x) + { + long long retval; + __asm__ __volatile__ \ + ("flds %1\n" \ + "fistpll %0" : "=m" (retval) : "m" (x)); \ + return retval; + } + + __CRT_INLINE long long __cdecl llrintl (long double x) + { + long long retval; + __asm__ __volatile__ \ + ("fldt %1\n" \ + "fistpll %0" : "=m" (retval) : "m" (x)); \ + return retval; + } + + #define FE_TONEAREST 0x0000 + #define FE_DOWNWARD 0x0400 + #define FE_UPWARD 0x0800 + #define FE_TOWARDZERO 0x0c00 + + __CRT_INLINE double trunc (double _x) + { + double retval; + unsigned short saved_cw; + unsigned short tmp_cw; + __asm__ ("fnstcw %0;" : "=m" (saved_cw)); /* save FPU control word */ + tmp_cw = (saved_cw & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)) + | FE_TOWARDZERO; + __asm__ ("fldcw %0;" : : "m" (tmp_cw)); + __asm__ ("fldl %1;" + "frndint;" + "fstl %0;" : "=m" (retval) : "m" (_x)); /* round towards zero */ + __asm__ ("fldcw %0;" : : "m" (saved_cw) ); /* restore saved control word */ + return retval; + } + + /* 7.12.9.6 */ + /* round away from zero, regardless of fpu control word settings */ + extern double __cdecl round (double); + extern float __cdecl roundf (float); + extern long double __cdecl roundl (long double); + + /* 7.12.9.7 */ + extern long __cdecl lround (double); + extern long __cdecl lroundf (float); + extern long __cdecl lroundl (long double); + + extern long long __cdecl llround (double); + extern long long __cdecl llroundf (float); + extern long long __cdecl llroundl (long double); + + /* 7.12.9.8 */ + /* round towards zero, regardless of fpu control word settings */ + extern double __cdecl trunc (double); + extern float __cdecl truncf (float); + extern long double __cdecl truncl (long double); + + extern long double __cdecl fmodl (long double, long double); + + /* 7.12.10.2 */ + extern double __cdecl remainder (double, double); + extern float __cdecl remainderf (float, float); + extern long double __cdecl remainderl (long double, long double); + + /* 7.12.10.3 */ + extern double __cdecl remquo(double, double, int *); + extern float __cdecl remquof(float, float, int *); + extern long double __cdecl remquol(long double, long double, int *); + + /* 7.12.11.1 */ + extern double __cdecl copysign (double, double); /* in libmoldname.a */ + extern float __cdecl copysignf (float, float); + extern long double __cdecl copysignl (long double, long double); + + /* 7.12.11.2 Return a NaN */ + extern double __cdecl nan(const char *tagp); + extern float __cdecl nanf(const char *tagp); + extern long double __cdecl nanl(const char *tagp); -extern __inline__ int __signbit (double x) { - unsigned short stw; - __asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x)); - return stw & 0x0200; -} - -extern __inline__ int __signbitf (float x) { - unsigned short stw; - __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x)); - return stw & 0x0200; -} +#ifndef __STRICT_ANSI__ +#define _nan() nan("") +#define _nanf() nanf("") +#define _nanl() nanl("") +#endif -#define signbit(x) ((sizeof(x) == sizeof(float)) ? __signbitf(x) \ - : __signbit(x)) -/* - * With these functions, comparisons involving quiet NaNs set the FP - * condition code to "unordered". The IEEE floating-point spec - * dictates that the result of floating-point comparisons should be - * false whenever a NaN is involved, with the exception of the !=, - * which always returns true. - */ + /* 7.12.11.3 */ + extern double __cdecl nextafter (double, double); /* in libmoldname.a */ + extern float __cdecl nextafterf (float, float); + extern long double __cdecl nextafterl (long double, long double); + + /* 7.12.11.4 The nexttoward functions: TODO */ + + /* 7.12.12.1 */ + /* x > y ? (x - y) : 0.0 */ + extern double __cdecl fdim (double x, double y); + extern float __cdecl fdimf (float x, float y); + extern long double __cdecl fdiml (long double x, long double y); + + /* fmax and fmin. + NaN arguments are treated as missing data: if one argument is a NaN + and the other numeric, then these functions choose the numeric + value. */ + + /* 7.12.12.2 */ + extern double __cdecl fmax (double, double); + extern float __cdecl fmaxf (float, float); + extern long double __cdecl fmaxl (long double, long double); + + /* 7.12.12.3 */ + extern double __cdecl fmin (double, double); + extern float __cdecl fminf (float, float); + extern long double __cdecl fminl (long double, long double); + + /* 7.12.13.1 */ + /* return x * y + z as a ternary op */ + extern double __cdecl fma (double, double, double); + extern float __cdecl fmaf (float, float, float); + extern long double __cdecl fmal (long double, long double, long double); + + +#if 0 // gr: duplicate, see below + /* 7.12.14 */ + /* + * With these functions, comparisons involving quiet NaNs set the FP + * condition code to "unordered". The IEEE floating-point spec + * dictates that the result of floating-point comparisons should be + * false whenever a NaN is involved, with the exception of the != op, + * which always returns true: yes, (NaN != NaN) is true). + */ #if __GNUC__ >= 3 @@ -331,108 +675,63 @@ extern __inline__ int __signbitf (float x) { #define isunordered(x, y) __builtin_isunordered(x, y) #else -/* helper */ -extern __inline__ int __fp_unordered_compare (double x, double y){ - unsigned short retval; - __asm__ ("fucom %%st(1);" - "fnstsw;": "=a" (retval) : "t" (x), "u" (y)); - return retval; -} + /* helper */ + __CRT_INLINE int __cdecl + __fp_unordered_compare (long double x, long double y){ + unsigned short retval; + __asm__ ("fucom %%st(1);" + "fnstsw;": "=a" (retval) : "t" (x), "u" (y)); + return retval; + } #define isgreater(x, y) ((__fp_unordered_compare(x, y) \ - & 0x4500) == 0) + & 0x4500) == 0) #define isless(x, y) ((__fp_unordered_compare (y, x) \ - & 0x4500) == 0) + & 0x4500) == 0) #define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) \ - & FP_INFINITE) == 0) + & FP_INFINITE) == 0) #define islessequal(x, y) ((__fp_unordered_compare(y, x) \ - & FP_INFINITE) == 0) + & FP_INFINITE) == 0) #define islessgreater(x, y) ((__fp_unordered_compare(x, y) \ - & FP_SUBNORMAL) == 0) + & FP_SUBNORMAL) == 0) #define isunordered(x, y) ((__fp_unordered_compare(x, y) \ - & 0x4500) == 0x4500) + & 0x4500) == 0x4500) #endif +#endif //0 -/* round, using fpu control word settings */ -extern __inline__ double rint (double x) -{ - double retval; - __asm__ ("frndint;": "=t" (retval) : "0" (x)); - return retval; -} - -extern __inline__ float rintf (float x) -{ - float retval; - __asm__ ("frndint;" : "=t" (retval) : "0" (x) ); - return retval; -} -/* round away from zero, regardless of fpu control word settings */ -extern double round (double); -extern float roundf (float); - -/* round towards zero, regardless of fpu control word settings */ -extern double trunc (double); -extern float truncf (float); - - -/* fmax and fmin. - NaN arguments are treated as missing data: if one argument is a NaN and the other numeric, then the - these functions choose the numeric value. -*/ - -extern double fmax (double, double); -extern double fmin (double, double); -extern float fmaxf (float, float); -float fminf (float, float); - -/* return x * y + z as a ternary op */ -extern double fma (double, double, double); -extern float fmaf (float, float, float); - -/* one lonely transcendental */ -extern double log2 (double _x); -extern float log2f (float _x); - -/* The underscored versions are in MSVCRT.dll. - The stubs for these are in libmingwex.a */ - -double copysign (double, double); -float copysignf (float, float); -double logb (double); -float logbf (float); -double nextafter (double, double); -float nextafterf (float, float); -double scalb (double, long); -float scalbf (float, long); - -#if !defined (__STRICT_ANSI__) /* inline using non-ANSI functions */ -extern __inline__ double copysign (double x, double y) - { return _copysign(x, y); } -extern __inline__ float copysignf (float x, float y) - { return _copysign(x, y); } -extern __inline__ double logb (double x) - { return _logb(x); } -extern __inline__ float logbf (float x) - { return _logb(x); } -extern __inline__ double nextafter(double x, double y) - { return _nextafter(x, y); } -extern __inline__ float nextafterf(float x, float y) - { return _nextafter(x, y); } -extern __inline__ double scalb (double x, long i) - { return _scalb (x, i); } -extern __inline__ float scalbf (float x, long i) - { return _scalb(x, i); } -#endif /* (__STRICT_ANSI__) */ +#endif /* __STDC_VERSION__ >= 199901L */ +#endif /* __NO_ISOCEXT */ #ifdef __cplusplus } +extern "C++" { + template<class _Ty> inline _Ty _Pow_int(_Ty _X,int _Y) { + unsigned int _N; + if(_Y >= 0) _N = (unsigned int)_Y; + else _N = (unsigned int)(-_Y); + for(_Ty _Z = _Ty(1);;_X *= _X) { + if((_N & 1)!=0) _Z *= _X; + if((_N >>= 1)==0) return (_Y < 0 ? _Ty(1) / _Z : _Z); + } + } +} #endif -#endif /* Not RC_INVOKED */ -#endif /* __NO_ISOCEXT */ +#pragma pack(pop) + +/* 7.12.14 */ +/* + * With these functions, comparisons involving quiet NaNs set the FP + * condition code to "unordered". The IEEE floating-point spec + * dictates that the result of floating-point comparisons should be + * false whenever a NaN is involved, with the exception of the != op, + * which always returns true: yes, (NaN != NaN) is true). + */ + +/* Mini libm (inline __fpclassify*, __signbit* and variants) */ +#include "tcc/tcc_libm.h" -#endif /* Not _MATH_H_ */ +#endif /* End _MATH_H_ */ diff --git a/tinyc/win32/include/mem.h b/tinyc/win32/include/mem.h index 20c8fa4a5..255202359 100644 --- a/tinyc/win32/include/mem.h +++ b/tinyc/win32/include/mem.h @@ -1,3 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ /* * This file is part of the Mingw32 package. * diff --git a/tinyc/win32/include/memory.h b/tinyc/win32/include/memory.h index e0c91d635..90d88aedd 100644 --- a/tinyc/win32/include/memory.h +++ b/tinyc/win32/include/memory.h @@ -1,9 +1,40 @@ -/* - * This file is part of the Mingw32 package. - * - * memory.h maps to the standard string.h header. +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ -#ifndef __STRICT_ANSI__ -#include <string.h> +#ifndef _INC_MEMORY +#define _INC_MEMORY + +#include <_mingw.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _CONST_RETURN +#define _CONST_RETURN #endif +#define _WConst_return _CONST_RETURN + +#ifndef _CRT_MEMORY_DEFINED +#define _CRT_MEMORY_DEFINED + _CRTIMP void *__cdecl _memccpy(void *_Dst,const void *_Src,int _Val,size_t _MaxCount); + _CONST_RETURN void *__cdecl memchr(const void *_Buf ,int _Val,size_t _MaxCount); + _CRTIMP int __cdecl _memicmp(const void *_Buf1,const void *_Buf2,size_t _Size); + _CRTIMP int __cdecl _memicmp_l(const void *_Buf1,const void *_Buf2,size_t _Size,_locale_t _Locale); + int __cdecl memcmp(const void *_Buf1,const void *_Buf2,size_t _Size); + void *__cdecl memcpy(void *_Dst,const void *_Src,size_t _Size); + void *__cdecl memset(void *_Dst,int _Val,size_t _Size); + +#ifndef NO_OLDNAMES + void *__cdecl memccpy(void *_Dst,const void *_Src,int _Val,size_t _Size); + int __cdecl memicmp(const void *_Buf1,const void *_Buf2,size_t _Size); +#endif +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tinyc/win32/include/process.h b/tinyc/win32/include/process.h index 3d764df0f..dadaf2b7d 100644 --- a/tinyc/win32/include/process.h +++ b/tinyc/win32/include/process.h @@ -1,158 +1,176 @@ -/* - * process.h - * - * Function calls for spawning child processes. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_PROCESS +#define _INC_PROCESS -#ifndef __STRICT_ANSI__ - -#ifndef _PROCESS_H_ -#define _PROCESS_H_ - -/* All the headers include this file. */ #include <_mingw.h> /* Includes a definition of _pid_t and pid_t */ #include <sys/types.h> -/* - * Constants for cwait actions. - * Obsolete for Win32. - */ -#define _WAIT_CHILD 0 -#define _WAIT_GRANDCHILD 1 - -#ifndef _NO_OLDNAMES -#define WAIT_CHILD _WAIT_CHILD -#define WAIT_GRANDCHILD _WAIT_GRANDCHILD -#endif /* Not _NO_OLDNAMES */ - -/* - * Mode constants for spawn functions. - */ -#define _P_WAIT 0 -#define _P_NOWAIT 1 -#define _P_OVERLAY 2 -#define _OLD_P_OVERLAY _P_OVERLAY -#define _P_NOWAITO 3 -#define _P_DETACH 4 - -#ifndef _NO_OLDNAMES -#define P_WAIT _P_WAIT -#define P_NOWAIT _P_NOWAIT -#define P_OVERLAY _P_OVERLAY -#define OLD_P_OVERLAY _OLD_P_OVERLAY -#define P_NOWAITO _P_NOWAITO -#define P_DETACH _P_DETACH -#endif /* Not _NO_OLDNAMES */ - - -#ifndef RC_INVOKED - -#ifdef __cplusplus +#ifndef _POSIX_ +#ifdef __cplusplus extern "C" { #endif -void _cexit(void); -void _c_exit(void); - -int _cwait (int*, _pid_t, int); - -_pid_t _getpid(void); - -int _execl (const char*, const char*, ...); -int _execle (const char*, const char*, ...); -int _execlp (const char*, const char*, ...); -int _execlpe (const char*, const char*, ...); -int _execv (const char*, char* const*); -int _execve (const char*, char* const*, char* const*); -int _execvp (const char*, char* const*); -int _execvpe (const char*, char* const*, char* const*); - -int _spawnl (int, const char*, const char*, ...); -int _spawnle (int, const char*, const char*, ...); -int _spawnlp (int, const char*, const char*, ...); -int _spawnlpe (int, const char*, const char*, ...); -int _spawnv (int, const char*, char* const*); -int _spawnve (int, const char*, char* const*, char* const*); -int _spawnvp (int, const char*, char* const*); -int _spawnvpe (int, const char*, char* const*, char* const*); - -/* - * The functions _beginthreadex and _endthreadex are not provided by CRTDLL. - * They are provided by MSVCRT. - * - * NOTE: Apparently _endthread calls CloseHandle on the handle of the thread, - * making for race conditions if you are not careful. Basically you have to - * make sure that no-one is going to do *anything* with the thread handle - * after the thread calls _endthread or returns from the thread function. - * - * NOTE: No old names for these functions. Use the underscore. - */ -unsigned long - _beginthread (void (*)(void *), unsigned, void*); -void _endthread (void); - -#ifdef __MSVCRT__ -unsigned long - _beginthreadex (void *, unsigned, unsigned (__stdcall *) (void *), - void*, unsigned, unsigned*); -void _endthreadex (unsigned); -#endif +#define _P_WAIT 0 +#define _P_NOWAIT 1 +#define _OLD_P_OVERLAY 2 +#define _P_NOWAITO 3 +#define _P_DETACH 4 +#define _P_OVERLAY 2 +#define _WAIT_CHILD 0 +#define _WAIT_GRANDCHILD 1 + + _CRTIMP uintptr_t __cdecl _beginthread(void (__cdecl *_StartAddress) (void *),unsigned _StackSize,void *_ArgList); + _CRTIMP void __cdecl _endthread(void); + _CRTIMP uintptr_t __cdecl _beginthreadex(void *_Security,unsigned _StackSize,unsigned (__stdcall *_StartAddress) (void *),void *_ArgList,unsigned _InitFlag,unsigned *_ThrdAddr); + _CRTIMP void __cdecl _endthreadex(unsigned _Retval); + +#ifndef _CRT_TERMINATE_DEFINED +#define _CRT_TERMINATE_DEFINED + void __cdecl __MINGW_NOTHROW exit(int _Code) __MINGW_ATTRIB_NORETURN; + _CRTIMP void __cdecl __MINGW_NOTHROW _exit(int _Code) __MINGW_ATTRIB_NORETURN; + +#pragma push_macro("abort") +#undef abort + void __cdecl __declspec(noreturn) abort(void); +#pragma pop_macro("abort") -#ifndef _NO_OLDNAMES -/* - * Functions without the leading underscore, for portability. These functions - * live in liboldnames.a. - */ -int cwait (int*, pid_t, int); -pid_t getpid (void); -int execl (const char*, const char*, ...); -int execle (const char*, const char*, ...); -int execlp (const char*, const char*, ...); -int execlpe (const char*, const char*, ...); -int execv (const char*, char* const*); -int execve (const char*, char* const*, char* const*); -int execvp (const char*, char* const*); -int execvpe (const char*, char* const*, char* const*); -int spawnl (int, const char*, const char*, ...); -int spawnle (int, const char*, const char*, ...); -int spawnlp (int, const char*, const char*, ...); -int spawnlpe (int, const char*, const char*, ...); -int spawnv (int, const char*, char* const*); -int spawnve (int, const char*, char* const*, char* const*); -int spawnvp (int, const char*, char* const*); -int spawnvpe (int, const char*, char* const*, char* const*); -#endif /* Not _NO_OLDNAMES */ - -#ifdef __cplusplus -} #endif -#endif /* Not RC_INVOKED */ + _CRTIMP void __cdecl __MINGW_NOTHROW _cexit(void); + _CRTIMP void __cdecl __MINGW_NOTHROW _c_exit(void); + _CRTIMP int __cdecl _getpid(void); + _CRTIMP intptr_t __cdecl _cwait(int *_TermStat,intptr_t _ProcHandle,int _Action); + _CRTIMP intptr_t __cdecl _execl(const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl _execle(const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl _execlp(const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl _execlpe(const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl _execv(const char *_Filename,const char *const *_ArgList); + _CRTIMP intptr_t __cdecl _execve(const char *_Filename,const char *const *_ArgList,const char *const *_Env); + _CRTIMP intptr_t __cdecl _execvp(const char *_Filename,const char *const *_ArgList); + _CRTIMP intptr_t __cdecl _execvpe(const char *_Filename,const char *const *_ArgList,const char *const *_Env); + _CRTIMP intptr_t __cdecl _spawnl(int _Mode,const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl _spawnle(int _Mode,const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl _spawnlp(int _Mode,const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl _spawnlpe(int _Mode,const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl _spawnv(int _Mode,const char *_Filename,const char *const *_ArgList); + _CRTIMP intptr_t __cdecl _spawnve(int _Mode,const char *_Filename,const char *const *_ArgList,const char *const *_Env); + _CRTIMP intptr_t __cdecl _spawnvp(int _Mode,const char *_Filename,const char *const *_ArgList); + _CRTIMP intptr_t __cdecl _spawnvpe(int _Mode,const char *_Filename,const char *const *_ArgList,const char *const *_Env); + +#ifndef _CRT_SYSTEM_DEFINED +#define _CRT_SYSTEM_DEFINED + int __cdecl system(const char *_Command); +#endif -#endif /* _PROCESS_H_ not defined */ +#ifndef _WPROCESS_DEFINED +#define _WPROCESS_DEFINED + _CRTIMP intptr_t __cdecl _wexecl(const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wexecle(const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wexeclp(const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wexeclpe(const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wexecv(const wchar_t *_Filename,const wchar_t *const *_ArgList); + _CRTIMP intptr_t __cdecl _wexecve(const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env); + _CRTIMP intptr_t __cdecl _wexecvp(const wchar_t *_Filename,const wchar_t *const *_ArgList); + _CRTIMP intptr_t __cdecl _wexecvpe(const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env); + _CRTIMP intptr_t __cdecl _wspawnl(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wspawnle(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wspawnlp(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wspawnlpe(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wspawnv(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList); + _CRTIMP intptr_t __cdecl _wspawnve(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env); + _CRTIMP intptr_t __cdecl _wspawnvp(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList); + _CRTIMP intptr_t __cdecl _wspawnvpe(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env); +#ifndef _CRT_WSYSTEM_DEFINED +#define _CRT_WSYSTEM_DEFINED + _CRTIMP int __cdecl _wsystem(const wchar_t *_Command); +#endif +#endif -#endif /* Not __STRICT_ANSI__ */ + void __cdecl __security_init_cookie(void); +#if (defined(_X86_) && !defined(__x86_64)) + void __fastcall __security_check_cookie(uintptr_t _StackCookie); + __declspec(noreturn) void __cdecl __report_gsfailure(void); +#else + void __cdecl __security_check_cookie(uintptr_t _StackCookie); + __declspec(noreturn) void __cdecl __report_gsfailure(uintptr_t _StackCookie); +#endif + extern uintptr_t __security_cookie; + + intptr_t __cdecl _loaddll(char *_Filename); + int __cdecl _unloaddll(intptr_t _Handle); + int (__cdecl *__cdecl _getdllprocaddr(intptr_t _Handle,char *_ProcedureName,intptr_t _Ordinal))(void); + +#ifdef _DECL_DLLMAIN +#ifdef _WINDOWS_ + WINBOOL WINAPI DllMain(HANDLE _HDllHandle,DWORD _Reason,LPVOID _Reserved); + WINBOOL WINAPI _CRT_INIT(HANDLE _HDllHandle,DWORD _Reason,LPVOID _Reserved); + WINBOOL WINAPI _wCRT_INIT(HANDLE _HDllHandle,DWORD _Reason,LPVOID _Reserved); + extern WINBOOL (WINAPI *const _pRawDllMain)(HANDLE,DWORD,LPVOID); +#else + int __stdcall DllMain(void *_HDllHandle,unsigned _Reason,void *_Reserved); + int __stdcall _CRT_INIT(void *_HDllHandle,unsigned _Reason,void *_Reserved); + int __stdcall _wCRT_INIT(void *_HDllHandle,unsigned _Reason,void *_Reserved); + extern int (__stdcall *const _pRawDllMain)(void *,unsigned,void *); +#endif +#endif +#ifndef NO_OLDNAMES +#define P_WAIT _P_WAIT +#define P_NOWAIT _P_NOWAIT +#define P_OVERLAY _P_OVERLAY +#define OLD_P_OVERLAY _OLD_P_OVERLAY +#define P_NOWAITO _P_NOWAITO +#define P_DETACH _P_DETACH +#define WAIT_CHILD _WAIT_CHILD +#define WAIT_GRANDCHILD _WAIT_GRANDCHILD + + intptr_t __cdecl cwait(int *_TermStat,intptr_t _ProcHandle,int _Action); +#ifdef __GNUC__ + int __cdecl execl(const char *_Filename,const char *_ArgList,...); + int __cdecl execle(const char *_Filename,const char *_ArgList,...); + int __cdecl execlp(const char *_Filename,const char *_ArgList,...); + int __cdecl execlpe(const char *_Filename,const char *_ArgList,...); +#else + intptr_t __cdecl execl(const char *_Filename,const char *_ArgList,...); + intptr_t __cdecl execle(const char *_Filename,const char *_ArgList,...); + intptr_t __cdecl execlp(const char *_Filename,const char *_ArgList,...); + intptr_t __cdecl execlpe(const char *_Filename,const char *_ArgList,...); +#endif + intptr_t __cdecl spawnl(int,const char *_Filename,const char *_ArgList,...); + intptr_t __cdecl spawnle(int,const char *_Filename,const char *_ArgList,...); + intptr_t __cdecl spawnlp(int,const char *_Filename,const char *_ArgList,...); + intptr_t __cdecl spawnlpe(int,const char *_Filename,const char *_ArgList,...); + int __cdecl getpid(void); +#ifdef __GNUC__ + /* Those methods are predefined by gcc builtins to return int. So to prevent + stupid warnings, define them in POSIX way. This is save, because those + methods do not return in success case, so that the return value is not + really dependent to its scalar width. */ + int __cdecl execv(const char *_Filename,const char *const _ArgList[]); + int __cdecl execve(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); + int __cdecl execvp(const char *_Filename,const char *const _ArgList[]); + int __cdecl execvpe(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); +#else + intptr_t __cdecl execv(const char *_Filename,const char *const _ArgList[]); + intptr_t __cdecl execve(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); + intptr_t __cdecl execvp(const char *_Filename,const char *const _ArgList[]); + intptr_t __cdecl execvpe(const char *_Filename,const char *const _ArgList[],const char *const _Env[]); +#endif + intptr_t __cdecl spawnv(int,const char *_Filename,const char *const _ArgList[]); + intptr_t __cdecl spawnve(int,const char *_Filename,const char *const _ArgList[],const char *const _Env[]); + intptr_t __cdecl spawnvp(int,const char *_Filename,const char *const _ArgList[]); + intptr_t __cdecl spawnvpe(int,const char *_Filename,const char *const _ArgList[],char *const _Env[]); +#endif + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/tinyc/win32/include/sec_api/conio_s.h b/tinyc/win32/include/sec_api/conio_s.h new file mode 100644 index 000000000..98d97ba2e --- /dev/null +++ b/tinyc/win32/include/sec_api/conio_s.h @@ -0,0 +1,42 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ + +#ifndef _INC_CONIO_S +#define _INC_CONIO_S + +#include <conio.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + + _CRTIMP errno_t __cdecl _cgets_s(char *_Buffer,size_t _Size,size_t *_SizeRead); + _CRTIMP int __cdecl _cprintf_s(const char *_Format,...); + _CRTIMP int __cdecl _cscanf_s(const char *_Format,...); + _CRTIMP int __cdecl _cscanf_s_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcprintf_s(const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _cprintf_s_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcprintf_s_l(const char *_Format,_locale_t _Locale,va_list _ArgList); + +#ifndef _WCONIO_DEFINED_S +#define _WCONIO_DEFINED_S + _CRTIMP errno_t __cdecl _cgetws_s(wchar_t *_Buffer,size_t _SizeInWords,size_t *_SizeRead); + _CRTIMP int __cdecl _cwprintf_s(const wchar_t *_Format,...); + _CRTIMP int __cdecl _cwscanf_s(const wchar_t *_Format,...); + _CRTIMP int __cdecl _cwscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf_s(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _cwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); +#endif + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/tinyc/win32/include/sec_api/crtdbg_s.h b/tinyc/win32/include/sec_api/crtdbg_s.h new file mode 100644 index 000000000..4598b4f7c --- /dev/null +++ b/tinyc/win32/include/sec_api/crtdbg_s.h @@ -0,0 +1,19 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ + +#ifndef _INC_CRTDBG_S +#define _INC_CRTDBG_S + +#include <crtdbg.h> + +#if defined(MINGW_HAS_SECURE_API) + +#define _dupenv_s_dbg(ps1,size,s2,t,f,l) _dupenv_s(ps1,size,s2) +#define _wdupenv_s_dbg(ps1,size,s2,t,f,l) _wdupenv_s(ps1,size,s2) + +#endif + +#endif diff --git a/tinyc/win32/include/sec_api/io_s.h b/tinyc/win32/include/sec_api/io_s.h new file mode 100644 index 000000000..ec565a617 --- /dev/null +++ b/tinyc/win32/include/sec_api/io_s.h @@ -0,0 +1,33 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_IO_S +#define _INC_IO_S + +#include <io.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + + _CRTIMP errno_t __cdecl _access_s(const char *_Filename,int _AccessMode); + _CRTIMP errno_t __cdecl _chsize_s(int _FileHandle,__int64 _Size); + _CRTIMP errno_t __cdecl _mktemp_s(char *_TemplateName,size_t _Size); + _CRTIMP errno_t __cdecl _umask_s(int _NewMode,int *_OldMode); + +#ifndef _WIO_S_DEFINED +#define _WIO_S_DEFINED + _CRTIMP errno_t __cdecl _waccess_s(const wchar_t *_Filename,int _AccessMode); + _CRTIMP errno_t __cdecl _wmktemp_s(wchar_t *_TemplateName,size_t _SizeInWords); +#endif + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/tinyc/win32/include/sec_api/mbstring_s.h b/tinyc/win32/include/sec_api/mbstring_s.h new file mode 100644 index 000000000..6b2b188f8 --- /dev/null +++ b/tinyc/win32/include/sec_api/mbstring_s.h @@ -0,0 +1,52 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_MBSTRING_S +#define _INC_MBSTRING_S + +#include <mbstring.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _MBSTRING_S_DEFINED +#define _MBSTRING_S_DEFINED + _CRTIMP errno_t __cdecl _mbscat_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src); + _CRTIMP errno_t __cdecl _mbscat_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbscpy_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src); + _CRTIMP errno_t __cdecl _mbscpy_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbslwr_s(unsigned char *_Str,size_t _SizeInBytes); + _CRTIMP errno_t __cdecl _mbslwr_s_l(unsigned char *_Str,size_t _SizeInBytes,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbsnbcat_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount); + _CRTIMP errno_t __cdecl _mbsnbcat_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbsnbcpy_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount); + _CRTIMP errno_t __cdecl _mbsnbcpy_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbsnbset_s(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Ch,size_t _MaxCount); + _CRTIMP errno_t __cdecl _mbsnbset_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Ch,size_t _MaxCount,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbsncat_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount); + _CRTIMP errno_t __cdecl _mbsncat_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbsncpy_s(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount); + _CRTIMP errno_t __cdecl _mbsncpy_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,const unsigned char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbsnset_s(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Val,size_t _MaxCount); + _CRTIMP errno_t __cdecl _mbsnset_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Val,size_t _MaxCount,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbsset_s(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Val); + _CRTIMP errno_t __cdecl _mbsset_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,unsigned int _Val,_locale_t _Locale); + _CRTIMP unsigned char *__cdecl _mbstok_s(unsigned char *_Str,const unsigned char *_Delim,unsigned char **_Context); + _CRTIMP unsigned char *__cdecl _mbstok_s_l(unsigned char *_Str,const unsigned char *_Delim,unsigned char **_Context,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbsupr_s(unsigned char *_Str,size_t _SizeInBytes); + _CRTIMP errno_t __cdecl _mbsupr_s_l(unsigned char *_Str,size_t _SizeInBytes,_locale_t _Locale); + _CRTIMP errno_t __cdecl _mbccpy_s(unsigned char *_Dst,size_t _DstSizeInBytes,int *_PCopied,const unsigned char *_Src); + _CRTIMP errno_t __cdecl _mbccpy_s_l(unsigned char *_Dst,size_t _DstSizeInBytes,int *_PCopied,const unsigned char *_Src,_locale_t _Locale); +#endif + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/tinyc/win32/include/sec_api/search_s.h b/tinyc/win32/include/sec_api/search_s.h new file mode 100644 index 000000000..cae899898 --- /dev/null +++ b/tinyc/win32/include/sec_api/search_s.h @@ -0,0 +1,25 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_SEARCH_S +#define _INC_SEARCH_S + +#include <search.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + + _CRTIMP void *__cdecl _lfind_s(const void *_Key,const void *_Base,unsigned int *_NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(void *,const void *,const void *),void *_Context); + _CRTIMP void *__cdecl _lsearch_s(const void *_Key,void *_Base,unsigned int *_NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(void *,const void *,const void *),void *_Context); + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/tinyc/win32/include/sec_api/stdio_s.h b/tinyc/win32/include/sec_api/stdio_s.h new file mode 100644 index 000000000..c9b803b12 --- /dev/null +++ b/tinyc/win32/include/sec_api/stdio_s.h @@ -0,0 +1,145 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_STDIO_S +#define _INC_STDIO_S + +#include <stdio.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _STDIO_S_DEFINED +#define _STDIO_S_DEFINED + _CRTIMP errno_t __cdecl clearerr_s(FILE *_File); + int __cdecl fprintf_s(FILE *_File,const char *_Format,...); + size_t __cdecl fread_s(void *_DstBuf,size_t _DstSize,size_t _ElementSize,size_t _Count,FILE *_File); + _CRTIMP int __cdecl _fscanf_s_l(FILE *_File,const char *_Format,_locale_t _Locale,...); + int __cdecl printf_s(const char *_Format,...); + _CRTIMP int __cdecl _scanf_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _scanf_s_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _snprintf_s(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,...); + _CRTIMP int __cdecl _snprintf_c(char *_DstBuf,size_t _MaxCount,const char *_Format,...); + _CRTIMP int __cdecl _vsnprintf_c(char *_DstBuf,size_t _MaxCount,const char *_Format,va_list _ArgList); + int __cdecl sprintf_s(char *_DstBuf,size_t _DstSize,const char *_Format,...); + _CRTIMP int __cdecl _fscanf_l(FILE *_File,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _sscanf_l(const char *_Src,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _sscanf_s_l(const char *_Src,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _snscanf_s(const char *_Src,size_t _MaxCount,const char *_Format,...); + _CRTIMP int __cdecl _snscanf_l(const char *_Src,size_t _MaxCount,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _snscanf_s_l(const char *_Src,size_t _MaxCount,const char *_Format,_locale_t _Locale,...); + int __cdecl vfprintf_s(FILE *_File,const char *_Format,va_list _ArgList); + int __cdecl vprintf_s(const char *_Format,va_list _ArgList); + int __cdecl vsnprintf_s(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _vsnprintf_s(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,va_list _ArgList); + int __cdecl vsprintf_s(char *_DstBuf,size_t _Size,const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _fprintf_p(FILE *_File,const char *_Format,...); + _CRTIMP int __cdecl _printf_p(const char *_Format,...); + _CRTIMP int __cdecl _sprintf_p(char *_Dst,size_t _MaxCount,const char *_Format,...); + _CRTIMP int __cdecl _vfprintf_p(FILE *_File,const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _vprintf_p(const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _vsprintf_p(char *_Dst,size_t _MaxCount,const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _scprintf_p(const char *_Format,...); + _CRTIMP int __cdecl _vscprintf_p(const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _printf_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _printf_p_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vprintf_l(const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vprintf_p_l(const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fprintf_l(FILE *_File,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _fprintf_p_l(FILE *_File,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vfprintf_l(FILE *_File,const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vfprintf_p_l(FILE *_File,const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _sprintf_l(char *_DstBuf,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _sprintf_p_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vsprintf_l(char *_DstBuf,const char *_Format,_locale_t,va_list _ArgList); + _CRTIMP int __cdecl _vsprintf_p_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _scprintf_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _scprintf_p_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vscprintf_l(const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vscprintf_p_l(const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _printf_s_l(const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vprintf_s_l(const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fprintf_s_l(FILE *_File,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vfprintf_s_l(FILE *_File,const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _sprintf_s_l(char *_DstBuf,size_t _DstSize,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vsprintf_s_l(char *_DstBuf,size_t _DstSize,const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _snprintf_s_l(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vsnprintf_s_l(char *_DstBuf,size_t _DstSize,size_t _MaxCount,const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _snprintf_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _snprintf_c_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vsnprintf_l(char *_DstBuf,size_t _MaxCount,const char *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vsnprintf_c_l(char *_DstBuf,size_t _MaxCount,const char *,_locale_t _Locale,va_list _ArgList); + +#ifndef _WSTDIO_S_DEFINED +#define _WSTDIO_S_DEFINED + _CRTIMP wchar_t *__cdecl _getws_s(wchar_t *_Str,size_t _SizeInWords); + int __cdecl fwprintf_s(FILE *_File,const wchar_t *_Format,...); + int __cdecl wprintf_s(const wchar_t *_Format,...); + int __cdecl vwprintf_s(const wchar_t *_Format,va_list _ArgList); + int __cdecl swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...); + int __cdecl vswprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _snwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vsnwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _wprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vfwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _swprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vswprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _snwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vsnwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fwscanf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _swscanf_s_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _snwscanf_s(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...); + _CRTIMP int __cdecl _snwscanf_s_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _wscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP errno_t __cdecl _wfopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode); + _CRTIMP errno_t __cdecl _wfreopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile); + _CRTIMP errno_t __cdecl _wtmpnam_s(wchar_t *_DstBuf,size_t _SizeInWords); + _CRTIMP int __cdecl _fwprintf_p(FILE *_File,const wchar_t *_Format,...); + _CRTIMP int __cdecl _wprintf_p(const wchar_t *_Format,...); + _CRTIMP int __cdecl _vfwprintf_p(FILE *_File,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _vwprintf_p(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _swprintf_p(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vswprintf_p(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _scwprintf_p(const wchar_t *_Format,...); + _CRTIMP int __cdecl _vscwprintf_p(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _wprintf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _wprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fwprintf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _fwprintf_p_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vfwprintf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vfwprintf_p_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _swprintf_c_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _swprintf_p_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vswprintf_c_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vswprintf_p_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _scwprintf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _scwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vscwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _snwprintf_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vsnwprintf_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl __swprintf_l(wchar_t *_Dest,const wchar_t *_Format,_locale_t _Plocinfo,...); + _CRTIMP int __cdecl __vswprintf_l(wchar_t *_Dest,const wchar_t *_Format,_locale_t _Plocinfo,va_list _Args); + _CRTIMP int __cdecl _vscwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fwscanf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _swscanf_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _snwscanf_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _wscanf_l(const wchar_t *_Format,_locale_t _Locale,...); +#endif +#endif + + _CRTIMP size_t __cdecl _fread_nolock_s(void *_DstBuf,size_t _DstSize,size_t _ElementSize,size_t _Count,FILE *_File); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/tinyc/win32/include/sec_api/stdlib_s.h b/tinyc/win32/include/sec_api/stdlib_s.h new file mode 100644 index 000000000..f98262ccc --- /dev/null +++ b/tinyc/win32/include/sec_api/stdlib_s.h @@ -0,0 +1,67 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_STDLIB_S +#define _INC_STDLIB_S + +#include <stdlib.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + + _CRTIMP errno_t __cdecl _dupenv_s(char **_PBuffer,size_t *_PBufferSizeInBytes,const char *_VarName); + _CRTIMP errno_t __cdecl _itoa_s(int _Value,char *_DstBuf,size_t _Size,int _Radix); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP errno_t __cdecl _i64toa_s(__int64 _Val,char *_DstBuf,size_t _Size,int _Radix); + _CRTIMP errno_t __cdecl _ui64toa_s(unsigned __int64 _Val,char *_DstBuf,size_t _Size,int _Radix); +#endif + _CRTIMP errno_t __cdecl _ltoa_s(long _Val,char *_DstBuf,size_t _Size,int _Radix); + _CRTIMP errno_t __cdecl mbstowcs_s(size_t *_PtNumOfCharConverted,wchar_t *_DstBuf,size_t _SizeInWords,const char *_SrcBuf,size_t _MaxCount); + _CRTIMP errno_t __cdecl _mbstowcs_s_l(size_t *_PtNumOfCharConverted,wchar_t *_DstBuf,size_t _SizeInWords,const char *_SrcBuf,size_t _MaxCount,_locale_t _Locale); + _CRTIMP errno_t __cdecl _ultoa_s(unsigned long _Val,char *_DstBuf,size_t _Size,int _Radix); + _CRTIMP errno_t __cdecl _wctomb_s_l(int *_SizeConverted,char *_MbCh,size_t _SizeInBytes,wchar_t _WCh,_locale_t _Locale); + _CRTIMP errno_t __cdecl wcstombs_s(size_t *_PtNumOfCharConverted,char *_Dst,size_t _DstSizeInBytes,const wchar_t *_Src,size_t _MaxCountInBytes); + _CRTIMP errno_t __cdecl _wcstombs_s_l(size_t *_PtNumOfCharConverted,char *_Dst,size_t _DstSizeInBytes,const wchar_t *_Src,size_t _MaxCountInBytes,_locale_t _Locale); + +#ifndef _WSTDLIB_S_DEFINED +#define _WSTDLIB_S_DEFINED + _CRTIMP errno_t __cdecl _itow_s (int _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); + _CRTIMP errno_t __cdecl _ltow_s (long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); + _CRTIMP errno_t __cdecl _ultow_s (unsigned long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); + _CRTIMP errno_t __cdecl _wgetenv_s(size_t *_ReturnSize,wchar_t *_DstBuf,size_t _DstSizeInWords,const wchar_t *_VarName); + _CRTIMP errno_t __cdecl _wdupenv_s(wchar_t **_Buffer,size_t *_BufferSizeInWords,const wchar_t *_VarName); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP errno_t __cdecl _i64tow_s(__int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); + _CRTIMP errno_t __cdecl _ui64tow_s(unsigned __int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); +#endif +#endif + +#ifndef _POSIX_ + _CRTIMP errno_t __cdecl _ecvt_s(char *_DstBuf,size_t _Size,double _Val,int _NumOfDights,int *_PtDec,int *_PtSign); + _CRTIMP errno_t __cdecl _fcvt_s(char *_DstBuf,size_t _Size,double _Val,int _NumOfDec,int *_PtDec,int *_PtSign); + _CRTIMP errno_t __cdecl _gcvt_s(char *_DstBuf,size_t _Size,double _Val,int _NumOfDigits); + _CRTIMP errno_t __cdecl _makepath_s(char *_PathResult,size_t _Size,const char *_Drive,const char *_Dir,const char *_Filename,const char *_Ext); + _CRTIMP errno_t __cdecl _putenv_s(const char *_Name,const char *_Value); + _CRTIMP errno_t __cdecl _searchenv_s(const char *_Filename,const char *_EnvVar,char *_ResultPath,size_t _SizeInBytes); + _CRTIMP errno_t __cdecl _splitpath_s(const char *_FullPath,char *_Drive,size_t _DriveSize,char *_Dir,size_t _DirSize,char *_Filename,size_t _FilenameSize,char *_Ext,size_t _ExtSize); + +#ifndef _WSTDLIBP_S_DEFINED +#define _WSTDLIBP_S_DEFINED + _CRTIMP errno_t __cdecl _wmakepath_s(wchar_t *_PathResult,size_t _SizeInWords,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext); + _CRTIMP errno_t __cdecl _wputenv_s(const wchar_t *_Name,const wchar_t *_Value); + _CRTIMP errno_t __cdecl _wsearchenv_s(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath,size_t _SizeInWords); + _CRTIMP errno_t __cdecl _wsplitpath_s(const wchar_t *_FullPath,wchar_t *_Drive,size_t _DriveSizeInWords,wchar_t *_Dir,size_t _DirSizeInWords,wchar_t *_Filename,size_t _FilenameSizeInWords,wchar_t *_Ext,size_t _ExtSizeInWords); +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/tinyc/win32/include/sec_api/stralign_s.h b/tinyc/win32/include/sec_api/stralign_s.h new file mode 100644 index 000000000..5b78f5860 --- /dev/null +++ b/tinyc/win32/include/sec_api/stralign_s.h @@ -0,0 +1,30 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef __STRALIGN_H_S_ +#define __STRALIGN_H_S_ + +#include <stralign.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(I_X86_) && defined(_WSTRING_S_DEFINED) +#if defined(__cplusplus) && defined(_WConst_Return) + static __inline PUWSTR ua_wcscpy_s(PUWSTR Destination,size_t DestinationSize,PCUWSTR Source) { + if(WSTR_ALIGNED(Source) && WSTR_ALIGNED(Destination)) return (wcscpy_s((PWSTR)Destination,DestinationSize,(PCWSTR)Source)==0 ? Destination : NULL); + return uaw_wcscpy((PCUWSTR)String,Character); + } +#endif +#endif + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/tinyc/win32/include/sec_api/string_s.h b/tinyc/win32/include/sec_api/string_s.h new file mode 100644 index 000000000..9db70e77d --- /dev/null +++ b/tinyc/win32/include/sec_api/string_s.h @@ -0,0 +1,41 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_STRING_S +#define _INC_STRING_S + +#include <string.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + + _CRTIMP errno_t __cdecl _strset_s(char *_Dst,size_t _DstSize,int _Value); + _CRTIMP errno_t __cdecl _strerror_s(char *_Buf,size_t _SizeInBytes,const char *_ErrMsg); + _CRTIMP errno_t __cdecl _strlwr_s(char *_Str,size_t _Size); + _CRTIMP errno_t __cdecl _strlwr_s_l(char *_Str,size_t _Size,_locale_t _Locale); + _CRTIMP errno_t __cdecl _strnset_s(char *_Str,size_t _Size,int _Val,size_t _MaxCount); + _CRTIMP errno_t __cdecl _strupr_s(char *_Str,size_t _Size); + _CRTIMP errno_t __cdecl _strupr_s_l(char *_Str,size_t _Size,_locale_t _Locale); +#ifndef _WSTRING_S_DEFINED +#define _WSTRING_S_DEFINED + _CRTIMP wchar_t *__cdecl wcstok_s(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context); + _CRTIMP errno_t __cdecl _wcserror_s(wchar_t *_Buf,size_t _SizeInWords,int _ErrNum); + _CRTIMP errno_t __cdecl __wcserror_s(wchar_t *_Buffer,size_t _SizeInWords,const wchar_t *_ErrMsg); + _CRTIMP errno_t __cdecl _wcsnset_s(wchar_t *_Dst,size_t _DstSizeInWords,wchar_t _Val,size_t _MaxCount); + _CRTIMP errno_t __cdecl _wcsset_s(wchar_t *_Str,size_t _SizeInWords,wchar_t _Val); + _CRTIMP errno_t __cdecl _wcslwr_s(wchar_t *_Str,size_t _SizeInWords); + _CRTIMP errno_t __cdecl _wcslwr_s_l(wchar_t *_Str,size_t _SizeInWords,_locale_t _Locale); + _CRTIMP errno_t __cdecl _wcsupr_s(wchar_t *_Str,size_t _Size); + _CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale); +#endif + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/tinyc/win32/include/sec_api/sys/timeb_s.h b/tinyc/win32/include/sec_api/sys/timeb_s.h new file mode 100644 index 000000000..af5ef098f --- /dev/null +++ b/tinyc/win32/include/sec_api/sys/timeb_s.h @@ -0,0 +1,34 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ + +#ifndef _TIMEB_H_S +#define _TIMEB_H_S + +#include <sys/timeb.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef _USE_32BIT_TIME_T +#define _ftime_s _ftime32_s +#else +#define _ftime_s _ftime64_s +#endif + + _CRTIMP errno_t __cdecl _ftime32_s(struct __timeb32 *_Time); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP errno_t __cdecl _ftime64_s(struct __timeb64 *_Time); +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tinyc/win32/include/sec_api/tchar_s.h b/tinyc/win32/include/sec_api/tchar_s.h new file mode 100644 index 000000000..343d348eb --- /dev/null +++ b/tinyc/win32/include/sec_api/tchar_s.h @@ -0,0 +1,266 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_TCHAR_S +#define _INC_TCHAR_S + +#include <tchar.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _UNICODE + +#define _tprintf_s wprintf_s +#define _tprintf_s_l _wprintf_s_l +#define _tcprintf_s _cwprintf_s +#define _tcprintf_s_l _cwprintf_s_l +#define _vtcprintf_s _vcwprintf_s +#define _vtcprintf_s_l _vcwprintf_s_l +#define _ftprintf_s fwprintf_s +#define _ftprintf_s_l _fwprintf_s_l +#define _stprintf_s swprintf_s +#define _stprintf_s_l _swprintf_s_l +#define _sntprintf_s _snwprintf_s +#define _sntprintf_s_l _snwprintf_s_l +#define _vtprintf_s vwprintf_s +#define _vtprintf_s_l _vwprintf_s_l +#define _vftprintf_s vfwprintf_s +#define _vftprintf_s_l _vfwprintf_s_l +#define _vstprintf_s vswprintf_s +#define _vstprintf_s_l _vswprintf_s_l +#define _vsntprintf_s _vsnwprintf_s +#define _vsntprintf_s_l _vsnwprintf_s_l + +#define _tscanf_s wscanf_s +#define _tscanf_s_l _wscanf_s_l +#define _tcscanf_s _cwscanf_s +#define _tcscanf_s_l _cwscanf_s_l +#define _ftscanf_s fwscanf_s +#define _ftscanf_s_l _fwscanf_s_l +#define _stscanf_s swscanf_s +#define _stscanf_s_l _swscanf_s_l +#define _sntscanf_s _snwscanf_s +#define _sntscanf_s_l _snwscanf_s_l + +#define _cgetts_s _cgetws_s +#define _getts_s _getws_s + +#define _itot_s _itow_s +#define _ltot_s _ltow_s +#define _ultot_s _ultow_s +#define _i64tot_s _i64tow_s +#define _ui64tot_s _ui64tow_s + +#define _tcscat_s wcscat_s +#define _tcscpy_s wcscpy_s +#define _tcsncat_s wcsncat_s +#define _tcsncat_s_l _wcsncat_s_l +#define _tcsncpy_s wcsncpy_s +#define _tcsncpy_s_l _wcsncpy_s_l +#define _tcstok_s wcstok_s +#define _tcstok_s_l _wcstok_s_l +#define _tcserror_s _wcserror_s +#define __tcserror_s __wcserror_s + +#define _tcsnset_s _wcsnset_s +#define _tcsnset_s_l _wcsnset_s_l +#define _tcsset_s _wcsset_s +#define _tcsset_s_l _wcsset_s_l + +#define _tasctime_s _wasctime_s +#define _tctime_s _wctime_s +#define _tctime32_s _wctime32_s +#define _tctime64_s _wctime64_s +#define _tstrdate_s _wstrdate_s +#define _tstrtime_s _wstrtime_s + +#define _tgetenv_s _wgetenv_s +#define _tdupenv_s _wdupenv_s +#define _tmakepath_s _wmakepath_s +#define _tputenv_s _wputenv_s +#define _tsearchenv_s _wsearchenv_s +#define _tsplitpath_s _wsplitpath_s + +#define _tfopen_s _wfopen_s +#define _tfreopen_s _wfreopen_s +#define _ttmpnam_s _wtmpnam_s +#define _taccess_s _waccess_s +#define _tmktemp_s _wmktemp_s + +#define _tcsnccat_s wcsncat_s +#define _tcsnccat_s_l _wcsncat_s_l +#define _tcsnccpy_s wcsncpy_s +#define _tcsnccpy_s_l _wcsncpy_s_l + +#define _tcslwr_s _wcslwr_s +#define _tcslwr_s_l _wcslwr_s_l +#define _tcsupr_s _wcsupr_s +#define _tcsupr_s_l _wcsupr_s_l + +#define _wcstok_s_l(_String,_Delimiters,_Current_position,_Locale) (wcstok_s(_String,_Delimiters,_Current_position)) +#define _wcsnset_s_l(_Destination,_Destination_size_chars,_Value,_Count,_Locale) (_wcsnset_s(_Destination,_Destination_size_chars,_Value,_Count)) +#define _wcsset_s_l(_Destination,_Destination_size_chars,_Value,_Locale) (_wcsset_s(_Destination,_Destination_size_chars,_Value)) + +#else + +#define _tprintf_s printf_s +#define _tprintf_s_l _printf_s_l +#define _tcprintf_s _cprintf_s +#define _tcprintf_s_l _cprintf_s_l +#define _vtcprintf_s _vcprintf_s +#define _vtcprintf_s_l _vcprintf_s_l +#define _ftprintf_s fprintf_s +#define _ftprintf_s_l _fprintf_s_l +#define _stprintf_s sprintf_s +#define _stprintf_s_l _sprintf_s_l +#define _sntprintf_s _snprintf_s +#define _sntprintf_s_l _snprintf_s_l +#define _vtprintf_s vprintf_s +#define _vtprintf_s_l _vprintf_s_l +#define _vftprintf_s vfprintf_s +#define _vftprintf_s_l _vfprintf_s_l +#define _vstprintf_s vsprintf_s +#define _vstprintf_s_l _vsprintf_s_l +#define _vsntprintf_s _vsnprintf_s +#define _vsntprintf_s_l _vsnprintf_s_l +#define _tscanf_s scanf_s +#define _tscanf_s_l _scanf_s_l +#define _tcscanf_s _cscanf_s +#define _tcscanf_s_l _cscanf_s_l +#define _ftscanf_s fscanf_s +#define _ftscanf_s_l _fscanf_s_l +#define _stscanf_s sscanf_s +#define _stscanf_s_l _sscanf_s_l +#define _sntscanf_s _snscanf_s +#define _sntscanf_s_l _snscanf_s_l + +#define _getts_s gets_s +#define _cgetts_s _cgets_s +#define _itot_s _itoa_s +#define _ltot_s _ltoa_s +#define _ultot_s _ultoa_s +#define _i64tot_s _i64toa_s +#define _ui64tot_s _ui64toa_s + +#define _tcscat_s strcat_s +#define _tcscpy_s strcpy_s +#define _tcserror_s strerror_s +#define __tcserror_s _strerror_s + +#define _tasctime_s asctime_s +#define _tctime_s ctime_s +#define _tctime32_s _ctime32_s +#define _tctime64_s _ctime64_s +#define _tstrdate_s _strdate_s +#define _tstrtime_s _strtime_s + +#define _tgetenv_s getenv_s +#define _tdupenv_s _dupenv_s +#define _tmakepath_s _makepath_s +#define _tputenv_s _putenv_s +#define _tsearchenv_s _searchenv_s +#define _tsplitpath_s _splitpath_s + +#define _tfopen_s fopen_s +#define _tfreopen_s freopen_s +#define _ttmpnam_s tmpnam_s +#define _tmktemp_s _mktemp_s + +#ifndef _POSIX_ +#define _taccess_s _access_s +#endif + +#define _tsopen_s _sopen_s + +#ifdef _MBCS + +#ifdef _MB_MAP_DIRECT + +#define _tcsncat_s _mbsnbcat_s +#define _tcsncat_s_l _mbsnbcat_s_l +#define _tcsncpy_s _mbsnbcpy_s +#define _tcsncpy_s_l _mbsnbcpy_s_l +#define _tcstok_s _mbstok_s +#define _tcstok_s_l _mbstok_s_l + +#define _tcsnset_s _mbsnbset_s +#define _tcsnset_s_l _mbsnbset_s_l +#define _tcsset_s _mbsset_s +#define _tcsset_s_l _mbsset_s_l + +#define _tcsnccat_s _mbsncat_s +#define _tcsnccat_s_l _mbsncat_s_l +#define _tcsnccpy_s _mbsncpy_s +#define _tcsnccpy_s_l _mbsncpy_s_l +#define _tcsncset_s _mbsnset_s +#define _tcsncset_s_l _mbsnset_s_l + +#define _tcslwr_s _mbslwr_s +#define _tcslwr_s_l _mbslwr_s_l +#define _tcsupr_s _mbsupr_s +#define _tcsupr_s_l _mbsupr_s_l + +#define _tccpy_s _mbccpy_s +#define _tccpy_s_l _mbccpy_s_l +#else + + _CRTIMP char *__cdecl _tcsncat_s(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsncat_s_l(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsncpy_s(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsncpy_s_l(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP char *__cdecl _tcstok_s(char *_Str,const char *_Delim,char **_Context); + _CRTIMP char *__cdecl _tcstok_s_l(char *_Str,const char *_Delim,char **_Context,_locale_t _Locale); + _CRTIMP errno_t __cdecl _tcsset_s(char *_Str,size_t _SizeInChars,unsigned int _Val); + _CRTIMP errno_t __cdecl _tcsset_s_l(char *_Str,size_t _SizeInChars,unsigned int,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsnccat_s(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsnccat_s_l(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsnccpy_s(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsnccpy_s_l(char *_Dst,size_t _DstSizeInChars,const char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP char *__cdecl _tcslwr_s(char *_Str,size_t _SizeInChars); + _CRTIMP char *__cdecl _tcslwr_s_l(char *_Str,size_t _SizeInChars,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsupr_s(char *_Str,size_t _SizeInChars); + _CRTIMP char *__cdecl _tcsupr_s_l(char *_Str,size_t _SizeInChars,_locale_t _Locale); + +#endif + +#else + +#define _tcsncat_s strncat_s +#define _tcsncat_s_l _strncat_s_l +#define _tcsncpy_s strncpy_s +#define _tcsncpy_s_l _strncpy_s_l +#define _tcstok_s strtok_s +#define _tcstok_s_l _strtok_s_l + +#define _tcsnset_s _strnset_s +#define _tcsnset_s_l _strnset_s_l +#define _tcsset_s _strset_s +#define _tcsset_s _strset_s +#define _tcsset_s_l _strset_s_l + +#define _tcsnccat_s strncat_s +#define _tcsnccat_s_l _strncat_s_l +#define _tcsnccpy_s strncpy_s +#define _tcsnccpy_s_l _strncpy_s_l + +#define _tcslwr_s _strlwr_s +#define _tcslwr_s_l _strlwr_s_l +#define _tcsupr_s _strupr_s +#define _tcsupr_s_l _strupr_s_l + +#define _strnset_s_l(_Destination,_Destination_size_chars,_Value,_Count,_Locale) (_strnset_s(_Destination,_Destination_size_chars,_Value,_Count)) +#define _strset_s_l(_Destination,_Destination_size_chars,_Value,_Locale) (_strset_s(_Destination,_Destination_size_chars,_Value)) +#endif +#endif + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/tinyc/win32/include/sec_api/time_s.h b/tinyc/win32/include/sec_api/time_s.h new file mode 100644 index 000000000..9603b94fc --- /dev/null +++ b/tinyc/win32/include/sec_api/time_s.h @@ -0,0 +1,61 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _TIME_H__S +#define _TIME_H__S + +#include <time.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + + _CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time); + _CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time); + _CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time); + _CRTIMP errno_t __cdecl _strdate_s(char *_Buf,size_t _SizeInBytes); + _CRTIMP errno_t __cdecl _strtime_s(char *_Buf ,size_t _SizeInBytes); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP errno_t __cdecl _ctime64_s(char *_Buf,size_t _SizeInBytes,const __time64_t *_Time); + _CRTIMP errno_t __cdecl _gmtime64_s(struct tm *_Tm,const __time64_t *_Time); + _CRTIMP errno_t __cdecl _localtime64_s(struct tm *_Tm,const __time64_t *_Time); +#endif + +#ifndef _WTIME_S_DEFINED +#define _WTIME_S_DEFINED + _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); + _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); + _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); + _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); +#endif + +#if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) +#define _INC_WTIME_S_INL +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime32_s(_Buffer,_SizeInWords,_Time); } +#else +__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); } +#endif +#endif +#endif + +#ifndef RC_INVOKED +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime32_s(_Tm,_Time); } +#else +__CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); } +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/tinyc/win32/include/sec_api/wchar_s.h b/tinyc/win32/include/sec_api/wchar_s.h new file mode 100644 index 000000000..94251aa8b --- /dev/null +++ b/tinyc/win32/include/sec_api/wchar_s.h @@ -0,0 +1,128 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_WCHAR_S +#define _INC_WCHAR_S + +#include <wchar.h> + +#if defined(MINGW_HAS_SECURE_API) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _WIO_S_DEFINED +#define _WIO_S_DEFINED + _CRTIMP errno_t __cdecl _waccess_s(const wchar_t *_Filename,int _AccessMode); + _CRTIMP errno_t __cdecl _wmktemp_s(wchar_t *_TemplateName,size_t _SizeInWords); +#endif + +#ifndef _WCONIO_S_DEFINED +#define _WCONIO_S_DEFINED + _CRTIMP errno_t __cdecl _cgetws_s(wchar_t *_Buffer,size_t _SizeInWords,size_t *_SizeRead); + _CRTIMP int __cdecl _cwprintf_s(const wchar_t *_Format,...); + _CRTIMP int __cdecl _cwscanf_s(const wchar_t *_Format,...); + _CRTIMP int __cdecl _cwscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf_s(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _cwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); +#endif + +#ifndef _WSTDIO_S_DEFINED +#define _WSTDIO_S_DEFINED + _CRTIMP wchar_t *__cdecl _getws_s(wchar_t *_Str,size_t _SizeInWords); + int __cdecl fwprintf_s(FILE *_File,const wchar_t *_Format,...); + int __cdecl wprintf_s(const wchar_t *_Format,...); + int __cdecl vfwprintf_s(FILE *_File,const wchar_t *_Format,va_list _ArgList); + int __cdecl vwprintf_s(const wchar_t *_Format,va_list _ArgList); + int __cdecl swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...); + int __cdecl vswprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _snwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vsnwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _wprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vfwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _swprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vswprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _snwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vsnwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fwscanf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _swscanf_s_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _snwscanf_s(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...); + _CRTIMP int __cdecl _snwscanf_s_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _wscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP errno_t __cdecl _wfopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode); + _CRTIMP errno_t __cdecl _wfreopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile); + _CRTIMP errno_t __cdecl _wtmpnam_s(wchar_t *_DstBuf,size_t _SizeInWords); +#endif + +#ifndef _WSTDLIB_S_DEFINED +#define _WSTDLIB_S_DEFINED + _CRTIMP errno_t __cdecl _itow_s (int _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); + _CRTIMP errno_t __cdecl _ltow_s (long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); + _CRTIMP errno_t __cdecl _ultow_s (unsigned long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); + _CRTIMP errno_t __cdecl _wgetenv_s(size_t *_ReturnSize,wchar_t *_DstBuf,size_t _DstSizeInWords,const wchar_t *_VarName); + _CRTIMP errno_t __cdecl _wdupenv_s(wchar_t **_Buffer,size_t *_BufferSizeInWords,const wchar_t *_VarName); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP errno_t __cdecl _i64tow_s(__int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); + _CRTIMP errno_t __cdecl _ui64tow_s(unsigned __int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix); +#endif +#endif + +#ifndef _POSIX_ +#ifndef _WSTDLIBP_S_DEFINED +#define _WSTDLIBP_S_DEFINED + _CRTIMP errno_t __cdecl _wmakepath_s(wchar_t *_PathResult,size_t _SizeInWords,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext); + _CRTIMP errno_t __cdecl _wputenv_s(const wchar_t *_Name,const wchar_t *_Value); + _CRTIMP errno_t __cdecl _wsearchenv_s(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath,size_t _SizeInWords); + _CRTIMP errno_t __cdecl _wsplitpath_s(const wchar_t *_FullPath,wchar_t *_Drive,size_t _DriveSizeInWords,wchar_t *_Dir,size_t _DirSizeInWords,wchar_t *_Filename,size_t _FilenameSizeInWords,wchar_t *_Ext,size_t _ExtSizeInWords); +#endif +#endif + +#ifndef _WSTRING_S_DEFINED +#define _WSTRING_S_DEFINED + _CRTIMP wchar_t *__cdecl wcstok_s(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context); + _CRTIMP errno_t __cdecl _wcserror_s(wchar_t *_Buf,size_t _SizeInWords,int _ErrNum); + _CRTIMP errno_t __cdecl __wcserror_s(wchar_t *_Buffer,size_t _SizeInWords,const wchar_t *_ErrMsg); + _CRTIMP errno_t __cdecl _wcsnset_s(wchar_t *_Dst,size_t _DstSizeInWords,wchar_t _Val,size_t _MaxCount); + _CRTIMP errno_t __cdecl _wcsset_s(wchar_t *_Str,size_t _SizeInWords,wchar_t _Val); + _CRTIMP errno_t __cdecl _wcslwr_s(wchar_t *_Str,size_t _SizeInWords); + _CRTIMP errno_t __cdecl _wcslwr_s_l(wchar_t *_Str,size_t _SizeInWords,_locale_t _Locale); + _CRTIMP errno_t __cdecl _wcsupr_s(wchar_t *_Str,size_t _Size); + _CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale); +#endif + +#ifndef _WTIME_S_DEFINED +#define _WTIME_S_DEFINED + _CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm); + _CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time); + _CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords); + _CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time); +#endif + +#if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL) +#define _INC_WTIME_S_INL +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime32_s(_Buffer,_SizeInWords,_Time); } +#else +__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); } +#endif +#endif +#endif + + _CRTIMP errno_t __cdecl mbsrtowcs_s(size_t *_Retval,wchar_t *_Dst,size_t _SizeInWords,const char **_PSrc,size_t _N,mbstate_t *_State); + _CRTIMP errno_t __cdecl wcrtomb_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,wchar_t _Ch,mbstate_t *_State); + _CRTIMP errno_t __cdecl wcsrtombs_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,const wchar_t **_Src,size_t _Size,mbstate_t *_State); + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/tinyc/win32/include/setjmp.h b/tinyc/win32/include/setjmp.h index 0d9897e63..e4f142a3f 100644 --- a/tinyc/win32/include/setjmp.h +++ b/tinyc/win32/include/setjmp.h @@ -1,72 +1,160 @@ -/* - * setjmp.h - * - * Declarations supporting setjmp and longjump, a method for avoiding - * the normal function call return sequence. (Bleah!) - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_SETJMP +#define _INC_SETJMP -#ifndef _SETJMP_H_ -#define _SETJMP_H_ - -/* All the headers include this file. */ #include <_mingw.h> -#ifndef RC_INVOKED +#pragma pack(push,_CRT_PACKING) #ifdef __cplusplus extern "C" { #endif -/* - * The buffer used by setjmp to store the information used by longjmp - * to perform it's evil goto-like work. The size of this buffer was - * determined through experimentation; it's contents are a mystery. - * NOTE: This was determined on an i386 (actually a Pentium). The - * contents could be different on an Alpha or something else. - */ +#if (defined(_X86_) && !defined(__x86_64)) + #define _JBLEN 16 #define _JBTYPE int -typedef _JBTYPE jmp_buf[_JBLEN]; -/* - * The function provided by CRTDLL which appears to do the actual work - * of setjmp. - */ -int _setjmp (jmp_buf); + typedef struct __JUMP_BUFFER { + unsigned long Ebp; + unsigned long Ebx; + unsigned long Edi; + unsigned long Esi; + unsigned long Esp; + unsigned long Eip; + unsigned long Registration; + unsigned long TryLevel; + unsigned long Cookie; + unsigned long UnwindFunc; + unsigned long UnwindData[6]; + } _JUMP_BUFFER; +#elif defined(__ia64__) + typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128 { + __int64 LowPart; + __int64 HighPart; + } SETJMP_FLOAT128; -#define setjmp(x) _setjmp(x) +#define _JBLEN 33 + typedef SETJMP_FLOAT128 _JBTYPE; -/* - * Return to the last setjmp call and act as if setjmp had returned - * nVal (which had better be non-zero!). - */ -void longjmp (jmp_buf, int); + typedef struct __JUMP_BUFFER { -#ifdef __cplusplus -} + unsigned long iAReserved[6]; + + unsigned long Registration; + unsigned long TryLevel; + unsigned long Cookie; + unsigned long UnwindFunc; + + unsigned long UnwindData[6]; + + SETJMP_FLOAT128 FltS0; + SETJMP_FLOAT128 FltS1; + SETJMP_FLOAT128 FltS2; + SETJMP_FLOAT128 FltS3; + SETJMP_FLOAT128 FltS4; + SETJMP_FLOAT128 FltS5; + SETJMP_FLOAT128 FltS6; + SETJMP_FLOAT128 FltS7; + SETJMP_FLOAT128 FltS8; + SETJMP_FLOAT128 FltS9; + SETJMP_FLOAT128 FltS10; + SETJMP_FLOAT128 FltS11; + SETJMP_FLOAT128 FltS12; + SETJMP_FLOAT128 FltS13; + SETJMP_FLOAT128 FltS14; + SETJMP_FLOAT128 FltS15; + SETJMP_FLOAT128 FltS16; + SETJMP_FLOAT128 FltS17; + SETJMP_FLOAT128 FltS18; + SETJMP_FLOAT128 FltS19; + __int64 FPSR; + __int64 StIIP; + __int64 BrS0; + __int64 BrS1; + __int64 BrS2; + __int64 BrS3; + __int64 BrS4; + __int64 IntS0; + __int64 IntS1; + __int64 IntS2; + __int64 IntS3; + __int64 RsBSP; + __int64 RsPFS; + __int64 ApUNAT; + __int64 ApLC; + __int64 IntSp; + __int64 IntNats; + __int64 Preds; + + } _JUMP_BUFFER; +#elif defined(__x86_64) + typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128 { + unsigned __int64 Part[2]; + } SETJMP_FLOAT128; + +#define _JBLEN 16 + typedef SETJMP_FLOAT128 _JBTYPE; + + typedef struct _JUMP_BUFFER { + unsigned __int64 Frame; + unsigned __int64 Rbx; + unsigned __int64 Rsp; + unsigned __int64 Rbp; + unsigned __int64 Rsi; + unsigned __int64 Rdi; + unsigned __int64 R12; + unsigned __int64 R13; + unsigned __int64 R14; + unsigned __int64 R15; + unsigned __int64 Rip; + unsigned __int64 Spare; + SETJMP_FLOAT128 Xmm6; + SETJMP_FLOAT128 Xmm7; + SETJMP_FLOAT128 Xmm8; + SETJMP_FLOAT128 Xmm9; + SETJMP_FLOAT128 Xmm10; + SETJMP_FLOAT128 Xmm11; + SETJMP_FLOAT128 Xmm12; + SETJMP_FLOAT128 Xmm13; + SETJMP_FLOAT128 Xmm14; + SETJMP_FLOAT128 Xmm15; + } _JUMP_BUFFER; +#endif +#ifndef _JMP_BUF_DEFINED + typedef _JBTYPE jmp_buf[_JBLEN]; +#define _JMP_BUF_DEFINED +#endif + + void * __cdecl __attribute__ ((__nothrow__)) mingw_getsp(void); + +#ifdef USE_MINGW_SETJMP_TWO_ARGS +#ifndef _INC_SETJMPEX +#define setjmp(BUF) _setjmp((BUF),mingw_getsp()) + int __cdecl __attribute__ ((__nothrow__)) _setjmp(jmp_buf _Buf,void *_Ctx); +#else +#undef setjmp +#define setjmp(BUF) _setjmpex((BUF),mingw_getsp()) +#define setjmpex(BUF) _setjmpex((BUF),mingw_getsp()) + int __cdecl __attribute__ ((__nothrow__)) _setjmpex(jmp_buf _Buf,void *_Ctx); +#endif +#else +#ifndef _INC_SETJMPEX +#define setjmp _setjmp +#endif + int __cdecl __attribute__ ((__nothrow__)) setjmp(jmp_buf _Buf); #endif -#endif /* Not RC_INVOKED */ + __declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl ms_longjmp(jmp_buf _Buf,int _Value)/* throw(...)*/; + __declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl longjmp(jmp_buf _Buf,int _Value); -#endif /* Not _SETJMP_H_ */ +#ifdef __cplusplus +} +#endif +#pragma pack(pop) +#endif diff --git a/tinyc/win32/include/share.h b/tinyc/win32/include/share.h index dd5bd452a..358855fe4 100644 --- a/tinyc/win32/include/share.h +++ b/tinyc/win32/include/share.h @@ -1,44 +1,28 @@ -/* - * share.h - * - * Constants for file sharing functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_SHARE +#define _INC_SHARE -#ifndef __STRICT_ANSI__ +#ifndef _WIN32 +#error Only Win32 target is supported! +#endif -#ifndef _SHARE_H_ -#define _SHARE_H_ +#define _SH_COMPAT 0x00 +#define _SH_DENYRW 0x10 +#define _SH_DENYWR 0x20 +#define _SH_DENYRD 0x30 +#define _SH_DENYNO 0x40 +#define _SH_SECURE 0x80 -/* All the headers include this file. */ -#include <_mingw.h> - -#define SH_COMPAT 0x00 /* Compatibility */ -#define SH_DENYRW 0x10 /* Deny read/write */ -#define SH_DENYWR 0x20 /* Deny write */ -#define SH_DENYRD 0x30 /* Deny read */ -#define SH_DENYNO 0x40 /* Deny nothing */ - -#endif /* Not _SHARE_H_ */ - -#endif /* Not __STRICT_ANSI__ */ +#ifndef NO_OLDNAMES +#define SH_COMPAT _SH_COMPAT +#define SH_DENYRW _SH_DENYRW +#define SH_DENYWR _SH_DENYWR +#define SH_DENYRD _SH_DENYRD +#define SH_DENYNO _SH_DENYNO +#endif +#endif diff --git a/tinyc/win32/include/signal.h b/tinyc/win32/include/signal.h index 4eced969a..a518f6b31 100644 --- a/tinyc/win32/include/signal.h +++ b/tinyc/win32/include/signal.h @@ -1,111 +1,63 @@ -/* - * signal.h - * - * A way to set handlers for exceptional conditions (also known as signals). - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_SIGNAL +#define _INC_SIGNAL -#ifndef _SIGNAL_H_ -#define _SIGNAL_H_ - -/* All the headers include this file. */ #include <_mingw.h> -/* - * The actual signal values. Using other values with signal - * produces a SIG_ERR return value. - * - * NOTE: SIGINT is produced when the user presses Ctrl-C. - * SIGILL has not been tested. - * SIGFPE doesn't seem to work? - * SIGSEGV does not catch writing to a NULL pointer (that shuts down - * your app; can you say "segmentation violation core dump"?). - * SIGTERM comes from what kind of termination request exactly? - * SIGBREAK is indeed produced by pressing Ctrl-Break. - * SIGABRT is produced by calling abort. - * TODO: The above results may be related to not installing an appropriate - * structured exception handling frame. Results may be better if I ever - * manage to get the SEH stuff down. - */ -#define SIGINT 2 /* Interactive attention */ -#define SIGILL 4 /* Illegal instruction */ -#define SIGFPE 8 /* Floating point error */ -#define SIGSEGV 11 /* Segmentation violation */ -#define SIGTERM 15 /* Termination request */ -#define SIGBREAK 21 /* Control-break */ -#define SIGABRT 22 /* Abnormal termination (abort) */ - -#define NSIG 23 /* maximum signal number + 1 */ - -#ifndef RC_INVOKED +#ifdef __cplusplus +extern "C" { +#endif #ifndef _SIG_ATOMIC_T_DEFINED -typedef int sig_atomic_t; #define _SIG_ATOMIC_T_DEFINED + typedef int sig_atomic_t; #endif -/* - * The prototypes (below) are the easy part. The hard part is figuring - * out what signals are available and what numbers they are assigned - * along with appropriate values of SIG_DFL and SIG_IGN. - */ +#define NSIG 23 + +#define SIGHUP 1 /* hangup */ +#define SIGINT 2 +#define SIGQUIT 3 /* quit */ +#define SIGILL 4 +#define SIGTRAP 5 /* trace trap (not reset when caught) */ +#define SIGIOT 6 /* IOT instruction */ +#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */ +#define SIGEMT 7 /* EMT instruction */ +#define SIGFPE 8 +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ +#define SIGBUS 10 /* bus error */ +#define SIGSEGV 11 +#define SIGSYS 12 /* bad argument to system call */ +#define SIGPIPE 13 /* write on a pipe with no one to read it */ +#ifdef __USE_MINGW_ALARM +#define SIGALRM 14 /* alarm clock */ +#endif +#define SIGTERM 15 +#define SIGBREAK 21 +#define SIGABRT2 22 -/* - * A pointer to a signal handler function. A signal handler takes a - * single int, which is the signal it handles. - */ -typedef void (*__p_sig_fn_t)(int); +#define SIGABRT_COMPAT 6 -/* - * These are special values of signal handler pointers which are - * used to send a signal to the default handler (SIG_DFL), ignore - * the signal (SIG_IGN), or indicate an error return (SIG_ERR). - */ -#define SIG_DFL ((__p_sig_fn_t) 0) -#define SIG_IGN ((__p_sig_fn_t) 1) -#define SIG_ERR ((__p_sig_fn_t) -1) + typedef void (*__p_sig_fn_t)(int); -#ifdef __cplusplus -extern "C" { -#endif +#define SIG_DFL (__p_sig_fn_t)0 +#define SIG_IGN (__p_sig_fn_t)1 +#define SIG_GET (__p_sig_fn_t)2 +#define SIG_SGE (__p_sig_fn_t)3 +#define SIG_ACK (__p_sig_fn_t)4 +#define SIG_ERR (__p_sig_fn_t)-1 -/* - * Call signal to set the signal handler for signal sig to the - * function pointed to by handler. Returns a pointer to the - * previous handler, or SIG_ERR if an error occurs. Initially - * unhandled signals defined above will return SIG_DFL. - */ -__p_sig_fn_t signal(int, __p_sig_fn_t); + extern void **__cdecl __pxcptinfoptrs(void); +#define _pxcptinfoptrs (*__pxcptinfoptrs()) -/* - * Raise the signal indicated by sig. Returns non-zero on success. - */ -int raise (int); + __p_sig_fn_t __cdecl signal(int _SigNum,__p_sig_fn_t _Func); + int __cdecl raise(int _SigNum); -#ifdef __cplusplus +#ifdef __cplusplus } #endif - -#endif /* Not RC_INVOKED */ - -#endif /* Not _SIGNAL_H_ */ - +#endif diff --git a/tinyc/win32/include/stdarg.h b/tinyc/win32/include/stdarg.h deleted file mode 100644 index a9b22b7b6..000000000 --- a/tinyc/win32/include/stdarg.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _STDARG_H -#define _STDARG_H - -typedef char *va_list; - -/* only correct for i386 */ -#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) -#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3))) -#define va_copy(dest, src) (dest) = (src) -#define va_end(ap) - -/* fix a buggy dependency on GCC in libio.h */ -typedef va_list __gnuc_va_list; -#define _VA_LIST_DEFINED - -#endif diff --git a/tinyc/win32/include/stdbool.h b/tinyc/win32/include/stdbool.h deleted file mode 100644 index 6ed13a611..000000000 --- a/tinyc/win32/include/stdbool.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _STDBOOL_H -#define _STDBOOL_H - -/* ISOC99 boolean */ - -#define bool _Bool -#define true 1 -#define false 0 - -#endif /* _STDBOOL_H */ diff --git a/tinyc/win32/include/stddef.h b/tinyc/win32/include/stddef.h deleted file mode 100644 index 6e4e2c88e..000000000 --- a/tinyc/win32/include/stddef.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _STDDEF_H -#define _STDDEF_H - -#define NULL ((void *)0) -typedef __SIZE_TYPE__ size_t; -typedef __WCHAR_TYPE__ wchar_t; -typedef __PTRDIFF_TYPE__ ptrdiff_t; -#define offsetof(type, field) ((size_t) &((type *)0)->field) - -/* need to do that because of glibc 2.1 bug (should have a way to test - presence of 'long long' without __GNUC__, or TCC should define - __GNUC__ ? */ -#if !defined(__int8_t_defined) && !defined(__dietlibc__) -#define __int8_t_defined -typedef char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long long int int64_t; -#endif - -void *alloca(size_t); - -#endif diff --git a/tinyc/win32/include/stdint.h b/tinyc/win32/include/stdint.h index 71c6708ff..cde32b6e3 100644 --- a/tinyc/win32/include/stdint.h +++ b/tinyc/win32/include/stdint.h @@ -1,3 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ /* ISO C9x 7.18 Integer types <stdint.h> * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794) * @@ -20,6 +25,14 @@ #ifndef _STDINT_H #define _STDINT_H +#include <_mingw.h> + +#define __need_wint_t +#define __need_wchar_t +#include "stddef.h" + +#ifndef __int8_t_defined +#define __int8_t_defined /* 7.18.1.1 Exact-width integer types */ typedef signed char int8_t; typedef unsigned char uint8_t; @@ -29,6 +42,7 @@ typedef int int32_t; typedef unsigned uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; +#endif /* 7.18.1.2 Minimum-width integer types */ typedef signed char int_least8_t; @@ -40,9 +54,9 @@ typedef unsigned uint_least32_t; typedef long long int_least64_t; typedef unsigned long long uint_least64_t; -/* 7.18.1.3 Fastest minimum-width integer types +/* 7.18.1.3 Fastest minimum-width integer types * Not actually guaranteed to be fastest for all purposes - * Here we use the exact-width types for 8 and 16-bit ints. + * Here we use the exact-width types for 8 and 16-bit ints. */ typedef char int_fast8_t; typedef unsigned char uint_fast8_t; @@ -53,10 +67,6 @@ typedef unsigned int uint_fast32_t; typedef long long int_fast64_t; typedef unsigned long long uint_fast64_t; -/* 7.18.1.4 Integer types capable of holding object pointers */ -typedef int intptr_t; -typedef unsigned uintptr_t; - /* 7.18.1.5 Greatest-width integer types */ typedef long long intmax_t; typedef unsigned long long uintmax_t; @@ -65,7 +75,7 @@ typedef unsigned long long uintmax_t; #if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS) /* 7.18.2.1 Limits of exact-width integer types */ -#define INT8_MIN (-128) +#define INT8_MIN (-128) #define INT16_MIN (-32768) #define INT32_MIN (-2147483647 - 1) #define INT64_MIN (-9223372036854775807LL - 1) @@ -113,10 +123,16 @@ typedef unsigned long long uintmax_t; #define UINT_FAST64_MAX UINT64_MAX /* 7.18.2.4 Limits of integer types capable of holding - object pointers */ + object pointers */ +#ifdef _WIN64 +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX +#else #define INTPTR_MIN INT32_MIN #define INTPTR_MAX INT32_MAX #define UINTPTR_MAX UINT32_MAX +#endif /* 7.18.2.5 Limits of greatest-width integer types */ #define INTMAX_MIN INT64_MIN @@ -124,25 +140,35 @@ typedef unsigned long long uintmax_t; #define UINTMAX_MAX UINT64_MAX /* 7.18.3 Limits of other integer types */ +#ifdef _WIN64 +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX +#else #define PTRDIFF_MIN INT32_MIN #define PTRDIFF_MAX INT32_MAX +#endif #define SIG_ATOMIC_MIN INT32_MIN #define SIG_ATOMIC_MAX INT32_MAX +#ifndef SIZE_MAX +#ifdef _WIN64 +#define SIZE_MAX UINT64_MAX +#else #define SIZE_MAX UINT32_MAX +#endif +#endif -#ifndef WCHAR_MIN /* also in wchar.h */ +#ifndef WCHAR_MIN /* also in wchar.h */ #define WCHAR_MIN 0 #define WCHAR_MAX ((wchar_t)-1) /* UINT16_MAX */ #endif /* - * wint_t is unsigned int in __MINGW32__, - * but unsigned short in MS runtime + * wint_t is unsigned short for compatibility with MS runtime */ #define WINT_MIN 0 -#define WINT_MAX UINT32_MAX +#define WINT_MAX ((wint_t)-1) /* UINT16_MAX */ #endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */ @@ -152,7 +178,7 @@ typedef unsigned long long uintmax_t; /* 7.18.4.1 Macros for minimum-width integer constants - Accoding to Douglas Gwyn <gwyn@arl.mil>: + According to Douglas Gwyn <gwyn@arl.mil>: "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC 9899:1999 as initially published, the expansion was required to be an integer constant of precisely matching type, which @@ -168,16 +194,18 @@ typedef unsigned long long uintmax_t; #define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val)) #define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val)) #define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val)) -#define INT64_C(val) (INT_LEAST64_MAX-INT_LEAST64_MAX+(val)) +/* The 'trick' doesn't work in C89 for long long because, without + suffix, (val) will be evaluated as int, not intmax_t */ +#define INT64_C(val) val##LL #define UINT8_C(val) (UINT_LEAST8_MAX-UINT_LEAST8_MAX+(val)) #define UINT16_C(val) (UINT_LEAST16_MAX-UINT_LEAST16_MAX+(val)) #define UINT32_C(val) (UINT_LEAST32_MAX-UINT_LEAST32_MAX+(val)) -#define UINT64_C(val) (UINT_LEAST64_MAX-UINT_LEAST64_MAX+(val)) +#define UINT64_C(val) val##ULL /* 7.18.4.2 Macros for greatest-width integer constants */ -#define INTMAX_C(val) (INTMAX_MAX-INTMAX_MAX+(val)) -#define UINTMAX_C(val) (UINTMAX_MAX-UINTMAX_MAX+(val)) +#define INTMAX_C(val) val##LL +#define UINTMAX_C(val) val##ULL #endif /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */ diff --git a/tinyc/win32/include/stdio.h b/tinyc/win32/include/stdio.h index 2d97e668c..da887936a 100644 --- a/tinyc/win32/include/stdio.h +++ b/tinyc/win32/include/stdio.h @@ -1,413 +1,429 @@ -/* - * stdio.h - * - * Definitions of types and prototypes of functions for standard input and - * output. - * - * NOTE: The file manipulation functions provided by Microsoft seem to - * work with either slash (/) or backslash (\) as the path separator. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_STDIO +#define _INC_STDIO -#ifndef _STDIO_H_ -#define _STDIO_H_ - -/* All the headers include this file. */ #include <_mingw.h> -#define __need_size_t -#define __need_NULL -#define __need_wchar_t -#define __need_wint_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ - - -/* Flags for the iobuf structure */ -#define _IOREAD 1 -#define _IOWRT 2 -#define _IORW 0x0080 /* opened as "r+w" */ - - -/* - * The three standard file pointers provided by the run time library. - * NOTE: These will go to the bit-bucket silently in GUI applications! - */ -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 - -/* Returned by various functions on end of file condition or error. */ -#define EOF (-1) - -/* - * The maximum length of a file name. You should use GetVolumeInformation - * instead of this constant. But hey, this works. - * - * NOTE: This is used in the structure _finddata_t (see io.h) so changing it - * is probably not a good idea. - */ -#define FILENAME_MAX (260) - -/* - * The maximum number of files that may be open at once. I have set this to - * a conservative number. The actual value may be higher. - */ -#define FOPEN_MAX (20) - -/* After creating this many names, tmpnam and tmpfile return NULL */ -#define TMP_MAX 32767 -/* - * Tmpnam, tmpfile and, sometimes, _tempnam try to create - * temp files in the root directory of the current drive - * (not in pwd, as suggested by some older MS doc's). - * Redefining these macros does not effect the CRT functions. - */ -#define _P_tmpdir "\\" -#define _wP_tmpdir L"\\" - -/* - * The maximum size of name (including NUL) that will be put in the user - * supplied buffer caName for tmpnam. - * Inferred from the size of the static buffer returned by tmpnam - * when passed a NULL argument. May actually be smaller. - */ -#define L_tmpnam (16) - -#define _IOFBF 0x0000 -#define _IOLBF 0x0040 -#define _IONBF 0x0004 +#pragma pack(push,_CRT_PACKING) -/* - * The buffer size as used by setbuf such that it is equivalent to - * (void) setvbuf(fileSetBuffer, caBuffer, _IOFBF, BUFSIZ). - */ -#define BUFSIZ 512 - -/* Constants for nOrigin indicating the position relative to which fseek - * sets the file position. Enclosed in ifdefs because io.h could also - * define them. (Though not anymore since io.h includes this file now.) */ -#ifndef SEEK_SET -#define SEEK_SET (0) +#ifdef __cplusplus +extern "C" { #endif -#ifndef SEEK_CUR -#define SEEK_CUR (1) -#endif +#define BUFSIZ 512 +#define _NFILE _NSTREAM_ +#define _NSTREAM_ 512 +#define _IOB_ENTRIES 20 +#define EOF (-1) -#ifndef SEEK_END -#define SEEK_END (2) +#ifndef _FILE_DEFINED + struct _iobuf { + char *_ptr; + int _cnt; + char *_base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char *_tmpfname; + }; + typedef struct _iobuf FILE; +#define _FILE_DEFINED #endif - -#ifndef RC_INVOKED - -/* - * I used to include stdarg.h at this point, in order to allow for the - * functions later on in the file which use va_list. That conflicts with - * using stdio.h and varargs.h in the same file, so I do the typedef myself. - */ -#ifndef _VA_LIST -#define _VA_LIST -#if defined __GNUC__ && __GNUC__ >= 3 -typedef __builtin_va_list va_list; +#ifdef _POSIX_ +#define _P_tmpdir "/" +#define _wP_tmpdir L"/" #else -typedef char* va_list; +#define _P_tmpdir "\\" +#define _wP_tmpdir L"\\" #endif -#endif -/* - * The structure underlying the FILE type. - * - * I still believe that nobody in their right mind should make use of the - * internals of this structure. Provided by Pedro A. Aranda Gutiirrez - * <paag@tid.es>. - */ -#ifndef _FILE_DEFINED -#define _FILE_DEFINED -typedef struct _iobuf -{ - char* _ptr; - int _cnt; - char* _base; - int _flag; - int _file; - int _charbuf; - int _bufsiz; - char* _tmpfname; -} FILE; -#endif /* Not _FILE_DEFINED */ - - -/* - * The standard file handles - */ -#ifndef __DECLSPEC_SUPPORTED - -extern FILE (*__imp__iob)[]; /* A pointer to an array of FILE */ -#define _iob (*__imp__iob) /* An array of FILE */ +#define L_tmpnam (sizeof(_P_tmpdir) + 12) -#else /* __DECLSPEC_SUPPORTED */ +#ifdef _POSIX_ +#define L_ctermid 9 +#define L_cuserid 32 +#endif -__MINGW_IMPORT FILE _iob[]; /* An array of FILE imported from DLL. */ +#define SEEK_CUR 1 +#define SEEK_END 2 +#define SEEK_SET 0 -#endif /* __DECLSPEC_SUPPORTED */ +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 -#define stdin (&_iob[STDIN_FILENO]) -#define stdout (&_iob[STDOUT_FILENO]) -#define stderr (&_iob[STDERR_FILENO]) +#define FILENAME_MAX 260 +#define FOPEN_MAX 20 +#define _SYS_OPEN 20 +#define TMP_MAX 32767 +#ifndef NULL #ifdef __cplusplus -extern "C" { +#define NULL 0 +#else +#define NULL ((void *)0) +#endif #endif -/* - * File Operations - */ -FILE* fopen (const char*, const char*); -FILE* freopen (const char*, const char*, FILE*); -int fflush (FILE*); -int fclose (FILE*); -/* MS puts remove & rename (but not wide versions) in io.h also */ -int remove (const char*); -int rename (const char*, const char*); -FILE* tmpfile (void); -char* tmpnam (char*); -char* _tempnam (const char*, const char*); - -#ifndef NO_OLDNAMES -char* tempnam (const char*, const char*); +#ifndef _OFF_T_DEFINED +#define _OFF_T_DEFINED +#ifndef _OFF_T_ +#define _OFF_T_ + typedef long _off_t; +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef long off_t; +#endif +#endif #endif -int setvbuf (FILE*, char*, int, size_t); +#ifndef _OFF64_T_DEFINED +#define _OFF64_T_DEFINED + typedef long long _off64_t; +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef long long off64_t; +#endif +#endif -void setbuf (FILE*, char*); +#ifndef _STDIO_DEFINED +#ifdef _WIN64 + _CRTIMP FILE *__cdecl __iob_func(void); +#else +#ifdef _MSVCRT_ +extern FILE _iob[]; /* A pointer to an array of FILE */ +#define __iob_func() (_iob) +#else +extern FILE (*_imp___iob)[]; /* A pointer to an array of FILE */ +#define __iob_func() (*_imp___iob) +#define _iob __iob_func() +#endif +#endif +#endif -/* - * Formatted Output - */ +#ifndef _FPOS_T_DEFINED +#define _FPOS_T_DEFINED +#undef _FPOSOFF -int fprintf (FILE*, const char*, ...); -int printf (const char*, ...); -int sprintf (char*, const char*, ...); -int _snprintf (char*, size_t, const char*, ...); -int vfprintf (FILE*, const char*, va_list); -int vprintf (const char*, va_list); -int vsprintf (char*, const char*, va_list); -int _vsnprintf (char*, size_t, const char*, va_list); +#if (!defined(NO_OLDNAMES) || defined(__GNUC__)) && _INTEGRAL_MAX_BITS >= 64 + typedef __int64 fpos_t; +#define _FPOSOFF(fp) ((long)(fp)) +#else + typedef long long fpos_t; +#define _FPOSOFF(fp) ((long)(fp)) +#endif -#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ -int snprintf(char* s, size_t n, const char* format, ...); -extern inline int vsnprintf (char* s, size_t n, const char* format, - va_list arg) - { return _vsnprintf ( s, n, format, arg); } #endif -/* - * Formatted Input - */ +#ifndef _STDSTREAM_DEFINED +#define _STDSTREAM_DEFINED -int fscanf (FILE*, const char*, ...); -int scanf (const char*, ...); -int sscanf (const char*, const char*, ...); -/* - * Character Input and Output Functions - */ +#define stdin (&__iob_func()[0]) +#define stdout (&__iob_func()[1]) +#define stderr (&__iob_func()[2]) +#endif -int fgetc (FILE*); -char* fgets (char*, int, FILE*); -int fputc (int, FILE*); -int fputs (const char*, FILE*); -int getc (FILE*); -int getchar (void); -char* gets (char*); -int putc (int, FILE*); -int putchar (int); -int puts (const char*); -int ungetc (int, FILE*); - -/* - * Direct Input and Output Functions - */ +#define _IOREAD 0x0001 +#define _IOWRT 0x0002 -size_t fread (void*, size_t, size_t, FILE*); -size_t fwrite (const void*, size_t, size_t, FILE*); +#define _IOFBF 0x0000 +#define _IOLBF 0x0040 +#define _IONBF 0x0004 -/* - * File Positioning Functions - */ +#define _IOMYBUF 0x0008 +#define _IOEOF 0x0010 +#define _IOERR 0x0020 +#define _IOSTRG 0x0040 +#define _IORW 0x0080 +#ifdef _POSIX_ +#define _IOAPPEND 0x0200 +#endif -int fseek (FILE*, long, int); -long ftell (FILE*); -void rewind (FILE*); +#define _TWO_DIGIT_EXPONENT 0x1 -#ifdef __USE_MINGW_FSEEK /* These are in libmingwex.a */ -/* - * Workaround for limitations on win9x where a file contents are - * not zero'd out if you seek past the end and then write. - */ +#ifndef _STDIO_DEFINED -int __mingw_fseek (FILE *, long, int); -int __mingw_fwrite (const void*, size_t, size_t, FILE*); -#define fseek(fp, offset, whence) __mingw_fseek(fp, offset, whence) -#define fwrite(buffer, size, count, fp) __mingw_fwrite(buffer, size, count, fp) -#endif /* __USE_MINGW_FSEEK */ - - -/* - * An opaque data type used for storing file positions... The contents of - * this type are unknown, but we (the compiler) need to know the size - * because the programmer using fgetpos and fsetpos will be setting aside - * storage for fpos_t structres. Actually I tested using a byte array and - * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL). - * Perhaps an unsigned long? TODO? It's definitely a 64-bit number in - * MSVCRT however, and for now `long long' will do. - */ -#ifdef __MSVCRT__ -typedef long long fpos_t; + _CRTIMP int __cdecl _filbuf(FILE *_File); + _CRTIMP int __cdecl _flsbuf(int _Ch,FILE *_File); +#ifdef _POSIX_ + _CRTIMP FILE *__cdecl _fsopen(const char *_Filename,const char *_Mode); #else -typedef long fpos_t; + _CRTIMP FILE *__cdecl _fsopen(const char *_Filename,const char *_Mode,int _ShFlag); #endif - -int fgetpos (FILE*, fpos_t*); -int fsetpos (FILE*, const fpos_t*); - -/* - * Error Functions - */ - -void clearerr (FILE*); -int feof (FILE*); -int ferror (FILE*); -void perror (const char*); - - -#ifndef __STRICT_ANSI__ -/* - * Pipes - */ -FILE* _popen (const char*, const char*); -int _pclose (FILE*); - + void __cdecl clearerr(FILE *_File); + int __cdecl fclose(FILE *_File); + _CRTIMP int __cdecl _fcloseall(void); +#ifdef _POSIX_ + FILE *__cdecl fdopen(int _FileHandle,const char *_Mode); +#else + _CRTIMP FILE *__cdecl _fdopen(int _FileHandle,const char *_Mode); +#endif + int __cdecl feof(FILE *_File); + int __cdecl ferror(FILE *_File); + int __cdecl fflush(FILE *_File); + int __cdecl fgetc(FILE *_File); + _CRTIMP int __cdecl _fgetchar(void); + int __cdecl fgetpos(FILE *_File ,fpos_t *_Pos); + char *__cdecl fgets(char *_Buf,int _MaxCount,FILE *_File); +#ifdef _POSIX_ + int __cdecl fileno(FILE *_File); +#else + _CRTIMP int __cdecl _fileno(FILE *_File); +#endif + _CRTIMP char *__cdecl _tempnam(const char *_DirName,const char *_FilePrefix); + _CRTIMP int __cdecl _flushall(void); + FILE *__cdecl fopen(const char *_Filename,const char *_Mode); + FILE *fopen64(const char *filename,const char *mode); + int __cdecl fprintf(FILE *_File,const char *_Format,...); + int __cdecl fputc(int _Ch,FILE *_File); + _CRTIMP int __cdecl _fputchar(int _Ch); + int __cdecl fputs(const char *_Str,FILE *_File); + size_t __cdecl fread(void *_DstBuf,size_t _ElementSize,size_t _Count,FILE *_File); + FILE *__cdecl freopen(const char *_Filename,const char *_Mode,FILE *_File); + int __cdecl fscanf(FILE *_File,const char *_Format,...); + int __cdecl fsetpos(FILE *_File,const fpos_t *_Pos); + int __cdecl fseek(FILE *_File,long _Offset,int _Origin); + int fseeko64(FILE* stream, _off64_t offset, int whence); + long __cdecl ftell(FILE *_File); + _off64_t ftello64(FILE * stream); + int __cdecl _fseeki64(FILE *_File,__int64 _Offset,int _Origin); + __int64 __cdecl _ftelli64(FILE *_File); + size_t __cdecl fwrite(const void *_Str,size_t _Size,size_t _Count,FILE *_File); + int __cdecl getc(FILE *_File); + int __cdecl getchar(void); + _CRTIMP int __cdecl _getmaxstdio(void); + char *__cdecl gets(char *_Buffer); + int __cdecl _getw(FILE *_File); +#ifndef _CRT_PERROR_DEFINED +#define _CRT_PERROR_DEFINED + void __cdecl perror(const char *_ErrMsg); +#endif + _CRTIMP int __cdecl _pclose(FILE *_File); + _CRTIMP FILE *__cdecl _popen(const char *_Command,const char *_Mode); +#if !defined(NO_OLDNAMES) && !defined(popen) +#define popen _popen +#define pclose _pclose +#endif + int __cdecl printf(const char *_Format,...); + int __cdecl putc(int _Ch,FILE *_File); + int __cdecl putchar(int _Ch); + int __cdecl puts(const char *_Str); + _CRTIMP int __cdecl _putw(int _Word,FILE *_File); +#ifndef _CRT_DIRECTORY_DEFINED +#define _CRT_DIRECTORY_DEFINED + int __cdecl remove(const char *_Filename); + int __cdecl rename(const char *_OldFilename,const char *_NewFilename); + _CRTIMP int __cdecl _unlink(const char *_Filename); #ifndef NO_OLDNAMES -FILE* popen (const char*, const char*); -int pclose (FILE*); + int __cdecl unlink(const char *_Filename); +#endif +#endif + void __cdecl rewind(FILE *_File); + _CRTIMP int __cdecl _rmtmp(void); + int __cdecl scanf(const char *_Format,...); + void __cdecl setbuf(FILE *_File,char *_Buffer); + _CRTIMP int __cdecl _setmaxstdio(int _Max); + _CRTIMP unsigned int __cdecl _set_output_format(unsigned int _Format); + _CRTIMP unsigned int __cdecl _get_output_format(void); + int __cdecl setvbuf(FILE *_File,char *_Buf,int _Mode,size_t _Size); + _CRTIMP int __cdecl _scprintf(const char *_Format,...); + int __cdecl sscanf(const char *_Src,const char *_Format,...); + _CRTIMP int __cdecl _snscanf(const char *_Src,size_t _MaxCount,const char *_Format,...); + FILE *__cdecl tmpfile(void); + char *__cdecl tmpnam(char *_Buffer); + int __cdecl ungetc(int _Ch,FILE *_File); + int __cdecl vfprintf(FILE *_File,const char *_Format,va_list _ArgList); + int __cdecl vprintf(const char *_Format,va_list _ArgList); + /* Make sure macros are not defined. */ +#pragma push_macro("vsnprintf") +#pragma push_macro("snprintf") +# undef vsnprintf +# undef snprintf + extern + __attribute__((format(gnu_printf, 3, 0))) __attribute__((nonnull (3))) + int __mingw_vsnprintf(char *_DstBuf,size_t _MaxCount,const char *_Format,va_list _ArgList); + extern + __attribute__((format(gnu_printf, 3, 4))) __attribute__((nonnull (3))) + int __mingw_snprintf(char* s, size_t n, const char* format, ...); + int __cdecl vsnprintf(char *_DstBuf,size_t _MaxCount,const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _snprintf(char *_Dest,size_t _Count,const char *_Format,...); + _CRTIMP int __cdecl _vsnprintf(char *_Dest,size_t _Count,const char *_Format,va_list _Args); + int __cdecl sprintf(char *_Dest,const char *_Format,...); + int __cdecl vsprintf(char *_Dest,const char *_Format,va_list _Args); +#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ + int __cdecl snprintf(char* s, size_t n, const char* format, ...); + __CRT_INLINE int __cdecl vsnprintf (char* s, size_t n, const char* format,va_list arg) { + return _vsnprintf ( s, n, format, arg); + } + int __cdecl vscanf(const char * Format, va_list argp); + int __cdecl vfscanf (FILE * fp, const char * Format,va_list argp); + int __cdecl vsscanf (const char * _Str,const char * Format,va_list argp); #endif +/* Restore may prior defined macros snprintf/vsnprintf. */ +#pragma pop_macro("snprintf") +#pragma pop_macro("vsnprintf") +/* Check if vsnprintf and snprintf are defaulting to gnu-style. */ +# if defined(USE_MINGW_GNU_SNPRINTF) && USE_MINGW_GNU_SNPRINTF +# ifndef vsnprint +# define vsnprintf __mingw_vsnprintf +# endif +# ifndef snprintf +# define snprintf __mingw_snprintf +# endif +# endif + _CRTIMP int __cdecl _vscprintf(const char *_Format,va_list _ArgList); + _CRTIMP int __cdecl _set_printf_count_output(int _Value); + _CRTIMP int __cdecl _get_printf_count_output(void); -/* - * Other Non ANSI functions - */ -int _flushall (void); -int _fgetchar (void); -int _fputchar (int); -FILE* _fdopen (int, const char*); -int _fileno (FILE*); +#ifndef _WSTDIO_DEFINED -#ifndef _NO_OLDNAMES -int fgetchar (void); -int fputchar (int); -FILE* fdopen (int, const char*); -int fileno (FILE*); -#endif /* Not _NO_OLDNAMES */ +#ifndef WEOF +#define WEOF (wint_t)(0xFFFF) +#endif -#endif /* Not __STRICT_ANSI__ */ +#ifdef _POSIX_ + _CRTIMP FILE *__cdecl _wfsopen(const wchar_t *_Filename,const wchar_t *_Mode); +#else + _CRTIMP FILE *__cdecl _wfsopen(const wchar_t *_Filename,const wchar_t *_Mode,int _ShFlag); +#endif + wint_t __cdecl fgetwc(FILE *_File); + _CRTIMP wint_t __cdecl _fgetwchar(void); + wint_t __cdecl fputwc(wchar_t _Ch,FILE *_File); + _CRTIMP wint_t __cdecl _fputwchar(wchar_t _Ch); + wint_t __cdecl getwc(FILE *_File); + wint_t __cdecl getwchar(void); + wint_t __cdecl putwc(wchar_t _Ch,FILE *_File); + wint_t __cdecl putwchar(wchar_t _Ch); + wint_t __cdecl ungetwc(wint_t _Ch,FILE *_File); + wchar_t *__cdecl fgetws(wchar_t *_Dst,int _SizeInWords,FILE *_File); + int __cdecl fputws(const wchar_t *_Str,FILE *_File); + _CRTIMP wchar_t *__cdecl _getws(wchar_t *_String); + _CRTIMP int __cdecl _putws(const wchar_t *_Str); + int __cdecl fwprintf(FILE *_File,const wchar_t *_Format,...); + int __cdecl wprintf(const wchar_t *_Format,...); + _CRTIMP int __cdecl _scwprintf(const wchar_t *_Format,...); + int __cdecl vfwprintf(FILE *_File,const wchar_t *_Format,va_list _ArgList); + int __cdecl vwprintf(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl swprintf(wchar_t*, const wchar_t*, ...); + _CRTIMP int __cdecl vswprintf(wchar_t*, const wchar_t*,va_list); + _CRTIMP int __cdecl _swprintf_c(wchar_t *_DstBuf,size_t _SizeInWords,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vswprintf_c(wchar_t *_DstBuf,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _snwprintf(wchar_t *_Dest,size_t _Count,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vsnwprintf(wchar_t *_Dest,size_t _Count,const wchar_t *_Format,va_list _Args); +#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ + int __cdecl snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...); + __CRT_INLINE int __cdecl vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, va_list arg) { return _vsnwprintf(s,n,format,arg); } + int __cdecl vwscanf (const wchar_t *, va_list); + int __cdecl vfwscanf (FILE *,const wchar_t *,va_list); + int __cdecl vswscanf (const wchar_t *,const wchar_t *,va_list); +#endif + _CRTIMP int __cdecl _swprintf(wchar_t *_Dest,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vswprintf(wchar_t *_Dest,const wchar_t *_Format,va_list _Args); -/* Wide versions */ +#ifndef RC_INVOKED +#include <vadefs.h> +#endif -#ifndef _WSTDIO_DEFINED -/* also in wchar.h - keep in sync */ -int fwprintf (FILE*, const wchar_t*, ...); -int wprintf (const wchar_t*, ...); -int swprintf (wchar_t*, const wchar_t*, ...); -int _snwprintf (wchar_t*, size_t, const wchar_t*, ...); -int vfwprintf (FILE*, const wchar_t*, va_list); -int vwprintf (const wchar_t*, va_list); -int vswprintf (wchar_t*, const wchar_t*, va_list); -int _vsnwprintf (wchar_t*, size_t, const wchar_t*, va_list); -int fwscanf (FILE*, const wchar_t*, ...); -int wscanf (const wchar_t*, ...); -int swscanf (const wchar_t*, const wchar_t*, ...); -wint_t fgetwc (FILE*); -wint_t fputwc (wchar_t, FILE*); -wint_t ungetwc (wchar_t, FILE*); -#ifdef __MSVCRT__ -wchar_t* fgetws (wchar_t*, int, FILE*); -int fputws (const wchar_t*, FILE*); -wint_t getwc (FILE*); -wint_t getwchar (void); -wchar_t* _getws (wchar_t*); -wint_t putwc (wint_t, FILE*); -int _putws (const wchar_t*); -wint_t putwchar (wint_t); -FILE* _wfopen (const wchar_t*, const wchar_t*); -FILE* _wfreopen (const wchar_t*, const wchar_t*, FILE*); -FILE* _wfsopen (const wchar_t*, const wchar_t*, int); -wchar_t* _wtmpnam (wchar_t*); -wchar_t* _wtempnam (const wchar_t*, const wchar_t*); -int _wrename (const wchar_t*, const wchar_t*); -int _wremove (const wchar_t*); -void _wperror (const wchar_t*); -FILE* _wpopen (const wchar_t*, const wchar_t*); -#endif /* __MSVCRT__ */ +#ifdef _CRT_NON_CONFORMING_SWPRINTFS +#ifndef __cplusplus +#define swprintf _swprintf +#define vswprintf _vswprintf +#define _swprintf_l __swprintf_l +#define _vswprintf_l __vswprintf_l +#endif +#endif -#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ -int snwprintf(wchar_t* s, size_t n, const wchar_t* format, ...); -extern inline int vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, - va_list arg) - { return _vsnwprintf ( s, n, format, arg); } + _CRTIMP wchar_t *__cdecl _wtempnam(const wchar_t *_Directory,const wchar_t *_FilePrefix); + _CRTIMP int __cdecl _vscwprintf(const wchar_t *_Format,va_list _ArgList); + int __cdecl fwscanf(FILE *_File,const wchar_t *_Format,...); + int __cdecl swscanf(const wchar_t *_Src,const wchar_t *_Format,...); + _CRTIMP int __cdecl _snwscanf(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...); + int __cdecl wscanf(const wchar_t *_Format,...); + _CRTIMP FILE *__cdecl _wfdopen(int _FileHandle ,const wchar_t *_Mode); + _CRTIMP FILE *__cdecl _wfopen(const wchar_t *_Filename,const wchar_t *_Mode); + _CRTIMP FILE *__cdecl _wfreopen(const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile); +#ifndef _CRT_WPERROR_DEFINED +#define _CRT_WPERROR_DEFINED + _CRTIMP void __cdecl _wperror(const wchar_t *_ErrMsg); +#endif + _CRTIMP FILE *__cdecl _wpopen(const wchar_t *_Command,const wchar_t *_Mode); +#if !defined(NO_OLDNAMES) && !defined(wpopen) +#define wpopen _wpopen #endif + _CRTIMP int __cdecl _wremove(const wchar_t *_Filename); + _CRTIMP wchar_t *__cdecl _wtmpnam(wchar_t *_Buffer); + _CRTIMP wint_t __cdecl _fgetwc_nolock(FILE *_File); + _CRTIMP wint_t __cdecl _fputwc_nolock(wchar_t _Ch,FILE *_File); + _CRTIMP wint_t __cdecl _ungetwc_nolock(wint_t _Ch,FILE *_File); -#define _WSTDIO_DEFINED -#endif /* _WSTDIO_DEFINED */ +#undef _CRT_GETPUTWCHAR_NOINLINE -#ifndef __STRICT_ANSI__ -#ifdef __MSVCRT__ -#ifndef NO_OLDNAMES -FILE* wpopen (const wchar_t*, const wchar_t*); -#endif /* not NO_OLDNAMES */ -#endif /* MSVCRT runtime */ +#if !defined(__cplusplus) || defined(_CRT_GETPUTWCHAR_NOINLINE) +#define getwchar() fgetwc(stdin) +#define putwchar(_c) fputwc((_c),stdout) +#else + __CRT_INLINE wint_t __cdecl getwchar() { return (fgetwc(stdin)); } + __CRT_INLINE wint_t __cdecl putwchar(wchar_t _C) { return (fputwc(_C,stdout)); } +#endif -/* - * Other Non ANSI wide functions - */ -wint_t _fgetwchar (void); -wint_t _fputwchar (wint_t); -int _getw (FILE*); -int _putw (int, FILE*); +#define getwc(_stm) fgetwc(_stm) +#define putwc(_c,_stm) fputwc(_c,_stm) +#define _putwc_nolock(_c,_stm) _fputwc_nolock(_c,_stm) +#define _getwc_nolock(_stm) _fgetwc_nolock(_stm) + +#define _WSTDIO_DEFINED +#endif -#ifndef _NO_OLDNAMES -wint_t fgetwchar (void); -wint_t fputwchar (wint_t); -int getw (FILE*); -int putw (int, FILE*); -#endif /* Not _NO_OLDNAMES */ +#define _STDIO_DEFINED +#endif -#endif /* __STRICT_ANSI */ +#define _fgetc_nolock(_stream) (--(_stream)->_cnt >= 0 ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream)) +#define _fputc_nolock(_c,_stream) (--(_stream)->_cnt >= 0 ? 0xff & (*(_stream)->_ptr++ = (char)(_c)) : _flsbuf((_c),(_stream))) +#define _getc_nolock(_stream) _fgetc_nolock(_stream) +#define _putc_nolock(_c,_stream) _fputc_nolock(_c,_stream) +#define _getchar_nolock() _getc_nolock(stdin) +#define _putchar_nolock(_c) _putc_nolock((_c),stdout) +#define _getwchar_nolock() _getwc_nolock(stdin) +#define _putwchar_nolock(_c) _putwc_nolock((_c),stdout) + + _CRTIMP void __cdecl _lock_file(FILE *_File); + _CRTIMP void __cdecl _unlock_file(FILE *_File); + _CRTIMP int __cdecl _fclose_nolock(FILE *_File); + _CRTIMP int __cdecl _fflush_nolock(FILE *_File); + _CRTIMP size_t __cdecl _fread_nolock(void *_DstBuf,size_t _ElementSize,size_t _Count,FILE *_File); + _CRTIMP int __cdecl _fseek_nolock(FILE *_File,long _Offset,int _Origin); + _CRTIMP long __cdecl _ftell_nolock(FILE *_File); + _CRTIMP int __cdecl _fseeki64_nolock(FILE *_File,__int64 _Offset,int _Origin); + _CRTIMP __int64 __cdecl _ftelli64_nolock(FILE *_File); + _CRTIMP size_t __cdecl _fwrite_nolock(const void *_DstBuf,size_t _Size,size_t _Count,FILE *_File); + _CRTIMP int __cdecl _ungetc_nolock(int _Ch,FILE *_File); + +#if !defined(NO_OLDNAMES) || !defined(_POSIX) +#define P_tmpdir _P_tmpdir +#define SYS_OPEN _SYS_OPEN + + char *__cdecl tempnam(const char *_Directory,const char *_FilePrefix); + int __cdecl fcloseall(void); + FILE *__cdecl fdopen(int _FileHandle,const char *_Format); + int __cdecl fgetchar(void); + int __cdecl fileno(FILE *_File); + int __cdecl flushall(void); + int __cdecl fputchar(int _Ch); + int __cdecl getw(FILE *_File); + int __cdecl putw(int _Ch,FILE *_File); + int __cdecl rmtmp(void); +#endif #ifdef __cplusplus } #endif -#endif /* Not RC_INVOKED */ +#pragma pack(pop) + +#include <sec_api/stdio_s.h> -#endif /* _STDIO_H_ */ +#endif diff --git a/tinyc/win32/include/stdlib.h b/tinyc/win32/include/stdlib.h index 37fae4879..96765b29e 100644 --- a/tinyc/win32/include/stdlib.h +++ b/tinyc/win32/include/stdlib.h @@ -1,482 +1,580 @@ -/* - * stdlib.h - * - * Definitions for common types, variables, and functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_STDLIB +#define _INC_STDLIB -#ifndef _STDLIB_H_ -#define _STDLIB_H_ - -/* All the headers include this file. */ #include <_mingw.h> +#include <limits.h> +#pragma pack(push,_CRT_PACKING) -#define __need_size_t -#define __need_wchar_t -#define __need_NULL -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* RC_INVOKED */ - -/* - * RAND_MAX is the maximum value that may be returned by rand. - * The minimum is zero. - */ -#define RAND_MAX 0x7FFF - -/* - * These values may be used as exit status codes. - */ -#define EXIT_SUCCESS 0 -#define EXIT_FAILURE 1 - -/* - * Definitions for path name functions. - * NOTE: All of these values have simply been chosen to be conservatively high. - * Remember that with long file names we can no longer depend on - * extensions being short. - */ -#ifndef __STRICT_ANSI__ - -#ifndef MAX_PATH -#define MAX_PATH (260) +#ifdef __cplusplus +extern "C" { #endif -#define _MAX_PATH MAX_PATH -#define _MAX_DRIVE (3) -#define _MAX_DIR 256 -#define _MAX_FNAME 256 -#define _MAX_EXT 256 +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif -#endif /* Not __STRICT_ANSI__ */ +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +#ifndef _ONEXIT_T_DEFINED +#define _ONEXIT_T_DEFINED -#ifndef RC_INVOKED + typedef int (__cdecl *_onexit_t)(void); -#ifdef __cplusplus -extern "C" { +#ifndef NO_OLDNAMES +#define onexit_t _onexit_t +#endif #endif -/* - * This seems like a convenient place to declare these variables, which - * give programs using WinMain (or main for that matter) access to main-ish - * argc and argv. environ is a pointer to a table of environment variables. - * NOTE: Strings in _argv and environ are ANSI strings. - */ -extern int _argc; -extern char** _argv; +#ifndef _DIV_T_DEFINED +#define _DIV_T_DEFINED -/* imports from runtime dll of the above variables */ -#ifdef __MSVCRT__ + typedef struct _div_t { + int quot; + int rem; + } div_t; -extern int* __p___argc(void); -extern char*** __p___argv(void); -extern wchar_t*** __p___wargv(void); + typedef struct _ldiv_t { + long quot; + long rem; + } ldiv_t; +#endif -#define __argc (*__p___argc()) -#define __argv (*__p___argv()) -#define __wargv (*__p___wargv()) +#ifndef _CRT_DOUBLE_DEC +#define _CRT_DOUBLE_DEC -#else /* !MSVCRT */ +#pragma pack(4) + typedef struct { + unsigned char ld[10]; + } _LDOUBLE; +#pragma pack() -#ifndef __DECLSPEC_SUPPORTED +#define _PTR_LD(x) ((unsigned char *)(&(x)->ld)) -extern int* __imp___argc_dll; -extern char*** __imp___argv_dll; -#define __argc (*__imp___argc_dll) -#define __argv (*__imp___argv_dll) + typedef struct { + double x; + } _CRT_DOUBLE; -#else /* __DECLSPEC_SUPPORTED */ + typedef struct { + float f; + } _CRT_FLOAT; -__MINGW_IMPORT int __argc_dll; -__MINGW_IMPORT char** __argv_dll; -#define __argc __argc_dll -#define __argv __argv_dll +#pragma push_macro("long") +#undef long -#endif /* __DECLSPEC_SUPPORTED */ + typedef struct { + long double x; + } _LONGDOUBLE; -#endif /* __MSVCRT */ +#pragma pop_macro("long") -/* - * Also defined in ctype.h. - */ +#pragma pack(4) + typedef struct { + unsigned char ld12[12]; + } _LDBL12; +#pragma pack() +#endif -#ifndef MB_CUR_MAX -# ifdef __MSVCRT__ -# define MB_CUR_MAX __mb_cur_max - __MINGW_IMPORT int __mb_cur_max; -# else /* not __MSVCRT */ -# define MB_CUR_MAX __mb_cur_max_dll - __MINGW_IMPORT int __mb_cur_max_dll; -# endif /* not __MSVCRT */ -#endif /* MB_CUR_MAX */ - -/* - * MS likes to declare errno in stdlib.h as well. - */ +#define RAND_MAX 0x7fff -#ifdef _UWIN -#undef errno -extern int errno; +#ifndef MB_CUR_MAX +#define MB_CUR_MAX ___mb_cur_max_func() +#ifndef __mb_cur_max +#ifdef _MSVCRT_ + extern int __mb_cur_max; #else -int* _errno(void); -#define errno (*_errno()) +#define __mb_cur_max (*_imp____mb_cur_max) + extern int *_imp____mb_cur_max; +#endif +#endif +#ifdef _MSVCRT_ + extern int __mbcur_max; +#define ___mb_cur_max_func() (__mb_cur_max) +#else + extern int* _imp____mbcur_max; +#define ___mb_cur_max_func() (*_imp____mb_cur_max) +#endif #endif -int* __doserrno(void); -#define _doserrno (*__doserrno()) - -/* - * Use environ from the DLL, not as a global. - */ - -#ifdef __MSVCRT__ - extern char *** __p__environ(void); - extern wchar_t *** __p__wenviron(void); -# define _environ (*__p__environ()) -# define _wenviron (*__p__wenviron()) -#else /* ! __MSVCRT__ */ -# ifndef __DECLSPEC_SUPPORTED - extern char *** __imp__environ_dll; -# define _environ (*__imp__environ_dll) -# else /* __DECLSPEC_SUPPORTED */ - __MINGW_IMPORT char ** _environ_dll; -# define _environ _environ_dll -# endif /* __DECLSPEC_SUPPORTED */ -#endif /* ! __MSVCRT__ */ -#define environ _environ +#define __max(a,b) (((a) > (b)) ? (a) : (b)) +#define __min(a,b) (((a) < (b)) ? (a) : (b)) -#ifdef __MSVCRT__ -/* One of the MSVCRTxx libraries */ - -#ifndef __DECLSPEC_SUPPORTED - extern int* __imp__sys_nerr; -# define sys_nerr (*__imp__sys_nerr) -#else /* __DECLSPEC_SUPPORTED */ - __MINGW_IMPORT int _sys_nerr; -# ifndef _UWIN -# define sys_nerr _sys_nerr -# endif /* _UWIN */ -#endif /* __DECLSPEC_SUPPORTED */ - -#else /* ! __MSVCRT__ */ - -/* CRTDLL run time library */ - -#ifndef __DECLSPEC_SUPPORTED - extern int* __imp__sys_nerr_dll; -# define sys_nerr (*__imp__sys_nerr_dll) -#else /* __DECLSPEC_SUPPORTED */ - __MINGW_IMPORT int _sys_nerr_dll; -# define sys_nerr _sys_nerr_dll -#endif /* __DECLSPEC_SUPPORTED */ - -#endif /* ! __MSVCRT__ */ - -#ifndef __DECLSPEC_SUPPORTED -extern char*** __imp__sys_errlist; -#define sys_errlist (*__imp__sys_errlist) -#else /* __DECLSPEC_SUPPORTED */ -__MINGW_IMPORT char* _sys_errlist[]; -#ifndef _UWIN -#define sys_errlist _sys_errlist -#endif /* _UWIN */ -#endif /* __DECLSPEC_SUPPORTED */ - -/* - * OS version and such constants. - */ -#ifndef __STRICT_ANSI__ +#define _MAX_PATH 260 +#define _MAX_DRIVE 3 +#define _MAX_DIR 256 +#define _MAX_FNAME 256 +#define _MAX_EXT 256 -#ifdef __MSVCRT__ -/* msvcrtxx.dll */ +#define _OUT_TO_DEFAULT 0 +#define _OUT_TO_STDERR 1 +#define _OUT_TO_MSGBOX 2 +#define _REPORT_ERRMODE 3 -extern unsigned int* __p__osver(void); -extern unsigned int* __p__winver(void); -extern unsigned int* __p__winmajor(void); -extern unsigned int* __p__winminor(void); +#define _WRITE_ABORT_MSG 0x1 +#define _CALL_REPORTFAULT 0x2 -#define _osver (*__p__osver()) -#define _winver (*__p__winver()) -#define _winmajor (*__p__winmajor()) -#define _winminor (*__p__winminor()) +#define _MAX_ENV 32767 -#else -/* Not msvcrtxx.dll, thus crtdll.dll */ - -#ifndef __DECLSPEC_SUPPORTED - -extern unsigned int* _imp___osver_dll; -extern unsigned int* _imp___winver_dll; -extern unsigned int* _imp___winmajor_dll; -extern unsigned int* _imp___winminor_dll; - -#define _osver (*_imp___osver_dll) -#define _winver (*_imp___winver_dll) -#define _winmajor (*_imp___winmajor_dll) -#define _winminor (*_imp___winminor_dll) - -#else /* __DECLSPEC_SUPPORTED */ - -__MINGW_IMPORT unsigned int _osver_dll; -__MINGW_IMPORT unsigned int _winver_dll; -__MINGW_IMPORT unsigned int _winmajor_dll; -__MINGW_IMPORT unsigned int _winminor_dll; - -#define _osver _osver_dll -#define _winver _winver_dll -#define _winmajor _winmajor_dll -#define _winminor _winminor_dll - -#endif /* __DECLSPEC_SUPPORTED */ - -#endif - -#if defined __MSVCRT__ -/* although the _pgmptr is exported as DATA, - * be safe and use the access function __p__pgmptr() to get it. */ -char** __p__pgmptr(void); -#define _pgmptr (*__p__pgmptr()) -wchar_t** __p__wpgmptr(void); -#define _wpgmptr (*__p__wpgmptr()) -#else /* ! __MSVCRT__ */ -# ifndef __DECLSPEC_SUPPORTED - extern char** __imp__pgmptr_dll; -# define _pgmptr (*__imp__pgmptr_dll) -# else /* __DECLSPEC_SUPPORTED */ - __MINGW_IMPORT char* _pgmptr_dll; -# define _pgmptr _pgmptr_dll -# endif /* __DECLSPEC_SUPPORTED */ -/* no wide version in CRTDLL */ -#endif /* __MSVCRT__ */ - -#endif /* Not __STRICT_ANSI__ */ - -#ifdef __GNUC__ -#define _ATTRIB_NORETURN __attribute__ ((noreturn)) -#else /* Not __GNUC__ */ -#define _ATTRIB_NORETURN -#endif /* __GNUC__ */ - -double atof (const char*); -int atoi (const char*); -long atol (const char*); -int _wtoi (const wchar_t *); -long _wtol (const wchar_t *); - -double strtod (const char*, char**); -#if !defined __NO_ISOCEXT /* extern stubs in static libmingwex.a */ -extern __inline__ float strtof (const char *nptr, char **endptr) - { return (strtod (nptr, endptr));} -#endif /* __NO_ISOCEXT */ + typedef void (__cdecl *_purecall_handler)(void); -long strtol (const char*, char**, int); -unsigned long strtoul (const char*, char**, int); + _CRTIMP _purecall_handler __cdecl _set_purecall_handler(_purecall_handler _Handler); + _CRTIMP _purecall_handler __cdecl _get_purecall_handler(void); -#ifndef _WSTDLIB_DEFINED -/* also declared in wchar.h */ -double wcstod (const wchar_t*, wchar_t**); -#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */ -extern __inline__ float wcstof( const wchar_t *nptr, wchar_t **endptr) -{ return (wcstod(nptr, endptr)); } -#endif /* __NO_ISOCEXT */ + typedef void (__cdecl *_invalid_parameter_handler)(const wchar_t *,const wchar_t *,const wchar_t *,unsigned int,uintptr_t); + _invalid_parameter_handler __cdecl _set_invalid_parameter_handler(_invalid_parameter_handler _Handler); + _invalid_parameter_handler __cdecl _get_invalid_parameter_handler(void); -long wcstol (const wchar_t*, wchar_t**, int); -unsigned long wcstoul (const wchar_t*, wchar_t**, int); -#define _WSTDLIB_DEFINED +#ifndef _CRT_ERRNO_DEFINED +#define _CRT_ERRNO_DEFINED + _CRTIMP extern int *__cdecl _errno(void); +#define errno (*_errno()) + errno_t __cdecl _set_errno(int _Value); + errno_t __cdecl _get_errno(int *_Value); +#endif + _CRTIMP unsigned long *__cdecl __doserrno(void); +#define _doserrno (*__doserrno()) + errno_t __cdecl _set_doserrno(unsigned long _Value); + errno_t __cdecl _get_doserrno(unsigned long *_Value); +#ifdef _MSVCRT_ + extern char *_sys_errlist[]; + extern int _sys_nerr; +#else + _CRTIMP char *_sys_errlist[1]; + _CRTIMP int _sys_nerr; +#endif +#if (defined(_X86_) && !defined(__x86_64)) + _CRTIMP int *__cdecl __p___argc(void); + _CRTIMP char ***__cdecl __p___argv(void); + _CRTIMP wchar_t ***__cdecl __p___wargv(void); + _CRTIMP char ***__cdecl __p__environ(void); + _CRTIMP wchar_t ***__cdecl __p__wenviron(void); + _CRTIMP char **__cdecl __p__pgmptr(void); + _CRTIMP wchar_t **__cdecl __p__wpgmptr(void); +#endif +#ifndef __argc +#ifdef _MSVCRT_ + extern int __argc; +#else +#define __argc (*_imp____argc) + extern int *_imp____argc; +#endif +#endif +#ifndef __argv +#ifdef _MSVCRT_ + extern char **__argv; +#else +#define __argv (*_imp____argv) + extern char ***_imp____argv; +#endif +#endif +#ifndef __wargv +#ifdef _MSVCRT_ + extern wchar_t **__wargv; +#else +#define __wargv (*_imp____wargv) + extern wchar_t ***_imp____wargv; +#endif #endif -size_t wcstombs (char*, const wchar_t*, size_t); -int wctomb (char*, wchar_t); - -int mblen (const char*, size_t); -size_t mbstowcs (wchar_t*, const char*, size_t); -int mbtowc (wchar_t*, const char*, size_t); +#ifdef _POSIX_ + extern char **environ; +#else +#ifndef _environ +#ifdef _MSVCRT_ + extern char **_environ; +#else +#define _environ (*_imp___environ) + extern char ***_imp___environ; +#endif +#endif -int rand (void); -void srand (unsigned int); +#ifndef _wenviron +#ifdef _MSVCRT_ + extern wchar_t **_wenviron; +#else +#define _wenviron (*_imp___wenviron) + extern wchar_t ***_imp___wenviron; +#endif +#endif +#endif +#ifndef _pgmptr +#ifdef _MSVCRT_ + extern char *_pgmptr; +#else +#define _pgmptr (*_imp___pgmptr) + extern char **_imp___pgmptr; +#endif +#endif -void* calloc (size_t, size_t); -void* malloc (size_t); -void* realloc (void*, size_t); -void free (void*); +#ifndef _wpgmptr +#ifdef _MSVCRT_ + extern wchar_t *_wpgmptr; +#else +#define _wpgmptr (*_imp___wpgmptr) + extern wchar_t **_imp___wpgmptr; +#endif +#endif + errno_t __cdecl _get_pgmptr(char **_Value); + errno_t __cdecl _get_wpgmptr(wchar_t **_Value); +#ifndef _fmode +#ifdef _MSVCRT_ + extern int _fmode; +#else +#define _fmode (*_imp___fmode) + extern int *_imp___fmode; +#endif +#endif + _CRTIMP errno_t __cdecl _set_fmode(int _Mode); + _CRTIMP errno_t __cdecl _get_fmode(int *_PMode); -void abort (void) _ATTRIB_NORETURN; -void exit (int) _ATTRIB_NORETURN; -int atexit (void (*)(void)); +#ifndef _osplatform +#ifdef _MSVCRT_ + extern unsigned int _osplatform; +#else +#define _osplatform (*_imp___osplatform) + extern unsigned int *_imp___osplatform; +#endif +#endif -int system (const char*); -char* getenv (const char*); +#ifndef _osver +#ifdef _MSVCRT_ + extern unsigned int _osver; +#else +#define _osver (*_imp___osver) + extern unsigned int *_imp___osver; +#endif +#endif -void* bsearch (const void*, const void*, size_t, size_t, - int (*)(const void*, const void*)); -void qsort (const void*, size_t, size_t, - int (*)(const void*, const void*)); +#ifndef _winver +#ifdef _MSVCRT_ + extern unsigned int _winver; +#else +#define _winver (*_imp___winver) + extern unsigned int *_imp___winver; +#endif +#endif -int abs (int); -long labs (long); +#ifndef _winmajor +#ifdef _MSVCRT_ + extern unsigned int _winmajor; +#else +#define _winmajor (*_imp___winmajor) + extern unsigned int *_imp___winmajor; +#endif +#endif -/* - * div_t and ldiv_t are structures used to return the results of div and - * ldiv. - * - * NOTE: div and ldiv appear not to work correctly unless - * -fno-pcc-struct-return is specified. This is included in the - * mingw32 specs file. - */ -typedef struct { int quot, rem; } div_t; -typedef struct { long quot, rem; } ldiv_t; +#ifndef _winminor +#ifdef _MSVCRT_ + extern unsigned int _winminor; +#else +#define _winminor (*_imp___winminor) + extern unsigned int *_imp___winminor; +#endif +#endif -div_t div (int, int); -ldiv_t ldiv (long, long); + errno_t __cdecl _get_osplatform(unsigned int *_Value); + errno_t __cdecl _get_osver(unsigned int *_Value); + errno_t __cdecl _get_winver(unsigned int *_Value); + errno_t __cdecl _get_winmajor(unsigned int *_Value); + errno_t __cdecl _get_winminor(unsigned int *_Value); +#ifndef _countof +#ifndef __cplusplus +#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) +#else + extern "C++" { + template <typename _CountofType,size_t _SizeOfArray> char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray]; +#define _countof(_Array) sizeof(*__countof_helper(_Array)) + } +#endif +#endif -#ifndef __STRICT_ANSI__ +#ifndef _CRT_TERMINATE_DEFINED +#define _CRT_TERMINATE_DEFINED + void __cdecl __MINGW_NOTHROW exit(int _Code) __MINGW_ATTRIB_NORETURN; + _CRTIMP void __cdecl __MINGW_NOTHROW _exit(int _Code) __MINGW_ATTRIB_NORETURN; +#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */ + /* C99 function name */ + void __cdecl _Exit(int) __MINGW_ATTRIB_NORETURN; + __CRT_INLINE __MINGW_ATTRIB_NORETURN void __cdecl _Exit(int status) + { _exit(status); } +#endif -/* - * NOTE: Officially the three following functions are obsolete. The Win32 API - * functions SetErrorMode, Beep and Sleep are their replacements. - */ -void _beep (unsigned int, unsigned int); -void _seterrormode (int); -void _sleep (unsigned long); +#pragma push_macro("abort") +#undef abort + void __cdecl __declspec(noreturn) abort(void); +#pragma pop_macro("abort") -void _exit (int) _ATTRIB_NORETURN; -#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */ -/* C99 function name */ -void _Exit(int) _ATTRIB_NORETURN; /* Declare to get noreturn attribute. */ -extern __inline__ void _Exit(int status) - { _exit(status); } #endif -/* _onexit is MS extension. Use atexit for portability. */ -typedef int (* _onexit_t)(void); -_onexit_t _onexit( _onexit_t ); -int _putenv (const char*); -void _searchenv (const char*, const char*, char*); + _CRTIMP unsigned int __cdecl _set_abort_behavior(unsigned int _Flags,unsigned int _Mask); +#ifndef _CRT_ABS_DEFINED +#define _CRT_ABS_DEFINED + int __cdecl abs(int _X); + long __cdecl labs(long _X); +#endif -char* _ecvt (double, int, int*, int*); -char* _fcvt (double, int, int*, int*); -char* _gcvt (double, int, char*); +#if _INTEGRAL_MAX_BITS >= 64 + __int64 __cdecl _abs64(__int64); +#endif + int __cdecl atexit(void (__cdecl *)(void)); +#ifndef _CRT_ATOF_DEFINED +#define _CRT_ATOF_DEFINED + double __cdecl atof(const char *_String); + double __cdecl _atof_l(const char *_String,_locale_t _Locale); +#endif + int __cdecl atoi(const char *_Str); + _CRTIMP int __cdecl _atoi_l(const char *_Str,_locale_t _Locale); + long __cdecl atol(const char *_Str); + _CRTIMP long __cdecl _atol_l(const char *_Str,_locale_t _Locale); +#ifndef _CRT_ALGO_DEFINED +#define _CRT_ALGO_DEFINED + void *__cdecl bsearch(const void *_Key,const void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); + void __cdecl qsort(void *_Base,size_t _NumOfElements,size_t _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); +#endif + unsigned short __cdecl _byteswap_ushort(unsigned short _Short); + /*unsigned long __cdecl _byteswap_ulong (unsigned long _Long); */ +#if _INTEGRAL_MAX_BITS >= 64 + unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 _Int64); +#endif + div_t __cdecl div(int _Numerator,int _Denominator); + char *__cdecl getenv(const char *_VarName); + _CRTIMP char *__cdecl _itoa(int _Value,char *_Dest,int _Radix); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP char *__cdecl _i64toa(__int64 _Val,char *_DstBuf,int _Radix); + _CRTIMP char *__cdecl _ui64toa(unsigned __int64 _Val,char *_DstBuf,int _Radix); + _CRTIMP __int64 __cdecl _atoi64(const char *_String); + _CRTIMP __int64 __cdecl _atoi64_l(const char *_String,_locale_t _Locale); + _CRTIMP __int64 __cdecl _strtoi64(const char *_String,char **_EndPtr,int _Radix); + _CRTIMP __int64 __cdecl _strtoi64_l(const char *_String,char **_EndPtr,int _Radix,_locale_t _Locale); + _CRTIMP unsigned __int64 __cdecl _strtoui64(const char *_String,char **_EndPtr,int _Radix); + _CRTIMP unsigned __int64 __cdecl _strtoui64_l(const char *_String,char **_EndPtr,int _Radix,_locale_t _Locale); +#endif + ldiv_t __cdecl ldiv(long _Numerator,long _Denominator); + _CRTIMP char *__cdecl _ltoa(long _Value,char *_Dest,int _Radix); + int __cdecl mblen(const char *_Ch,size_t _MaxCount); + _CRTIMP int __cdecl _mblen_l(const char *_Ch,size_t _MaxCount,_locale_t _Locale); + _CRTIMP size_t __cdecl _mbstrlen(const char *_Str); + _CRTIMP size_t __cdecl _mbstrlen_l(const char *_Str,_locale_t _Locale); + _CRTIMP size_t __cdecl _mbstrnlen(const char *_Str,size_t _MaxCount); + _CRTIMP size_t __cdecl _mbstrnlen_l(const char *_Str,size_t _MaxCount,_locale_t _Locale); + int __cdecl mbtowc(wchar_t *_DstCh,const char *_SrcCh,size_t _SrcSizeInBytes); + _CRTIMP int __cdecl _mbtowc_l(wchar_t *_DstCh,const char *_SrcCh,size_t _SrcSizeInBytes,_locale_t _Locale); + size_t __cdecl mbstowcs(wchar_t *_Dest,const char *_Source,size_t _MaxCount); + _CRTIMP size_t __cdecl _mbstowcs_l(wchar_t *_Dest,const char *_Source,size_t _MaxCount,_locale_t _Locale); + int __cdecl rand(void); + _CRTIMP int __cdecl _set_error_mode(int _Mode); + void __cdecl srand(unsigned int _Seed); + double __cdecl strtod(const char *_Str,char **_EndPtr); + float __cdecl strtof(const char *nptr, char **endptr); +#if !defined __NO_ISOCEXT /* in libmingwex.a */ + float __cdecl strtof (const char * __restrict__, char ** __restrict__); + long double __cdecl strtold(const char * __restrict__, char ** __restrict__); +#endif /* __NO_ISOCEXT */ + _CRTIMP double __cdecl _strtod_l(const char *_Str,char **_EndPtr,_locale_t _Locale); + long __cdecl strtol(const char *_Str,char **_EndPtr,int _Radix); + _CRTIMP long __cdecl _strtol_l(const char *_Str,char **_EndPtr,int _Radix,_locale_t _Locale); + unsigned long __cdecl strtoul(const char *_Str,char **_EndPtr,int _Radix); + _CRTIMP unsigned long __cdecl _strtoul_l(const char *_Str,char **_EndPtr,int _Radix,_locale_t _Locale); +#ifndef _CRT_SYSTEM_DEFINED +#define _CRT_SYSTEM_DEFINED + int __cdecl system(const char *_Command); +#endif + _CRTIMP char *__cdecl _ultoa(unsigned long _Value,char *_Dest,int _Radix); + int __cdecl wctomb(char *_MbCh,wchar_t _WCh); + _CRTIMP int __cdecl _wctomb_l(char *_MbCh,wchar_t _WCh,_locale_t _Locale); + size_t __cdecl wcstombs(char *_Dest,const wchar_t *_Source,size_t _MaxCount); + _CRTIMP size_t __cdecl _wcstombs_l(char *_Dest,const wchar_t *_Source,size_t _MaxCount,_locale_t _Locale); + +#ifndef _CRT_ALLOCATION_DEFINED +#define _CRT_ALLOCATION_DEFINED + void *__cdecl calloc(size_t _NumOfElements,size_t _SizeOfElements); + void __cdecl free(void *_Memory); + void *__cdecl malloc(size_t _Size); + void *__cdecl realloc(void *_Memory,size_t _NewSize); + _CRTIMP void *__cdecl _recalloc(void *_Memory,size_t _Count,size_t _Size); + //_CRTIMP void __cdecl _aligned_free(void *_Memory); + //_CRTIMP void *__cdecl _aligned_malloc(size_t _Size,size_t _Alignment); + _CRTIMP void *__cdecl _aligned_offset_malloc(size_t _Size,size_t _Alignment,size_t _Offset); + _CRTIMP void *__cdecl _aligned_realloc(void *_Memory,size_t _Size,size_t _Alignment); + _CRTIMP void *__cdecl _aligned_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment); + _CRTIMP void *__cdecl _aligned_offset_realloc(void *_Memory,size_t _Size,size_t _Alignment,size_t _Offset); + _CRTIMP void *__cdecl _aligned_offset_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment,size_t _Offset); +#endif -void _makepath (char*, const char*, const char*, const char*, const char*); -void _splitpath (const char*, char*, char*, char*, char*); -char* _fullpath (char*, const char*, size_t); +#ifndef _WSTDLIB_DEFINED +#define _WSTDLIB_DEFINED + _CRTIMP wchar_t *__cdecl _itow(int _Value,wchar_t *_Dest,int _Radix); + _CRTIMP wchar_t *__cdecl _ltow(long _Value,wchar_t *_Dest,int _Radix); + _CRTIMP wchar_t *__cdecl _ultow(unsigned long _Value,wchar_t *_Dest,int _Radix); + double __cdecl wcstod(const wchar_t *_Str,wchar_t **_EndPtr); + float __cdecl wcstof(const wchar_t *nptr, wchar_t **endptr); +#if !defined __NO_ISOCEXT /* in libmingwex.a */ + float __cdecl wcstof( const wchar_t * __restrict__, wchar_t ** __restrict__); + long double __cdecl wcstold(const wchar_t * __restrict__, wchar_t ** __restrict__); +#endif /* __NO_ISOCEXT */ + _CRTIMP double __cdecl _wcstod_l(const wchar_t *_Str,wchar_t **_EndPtr,_locale_t _Locale); + long __cdecl wcstol(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix); + _CRTIMP long __cdecl _wcstol_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale); + unsigned long __cdecl wcstoul(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix); + _CRTIMP unsigned long __cdecl _wcstoul_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale); + _CRTIMP wchar_t *__cdecl _wgetenv(const wchar_t *_VarName); +#ifndef _CRT_WSYSTEM_DEFINED +#define _CRT_WSYSTEM_DEFINED + _CRTIMP int __cdecl _wsystem(const wchar_t *_Command); +#endif + _CRTIMP double __cdecl _wtof(const wchar_t *_Str); + _CRTIMP double __cdecl _wtof_l(const wchar_t *_Str,_locale_t _Locale); + _CRTIMP int __cdecl _wtoi(const wchar_t *_Str); + _CRTIMP int __cdecl _wtoi_l(const wchar_t *_Str,_locale_t _Locale); + _CRTIMP long __cdecl _wtol(const wchar_t *_Str); + _CRTIMP long __cdecl _wtol_l(const wchar_t *_Str,_locale_t _Locale); + +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP wchar_t *__cdecl _i64tow(__int64 _Val,wchar_t *_DstBuf,int _Radix); + _CRTIMP wchar_t *__cdecl _ui64tow(unsigned __int64 _Val,wchar_t *_DstBuf,int _Radix); + _CRTIMP __int64 __cdecl _wtoi64(const wchar_t *_Str); + _CRTIMP __int64 __cdecl _wtoi64_l(const wchar_t *_Str,_locale_t _Locale); + _CRTIMP __int64 __cdecl _wcstoi64(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix); + _CRTIMP __int64 __cdecl _wcstoi64_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale); + _CRTIMP unsigned __int64 __cdecl _wcstoui64(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix); + _CRTIMP unsigned __int64 __cdecl _wcstoui64_l(const wchar_t *_Str ,wchar_t **_EndPtr,int _Radix,_locale_t _Locale); +#endif +#endif -char* _itoa (int, char*, int); -char* _ltoa (long, char*, int); -char* _ultoa(unsigned long, char*, int); -wchar_t* _itow (int, wchar_t*, int); -wchar_t* _ltow (long, wchar_t*, int); -wchar_t* _ultow (unsigned long, wchar_t*, int); +#ifndef _POSIX_ +#define _CVTBUFSIZE (309+40) + _CRTIMP char *__cdecl _fullpath(char *_FullPath,const char *_Path,size_t _SizeInBytes); + _CRTIMP char *__cdecl _ecvt(double _Val,int _NumOfDigits,int *_PtDec,int *_PtSign); + _CRTIMP char *__cdecl _fcvt(double _Val,int _NumOfDec,int *_PtDec,int *_PtSign); + _CRTIMP char *__cdecl _gcvt(double _Val,int _NumOfDigits,char *_DstBuf); + _CRTIMP int __cdecl _atodbl(_CRT_DOUBLE *_Result,char *_Str); + _CRTIMP int __cdecl _atoldbl(_LDOUBLE *_Result,char *_Str); + _CRTIMP int __cdecl _atoflt(_CRT_FLOAT *_Result,char *_Str); + _CRTIMP int __cdecl _atodbl_l(_CRT_DOUBLE *_Result,char *_Str,_locale_t _Locale); + _CRTIMP int __cdecl _atoldbl_l(_LDOUBLE *_Result,char *_Str,_locale_t _Locale); + _CRTIMP int __cdecl _atoflt_l(_CRT_FLOAT *_Result,char *_Str,_locale_t _Locale); + unsigned long __cdecl _lrotl(unsigned long _Val,int _Shift); + unsigned long __cdecl _lrotr(unsigned long _Val,int _Shift); + _CRTIMP void __cdecl _makepath(char *_Path,const char *_Drive,const char *_Dir,const char *_Filename,const char *_Ext); + _onexit_t __cdecl _onexit(_onexit_t _Func); + +#ifndef _CRT_PERROR_DEFINED +#define _CRT_PERROR_DEFINED + void __cdecl perror(const char *_ErrMsg); +#endif + _CRTIMP int __cdecl _putenv(const char *_EnvString); + unsigned int __cdecl _rotl(unsigned int _Val,int _Shift); +#if _INTEGRAL_MAX_BITS >= 64 + unsigned __int64 __cdecl _rotl64(unsigned __int64 _Val,int _Shift); +#endif + unsigned int __cdecl _rotr(unsigned int _Val,int _Shift); +#if _INTEGRAL_MAX_BITS >= 64 + unsigned __int64 __cdecl _rotr64(unsigned __int64 _Val,int _Shift); +#endif + _CRTIMP void __cdecl _searchenv(const char *_Filename,const char *_EnvVar,char *_ResultPath); + _CRTIMP void __cdecl _splitpath(const char *_FullPath,char *_Drive,char *_Dir,char *_Filename,char *_Ext); + _CRTIMP void __cdecl _swab(char *_Buf1,char *_Buf2,int _SizeInBytes); + +#ifndef _WSTDLIBP_DEFINED +#define _WSTDLIBP_DEFINED + _CRTIMP wchar_t *__cdecl _wfullpath(wchar_t *_FullPath,const wchar_t *_Path,size_t _SizeInWords); + _CRTIMP void __cdecl _wmakepath(wchar_t *_ResultPath,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext); +#ifndef _CRT_WPERROR_DEFINED +#define _CRT_WPERROR_DEFINED + _CRTIMP void __cdecl _wperror(const wchar_t *_ErrMsg); +#endif + _CRTIMP int __cdecl _wputenv(const wchar_t *_EnvString); + _CRTIMP void __cdecl _wsearchenv(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath); + _CRTIMP void __cdecl _wsplitpath(const wchar_t *_FullPath,wchar_t *_Drive,wchar_t *_Dir,wchar_t *_Filename,wchar_t *_Ext); +#endif -#ifdef __MSVCRT__ -__int64 _atoi64(const char *); -char* _i64toa(__int64, char *, int); -char* _ui64toa(unsigned __int64, char *, int); -__int64 _wtoi64(const wchar_t *); -wchar_t* _i64tow(__int64, wchar_t *, int); -wchar_t* _ui64tow(unsigned __int64, wchar_t *, int); + _CRTIMP void __cdecl _beep(unsigned _Frequency,unsigned _Duration) __MINGW_ATTRIB_DEPRECATED; + /* Not to be confused with _set_error_mode (int). */ + _CRTIMP void __cdecl _seterrormode(int _Mode) __MINGW_ATTRIB_DEPRECATED; + _CRTIMP void __cdecl _sleep(unsigned long _Duration) __MINGW_ATTRIB_DEPRECATED; +#endif -wchar_t* _wgetenv(const wchar_t*); -int _wputenv(const wchar_t*); -void _wsearchenv(const wchar_t*, const wchar_t*, wchar_t*); -void _wmakepath(wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*); -void _wsplitpath (const wchar_t*, wchar_t*, wchar_t*, wchar_t*, wchar_t*); -wchar_t* _wfullpath (wchar_t*, const wchar_t*, size_t); +#ifndef NO_OLDNAMES +#ifndef _POSIX_ +#if 0 +#ifndef __cplusplus +#ifndef NOMINMAX +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif +#endif +#endif #endif -#ifndef _NO_OLDNAMES +#define sys_errlist _sys_errlist +#define sys_nerr _sys_nerr +#define environ _environ + char *__cdecl ecvt(double _Val,int _NumOfDigits,int *_PtDec,int *_PtSign); + char *__cdecl fcvt(double _Val,int _NumOfDec,int *_PtDec,int *_PtSign); + char *__cdecl gcvt(double _Val,int _NumOfDigits,char *_DstBuf); + char *__cdecl itoa(int _Val,char *_DstBuf,int _Radix); + char *__cdecl ltoa(long _Val,char *_DstBuf,int _Radix); + int __cdecl putenv(const char *_EnvString); + void __cdecl swab(char *_Buf1,char *_Buf2,int _SizeInBytes); + char *__cdecl ultoa(unsigned long _Val,char *_Dstbuf,int _Radix); + onexit_t __cdecl onexit(onexit_t _Func); +#endif +#endif -int putenv (const char*); -void searchenv (const char*, const char*, char*); +#if !defined __NO_ISOCEXT /* externs in static libmingwex.a */ -char* itoa (int, char*, int); -char* ltoa (long, char*, int); + typedef struct { long long quot, rem; } lldiv_t; -#ifndef _UWIN -char* ecvt (double, int, int*, int*); -char* fcvt (double, int, int*, int*); -char* gcvt (double, int, char*); -#endif /* _UWIN */ -#endif /* Not _NO_OLDNAMES */ + lldiv_t __cdecl lldiv(long long, long long); -#endif /* Not __STRICT_ANSI__ */ + __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); } -/* C99 names */ + long long __cdecl strtoll(const char* __restrict__, char** __restrict, int); + unsigned long long __cdecl strtoull(const char* __restrict__, char** __restrict__, int); -#if !defined __NO_ISOCEXT /* externs in static libmingwex.a */ + /* these are stubs for MS _i64 versions */ + long long __cdecl atoll (const char *); -typedef struct { long long quot, rem; } lldiv_t; - -lldiv_t lldiv (long long, long long); - -extern __inline__ long long llabs(long long _j) - {return (_j >= 0 ? _j : -_j);} - -long long strtoll (const char* __restrict__, char** __restrict, int); -unsigned long long strtoull (const char* __restrict__, char** __restrict__, int); - -#if defined (__MSVCRT__) /* these are stubs for MS _i64 versions */ -long long atoll (const char *); - -#if !defined (__STRICT_ANSI__) -long long wtoll(const wchar_t *); -char* lltoa(long long, char *, int); -char* ulltoa(unsigned long long , char *, int); -wchar_t* lltow(long long, wchar_t *, int); -wchar_t* ulltow(unsigned long long, wchar_t *, int); - - /* inline using non-ansi functions */ -extern __inline__ long long atoll (const char * _c) - { return _atoi64 (_c); } -extern __inline__ char* lltoa(long long _n, char * _c, int _i) - { return _i64toa (_n, _c, _i); } -extern __inline__ char* ulltoa(unsigned long long _n, char * _c, int _i) - { return _ui64toa (_n, _c, _i); } -extern __inline__ long long wtoll(const wchar_t * _w) - { return _wtoi64 (_w); } -extern __inline__ wchar_t* lltow(long long _n, wchar_t * _w, int _i) - { return _i64tow (_n, _w, _i); } -extern __inline__ wchar_t* ulltow(unsigned long long _n, wchar_t * _w, int _i) - { return _ui64tow (_n, _w, _i); } +#ifndef __STRICT_ANSI__ + long long __cdecl wtoll (const wchar_t *); + char *__cdecl lltoa (long long, char *, int); + char *__cdecl ulltoa (unsigned long long , char *, int); + wchar_t *__cdecl lltow (long long, wchar_t *, int); + wchar_t *__cdecl ulltow (unsigned long long, wchar_t *, int); + + /* __CRT_INLINE using non-ansi functions */ + __CRT_INLINE long long __cdecl atoll (const char * _c) { return _atoi64 (_c); } + __CRT_INLINE char *__cdecl lltoa (long long _n, char * _c, int _i) { return _i64toa (_n, _c, _i); } + __CRT_INLINE char *__cdecl ulltoa (unsigned long long _n, char * _c, int _i) { return _ui64toa (_n, _c, _i); } + __CRT_INLINE long long __cdecl wtoll (const wchar_t * _w) { return _wtoi64 (_w); } + __CRT_INLINE wchar_t *__cdecl lltow (long long _n, wchar_t * _w, int _i) { return _i64tow (_n, _w, _i); } + __CRT_INLINE wchar_t *__cdecl ulltow (unsigned long long _n, wchar_t * _w, int _i) { return _ui64tow (_n, _w, _i); } #endif /* (__STRICT_ANSI__) */ -#endif /* __MSVCRT__ */ - #endif /* !__NO_ISOCEXT */ -/* - * Undefine the no return attribute used in some function definitions - */ -#undef _ATTRIB_NORETURN - #ifdef __cplusplus } #endif -#endif /* Not RC_INVOKED */ +#pragma pack(pop) -#endif /* Not _STDLIB_H_ */ +#include <sec_api/stdlib_s.h> +#include <malloc.h> +#endif diff --git a/tinyc/win32/include/string.h b/tinyc/win32/include/string.h index 03dd48f8c..3249dc3ba 100644 --- a/tinyc/win32/include/string.h +++ b/tinyc/win32/include/string.h @@ -1,206 +1,164 @@ -/* - * string.h - * - * Definitions for memory and string functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_STRING +#define _INC_STRING -#ifndef _STRING_H_ -#define _STRING_H_ - -/* All the headers include this file. */ #include <_mingw.h> -/* - * Define size_t, wchar_t and NULL - */ -#define __need_size_t -#define __need_wchar_t -#define __need_NULL -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ - -#ifndef RC_INVOKED - #ifdef __cplusplus extern "C" { #endif -/* - * Prototypes of the ANSI Standard C library string functions. - */ -void* memchr (const void*, int, size_t); -int memcmp (const void*, const void*, size_t); -void* memcpy (void*, const void*, size_t); -void* memmove (void*, const void*, size_t); -void* memset (void*, int, size_t); -char* strcat (char*, const char*); -char* strchr (const char*, int); -int strcmp (const char*, const char*); -int strcoll (const char*, const char*); /* Compare using locale */ -char* strcpy (char*, const char*); -size_t strcspn (const char*, const char*); -char* strerror (int); /* NOTE: NOT an old name wrapper. */ -char* _strerror (const char *); -size_t strlen (const char*); -char* strncat (char*, const char*, size_t); -int strncmp (const char*, const char*, size_t); -char* strncpy (char*, const char*, size_t); -char* strpbrk (const char*, const char*); -char* strrchr (const char*, int); -size_t strspn (const char*, const char*); -char* strstr (const char*, const char*); -char* strtok (char*, const char*); -size_t strxfrm (char*, const char*, size_t); - -#ifndef __STRICT_ANSI__ -/* - * Extra non-ANSI functions provided by the CRTDLL library - */ -void* _memccpy (void*, const void*, int, size_t); -int _memicmp (const void*, const void*, size_t); -char* _strdup (const char*); -int _strcmpi (const char*, const char*); -int _stricmp (const char*, const char*); -int _stricoll (const char*, const char*); -char* _strlwr (char*); -int _strnicmp (const char*, const char*, size_t); -char* _strnset (char*, int, size_t); -char* _strrev (char*); -char* _strset (char*, int); -char* _strupr (char*); -void _swab (const char*, char*, size_t); - -/* - * Multi-byte character functions - */ -unsigned char* _mbschr (unsigned char*, unsigned char*); -unsigned char* _mbsncat (unsigned char*, const unsigned char*, size_t); -unsigned char* _mbstok (unsigned char*, unsigned char*); - -#ifdef __MSVCRT__ -int _strncoll(const char*, const char*, size_t); -int _strnicoll(const char*, const char*, size_t); +#ifndef _NLSCMP_DEFINED +#define _NLSCMP_DEFINED +#define _NLSCMPERROR 2147483647 #endif -#endif /* Not __STRICT_ANSI__ */ - -/* - * Unicode versions of the standard calls. - */ -wchar_t* wcscat (wchar_t*, const wchar_t*); -wchar_t* wcschr (const wchar_t*, wchar_t); -int wcscmp (const wchar_t*, const wchar_t*); -int wcscoll (const wchar_t*, const wchar_t*); -wchar_t* wcscpy (wchar_t*, const wchar_t*); -size_t wcscspn (const wchar_t*, const wchar_t*); -/* Note: No wcserror in CRTDLL. */ -size_t wcslen (const wchar_t*); -wchar_t* wcsncat (wchar_t*, const wchar_t*, size_t); -int wcsncmp(const wchar_t*, const wchar_t*, size_t); -wchar_t* wcsncpy(wchar_t*, const wchar_t*, size_t); -wchar_t* wcspbrk(const wchar_t*, const wchar_t*); -wchar_t* wcsrchr(const wchar_t*, wchar_t); -size_t wcsspn(const wchar_t*, const wchar_t*); -wchar_t* wcsstr(const wchar_t*, const wchar_t*); -wchar_t* wcstok(wchar_t*, const wchar_t*); -size_t wcsxfrm(wchar_t*, const wchar_t*, size_t); - -#ifndef __STRICT_ANSI__ -/* - * Unicode versions of non-ANSI functions provided by CRTDLL. - */ - -/* NOTE: _wcscmpi not provided by CRTDLL, this define is for portability */ -#define _wcscmpi _wcsicmp - -wchar_t* _wcsdup (wchar_t*); -int _wcsicmp (const wchar_t*, const wchar_t*); -int _wcsicoll (const wchar_t*, const wchar_t*); -wchar_t* _wcslwr (wchar_t*); -int _wcsnicmp (const wchar_t*, const wchar_t*, size_t); -wchar_t* _wcsnset (wchar_t*, wchar_t, size_t); -wchar_t* _wcsrev (wchar_t*); -wchar_t* _wcsset (wchar_t*, wchar_t); -wchar_t* _wcsupr (wchar_t*); - -#ifdef __MSVCRT__ -int _wcsncoll(const wchar_t*, const wchar_t*, size_t); -int _wcsnicoll(const wchar_t*, const wchar_t*, size_t); +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif #endif +#define _WConst_return _CONST_RETURN + +#ifndef _CRT_MEMORY_DEFINED +#define _CRT_MEMORY_DEFINED + _CRTIMP void *__cdecl _memccpy(void *_Dst,const void *_Src,int _Val,size_t _MaxCount); + _CONST_RETURN void *__cdecl memchr(const void *_Buf ,int _Val,size_t _MaxCount); + _CRTIMP int __cdecl _memicmp(const void *_Buf1,const void *_Buf2,size_t _Size); + _CRTIMP int __cdecl _memicmp_l(const void *_Buf1,const void *_Buf2,size_t _Size,_locale_t _Locale); + int __cdecl memcmp(const void *_Buf1,const void *_Buf2,size_t _Size); + void *__cdecl memcpy(void *_Dst,const void *_Src,size_t _Size); + void *__cdecl memset(void *_Dst,int _Val,size_t _Size); +#ifndef NO_OLDNAMES + void *__cdecl memccpy(void *_Dst,const void *_Src,int _Val,size_t _Size); + int __cdecl memicmp(const void *_Buf1,const void *_Buf2,size_t _Size); +#endif +#endif + char *__cdecl _strset(char *_Str,int _Val); + char *__cdecl strcpy(char *_Dest,const char *_Source); + char *__cdecl strcat(char *_Dest,const char *_Source); + int __cdecl strcmp(const char *_Str1,const char *_Str2); + size_t __cdecl strlen(const char *_Str); +#if 0 + size_t __cdecl strnlen(const char *_Str,size_t _MaxCount); +#endif + void *__cdecl memmove(void *_Dst,const void *_Src,size_t _Size); + _CRTIMP char *__cdecl _strdup(const char *_Src); + _CONST_RETURN char *__cdecl strchr(const char *_Str,int _Val); + _CRTIMP int __cdecl _stricmp(const char *_Str1,const char *_Str2); + _CRTIMP int __cdecl _strcmpi(const char *_Str1,const char *_Str2); + _CRTIMP int __cdecl _stricmp_l(const char *_Str1,const char *_Str2,_locale_t _Locale); + int __cdecl strcoll(const char *_Str1,const char *_Str2); + _CRTIMP int __cdecl _strcoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _stricoll(const char *_Str1,const char *_Str2); + _CRTIMP int __cdecl _stricoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _strncoll (const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _strncoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP int __cdecl _strnicoll (const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _strnicoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + size_t __cdecl strcspn(const char *_Str,const char *_Control); + _CRTIMP char *__cdecl _strerror(const char *_ErrMsg); + char *__cdecl strerror(int); + _CRTIMP char *__cdecl _strlwr(char *_String); + char *strlwr_l(char *_String,_locale_t _Locale); + char *__cdecl strncat(char *_Dest,const char *_Source,size_t _Count); + int __cdecl strncmp(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _strnicmp(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _strnicmp_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + char *strncpy(char *_Dest,const char *_Source,size_t _Count); + _CRTIMP char *__cdecl _strnset(char *_Str,int _Val,size_t _MaxCount); + _CONST_RETURN char *__cdecl strpbrk(const char *_Str,const char *_Control); + _CONST_RETURN char *__cdecl strrchr(const char *_Str,int _Ch); + _CRTIMP char *__cdecl _strrev(char *_Str); + size_t __cdecl strspn(const char *_Str,const char *_Control); + _CONST_RETURN char *__cdecl strstr(const char *_Str,const char *_SubStr); + char *__cdecl strtok(char *_Str,const char *_Delim); + _CRTIMP char *__cdecl _strupr(char *_String); + _CRTIMP char *_strupr_l(char *_String,_locale_t _Locale); + size_t __cdecl strxfrm(char *_Dst,const char *_Src,size_t _MaxCount); + _CRTIMP size_t __cdecl _strxfrm_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); + +#ifndef NO_OLDNAMES + char *__cdecl strdup(const char *_Src); + int __cdecl strcmpi(const char *_Str1,const char *_Str2); + int __cdecl stricmp(const char *_Str1,const char *_Str2); + char *__cdecl strlwr(char *_Str); + int __cdecl strnicmp(const char *_Str1,const char *_Str,size_t _MaxCount); + __CRT_INLINE int __cdecl strncasecmp (const char *__sz1, const char *__sz2, size_t __sizeMaxCompare) { return _strnicmp (__sz1, __sz2, __sizeMaxCompare); } + __CRT_INLINE int __cdecl strcasecmp (const char *__sz1, const char *__sz2) { return _stricmp (__sz1, __sz2); } + char *__cdecl strnset(char *_Str,int _Val,size_t _MaxCount); + char *__cdecl strrev(char *_Str); + char *__cdecl strset(char *_Str,int _Val); + char *__cdecl strupr(char *_Str); +#endif -#endif /* Not __STRICT_ANSI__ */ - - -#ifndef __STRICT_ANSI__ -#ifndef _NO_OLDNAMES - -/* - * Non-underscored versions of non-ANSI functions. They live in liboldnames.a - * and provide a little extra portability. Also a few extra UNIX-isms like - * strcasecmp. - */ - -void* memccpy (void*, const void*, int, size_t); -int memicmp (const void*, const void*, size_t); -char* strdup (const char*); -int strcmpi (const char*, const char*); -int stricmp (const char*, const char*); -int strcasecmp (const char*, const char*); -int stricoll (const char*, const char*); -char* strlwr (char*); -int strnicmp (const char*, const char*, size_t); -int strncasecmp (const char*, const char*, size_t); -char* strnset (char*, int, size_t); -char* strrev (char*); -char* strset (char*, int); -char* strupr (char*); -#ifndef _UWIN -void swab (const char*, char*, size_t); -#endif /* _UWIN */ - -/* NOTE: There is no _wcscmpi, but this is for compatibility. */ -int wcscmpi (const wchar_t*, const wchar_t*); -wchar_t* wcsdup (wchar_t*); -int wcsicmp (const wchar_t*, const wchar_t*); -int wcsicoll (const wchar_t*, const wchar_t*); -wchar_t* wcslwr (wchar_t*); -int wcsnicmp (const wchar_t*, const wchar_t*, size_t); -wchar_t* wcsnset (wchar_t*, wchar_t, size_t); -wchar_t* wcsrev (wchar_t*); -wchar_t* wcsset (wchar_t*, wchar_t); -wchar_t* wcsupr (wchar_t*); - -#endif /* Not _NO_OLDNAMES */ -#endif /* Not strict ANSI */ - +#ifndef _WSTRING_DEFINED +#define _WSTRING_DEFINED + + _CRTIMP wchar_t *__cdecl _wcsdup(const wchar_t *_Str); + wchar_t *__cdecl wcscat(wchar_t *_Dest,const wchar_t *_Source); + _CONST_RETURN wchar_t *__cdecl wcschr(const wchar_t *_Str,wchar_t _Ch); + int __cdecl wcscmp(const wchar_t *_Str1,const wchar_t *_Str2); + wchar_t *__cdecl wcscpy(wchar_t *_Dest,const wchar_t *_Source); + size_t __cdecl wcscspn(const wchar_t *_Str,const wchar_t *_Control); + size_t __cdecl wcslen(const wchar_t *_Str); + size_t __cdecl wcsnlen(const wchar_t *_Src,size_t _MaxCount); + wchar_t *wcsncat(wchar_t *_Dest,const wchar_t *_Source,size_t _Count); + int __cdecl wcsncmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + wchar_t *wcsncpy(wchar_t *_Dest,const wchar_t *_Source,size_t _Count); + _CONST_RETURN wchar_t *__cdecl wcspbrk(const wchar_t *_Str,const wchar_t *_Control); + _CONST_RETURN wchar_t *__cdecl wcsrchr(const wchar_t *_Str,wchar_t _Ch); + size_t __cdecl wcsspn(const wchar_t *_Str,const wchar_t *_Control); + _CONST_RETURN wchar_t *__cdecl wcsstr(const wchar_t *_Str,const wchar_t *_SubStr); + wchar_t *__cdecl wcstok(wchar_t *_Str,const wchar_t *_Delim); + _CRTIMP wchar_t *__cdecl _wcserror(int _ErrNum); + _CRTIMP wchar_t *__cdecl __wcserror(const wchar_t *_Str); + _CRTIMP int __cdecl _wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2); + _CRTIMP int __cdecl _wcsicmp_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _wcsnicmp_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP wchar_t *__cdecl _wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount); + _CRTIMP wchar_t *__cdecl _wcsrev(wchar_t *_Str); + _CRTIMP wchar_t *__cdecl _wcsset(wchar_t *_Str,wchar_t _Val); + _CRTIMP wchar_t *__cdecl _wcslwr(wchar_t *_String); + _CRTIMP wchar_t *_wcslwr_l(wchar_t *_String,_locale_t _Locale); + _CRTIMP wchar_t *__cdecl _wcsupr(wchar_t *_String); + _CRTIMP wchar_t *_wcsupr_l(wchar_t *_String,_locale_t _Locale); + size_t __cdecl wcsxfrm(wchar_t *_Dst,const wchar_t *_Src,size_t _MaxCount); + _CRTIMP size_t __cdecl _wcsxfrm_l(wchar_t *_Dst,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale); + int __cdecl wcscoll(const wchar_t *_Str1,const wchar_t *_Str2); + _CRTIMP int __cdecl _wcscoll_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2); + _CRTIMP int __cdecl _wcsicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _wcsncoll(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _wcsncoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP int __cdecl _wcsnicoll(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _wcsnicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale); + +#ifndef NO_OLDNAMES + wchar_t *__cdecl wcsdup(const wchar_t *_Str); +#define wcswcs wcsstr + int __cdecl wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2); + int __cdecl wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + wchar_t *__cdecl wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount); + wchar_t *__cdecl wcsrev(wchar_t *_Str); + wchar_t *__cdecl wcsset(wchar_t *_Str,wchar_t _Val); + wchar_t *__cdecl wcslwr(wchar_t *_Str); + wchar_t *__cdecl wcsupr(wchar_t *_Str); + int __cdecl wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2); +#endif +#endif #ifdef __cplusplus } #endif -#endif /* Not RC_INVOKED */ - -#endif /* Not _STRING_H_ */ - +#include <sec_api/string_s.h> +#endif diff --git a/tinyc/win32/include/sys/fcntl.h b/tinyc/win32/include/sys/fcntl.h index b343f272f..29fd55a1f 100644 --- a/tinyc/win32/include/sys/fcntl.h +++ b/tinyc/win32/include/sys/fcntl.h @@ -1,3 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ /* * This file is part of the Mingw32 package. * diff --git a/tinyc/win32/include/sys/file.h b/tinyc/win32/include/sys/file.h index 96c49e117..370f352d6 100644 --- a/tinyc/win32/include/sys/file.h +++ b/tinyc/win32/include/sys/file.h @@ -1,3 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ /* * This file is part of the Mingw32 package. * diff --git a/tinyc/win32/include/sys/locking.h b/tinyc/win32/include/sys/locking.h index 2ecd11628..e3fc85b3a 100644 --- a/tinyc/win32/include/sys/locking.h +++ b/tinyc/win32/include/sys/locking.h @@ -1,52 +1,30 @@ -/* - * locking.h - * - * Constants for the mode parameter of the locking function. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_LOCKING +#define _INC_LOCKING -#ifndef __STRICT_ANSI__ - -#ifndef _LOCKING_H_ -#define _LOCKING_H_ +#ifndef _WIN32 +#error Only Win32 target is supported! +#endif /* All the headers include this file. */ #include <_mingw.h> -#define _LK_UNLCK 0 /* Unlock */ -#define _LK_LOCK 1 /* Lock */ -#define _LK_NBLCK 2 /* Non-blocking lock */ -#define _LK_RLCK 3 /* Lock for read only */ -#define _LK_NBRLCK 4 /* Non-blocking lock for read only */ +#define _LK_UNLCK 0 +#define _LK_LOCK 1 +#define _LK_NBLCK 2 +#define _LK_RLCK 3 +#define _LK_NBRLCK 4 #ifndef NO_OLDNAMES -#define LK_UNLCK _LK_UNLCK -#define LK_LOCK _LK_LOCK -#define LK_NBLCK _LK_NBLCK -#define LK_RLCK _LK_RLCK -#define LK_NBRLCK _LK_NBRLCK -#endif /* Not NO_OLDNAMES */ - -#endif /* Not _LOCKING_H_ */ - -#endif /* Not __STRICT_ANSI__ */ - +#define LK_UNLCK _LK_UNLCK +#define LK_LOCK _LK_LOCK +#define LK_NBLCK _LK_NBLCK +#define LK_RLCK _LK_RLCK +#define LK_NBRLCK _LK_NBRLCK +#endif + +#endif diff --git a/tinyc/win32/include/sys/stat.h b/tinyc/win32/include/sys/stat.h index 0e2054942..344d4a249 100644 --- a/tinyc/win32/include/sys/stat.h +++ b/tinyc/win32/include/sys/stat.h @@ -1,139 +1,108 @@ -/* - * stat.h - * - * Symbolic constants for opening and creating files, also stat, fstat and - * chmod functions. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_STAT +#define _INC_STAT -#ifndef __STRICT_ANSI__ - -#ifndef _STAT_H_ -#define _STAT_H_ +#ifndef _WIN32 +#error Only Win32 target is supported! +#endif -/* All the headers include this file. */ #include <_mingw.h> +#include <io.h> -#define __need_size_t -#define __need_wchar_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ +#pragma pack(push,_CRT_PACKING) -#include <sys/types.h> +#ifdef __cplusplus +extern "C" { +#endif -/* - * Constants for the stat st_mode member. - */ -#define _S_IFIFO 0x1000 /* FIFO */ -#define _S_IFCHR 0x2000 /* Character */ -#define _S_IFBLK 0x3000 /* Block: Is this ever set under w32? */ -#define _S_IFDIR 0x4000 /* Directory */ -#define _S_IFREG 0x8000 /* Regular */ +#ifndef _CRTIMP +#define _CRTIMP __declspec(dllimport) +#endif -#define _S_IFMT 0xF000 /* File type mask */ +#include <sys/types.h> -#define _S_IEXEC 0x0040 -#define _S_IWRITE 0x0080 -#define _S_IREAD 0x0100 +#ifndef __TINYC__ /* gr */ +#ifdef _USE_32BIT_TIME_T +#ifdef _WIN64 +#undef _USE_32BIT_TIME_T +#endif +#else +#if _INTEGRAL_MAX_BITS < 64 +#define _USE_32BIT_TIME_T +#endif +#endif +#endif -#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC) -#define _S_IXUSR _S_IEXEC -#define _S_IWUSR _S_IWRITE -#define _S_IRUSR _S_IREAD +#ifndef _TIME32_T_DEFINED + typedef long __time32_t; +#define _TIME32_T_DEFINED +#endif -#define _S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) -#define _S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO) -#define _S_ISCHR(m) (((m) & _S_IFMT) == _S_IFCHR) -#define _S_ISBLK(m) (((m) & _S_IFMT) == _S_IFBLK) -#define _S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#ifndef _TIME64_T_DEFINED +#if _INTEGRAL_MAX_BITS >= 64 + typedef __int64 __time64_t; +#endif +#define _TIME64_T_DEFINED +#endif -#ifndef _NO_OLDNAMES +#ifndef _TIME_T_DEFINED +#ifdef _USE_32BIT_TIME_T + typedef __time32_t time_t; +#else + typedef __time64_t time_t; +#endif +#define _TIME_T_DEFINED +#endif -#define S_IFIFO _S_IFIFO -#define S_IFCHR _S_IFCHR -#define S_IFBLK _S_IFBLK -#define S_IFDIR _S_IFDIR -#define S_IFREG _S_IFREG -#define S_IFMT _S_IFMT -#define S_IEXEC _S_IEXEC -#define S_IWRITE _S_IWRITE -#define S_IREAD _S_IREAD -#define S_IRWXU _S_IRWXU -#define S_IXUSR _S_IXUSR -#define S_IWUSR _S_IWUSR -#define S_IRUSR _S_IRUSR +#ifndef _WCHAR_T_DEFINED + typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED +#endif -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#ifndef _STAT_DEFINED -#endif /* Not _NO_OLDNAMES */ +#ifdef _USE_32BIT_TIME_T +#ifndef _WIN64 +#define _fstat32 _fstat +#define _stat32 _stat +#define _wstat32 _wstat +#else +#define _fstat _fstat32 +#define _stat _stat32 +#define _wstat _wstat32 +#endif +#define _fstati64 _fstat32i64 +#define _stati64 _stat32i64 +#define _wstati64 _wstat32i64 +#else +#define _fstat _fstat64i32 +#define _fstati64 _fstat64 +#define _stat _stat64i32 +#define _stati64 _stat64 +#define _wstat _wstat64i32 +#define _wstati64 _wstat64 +#endif -#ifndef RC_INVOKED + struct _stat32 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + _off_t st_size; + __time32_t st_atime; + __time32_t st_mtime; + __time32_t st_ctime; + }; -#ifndef _STAT_DEFINED -/* - * The structure manipulated and returned by stat and fstat. - * - * NOTE: If called on a directory the values in the time fields are not only - * invalid, they will cause localtime et. al. to return NULL. And calling - * asctime with a NULL pointer causes an Invalid Page Fault. So watch it! - */ -struct _stat -{ - _dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ - _ino_t st_ino; /* Always zero ? */ - _mode_t st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - short st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - _dev_t st_rdev; /* Seems useless (not even filled in) */ - _off_t st_size; /* File size in bytes */ - time_t st_atime; /* Accessed date (always 00:00 hrs local - * on FAT) */ - time_t st_mtime; /* Modified time */ - time_t st_ctime; /* Creation time */ -}; - -struct stat -{ - _dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ - _ino_t st_ino; /* Always zero ? */ - _mode_t st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - short st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - _dev_t st_rdev; /* Seems useless (not even filled in) */ - _off_t st_size; /* File size in bytes */ - time_t st_atime; /* Accessed date (always 00:00 hrs local - * on FAT) */ - time_t st_mtime; /* Modified time */ - time_t st_ctime; /* Creation time */ -}; -#if defined (__MSVCRT__) -struct _stati64 { +#ifndef NO_OLDNAMES + struct stat { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; @@ -141,50 +110,181 @@ struct _stati64 { short st_uid; short st_gid; _dev_t st_rdev; - __int64 st_size; + _off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; -}; -#endif /* __MSVCRT__ */ -#define _STAT_DEFINED -#endif /* _STAT_DEFINED */ + }; +#endif -#ifdef __cplusplus -extern "C" { +#if _INTEGRAL_MAX_BITS >= 64 + struct _stat32i64 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time32_t st_atime; + __time32_t st_mtime; + __time32_t st_ctime; + }; + + struct _stat64i32 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + _off_t st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; + }; + + struct _stat64 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; + }; +#endif + +#define __stat64 _stat64 + +#define _STAT_DEFINED #endif -int _fstat (int, struct _stat*); -int _chmod (const char*, int); -int _stat (const char*, struct _stat*); +#define _S_IFMT 0xF000 +#define _S_IFDIR 0x4000 +#define _S_IFCHR 0x2000 +#define _S_IFIFO 0x1000 +#define _S_IFREG 0x8000 +#define _S_IREAD 0x0100 +#define _S_IWRITE 0x0080 +#define _S_IEXEC 0x0040 + + _CRTIMP int __cdecl _fstat32(int _FileDes,struct _stat32 *_Stat); + _CRTIMP int __cdecl _stat32(const char *_Name,struct _stat32 *_Stat); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP int __cdecl _fstat64(int _FileDes,struct _stat64 *_Stat); + _CRTIMP int __cdecl _fstat32i64(int _FileDes,struct _stat32i64 *_Stat); + int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat); + __CRT_INLINE int __cdecl _fstat64i32(int _FileDes,struct _stat64i32 *_Stat) + { + struct _stat64 st; + int ret=_fstat64(_FileDes,&st); + _Stat->st_dev=st.st_dev; + _Stat->st_ino=st.st_ino; + _Stat->st_mode=st.st_mode; + _Stat->st_nlink=st.st_nlink; + _Stat->st_uid=st.st_uid; + _Stat->st_gid=st.st_gid; + _Stat->st_rdev=st.st_rdev; + _Stat->st_size=(_off_t) st.st_size; + _Stat->st_atime=st.st_atime; + _Stat->st_mtime=st.st_mtime; + _Stat->st_ctime=st.st_ctime; + return ret; + } + _CRTIMP int __cdecl _stat64(const char *_Name,struct _stat64 *_Stat); + _CRTIMP int __cdecl _stat32i64(const char *_Name,struct _stat32i64 *_Stat); + int __cdecl _stat64i32(const char *_Name,struct _stat64i32 *_Stat); + __CRT_INLINE int __cdecl _stat64i32(const char *_Name,struct _stat64i32 *_Stat) + { + struct _stat64 st; + int ret=_stat64(_Name,&st); + _Stat->st_dev=st.st_dev; + _Stat->st_ino=st.st_ino; + _Stat->st_mode=st.st_mode; + _Stat->st_nlink=st.st_nlink; + _Stat->st_uid=st.st_uid; + _Stat->st_gid=st.st_gid; + _Stat->st_rdev=st.st_rdev; + _Stat->st_size=(_off_t) st.st_size; + _Stat->st_atime=st.st_atime; + _Stat->st_mtime=st.st_mtime; + _Stat->st_ctime=st.st_ctime; + return ret; + } +#endif -#if defined (__MSVCRT__) -int _fstati64(int, struct _stati64 *); -int _stati64(const char *, struct _stati64 *); -#if !defined ( _WSTAT_DEFINED) /* also declared in wchar.h */ -int _wstat(const wchar_t*, struct _stat*); -int _wstati64 (const wchar_t*, struct _stati64*); +#ifndef _WSTAT_DEFINED #define _WSTAT_DEFINED -#endif /* _WSTAT_DEFIND */ -#endif /* __MSVCRT__ */ + _CRTIMP int __cdecl _wstat32(const wchar_t *_Name,struct _stat32 *_Stat); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP int __cdecl _wstat32i64(const wchar_t *_Name,struct _stat32i64 *_Stat); + int __cdecl _wstat64i32(const wchar_t *_Name,struct _stat64i32 *_Stat); + _CRTIMP int __cdecl _wstat64(const wchar_t *_Name,struct _stat64 *_Stat); +#endif +#endif -#ifndef _NO_OLDNAMES +#ifndef NO_OLDNAMES +#define _S_IFBLK 0x3000 /* Block: Is this ever set under w32? */ -/* These functions live in liboldnames.a. */ -int fstat (int, struct stat*); -int chmod (const char*, int); -int stat (const char*, struct stat*); +#define S_IFMT _S_IFMT +#define S_IFDIR _S_IFDIR +#define S_IFCHR _S_IFCHR +#define S_IFREG _S_IFREG +#define S_IREAD _S_IREAD +#define S_IWRITE _S_IWRITE +#define S_IEXEC _S_IEXEC +#define S_IFIFO _S_IFIFO +#define S_IFBLK _S_IFBLK -#endif /* Not _NO_OLDNAMES */ +#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC) +#define _S_IXUSR _S_IEXEC +#define _S_IWUSR _S_IWRITE +#define S_IRWXU _S_IRWXU +#define S_IXUSR _S_IXUSR +#define S_IWUSR _S_IWUSR +#define S_IRUSR _S_IRUSR +#define _S_IRUSR _S_IREAD -#ifdef __cplusplus -} -#endif +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif /* Not RC_INVOKED */ +#endif -#endif /* Not _STAT_H_ */ +#if !defined (RC_INVOKED) && !defined (NO_OLDNAMES) +int __cdecl stat(const char *_Filename,struct stat *_Stat); +int __cdecl fstat(int _Desc,struct stat *_Stat); +int __cdecl wstat(const wchar_t *_Filename,struct stat *_Stat); +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE int __cdecl fstat(int _Desc,struct stat *_Stat) { + return _fstat32(_Desc,(struct _stat32 *)_Stat); +} +__CRT_INLINE int __cdecl stat(const char *_Filename,struct stat *_Stat) { + return _stat32(_Filename,(struct _stat32 *)_Stat); +} +#else +__CRT_INLINE int __cdecl fstat(int _Desc,struct stat *_Stat) { + return _fstat64i32(_Desc,(struct _stat64i32 *)_Stat); +} +__CRT_INLINE int __cdecl stat(const char *_Filename,struct stat *_Stat) { + return _stat64i32(_Filename,(struct _stat64i32 *)_Stat); +} +#endif +#endif -#endif /* Not __STRICT_ANSI__ */ +#ifdef __cplusplus +} +#endif +#pragma pack(pop) +#endif diff --git a/tinyc/win32/include/sys/time.h b/tinyc/win32/include/sys/time.h index 39d85f67b..8ccab8319 100644 --- a/tinyc/win32/include/sys/time.h +++ b/tinyc/win32/include/sys/time.h @@ -1,3 +1,69 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ + +#ifndef _SYS_TIME_H_ +#define _SYS_TIME_H_ #include <time.h> +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __STRICT_ANSI__ +#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */ +#define _TIMEVAL_DEFINED +struct timeval { + long tv_sec; + long tv_usec; +}; +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec != (uvp)->tv_sec) ? \ + ((tvp)->tv_sec cmp (uvp)->tv_sec) : \ + ((tvp)->tv_usec cmp (uvp)->tv_usec)) +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#endif /* _TIMEVAL_DEFINED */ + +#ifndef _TIMEZONE_DEFINED /* also in sys/time.h */ +#define _TIMEZONE_DEFINED +/* Provided for compatibility with code that assumes that + the presence of gettimeofday function implies a definition + of struct timezone. */ +struct timezone +{ + int tz_minuteswest; /* of Greenwich */ + int tz_dsttime; /* type of dst correction to apply */ +}; + + extern int __cdecl mingw_gettimeofday (struct timeval *p, struct timezone *z); + +#endif + +/* + Implementation as per: + The Open Group Base Specifications, Issue 6 + IEEE Std 1003.1, 2004 Edition + + The timezone pointer arg is ignored. Errors are ignored. +*/ +#ifndef _GETTIMEOFDAY_DEFINED +#define _GETTIMEOFDAY_DEFINED +int __cdecl gettimeofday(struct timeval *__restrict__, + void *__restrict__ /* tzp (unused) */); +#endif + +#endif /* __STRICT_ANSI__ */ + +#ifdef __cplusplus +} +#endif + +/* Adding timespec definition. */ +#include <sys/timeb.h> + + +#endif /* _SYS_TIME_H_ */ diff --git a/tinyc/win32/include/sys/timeb.h b/tinyc/win32/include/sys/timeb.h index b5bb0fc3d..34837738b 100644 --- a/tinyc/win32/include/sys/timeb.h +++ b/tinyc/win32/include/sys/timeb.h @@ -1,82 +1,133 @@ -/* - * timeb.h - * - * Support for the UNIX System V ftime system call. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _TIMEB_H_ +#define _TIMEB_H_ -#ifndef __STRICT_ANSI__ +#include <_mingw.h> -#ifndef _TIMEB_H_ -#define _TIMEB_H_ +#ifndef _WIN32 +#error Only Win32 target is supported! +#endif -/* All the headers include this file. */ -#include <_mingw.h> +#pragma pack(push,_CRT_PACKING) -#ifndef RC_INVOKED +#ifdef __cplusplus +extern "C" { +#endif -/* - * TODO: Structure not tested. - */ -struct _timeb -{ - long time; - short millitm; - short timezone; - short dstflag; -}; +#ifndef _CRTIMP +#define _CRTIMP __declspec(dllimport) +#endif -#ifndef _NO_OLDNAMES -/* - * TODO: Structure not tested. - */ -struct timeb -{ - long time; - short millitm; - short timezone; - short dstflag; -}; +#ifndef __TINYC__ /* gr */ +#ifdef _USE_32BIT_TIME_T +#ifdef _WIN64 +#undef _USE_32BIT_TIME_T +#endif +#else +#if _INTEGRAL_MAX_BITS < 64 +#define _USE_32BIT_TIME_T +#endif +#endif #endif +#ifndef _TIME32_T_DEFINED + typedef long __time32_t; +#define _TIME32_T_DEFINED +#endif -#ifdef __cplusplus -extern "C" { +#ifndef _TIME64_T_DEFINED +#if _INTEGRAL_MAX_BITS >= 64 + typedef __int64 __time64_t; +#endif +#define _TIME64_T_DEFINED #endif -/* TODO: Not tested. */ -void _ftime (struct _timeb*); +#ifndef _TIME_T_DEFINED +#ifdef _USE_32BIT_TIME_T + typedef __time32_t time_t; +#else + typedef __time64_t time_t; +#endif +#define _TIME_T_DEFINED +#endif -#ifndef _NO_OLDNAMES -void ftime (struct timeb*); -#endif /* Not _NO_OLDNAMES */ +#ifndef _TIMEB_DEFINED +#define _TIMEB_DEFINED -#ifdef __cplusplus -} + struct __timeb32 { + __time32_t time; + unsigned short millitm; + short timezone; + short dstflag; + }; + +#ifndef NO_OLDNAMES + struct timeb { + time_t time; + unsigned short millitm; + short timezone; + short dstflag; + }; #endif -#endif /* Not RC_INVOKED */ +#if _INTEGRAL_MAX_BITS >= 64 + struct __timeb64 { + __time64_t time; + unsigned short millitm; + short timezone; + short dstflag; + }; +#endif + +#ifdef _USE_32BIT_TIME_T +#define _timeb __timeb32 +//gr #define _ftime _ftime32 +#define _ftime32 _ftime +#else +#define _timeb __timeb64 +#define _ftime _ftime64 +#endif +#endif + + _CRTIMP void __cdecl _ftime32(struct __timeb32 *_Time); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP void __cdecl _ftime64(struct __timeb64 *_Time); +#endif -#endif /* Not _TIMEB_H_ */ +#ifndef _TIMESPEC_DEFINED +#define _TIMESPEC_DEFINED +struct timespec { + time_t tv_sec; /* Seconds */ + long tv_nsec; /* Nanoseconds */ +}; -#endif /* Not __STRICT_ANSI__ */ +struct itimerspec { + struct timespec it_interval; /* Timer period */ + struct timespec it_value; /* Timer expiration */ +}; +#endif +#if !defined (RC_INVOKED) && !defined (NO_OLDNAMES) +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE void __cdecl ftime(struct timeb *_Tmb) { + _ftime32((struct __timeb32 *)_Tmb); +} +#else +__CRT_INLINE void __cdecl ftime(struct timeb *_Tmb) { + _ftime64((struct __timeb64 *)_Tmb); +} +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) + +#include <sec_api/sys/timeb_s.h> +#endif diff --git a/tinyc/win32/include/sys/types.h b/tinyc/win32/include/sys/types.h index 0679ac9b3..7379b0f1e 100644 --- a/tinyc/win32/include/sys/types.h +++ b/tinyc/win32/include/sys/types.h @@ -1,118 +1,118 @@ -/* - * types.h - * - * The definition of constants, data types and global variables. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * Lots of types supplied by Pedro A. Aranda <paag@tid.es> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warrenties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_TYPES +#define _INC_TYPES -#ifndef _TYPES_H_ -#define _TYPES_H_ +#ifndef _WIN32 +#error Only Win32 target is supported! +#endif -/* All the headers include this file. */ #include <_mingw.h> -#define __need_wchar_t -#define __need_size_t -#define __need_ptrdiff_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ - -#ifndef RC_INVOKED - -#ifndef _TIME_T_DEFINED -typedef long time_t; -#define _TIME_T_DEFINED +#ifndef __TINYC__ /* gr */ +#ifdef _USE_32BIT_TIME_T +#ifdef _WIN64 +#undef _USE_32BIT_TIME_T +#endif +#else +#if _INTEGRAL_MAX_BITS < 64 +#define _USE_32BIT_TIME_T +#endif +#endif #endif - -#ifndef __STRICT_ANSI__ - -#ifndef _OFF_T_ -#define _OFF_T_ -typedef long _off_t; - -#ifndef _NO_OLDNAMES -typedef _off_t off_t; +#ifndef _TIME32_T_DEFINED +#define _TIME32_T_DEFINED +typedef long __time32_t; #endif -#endif /* Not _OFF_T_ */ +#ifndef _TIME64_T_DEFINED +#define _TIME64_T_DEFINED +#if _INTEGRAL_MAX_BITS >= 64 +typedef __int64 __time64_t; +#endif +#endif -#ifndef _DEV_T_ -#define _DEV_T_ -#ifdef __MSVCRT__ -typedef unsigned int _dev_t; +#ifndef _TIME_T_DEFINED +#define _TIME_T_DEFINED +#ifdef _USE_32BIT_TIME_T +typedef __time32_t time_t; #else -typedef short _dev_t; +typedef __time64_t time_t; #endif - -#ifndef _NO_OLDNAMES -typedef _dev_t dev_t; #endif -#endif /* Not _DEV_T_ */ - -#ifndef _INO_T_ -#define _INO_T_ -typedef short _ino_t; - -#ifndef _NO_OLDNAMES -typedef _ino_t ino_t; +#ifndef _INO_T_DEFINED +#define _INO_T_DEFINED +typedef unsigned short _ino_t; +#ifndef NO_OLDNAMES +typedef unsigned short ino_t; +#endif #endif -#endif /* Not _INO_T_ */ +#ifndef _DEV_T_DEFINED +#define _DEV_T_DEFINED +typedef unsigned int _dev_t; +#ifndef NO_OLDNAMES +typedef unsigned int dev_t; +#endif +#endif #ifndef _PID_T_ #define _PID_T_ +#ifndef _WIN64 typedef int _pid_t; +#else +typedef __int64 _pid_t; +#endif -#ifndef _NO_OLDNAMES +#ifndef NO_OLDNAMES typedef _pid_t pid_t; #endif #endif /* Not _PID_T_ */ - #ifndef _MODE_T_ #define _MODE_T_ typedef unsigned short _mode_t; -#ifndef _NO_OLDNAMES +#ifndef NO_OLDNAMES typedef _mode_t mode_t; #endif #endif /* Not _MODE_T_ */ - -#ifndef _SIGSET_T_ -#define _SIGSET_T_ -typedef int _sigset_t; - -#ifndef _NO_OLDNAMES -typedef _sigset_t sigset_t; +#ifndef _OFF_T_DEFINED +#define _OFF_T_DEFINED +#ifndef _OFF_T_ +#define _OFF_T_ + typedef long _off_t; +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef long off_t; +#endif +#endif #endif -#endif /* Not _SIGSET_T_ */ -#endif /* Not __STRICT_ANSI__ */ +#ifndef _OFF64_T_DEFINED +#define _OFF64_T_DEFINED + typedef long long _off64_t; +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef long long off64_t; +#endif +#endif -#endif /* Not RC_INVOKED */ +#ifndef _TIMESPEC_DEFINED +#define _TIMESPEC_DEFINED +struct timespec { + time_t tv_sec; /* Seconds */ + long tv_nsec; /* Nanoseconds */ +}; + +struct itimerspec { + struct timespec it_interval; /* Timer period */ + struct timespec it_value; /* Timer expiration */ +}; +#endif -#endif /* Not _TYPES_H_ */ +#endif diff --git a/tinyc/win32/include/sys/unistd.h b/tinyc/win32/include/sys/unistd.h index ed122d9dd..31006d325 100644 --- a/tinyc/win32/include/sys/unistd.h +++ b/tinyc/win32/include/sys/unistd.h @@ -1,3 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ /* * This file is part of the Mingw32 package. * diff --git a/tinyc/win32/include/sys/utime.h b/tinyc/win32/include/sys/utime.h index 049524bed..fec8304ff 100644 --- a/tinyc/win32/include/sys/utime.h +++ b/tinyc/win32/include/sys/utime.h @@ -1,89 +1,146 @@ -/* - * utime.h - * - * Support for the utime function. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_UTIME +#define _INC_UTIME -#ifndef __STRICT_ANSI__ - -#ifndef _UTIME_H_ -#define _UTIME_H_ +#ifndef _WIN32 +#error Only Win32 target is supported! +#endif -/* All the headers include this file. */ #include <_mingw.h> -#define __need_wchar_t -#define __need_size_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ -#include <sys/types.h> +#pragma pack(push,_CRT_PACKING) -#ifndef RC_INVOKED +#ifdef __cplusplus +extern "C" { +#endif -/* - * Structure used by _utime function. - */ -struct _utimbuf -{ - time_t actime; /* Access time */ - time_t modtime; /* Modification time */ -}; +#ifndef _CRTIMP +#define _CRTIMP __declspec(dllimport) +#endif +#ifndef _WCHAR_T_DEFINED + typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED +#endif -#ifndef _NO_OLDNAMES -/* NOTE: Must be the same as _utimbuf above. */ -struct utimbuf -{ - time_t actime; - time_t modtime; -}; -#endif /* Not _NO_OLDNAMES */ +#ifndef __TINYC__ /* gr */ +#ifdef _USE_32BIT_TIME_T +#ifdef _WIN64 +#undef _USE_32BIT_TIME_T +#endif +#else +#if _INTEGRAL_MAX_BITS < 64 +#define _USE_32BIT_TIME_T +#endif +#endif +#endif +#ifndef _TIME32_T_DEFINED +#define _TIME32_T_DEFINED + typedef long __time32_t; +#endif -#ifdef __cplusplus -extern "C" { +#ifndef _TIME64_T_DEFINED +#define _TIME64_T_DEFINED +#if _INTEGRAL_MAX_BITS >= 64 + typedef __int64 __time64_t; +#endif +#endif + +#ifndef _TIME_T_DEFINED +#define _TIME_T_DEFINED +#ifdef _USE_32BIT_TIME_T + typedef __time32_t time_t; +#else + typedef __time64_t time_t; +#endif #endif -int _utime (const char*, struct _utimbuf*); -int _futime (int, struct _utimbuf*); +#ifndef _UTIMBUF_DEFINED +#define _UTIMBUF_DEFINED -/* The wide character version, only available for MSVCRT versions of the - * C runtime library. */ -#ifdef __MSVCRT__ -int _wutime (const wchar_t*, struct _utimbuf*); -#endif /* MSVCRT runtime */ -#ifndef _NO_OLDNAMES -int utime (const char*, struct utimbuf*); -#endif /* Not _NO_OLDNAMES */ + struct _utimbuf { + time_t actime; + time_t modtime; + }; -#ifdef __cplusplus -} + struct __utimbuf32 { + __time32_t actime; + __time32_t modtime; + }; + +#if _INTEGRAL_MAX_BITS >= 64 + struct __utimbuf64 { + __time64_t actime; + __time64_t modtime; + }; +#endif + +#ifndef NO_OLDNAMES + struct utimbuf { + time_t actime; + time_t modtime; + }; + + struct utimbuf32 { + __time32_t actime; + __time32_t modtime; + }; +#endif #endif -#endif /* Not RC_INVOKED */ + _CRTIMP int __cdecl _utime32(const char *_Filename,struct __utimbuf32 *_Time); + _CRTIMP int __cdecl _futime32(int _FileDes,struct __utimbuf32 *_Time); + _CRTIMP int __cdecl _wutime32(const wchar_t *_Filename,struct __utimbuf32 *_Time); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP int __cdecl _utime64(const char *_Filename,struct __utimbuf64 *_Time); + _CRTIMP int __cdecl _futime64(int _FileDes,struct __utimbuf64 *_Time); + _CRTIMP int __cdecl _wutime64(const wchar_t *_Filename,struct __utimbuf64 *_Time); +#endif -#endif /* Not _UTIME_H_ */ +#ifndef RC_INVOKED +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) { + return _utime32(_Filename,(struct __utimbuf32 *)_Utimbuf); +} +__CRT_INLINE int __cdecl _futime(int _Desc,struct _utimbuf *_Utimbuf) { + return _futime32(_Desc,(struct __utimbuf32 *)_Utimbuf); +} +__CRT_INLINE int __cdecl _wutime(const wchar_t *_Filename,struct _utimbuf *_Utimbuf) { + return _wutime32(_Filename,(struct __utimbuf32 *)_Utimbuf); +} +#else +__CRT_INLINE int __cdecl _utime(const char *_Filename,struct _utimbuf *_Utimbuf) { + return _utime64(_Filename,(struct __utimbuf64 *)_Utimbuf); +} +__CRT_INLINE int __cdecl _futime(int _Desc,struct _utimbuf *_Utimbuf) { + return _futime64(_Desc,(struct __utimbuf64 *)_Utimbuf); +} +__CRT_INLINE int __cdecl _wutime(const wchar_t *_Filename,struct _utimbuf *_Utimbuf) { + return _wutime64(_Filename,(struct __utimbuf64 *)_Utimbuf); +} +#endif + +#ifndef NO_OLDNAMES +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE int __cdecl utime(const char *_Filename,struct utimbuf *_Utimbuf) { + return _utime32(_Filename,(struct __utimbuf32 *)_Utimbuf); +} +#else +__CRT_INLINE int __cdecl utime(const char *_Filename,struct utimbuf *_Utimbuf) { + return _utime64(_Filename,(struct __utimbuf64 *)_Utimbuf); +} +#endif +#endif +#endif -#endif /* Not __STRICT_ANSI__ */ +#ifdef __cplusplus +} +#endif +#pragma pack(pop) +#endif diff --git a/tinyc/win32/include/tcc/tcc_libm.h b/tinyc/win32/include/tcc/tcc_libm.h new file mode 100644 index 000000000..0a62e6fb7 --- /dev/null +++ b/tinyc/win32/include/tcc/tcc_libm.h @@ -0,0 +1,201 @@ +#ifndef _TCC_LIBM_H_ +#define _TCC_LIBM_H_ + +#include "../math.h" + +/* TCC uses 8 bytes for double and long double, so effectively the l variants + * are never used. For now, they just run the normal (double) variant. + */ + +/* + * most of the code in this file is taken from MUSL rs-1.0 (MIT license) + * - musl-libc: http://git.musl-libc.org/cgit/musl/tree/src/math?h=rs-1.0 + * - License: http://git.musl-libc.org/cgit/musl/tree/COPYRIGHT?h=rs-1.0 + */ + +/******************************************************************************* + Start of code based on MUSL +*******************************************************************************/ +/* +musl as a whole is licensed under the following standard MIT license: + +---------------------------------------------------------------------- +Copyright © 2005-2014 Rich Felker, et al. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------------------------------------------------------------- +*/ + +/* fpclassify */ + +__CRT_INLINE int __cdecl __fpclassify (double x) { + union {double f; uint64_t i;} u = {x}; + int e = u.i>>52 & 0x7ff; + if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; + if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE; + return FP_NORMAL; +} + +__CRT_INLINE int __cdecl __fpclassifyf (float x) { + union {float f; uint32_t i;} u = {x}; + int e = u.i>>23 & 0xff; + if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO; + if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE; + return FP_NORMAL; +} + +__CRT_INLINE int __cdecl __fpclassifyl (long double x) { + return __fpclassify(x); +} + + +/* signbit */ + +__CRT_INLINE int __cdecl __signbit (double x) { + union {double d; uint64_t i;} y = { x }; + return y.i>>63; +} + +__CRT_INLINE int __cdecl __signbitf (float x) { + union {float f; uint32_t i; } y = { x }; + return y.i>>31; +} + +__CRT_INLINE int __cdecl __signbitl (long double x) { + return __signbit(x); +} + + +/* fmin*, fmax* */ + +#define TCCFP_FMIN_EVAL (isnan(x) ? y : \ + isnan(y) ? x : \ + (signbit(x) != signbit(y)) ? (signbit(x) ? x : y) : \ + x < y ? x : y) + +__CRT_INLINE double __cdecl fmin (double x, double y) { + return TCCFP_FMIN_EVAL; +} + +__CRT_INLINE float __cdecl fminf (float x, float y) { + return TCCFP_FMIN_EVAL; +} + +__CRT_INLINE long double __cdecl fminl (long double x, long double y) { + return TCCFP_FMIN_EVAL; +} + +#define TCCFP_FMAX_EVAL (isnan(x) ? y : \ + isnan(y) ? x : \ + (signbit(x) != signbit(y)) ? (signbit(x) ? y : x) : \ + x < y ? y : x) + +__CRT_INLINE double __cdecl fmax (double x, double y) { + return TCCFP_FMAX_EVAL; +} + +__CRT_INLINE float __cdecl fmaxf (float x, float y) { + return TCCFP_FMAX_EVAL; +} + +__CRT_INLINE long double __cdecl fmaxl (long double x, long double y) { + return TCCFP_FMAX_EVAL; +} + + +/* *round* */ + +#define TCCFP_FORCE_EVAL(x) do { \ +if (sizeof(x) == sizeof(float)) { \ + volatile float __x; \ + __x = (x); \ +} else if (sizeof(x) == sizeof(double)) { \ + volatile double __x; \ + __x = (x); \ +} else { \ + volatile long double __x; \ + __x = (x); \ +} \ +} while(0) + +__CRT_INLINE double __cdecl round (double x) { + union {double f; uint64_t i;} u = {x}; + int e = u.i >> 52 & 0x7ff; + double y; + + if (e >= 0x3ff+52) + return x; + if (u.i >> 63) + x = -x; + if (e < 0x3ff-1) { + /* raise inexact if x!=0 */ + TCCFP_FORCE_EVAL(x + 0x1p52); + return 0*u.f; + } + y = (double)(x + 0x1p52) - 0x1p52 - x; + if (y > 0.5) + y = y + x - 1; + else if (y <= -0.5) + y = y + x + 1; + else + y = y + x; + if (u.i >> 63) + y = -y; + return y; +} + +__CRT_INLINE long __cdecl lround (double x) { + return round(x); +} + +__CRT_INLINE long long __cdecl llround (double x) { + return round(x); +} + +__CRT_INLINE float __cdecl roundf (float x) { + return round(x); +} + +__CRT_INLINE long __cdecl lroundf (float x) { + return round(x); +} + +__CRT_INLINE long long __cdecl llroundf (float x) { + return round(x); +} + +__CRT_INLINE long double __cdecl roundl (long double x) { + return round(x); +} + +__CRT_INLINE long __cdecl lroundl (long double x) { + return round(x); +} + +__CRT_INLINE long long __cdecl llroundl (long double x) { + return round(x); +} + + +/******************************************************************************* + End of code based on MUSL +*******************************************************************************/ + +#endif /* _TCC_LIBM_H_ */ diff --git a/tinyc/win32/include/tchar.h b/tinyc/win32/include/tchar.h index 72c1b3c81..cd44beca1 100644 --- a/tinyc/win32/include/tchar.h +++ b/tinyc/win32/include/tchar.h @@ -1,367 +1,1102 @@ -/* - * tchar.h - * - * Unicode mapping layer for the standard C library. By including this - * file and using the 't' names for string functions - * (eg. _tprintf) you can make code which can be easily adapted to both - * Unicode and non-unicode environments. In a unicode enabled compile define - * _UNICODE before including tchar.h, otherwise the standard non-unicode - * library functions will be used. - * - * Note that you still need to include string.h or stdlib.h etc. to define - * the appropriate functions. Also note that there are several defines - * included for non-ANSI functions which are commonly available (but using - * the convention of prepending an underscore to non-ANSI library function - * names). - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#include <_mingw.h> -#ifndef _TCHAR_H_ -#define _TCHAR_H_ +#ifndef _INC_TCHAR +#define _INC_TCHAR -/* All the headers include this file. */ -#include <_mingw.h> +#ifdef _STRSAFE_H_INCLUDED_ +#error Need to include strsafe.h after tchar.h +#endif -/* - * NOTE: This tests _UNICODE, which is different from the UNICODE define - * used to differentiate Win32 API calls. - */ -#ifdef _UNICODE +#ifdef __cplusplus +extern "C" { +#endif +#define _ftcscat _tcscat +#define _ftcschr _tcschr +#define _ftcscpy _tcscpy +#define _ftcscspn _tcscspn +#define _ftcslen _tcslen +#define _ftcsncat _tcsncat +#define _ftcsncpy _tcsncpy +#define _ftcspbrk _tcspbrk +#define _ftcsrchr _tcsrchr +#define _ftcsspn _tcsspn +#define _ftcsstr _tcsstr +#define _ftcstok _tcstok + +#define _ftcsdup _tcsdup +#define _ftcsnset _tcsnset +#define _ftcsrev _tcsrev +#define _ftcsset _tcsset + +#define _ftcscmp _tcscmp +#define _ftcsicmp _tcsicmp +#define _ftcsnccmp _tcsnccmp +#define _ftcsncmp _tcsncmp +#define _ftcsncicmp _tcsncicmp +#define _ftcsnicmp _tcsnicmp + +#define _ftcscoll _tcscoll +#define _ftcsicoll _tcsicoll +#define _ftcsnccoll _tcsnccoll +#define _ftcsncoll _tcsncoll +#define _ftcsncicoll _tcsncicoll +#define _ftcsnicoll _tcsnicoll + +#define _ftcsclen _tcsclen +#define _ftcsnccat _tcsnccat +#define _ftcsnccpy _tcsnccpy +#define _ftcsncset _tcsncset + +#define _ftcsdec _tcsdec +#define _ftcsinc _tcsinc +#define _ftcsnbcnt _tcsnbcnt +#define _ftcsnccnt _tcsnccnt +#define _ftcsnextc _tcsnextc +#define _ftcsninc _tcsninc +#define _ftcsspnp _tcsspnp + +#define _ftcslwr _tcslwr +#define _ftcsupr _tcsupr + +#define _ftclen _tclen +#define _ftccpy _tccpy +#define _ftccmp _tccmp + +#ifndef _CONST_RETURN +#ifdef __cplusplus +#define _CONST_RETURN const +#define _CRT_CONST_CORRECT_OVERLOADS +#else +#define _CONST_RETURN +#endif +#endif + +#define _WConst_return _CONST_RETURN + +#ifdef _UNICODE + +#ifdef __cplusplus +} +#endif + +#include <wchar.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _WCTYPE_T_DEFINED +#define _WCTYPE_T_DEFINED + typedef unsigned short wint_t; + typedef unsigned short wctype_t; +#endif + +#ifndef __TCHAR_DEFINED +#define __TCHAR_DEFINED + typedef wchar_t _TCHAR; + typedef wchar_t _TSCHAR; + typedef wchar_t _TUCHAR; + typedef wchar_t _TXCHAR; + typedef wint_t _TINT; +#endif -/* - * Use TCHAR instead of char or wchar_t. It will be appropriately translated - * if _UNICODE is correctly defined (or not). - */ #ifndef _TCHAR_DEFINED -#ifndef RC_INVOKED -typedef wchar_t TCHAR; -typedef wchar_t _TCHAR; -#endif /* Not RC_INVOKED */ #define _TCHAR_DEFINED +#ifndef NO_OLDNAMES + typedef wchar_t TCHAR; +#endif #endif +#define _TEOF WEOF -/* - * __TEXT is a private macro whose specific use is to force the expansion of a - * macro passed as an argument to the macros _T or _TEXT. DO NOT use this - * macro within your programs. It's name and function could change without - * notice. - */ -#define __TEXT(x) L##x +#define __T(x) L##x -/* for porting from other Windows compilers */ -#if 0 // no wide startup module -#define _tmain wmain -#define _tWinMain wWinMain -#define _tenviron _wenviron -#define __targv __wargv -#endif +#define _tmain wmain +#define _tWinMain wWinMain +#define _tenviron _wenviron +#define __targv __wargv -/* - * Unicode functions - */ -#define _tprintf wprintf -#define _ftprintf fwprintf -#define _stprintf swprintf -#define _sntprintf _snwprintf -#define _vtprintf vwprintf -#define _vftprintf vfwprintf -#define _vstprintf vswprintf -#define _vsntprintf _vsnwprintf -#define _tscanf wscanf -#define _ftscanf fwscanf -#define _stscanf swscanf -#define _fgettc fgetwc -#define _fgettchar _fgetwchar -#define _fgetts fgetws -#define _fputtc fputwc -#define _fputtchar _fputwchar -#define _fputts fputws -#define _gettc getwc -#define _getts getws -#define _puttc putwc -#define _putts putws -#define _ungettc ungetwc -#define _tcstod wcstod -#define _tcstol wcstol -#define _tcstoul wcstoul -#define _itot _itow -#define _ltot _ltow -#define _ultot _ultow -#define _ttoi _wtoi -#define _ttol _wtol -#define _tcscat wcscat -#define _tcschr wcschr -#define _tcscmp wcscmp -#define _tcscpy wcscpy -#define _tcscspn wcscspn -#define _tcslen wcslen -#define _tcsncat wcsncat -#define _tcsncmp wcsncmp -#define _tcsncpy wcsncpy -#define _tcspbrk wcspbrk -#define _tcsrchr wcsrchr -#define _tcsspn wcsspn -#define _tcsstr wcsstr -#define _tcstok wcstok -#define _tcsdup _wcsdup -#define _tcsicmp _wcsicmp -#define _tcsnicmp _wcsnicmp -#define _tcsnset _wcsnset -#define _tcsrev _wcsrev -#define _tcsset _wcsset -#define _tcslwr _wcslwr -#define _tcsupr _wcsupr -#define _tcsxfrm wcsxfrm -#define _tcscoll wcscoll -#define _tcsicoll _wcsicoll -#define _istalpha iswalpha -#define _istupper iswupper -#define _istlower iswlower -#define _istdigit iswdigit -#define _istxdigit iswxdigit -#define _istspace iswspace -#define _istpunct iswpunct -#define _istalnum iswalnum -#define _istprint iswprint -#define _istgraph iswgraph -#define _istcntrl iswcntrl -#define _istascii iswascii -#define _totupper towupper -#define _totlower towlower -#define _tcsftime wcsftime -/* Macro functions */ -#define _tcsdec _wcsdec -#define _tcsinc _wcsinc -#define _tcsnbcnt _wcsncnt -#define _tcsnccnt _wcsncnt -#define _tcsnextc _wcsnextc -#define _tcsninc _wcsninc -#define _tcsspnp _wcsspnp -#define _wcsdec(_wcs1, _wcs2) ((_wcs1)>=(_wcs2) ? NULL : (_wcs2)-1) -#define _wcsinc(_wcs) ((_wcs)+1) -#define _wcsnextc(_wcs) ((unsigned int) *(_wcs)) -#define _wcsninc(_wcs, _inc) (((_wcs)+(_inc))) -#define _wcsncnt(_wcs, _cnt) ((wcslen(_wcs)>_cnt) ? _count : wcslen(_wcs)) -#define _wcsspnp(_wcs1, _wcs2) ((*((_wcs1)+wcsspn(_wcs1,_wcs2))) ? ((_wcs1)+wcsspn(_wcs1,_wcs2)) : NULL) - -#if 1 // defined __MSVCRT__ -/* - * These wide functions not in crtdll.dll. - * Define macros anyway so that _wfoo rather than _tfoo is undefined - */ -#define _ttoi64 _wtoi64 -#define _i64tot _i64tow -#define _ui64tot _ui64tow -#define _tasctime _wasctime -#define _tctime _wctime -#define _tstrdate _wstrdate -#define _tstrtime _wstrtime -#define _tutime _wutime -#define _tcsnccoll _wcsncoll -#define _tcsncoll _wcsncoll +#define _tprintf wprintf +#define _tprintf_l _wprintf_l +#define _tprintf_p _wprintf_p +#define _tprintf_p_l _wprintf_p_l +#define _tcprintf _cwprintf +#define _tcprintf_l _cwprintf_l +#define _tcprintf_p _cwprintf_p +#define _tcprintf_p_l _cwprintf_p_l +#define _vtcprintf _vcwprintf +#define _vtcprintf_l _vcwprintf_l +#define _vtcprintf_p _vcwprintf_p +#define _vtcprintf_p_l _vcwprintf_p_l +#define _ftprintf fwprintf +#define _ftprintf_l _fwprintf_l +#define _ftprintf_p _fwprintf_p +#define _ftprintf_p_l _fwprintf_p_l +#define _stprintf swprintf +#define _stprintf_l __swprintf_l +#define _stprintf_p _swprintf_p +#define _stprintf_p_l _swprintf_p_l +#define _sctprintf _scwprintf +#define _sctprintf_l _scwprintf_l +#define _sctprintf_p _scwprintf_p +#define _sctprintf_p_l _scwprintf_p_l +#define _sntprintf _snwprintf +#define _sntprintf_l _snwprintf_l +#define _vtprintf vwprintf +#define _vtprintf_l _vwprintf_l +#define _vtprintf_p _vwprintf_p +#define _vtprintf_p_l _vwprintf_p_l +#define _vftprintf vfwprintf +#define _vftprintf_l _vfwprintf_l +#define _vftprintf_p _vfwprintf_p +#define _vftprintf_p_l _vfwprintf_p_l +#define _vstprintf vswprintf +#define _vstprintf_l _vswprintf_l +#define _vstprintf_p _vswprintf_p +#define _vstprintf_p_l _vswprintf_p_l +#define _vsctprintf _vscwprintf +#define _vsctprintf_l _vscwprintf_l +#define _vsctprintf_p _vscwprintf_p +#define _vsctprintf_p_l _vscwprintf_p_l +#define _vsntprintf _vsnwprintf +#define _vsntprintf_l _vsnwprintf_l + +#define _tscanf wscanf +#define _tscanf_l _wscanf_l +#define _tcscanf _cwscanf +#define _tcscanf_l _cwscanf_l +#define _ftscanf fwscanf +#define _ftscanf_l _fwscanf_l +#define _stscanf swscanf +#define _stscanf_l _swscanf_l +#define _sntscanf _snwscanf +#define _sntscanf_l _snwscanf_l + +#define _fgettc fgetwc +#define _fgettc_nolock _fgetwc_nolock +#define _fgettchar _fgetwchar +#define _fgetts fgetws +#define _fputtc fputwc +#define _fputtc_nolock _fputwc_nolock +#define _fputtchar _fputwchar +#define _fputts fputws +#define _cputts _cputws +#define _cgetts _cgetws +#define _gettc getwc +#define _gettc_nolock _getwc_nolock +#define _gettch _getwch +#define _gettch_nolock _getwch_nolock +#define _gettche _getwche +#define _gettche_nolock _getwche_nolock +#define _gettchar getwchar +#define _gettchar_nolock _getwchar_nolock +#define _getts _getws +#define _puttc putwc +#define _puttc_nolock _putwc_nolock +#define _puttchar putwchar +#define _puttchar_nolock _putwchar_nolock +#define _puttch _putwch +#define _puttch_nolock _putwch_nolock +#define _putts _putws +#define _ungettc ungetwc +#define _ungettc_nolock _ungetwc_nolock +#define _ungettch _ungetwch +#define _ungettch_nolock _ungetwch_nolock + +#define _tcstod wcstod +#define _tcstol wcstol +#define _tcstoul wcstoul +#define _tcstoi64 _wcstoi64 +#define _tcstoui64 _wcstoui64 +#define _tstof _wtof +#define _tstol _wtol +#define _tstoi _wtoi +#define _tstoi64 _wtoi64 +#define _tcstod_l _wcstod_l +#define _tcstol_l _wcstol_l +#define _tcstoul_l _wcstoul_l +#define _tcstoi64_l _wcstoi64_l +#define _tcstoui64_l _wcstoui64_l +#define _tstof_l _wtof_l +#define _tstol_l _wtol_l +#define _tstoi_l _wtoi_l +#define _tstoi64_l _wtoi64_l + +#define _itot _itow +#define _ltot _ltow +#define _ultot _ultow +#define _ttoi _wtoi +#define _ttol _wtol + +#define _ttoi64 _wtoi64 +#define _i64tot _i64tow +#define _ui64tot _ui64tow + +#define _tcscat wcscat +#define _tcschr wcschr +#define _tcscpy wcscpy +#define _tcscspn wcscspn +#define _tcslen wcslen +#define _tcsnlen wcsnlen +#define _tcsncat wcsncat +#define _tcsncat_l _wcsncat_l +#define _tcsncpy wcsncpy +#define _tcsncpy_l _wcsncpy_l +#define _tcspbrk wcspbrk +#define _tcsrchr wcsrchr +#define _tcsspn wcsspn +#define _tcsstr wcsstr +#define _tcstok wcstok +#define _tcstok_l _wcstok_l +#define _tcserror _wcserror +#define __tcserror __wcserror + +#define _tcsdup _wcsdup +#define _tcsnset _wcsnset +#define _tcsnset_l _wcsnset_l +#define _tcsrev _wcsrev +#define _tcsset _wcsset +#define _tcsset_l _wcsset_l + +#define _tcscmp wcscmp +#define _tcsicmp _wcsicmp +#define _tcsicmp_l _wcsicmp_l +#define _tcsnccmp wcsncmp +#define _tcsncmp wcsncmp +#define _tcsncicmp _wcsnicmp +#define _tcsncicmp_l _wcsnicmp_l +#define _tcsnicmp _wcsnicmp +#define _tcsnicmp_l _wcsnicmp_l + +#define _tcscoll wcscoll +#define _tcscoll_l _wcscoll_l +#define _tcsicoll _wcsicoll +#define _tcsicoll_l _wcsicoll_l +#define _tcsnccoll _wcsncoll +#define _tcsnccoll_l _wcsncoll_l +#define _tcsncoll _wcsncoll +#define _tcsncoll_l _wcsncoll_l #define _tcsncicoll _wcsnicoll -#define _tcsnicoll _wcsnicoll -#define _taccess _waccess -#define _tchmod _wchmod -#define _tcreat _wcreat +#define _tcsncicoll_l _wcsnicoll_l +#define _tcsnicoll _wcsnicoll +#define _tcsnicoll_l _wcsnicoll_l + +#define _texecl _wexecl +#define _texecle _wexecle +#define _texeclp _wexeclp +#define _texeclpe _wexeclpe +#define _texecv _wexecv +#define _texecve _wexecve +#define _texecvp _wexecvp +#define _texecvpe _wexecvpe + +#define _tspawnl _wspawnl +#define _tspawnle _wspawnle +#define _tspawnlp _wspawnlp +#define _tspawnlpe _wspawnlpe +#define _tspawnv _wspawnv +#define _tspawnve _wspawnve +#define _tspawnvp _wspawnvp +#define _tspawnvp _wspawnvp +#define _tspawnvpe _wspawnvpe + +#define _tsystem _wsystem + +#define _tasctime _wasctime +#define _tctime _wctime +#define _tctime32 _wctime32 +#define _tctime64 _wctime64 +#define _tstrdate _wstrdate +#define _tstrtime _wstrtime +#define _tutime _wutime +#define _tutime32 _wutime32 +#define _tutime64 _wutime64 +#define _tcsftime wcsftime +#define _tcsftime_l _wcsftime_l + +#define _tchdir _wchdir +#define _tgetcwd _wgetcwd +#define _tgetdcwd _wgetdcwd +#define _tgetdcwd_nolock _wgetdcwd_nolock +#define _tmkdir _wmkdir +#define _trmdir _wrmdir + +#define _tfullpath _wfullpath +#define _tgetenv _wgetenv +#define _tmakepath _wmakepath +#define _tpgmptr _wpgmptr +#define _get_tpgmptr _get_wpgmptr +#define _tputenv _wputenv +#define _tsearchenv _wsearchenv +#define _tsplitpath _wsplitpath + +#define _tfdopen _wfdopen +#define _tfsopen _wfsopen +#define _tfopen _wfopen +#define _tfreopen _wfreopen +#define _tperror _wperror +#define _tpopen _wpopen +#define _ttempnam _wtempnam +#define _ttmpnam _wtmpnam + +#define _taccess _waccess +#define _tchmod _wchmod +#define _tcreat _wcreat #define _tfindfirst _wfindfirst -#define _tfindnext _wfindnext -#define _tfopen _wfopen -#define _tgetenv _wgetenv -#define _tmktemp _wmktemp -#define _topen _wopen -#define _tremove _wremove -#define _trename _wrename -#define _tsopen _wsopen -#define _tsetlocale _wsetlocale -#define _tunlink _wunlink -#define _tfinddata_t _wfinddata_t -#define _tfindfirsti64 _wfindfirsti64 -#define _tfindnexti64 _wfindnexti64 +#define _tfindfirst32 _wfindfirst32 +#define _tfindfirst64 _wfindfirst64 +#define _tfindfirsti64 _wfindfirsti64 +#define _tfindfirst32i64 _wfindfirst32i64 +#define _tfindfirst64i32 _wfindfirst64i32 +#define _tfindnext _wfindnext +#define _tfindnext32 _wfindnext32 +#define _tfindnext64 _wfindnext64 +#define _tfindnexti64 _wfindnexti64 +#define _tfindnext32i64 _wfindnext32i64 +#define _tfindnext64i32 _wfindnext64i32 +#define _tmktemp _wmktemp +#define _topen _wopen +#define _tremove _wremove +#define _trename _wrename +#define _tsopen _wsopen +#define _tunlink _wunlink + +#define _tfinddata_t _wfinddata_t +#define _tfinddata32_t _wfinddata32_t +#define _tfinddata64_t _wfinddata64_t #define _tfinddatai64_t _wfinddatai64_t -#endif /* __MSVCRT__ */ +#define _tfinddata32i64_t _wfinddata32i64_t +#define _tfinddata64i32_t _wfinddata64i32_t -#else /* Not _UNICODE */ +#define _tstat _wstat +#define _tstat32 _wstat32 +#define _tstat32i64 _wstat32i64 +#define _tstat64 _wstat64 +#define _tstat64i32 _wstat64i32 +#define _tstati64 _wstati64 -/* - * TCHAR, the type you should use instead of char. - */ -#ifndef _TCHAR_DEFINED -#ifndef RC_INVOKED -typedef char TCHAR; -typedef char _TCHAR; +#define _tsetlocale _wsetlocale + +#define _tcsclen wcslen +#define _tcscnlen wcsnlen +#define _tcsclen_l(_String,_Locale) wcslen(_String) +#define _tcscnlen_l(_String,_Max_count,_Locale) wcsnlen_l((_String),(_Max_count)) +#define _tcsnccat wcsncat +#define _tcsnccat_l _wcsncat_l +#define _tcsnccpy wcsncpy +#define _tcsnccpy_l _wcsncpy_l +#define _tcsncset _wcsnset + +#define _tcsdec _wcsdec +#define _tcsinc _wcsinc +#define _tcsnbcnt _wcsncnt +#define _tcsnccnt _wcsncnt +#define _tcsnextc _wcsnextc +#define _tcsninc _wcsninc +#define _tcsspnp _wcsspnp + +#define _tcslwr _wcslwr +#define _tcslwr_l _wcslwr_l +#define _tcsupr _wcsupr +#define _tcsupr_l _wcsupr_l +#define _tcsxfrm wcsxfrm +#define _tcsxfrm_l _wcsxfrm_l + +#define _tclen(_pc) (1) +#define _tccpy(_pc1,_cpc2) ((*(_pc1) = *(_cpc2))) +#define _tccmp(_cpc1,_cpc2) ((*(_cpc1))-(*(_cpc2))) + +#define _istalnum iswalnum +#define _istalnum_l _iswalnum_l +#define _istalpha iswalpha +#define _istalpha_l _iswalpha_l +#define _istascii iswascii +#define _istcntrl iswcntrl +#define _istcntrl_l _iswcntrl_l +#define _istdigit iswdigit +#define _istdigit_l _iswdigit_l +#define _istgraph iswgraph +#define _istgraph_l _iswgraph_l +#define _istlower iswlower +#define _istlower_l _iswlower_l +#define _istprint iswprint +#define _istprint_l _iswprint_l +#define _istpunct iswpunct +#define _istpunct_l _iswpunct_l +#define _istspace iswspace +#define _istspace_l _iswspace_l +#define _istupper iswupper +#define _istupper_l _iswupper_l +#define _istxdigit iswxdigit +#define _istxdigit_l _iswxdigit_l + +#define _totupper towupper +#define _totupper_l _towupper_l +#define _totlower towlower +#define _totlower_l _towlower_l + +#define _istlegal(_Char) (1) +#define _istlead(_Char) (0) +#define _istleadbyte(_Char) (0) +#define _istleadbyte_l(_Char,_Locale) (0) + +#define _wcsdec(_cpc1,_cpc2) ((_cpc1)>=(_cpc2) ? NULL : (_cpc2)-1) +#define _wcsinc(_pc) ((_pc)+1) +#define _wcsnextc(_cpc) ((unsigned int) *(_cpc)) +#define _wcsninc(_pc,_sz) (((_pc)+(_sz))) + _CRTIMP size_t __cdecl __wcsncnt(const wchar_t *_Str,size_t _MaxCount); +#define _wcsncnt(_cpc,_sz) (__wcsncnt(_cpc,_sz)) +#define _wcsspnp(_cpc1,_cpc2) (!_cpc1 ? NULL : ((*((_cpc1)+wcsspn(_cpc1,_cpc2))) ? ((_cpc1)+wcsspn(_cpc1,_cpc2)) : NULL)) +#define _wcsncpy_l(_Destination,_Source,_Count,_Locale) (wcsncpy(_Destination,_Source,_Count)) +#define _wcsncat_l(_Destination,_Source,_Count,_Locale) (wcsncat(_Destination,_Source,_Count)) +#define _wcstok_l(_String,_Delimiters,_Locale) (wcstok(_String,_Delimiters)) +#define _wcsnset_l(_Destination,_Value,_Count,_Locale) (_wcsnset(_Destination,_Value,_Count)) +#define _wcsset_l(_Destination,_Value,_Locale) (_wcsset(_Destination,_Value)) + + /* dirent structures and functions */ +#define _tdirent _wdirent +#define _TDIR _WDIR +#define _topendir _wopendir +#define _tclosedir _wclosedir +#define _treaddir _wreaddir +#define _trewinddir _wrewinddir +#define _ttelldir _wtelldir +#define _tseekdir _wseekdir + +#else + +#ifdef __cplusplus +} #endif -#define _TCHAR_DEFINED + +#include <string.h> + +#ifdef __cplusplus +extern "C" { #endif -/* - * __TEXT is a private macro whose specific use is to force the expansion of a - * macro passed as an argument to the macros _T or _TEXT. DO NOT use this - * macro within your programs. It's name and function could change without - * notice. - */ -#define __TEXT(x) x +#define _TEOF EOF -/* for porting from other Windows compilers */ -#define _tmain main -#define _tWinMain WinMain -#define _tenviron _environ -#define __targv __argv +#define __T(x) x -/* - * Non-unicode (standard) functions - */ +#define _tmain main +#define _tWinMain WinMain +#ifdef _POSIX_ +#define _tenviron environ +#else +#define _tenviron _environ +#endif +#define __targv __argv + +#define _tprintf printf +#define _tprintf_l _printf_l +#define _tprintf_p _printf_p +#define _tprintf_p_l _printf_p_l +#define _tcprintf _cprintf +#define _tcprintf_l _cprintf_l +#define _tcprintf_p _cprintf_p +#define _tcprintf_p_l _cprintf_p_l +#define _vtcprintf _vcprintf +#define _vtcprintf_l _vcprintf_l +#define _vtcprintf_p _vcprintf_p +#define _vtcprintf_p_l _vcprintf_p_l +#define _ftprintf fprintf +#define _ftprintf_l _fprintf_l +#define _ftprintf_p _fprintf_p +#define _ftprintf_p_l _fprintf_p_l +#define _stprintf sprintf +#define _stprintf_l _sprintf_l +#define _stprintf_p _sprintf_p +#define _stprintf_p_l _sprintf_p_l +#define _sctprintf _scprintf +#define _sctprintf_l _scprintf_l +#define _sctprintf_p _scprintf_p +#define _sctprintf_p_l _scprintf_p_l +#define _sntprintf _snprintf +#define _sntprintf_l _snprintf_l +#define _vtprintf vprintf +#define _vtprintf_l _vprintf_l +#define _vtprintf_p _vprintf_p +#define _vtprintf_p_l _vprintf_p_l +#define _vftprintf vfprintf +#define _vftprintf_l _vfprintf_l +#define _vftprintf_p _vfprintf_p +#define _vftprintf_p_l _vfprintf_p_l +#define _vstprintf vsprintf +#define _vstprintf_l _vsprintf_l +#define _vstprintf_p _vsprintf_p +#define _vstprintf_p_l _vsprintf_p_l +#define _vsctprintf _vscprintf +#define _vsctprintf_l _vscprintf_l +#define _vsctprintf_p _vscprintf_p +#define _vsctprintf_p_l _vscprintf_p_l +#define _vsntprintf _vsnprintf +#define _vsntprintf_l _vsnprintf_l + +#define _tscanf scanf +#define _tscanf_l _scanf_l +#define _tcscanf _cscanf +#define _tcscanf_l _cscanf_l +#define _ftscanf fscanf +#define _ftscanf_l _fscanf_l +#define _stscanf sscanf +#define _stscanf_l _sscanf_l +#define _sntscanf _snscanf +#define _sntscanf_l _snscanf_l + +#define _fgettc fgetc +#define _fgettc_nolock _fgetc_nolock +#define _fgettchar _fgetchar +#define _fgetts fgets +#define _fputtc fputc +#define _fputtc_nolock _fputc_nolock +#define _fputtchar _fputchar +#define _fputts fputs +#define _cputts _cputs +#define _gettc getc +#define _gettc_nolock _getc_nolock +#define _gettch _getch +#define _gettch_nolock _getch_nolock +#define _gettche _getche +#define _gettche_nolock _getche_nolock +#define _gettchar getchar +#define _gettchar_nolock _getchar_nolock +#define _getts gets +#define _cgetts _cgets +#define _puttc putc +#define _puttc_nolock _putc_nolock +#define _puttchar putchar +#define _puttchar_nolock _putchar_nolock +#define _puttch _putch +#define _puttch_nolock _putch_nolock +#define _putts puts +#define _ungettc ungetc +#define _ungettc_nolock _ungetc_nolock +#define _ungettch _ungetch +#define _ungettch_nolock _ungetch_nolock + +#define _tcstod strtod +#define _tcstol strtol +#define _tcstoul strtoul +#define _tstof atof +#define _tstol atol +#define _tstoi atoi +#define _tstoi64 _atoi64 +#define _tcstod_l _strtod_l +#define _tcstol_l _strtol_l +#define _tcstoul_l _strtoul_l +#define _tstof_l _atof_l +#define _tstol_l _atol_l +#define _tstoi_l _atoi_l +#define _tstoi64_l _atoi64_l + +#define _itot _itoa +#define _ltot _ltoa +#define _ultot _ultoa +#define _ttoi atoi +#define _ttol atol + +#define _ttoi64 _atoi64 +#define _tcstoi64 _strtoi64 +#define _tcstoi64_l _strtoi64_l +#define _tcstoui64 _strtoui64 +#define _tcstoui64_l _strtoui64_l +#define _i64tot _i64toa +#define _ui64tot _ui64toa -#define _tprintf printf -#define _ftprintf fprintf -#define _stprintf sprintf -#define _sntprintf _snprintf -#define _vtprintf vprintf -#define _vftprintf vfprintf -#define _vstprintf vsprintf -#define _vsntprintf _vsnprintf -#define _tscanf scanf -#define _ftscanf fscanf -#define _stscanf sscanf -#define _fgettc fgetc -#define _fgettchar _fgetchar -#define _fgetts fgets -#define _fputtc fputc -#define _fputtchar _fputchar -#define _fputts fputs -#define _tfopen fopen -#define _tgetenv getenv -#define _gettc getc -#define _getts gets -#define _puttc putc -#define _putts puts -#define _ungettc ungetc -#define _tcstod strtod -#define _tcstol strtol -#define _tcstoul strtoul -#define _itot _itoa -#define _ltot _ltoa -#define _ultot _ultoa -#define _ttoi atoi -#define _ttol atol -#define _tcscat strcat -#define _tcschr strchr -#define _tcscmp strcmp -#define _tcscpy strcpy -#define _tcscspn strcspn -#define _tcslen strlen -#define _tcsncat strncat -#define _tcsncmp strncmp -#define _tcsncpy strncpy -#define _tcspbrk strpbrk -#define _tcsrchr strrchr -#define _tcsspn strspn -#define _tcsstr strstr -#define _tcstok strtok -#define _tcsdup _strdup -#define _tcsicmp _stricmp -#define _tcsnicmp _strnicmp -#define _tcsnset _strnset -#define _tcsrev _strrev -#define _tcsset _strset -#define _tcslwr _strlwr -#define _tcsupr _strupr -#define _tcsxfrm strxfrm -#define _tcscoll strcoll -#define _tcsicoll _stricoll -#define _istalpha isalpha -#define _istupper isupper -#define _istlower islower -#define _istdigit isdigit -#define _istxdigit isxdigit -#define _istspace isspace -#define _istpunct ispunct -#define _istalnum isalnum -#define _istprint isprint -#define _istgraph isgraph -#define _istcntrl iscntrl -#define _istascii isascii -#define _totupper toupper -#define _totlower tolower -#define _tasctime asctime -#define _tctime ctime -#define _tstrdate _strdate -#define _tstrtime _strtime -#define _tutime _utime -#define _tcsftime strftime -/* Macro functions */ -#define _tcsdec _strdec -#define _tcsinc _strinc -#define _tcsnbcnt _strncnt -#define _tcsnccnt _strncnt -#define _tcsnextc _strnextc -#define _tcsninc _strninc -#define _tcsspnp _strspnp -#define _strdec(_str1, _str2) ((_str1)>=(_str2) ? NULL : (_str2)-1) -#define _strinc(_str) ((_str)+1) -#define _strnextc(_str) ((unsigned int) *(_str)) -#define _strninc(_str, _inc) (((_str)+(_inc))) -#define _strncnt(_str, _cnt) ((strlen(_str)>_cnt) ? _count : strlen(_str)) -#define _strspnp(_str1, _str2) ((*((_str1)+strspn(_str1,_str2))) ? ((_str1)+strspn(_str1,_str2)) : NULL) - -#define _tchmod _chmod -#define _tcreat _creat +#define _tcscat strcat +#define _tcscpy strcpy +#define _tcsdup _strdup +#define _tcslen strlen +#if 0 +#define _tcsnlen strnlen +#endif +#define _tcsxfrm strxfrm +#define _tcsxfrm_l _strxfrm_l +#define _tcserror strerror +#define __tcserror _strerror + +#define _texecl _execl +#define _texecle _execle +#define _texeclp _execlp +#define _texeclpe _execlpe +#define _texecv _execv +#define _texecve _execve +#define _texecvp _execvp +#define _texecvpe _execvpe + +#define _tspawnl _spawnl +#define _tspawnle _spawnle +#define _tspawnlp _spawnlp +#define _tspawnlpe _spawnlpe +#define _tspawnv _spawnv +#define _tspawnve _spawnve +#define _tspawnvp _spawnvp +#define _tspawnvpe _spawnvpe + +#define _tsystem system + +#define _tasctime asctime +#define _tctime ctime +#define _tctime32 _ctime32 +#define _tctime64 _ctime64 +#define _tstrdate _strdate +#define _tstrtime _strtime +#define _tutime _utime +#define _tutime32 _utime32 +#define _tutime64 _utime64 +#define _tcsftime strftime +#define _tcsftime_l _strftime_l + +#define _tchdir _chdir +#define _tgetcwd _getcwd +#define _tgetdcwd _getdcwd +#define _tgetdcwd_nolock _getdcwd_nolock +#define _tmkdir _mkdir +#define _trmdir _rmdir + +#define _tfullpath _fullpath +#define _tgetenv getenv +#define _tmakepath _makepath +#define _tpgmptr _pgmptr +#define _get_tpgmptr _get_pgmptr +#define _tputenv _putenv +#define _tsearchenv _searchenv +#define _tsplitpath _splitpath + +#ifdef _POSIX_ +#define _tfdopen fdopen +#else +#define _tfdopen _fdopen +#endif +#define _tfsopen _fsopen +#define _tfopen fopen +#define _tfreopen freopen +#define _tperror perror +#define _tpopen _popen +#define _ttempnam _tempnam +#define _ttmpnam tmpnam + +#define _tchmod _chmod +#define _tcreat _creat #define _tfindfirst _findfirst -#define _tfindnext _findnext -#define _tmktemp _mktemp -#define _topen _open -#define _taccess _access -#define _tremove remove -#define _trename rename -#define _tsopen _sopen +#define _tfindfirst32 _findfirst32 +#define _tfindfirst64 _findfirst64 +#define _tfindfirsti64 _findfirsti64 +#define _tfindfirst32i64 _findfirst32i64 +#define _tfindfirst64i32 _findfirst64i32 +#define _tfindnext _findnext +#define _tfindnext32 _findnext32 +#define _tfindnext64 _findnext64 +#define _tfindnexti64 _findnexti64 +#define _tfindnext32i64 _findnext32i64 +#define _tfindnext64i32 _findnext64i32 +#define _tmktemp _mktemp + +#ifdef _POSIX_ +#define _topen open +#define _taccess access +#else +#define _topen _open +#define _taccess _access +#endif + +#define _tremove remove +#define _trename rename +#define _tsopen _sopen +#define _tunlink _unlink + +#define _tfinddata_t _finddata_t +#define _tfinddata32_t _finddata32_t +#define _tfinddata64_t __finddata64_t +#define _tfinddatai64_t _finddatai64_t +#define _tfinddata32i64_t _finddata32i64_t +#define _tfinddata64i32_t _finddata64i32_t + +#define _istascii __isascii +#define _istcntrl iscntrl +#define _istcntrl_l _iscntrl_l +#define _istxdigit isxdigit +#define _istxdigit_l _isxdigit_l + +#define _tstat _stat +#define _tstat32 _stat32 +#define _tstat32i64 _stat32i64 +#define _tstat64 _stat64 +#define _tstat64i32 _stat64i32 +#define _tstati64 _stati64 + #define _tsetlocale setlocale -#define _tunlink _unlink -#define _tfinddata_t _finddata_t +#ifdef _MBCS + +#ifdef __cplusplus +} +#endif + +#include <mbstring.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __TCHAR_DEFINED + typedef char _TCHAR; + typedef signed char _TSCHAR; + typedef unsigned char _TUCHAR; + typedef unsigned char _TXCHAR; + typedef unsigned int _TINT; +#define __TCHAR_DEFINED +#endif + +#ifndef _TCHAR_DEFINED +#ifndef NO_OLDNAMES + typedef char TCHAR; +#endif +#define _TCHAR_DEFINED +#endif + +#ifdef _MB_MAP_DIRECT + +#define _tcschr _mbschr +#define _tcscspn _mbscspn +#define _tcsncat _mbsnbcat +#define _tcsncat_l _mbsnbcat_l +#define _tcsncpy _mbsnbcpy +#define _tcsncpy_l _mbsnbcpy_l +#define _tcspbrk _mbspbrk +#define _tcsrchr _mbsrchr +#define _tcsspn _mbsspn +#define _tcsstr _mbsstr +#define _tcstok _mbstok +#define _tcstok_l _mbstok_l + +#define _tcsnset _mbsnbset +#define _tcsnset_l _mbsnbset_l +#define _tcsrev _mbsrev +#define _tcsset _mbsset +#define _tcsset_l _mbsset_l + +#define _tcscmp _mbscmp +#define _tcsicmp _mbsicmp +#define _tcsicmp_l _mbsicmp_l +#define _tcsnccmp _mbsncmp +#define _tcsncmp _mbsnbcmp +#define _tcsncicmp _mbsnicmp +#define _tcsncicmp_l _mbsnicmp_l +#define _tcsnicmp _mbsnbicmp +#define _tcsnicmp_l _mbsnbicmp_l + +#define _tcscoll _mbscoll +#define _tcscoll_l _mbscoll_l +#define _tcsicoll _mbsicoll +#define _tcsicoll_l _mbsicoll_l +#define _tcsnccoll _mbsncoll +#define _tcsnccoll_l _mbsncoll_l +#define _tcsncoll _mbsnbcoll +#define _tcsncoll_l _mbsnbcoll_l +#define _tcsncicoll _mbsnicoll +#define _tcsncicoll_l _mbsnicoll_l +#define _tcsnicoll _mbsnbicoll +#define _tcsnicoll_l _mbsnbicoll_l + +#define _tcsclen _mbslen +#define _tcscnlen _mbsnlen +#define _tcsclen_l _mbslen_l +#define _tcscnlen_l _mbsnlen_l +#define _tcsnccat _mbsncat +#define _tcsnccat_l _mbsncat_l +#define _tcsnccpy _mbsncpy +#define _tcsnccpy_l _mbsncpy_l +#define _tcsncset _mbsnset +#define _tcsncset_l _mbsnset_l + +#define _tcsdec _mbsdec +#define _tcsinc _mbsinc +#define _tcsnbcnt _mbsnbcnt +#define _tcsnccnt _mbsnccnt +#define _tcsnextc _mbsnextc +#define _tcsninc _mbsninc +#define _tcsspnp _mbsspnp + +#define _tcslwr _mbslwr +#define _tcslwr_l _mbslwr_l +#define _tcsupr _mbsupr +#define _tcsupr_l _mbsupr_l + +#define _tclen _mbclen +#define _tccpy _mbccpy +#define _tccpy_l _mbccpy_l +#else -#if 1 // defined __MSVCRT__ -/* Not in crtdll.dll. Define macros anyway? */ -#define _ttoi64 _atoi64 -#define _i64tot _i64toa -#define _ui64tot _ui64toa -#define _tcsnccoll _strncoll -#define _tcsncoll _strncoll + _CRTIMP _CONST_RETURN char *__cdecl _tcschr(const char *_Str,unsigned int _Val); + _CRTIMP size_t __cdecl _tcscspn(const char *_Str,const char *_Control); + _CRTIMP char *__cdecl _tcsncat(char *_Dst,const char *_Src,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsncat_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsncpy(char *_Dst,const char *_Src,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsncpy_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP _CONST_RETURN char *__cdecl _tcspbrk(const char *_Str,const char *_Control); + _CRTIMP _CONST_RETURN char *__cdecl _tcsrchr(const char *_Str,unsigned int _Ch); + _CRTIMP size_t __cdecl _tcsspn(const char *_Str,const char *_Control); + _CRTIMP _CONST_RETURN char *__cdecl _tcsstr(const char *_Str,const char *_Substr); + _CRTIMP char *__cdecl _tcstok(char *_Str,const char *_Delim); + _CRTIMP char *__cdecl _tcstok_l(char *_Str,const char *_Delim,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsnset(char *_Str,unsigned int _Val,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsrev(char *_Str); + _CRTIMP char *__cdecl _tcsset(char *_Str,unsigned int _Val); + _CRTIMP char *__cdecl _tcsset_l(char *_Str,unsigned int _Val,_locale_t _Locale); + _CRTIMP int __cdecl _tcscmp(const char *_Str1,const char *_Str); + _CRTIMP int __cdecl _tcsicmp(const char *_Str1,const char *_Str2); + _CRTIMP int __cdecl _tcsicmp_l(const char *_Str1,const char *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _tcsnccmp(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _tcsncmp(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _tcsncicmp(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _tcsncicmp_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP int __cdecl _tcsnicmp(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _tcsnicmp_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP int __cdecl _tcscoll(const char *_Str1,const char *_Str2); + _CRTIMP int __cdecl _tcscoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _tcsicoll(const char *_Str1,const char *_Str2); + _CRTIMP int __cdecl _tcsicoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _tcsnccoll(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _tcsnccoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP int __cdecl _tcsncoll(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _tcsncoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP int __cdecl _tcsncicoll(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _tcsncicoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP int __cdecl _tcsnicoll(const char *_Str1,const char *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _tcsnicoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP size_t __cdecl _tcsclen(const char *_Str); + _CRTIMP size_t __cdecl _tcscnlen(const char *_Str,size_t _MaxCount); + _CRTIMP size_t __cdecl _tcsclen_l(const char *_Str,_locale_t _Locale); + _CRTIMP size_t __cdecl _tcscnlen_l(const char *_Str,size_t _MaxCount,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsnccat(char *_Dst,const char *_Src,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsnccat_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsnccpy(char *_Dst,const char *_Src,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsnccpy_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsncset(char *_Str,unsigned int _Val,size_t _MaxCount); + _CRTIMP char *__cdecl _tcsdec(const char *_Start,const char *_Pos); + _CRTIMP char *__cdecl _tcsinc(const char *_Ptr); + _CRTIMP size_t __cdecl _tcsnbcnt(const char *_Str,size_t _MaxCount); + _CRTIMP size_t __cdecl _tcsnccnt(const char *_Str,size_t _MaxCount); + _CRTIMP unsigned int __cdecl _tcsnextc (const char *_Str); + _CRTIMP char *__cdecl _tcsninc(const char *_Ptr,size_t _Count); + _CRTIMP char *__cdecl _tcsspnp(const char *_Str1,const char *_Str2); + _CRTIMP char *__cdecl _tcslwr(char *_Str); + _CRTIMP char *__cdecl _tcslwr_l(char *_Str,_locale_t _Locale); + _CRTIMP char *__cdecl _tcsupr(char *_Str); + _CRTIMP char *__cdecl _tcsupr_l(char *_Str,_locale_t _Locale); + _CRTIMP size_t __cdecl _tclen(const char *_Str); + _CRTIMP void __cdecl _tccpy(char *_DstCh,const char *_SrcCh); + +#ifdef __cplusplus +#ifndef _CPP_TCHAR_INLINES_DEFINED +#define _CPP_TCHAR_INLINES_DEFINED + extern "C++" { + extern inline char *__cdecl _tcschr(char *_S,unsigned int _C) { return ((char *)_tcschr((const char *)_S,_C)); } + extern inline char *__cdecl _tcspbrk(char *_S,const char *_P) { return ((char *)_tcspbrk((const char *)_S,_P)); } + extern inline char *__cdecl _tcsrchr(char *_S,unsigned int _C) { return ((char *)_tcsrchr((const char *)_S,_C)); } + extern inline char *__cdecl _tcsstr(char *_S,const char *_P) { return ((char *)_tcsstr((const char *)_S,_P)); } + } +#endif +#endif +#endif + +#define _tccmp(_cp1,_cp2) _tcsnccmp(_cp1,_cp2,1) + +#define _istalnum _ismbcalnum +#define _istalnum_l _ismbcalnum_l +#define _istalpha _ismbcalpha +#define _istalpha_l _ismbcalpha_l +#define _istdigit _ismbcdigit +#define _istdigit_l _ismbcdigit_l +#define _istgraph _ismbcgraph +#define _istgraph_l _ismbcgraph_l +#define _istlegal _ismbclegal +#define _istlegal_l _ismbclegal_l +#define _istlower _ismbclower +#define _istlower_l _ismbclower_l +#define _istprint _ismbcprint +#define _istprint_l _ismbcprint_l +#define _istpunct _ismbcpunct +#define _istpunct_l _ismbcpunct_l +#define _istspace _ismbcspace +#define _istspace_l _ismbcspace_l +#define _istupper _ismbcupper +#define _istupper_l _ismbcupper_l + +#define _totupper _mbctoupper +#define _totupper_l _mbctoupper_l +#define _totlower _mbctolower +#define _totlower_l _mbctolower_l + +#define _istlead _ismbblead +#define _istleadbyte isleadbyte +#define _istleadbyte_l _isleadbyte_l +#else + +#ifndef __TCHAR_DEFINED +#define __TCHAR_DEFINED + typedef char _TCHAR; + typedef signed char _TSCHAR; + typedef unsigned char _TUCHAR; + typedef char _TXCHAR; + typedef int _TINT; +#endif + +#ifndef _TCHAR_DEFINED +#define _TCHAR_DEFINED +#ifndef NO_OLDNAMES + typedef char TCHAR; +#endif +#endif + +#define _tcschr strchr +#define _tcscspn strcspn +#define _tcsncat strncat +#define _tcsncat_l _strncat_l +#define _tcsncpy strncpy +#define _tcsncpy_l _strncpy_l +#define _tcspbrk strpbrk +#define _tcsrchr strrchr +#define _tcsspn strspn +#define _tcsstr strstr +#define _tcstok strtok +#define _tcstok_l _strtok_l + +#define _tcsnset _strnset +#define _tcsnset_l _strnset_l +#define _tcsrev _strrev +#define _tcsset _strset + +#define _tcscmp strcmp +#define _tcsicmp _stricmp +#define _tcsicmp_l _stricmp_l +#define _tcsnccmp strncmp +#define _tcsncmp strncmp +#define _tcsncicmp _strnicmp +#define _tcsncicmp_l _strnicmp_l +#define _tcsnicmp _strnicmp +#define _tcsnicmp_l _strnicmp_l + +#define _tcscoll strcoll +#define _tcscoll_l _strcoll_l +#define _tcsicoll _stricoll +#define _tcsicoll_l _stricoll_l +#define _tcsnccoll _strncoll +#define _tcsnccoll_l _strncoll_l +#define _tcsncoll _strncoll +#define _tcsncoll_l _strncoll_l #define _tcsncicoll _strnicoll -#define _tcsnicoll _strnicoll -#define _tfindfirsti64 _findfirsti64 -#define _tfindnexti64 _findnexti64 -#define _tfinddatai64_t _finddatai64_t -#endif /* __MSVCRT__ */ +#define _tcsncicoll_l _strnicoll_l +#define _tcsnicoll _strnicoll +#define _tcsnicoll_l _strnicoll_l -#endif /* Not _UNICODE */ +#define _tcsclen strlen +#define _tcscnlen strnlen +#define _tcsclen_l(_String,_Locale) strlen(_String) +#define _tcscnlen_l(_String,_Max_count,_Locale) strnlen_l((_String),(_Max_count)) +#define _tcsnccat strncat +#define _tcsnccat_l _strncat_l +#define _tcsnccpy strncpy +#define _tcsnccpy_l _strncpy_l +#define _tcsncset _strnset -/* - * UNICODE a constant string when _UNICODE is defined else returns the string - * unmodified. Also defined in w32api/winnt.h. - */ -#define _TEXT(x) __TEXT(x) -#define _T(x) __TEXT(x) +#define _tcsdec _strdec +#define _tcsinc _strinc +#define _tcsnbcnt _strncnt +#define _tcsnccnt _strncnt +#define _tcsnextc _strnextc +#define _tcsninc _strninc +#define _tcsspnp _strspnp + +#define _tcslwr _strlwr +#define _tcslwr_l _strlwr_l +#define _tcsupr _strupr +#define _tcsupr_l _strupr_l +#define _tcsxfrm strxfrm +#define _tcsxfrm_l _strxfrm_l + +#define _istlead(_Char) (0) +#define _istleadbyte(_Char) (0) +#define _istleadbyte_l(_Char,_Locale) (0) + +#define _tclen(_pc) (1) +#define _tccpy(_pc1,_cpc2) (*(_pc1) = *(_cpc2)) +#define _tccmp(_cpc1,_cpc2) (((unsigned char)*(_cpc1))-((unsigned char)*(_cpc2))) -#endif /* Not _TCHAR_H_ */ + /* dirent structures and functions */ +#define _tdirent dirent +#define _TDIR DIR +#define _topendir opendir +#define _tclosedir closedir +#define _treaddir readdir +#define _trewinddir rewinddir +#define _ttelldir telldir +#define _tseekdir seekdir +#define _istalnum isalnum +#define _istalnum_l _isalnum_l +#define _istalpha isalpha +#define _istalpha_l _isalpha_l +#define _istdigit isdigit +#define _istdigit_l _isdigit_l +#define _istgraph isgraph +#define _istgraph_l _isgraph_l +#define _istlower islower +#define _istlower_l _islower_l +#define _istprint isprint +#define _istprint_l _isprint_l +#define _istpunct ispunct +#define _istpunct_l _ispunct_l +#define _istspace isspace +#define _istspace_l _isspace_l +#define _istupper isupper +#define _istupper_l _isupper_l + +#define _totupper toupper +#define _totupper_l _toupper_l +#define _totlower tolower +#define _totlower_l _tolower_l + +#define _istlegal(_c) (1) + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +#define _strdec(_cpc1,_cpc2) ((_cpc1)>=(_cpc2) ? NULL : (_cpc2)-1) +#define _strinc(_pc) ((_pc)+1) +#define _strnextc(_cpc) ((unsigned int) *(const unsigned char *)(_cpc)) +#define _strninc(_pc,_sz) (((_pc)+(_sz))) + _CRTIMP size_t __cdecl __strncnt(const char *_Str,size_t _Cnt); +#define _strncnt(_cpc,_sz) (__strncnt(_cpc,_sz)) +#define _strspnp(_cpc1,_cpc2) (!_cpc1 ? NULL : ((*((_cpc1)+strspn(_cpc1,_cpc2))) ? ((_cpc1)+strspn(_cpc1,_cpc2)) : NULL)) + +#define _strncpy_l(_Destination,_Source,_Count,_Locale) (strncpy(_Destination,_Source,_Count)) +#define _strncat_l(_Destination,_Source,_Count,_Locale) (strncat(_Destination,_Source,_Count)) +#define _strtok_l(_String,_Delimiters,_Locale) (strtok(_String,_Delimiters)) +#define _strnset_l(_Destination,_Value,_Count,_Locale) (_strnset(_Destination,_Value,_Count)) +#define _strset_l(_Destination,_Value,_Locale) (_strset(_Destination,_Value)) +#endif +#endif + +#define _T(x) __T(x) +#define _TEXT(x) __T(x) + +#ifdef __cplusplus +} +#endif + +#include <sec_api/tchar_s.h> +#endif diff --git a/tinyc/win32/include/time.h b/tinyc/win32/include/time.h index ade7f6db7..6c72e2660 100644 --- a/tinyc/win32/include/time.h +++ b/tinyc/win32/include/time.h @@ -1,219 +1,287 @@ -/* - * time.h - * - * Date and time functions and types. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _TIME_H_ +#define _TIME_H_ -#ifndef _TIME_H_ -#define _TIME_H_ - -/* All the headers include this file. */ #include <_mingw.h> -#define __need_wchar_t -#define __need_size_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ +#ifndef _WIN32 +#error Only Win32 target is supported! +#endif -/* - * Need a definition of time_t. - */ -#include <sys/types.h> +#pragma pack(push,_CRT_PACKING) -/* - * Number of clock ticks per second. A clock tick is the unit by which - * processor time is measured and is returned by 'clock'. - */ -#define CLOCKS_PER_SEC ((clock_t)1000) -#define CLK_TCK CLOCKS_PER_SEC +#ifdef __cplusplus +extern "C" { +#endif +#ifndef _CRTIMP +#define _CRTIMP __declspec(dllimport) +#endif -#ifndef RC_INVOKED +#ifndef _WCHAR_T_DEFINED +#define _WCHAR_T_DEFINED + typedef unsigned short wchar_t; +#endif + +#ifndef _TIME32_T_DEFINED +#define _TIME32_T_DEFINED + typedef long __time32_t; +#endif + +#ifndef _TIME64_T_DEFINED +#define _TIME64_T_DEFINED +#if _INTEGRAL_MAX_BITS >= 64 +#if defined(__GNUC__) && defined(__STRICT_ANSI__) + typedef int _time64_t __attribute__ ((mode (DI))); +#else + typedef __int64 __time64_t; +#endif +#endif +#endif -/* - * A type for storing the current time and date. This is the number of - * seconds since midnight Jan 1, 1970. - * NOTE: Normally this is defined by the above include of sys/types.h - */ #ifndef _TIME_T_DEFINED -typedef long time_t; #define _TIME_T_DEFINED +#ifdef _USE_32BIT_TIME_T + typedef __time32_t time_t; +#else + typedef __time64_t time_t; +#endif #endif -/* - * A type for measuring processor time (in clock ticks). - */ #ifndef _CLOCK_T_DEFINED -typedef long clock_t; #define _CLOCK_T_DEFINED + typedef long clock_t; #endif - -/* - * A structure for storing all kinds of useful information about the - * current (or another) time. - */ -struct tm -{ - int tm_sec; /* Seconds: 0-59 (K&R says 0-61?) */ - int tm_min; /* Minutes: 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 Jan. 1: 0-365 */ - int tm_isdst; /* +1 Daylight Savings Time, 0 No DST, - * -1 don't know */ -}; - -#ifdef __cplusplus -extern "C" { +#ifndef _SIZE_T_DEFINED +#define _SIZE_T_DEFINED +#undef size_t +#ifdef _WIN64 +#if defined(__GNUC__) && defined(__STRICT_ANSI__) + typedef unsigned int size_t __attribute__ ((mode (DI))); +#else + typedef unsigned __int64 size_t; +#endif +#else + typedef unsigned int size_t; #endif - -clock_t clock (void); -time_t time (time_t*); -double difftime (time_t, time_t); -time_t mktime (struct tm*); - -/* - * These functions write to and return pointers to static buffers that may - * be overwritten by other function calls. Yikes! - * - * NOTE: localtime, and perhaps the others of the four functions grouped - * below may return NULL if their argument is not 'acceptable'. Also note - * that calling asctime with a NULL pointer will produce an Invalid Page - * Fault and crap out your program. Guess how I know. Hint: stat called on - * a directory gives 'invalid' times in st_atime etc... - */ -char* asctime (const struct tm*); -char* ctime (const time_t*); -struct tm* gmtime (const time_t*); -struct tm* localtime (const time_t*); - - -size_t strftime (char*, size_t, const char*, const struct tm*); - -size_t wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*); - -#ifndef __STRICT_ANSI__ -extern void _tzset (void); - -#ifndef _NO_OLDNAMES -extern void tzset (void); #endif -size_t strftime(char*, size_t, const char*, const struct tm*); -char* _strdate(char*); -char* _strtime(char*); - -#endif /* Not __STRICT_ANSI__ */ - -/* - * _daylight: non zero if daylight savings time is used. - * _timezone: difference in seconds between GMT and local time. - * _tzname: standard/daylight savings time zone names (an array with two - * elements). - */ -#ifdef __MSVCRT__ - -/* These are for compatibility with pre-VC 5.0 suppied MSVCRT. */ -extern int* __p__daylight (void); -extern long* __p__timezone (void); -extern char** __p__tzname (void); - -__MINGW_IMPORT int _daylight; -__MINGW_IMPORT long _timezone; -__MINGW_IMPORT char *_tzname[2]; - -#else /* not __MSVCRT (ie. crtdll) */ - -#ifndef __DECLSPEC_SUPPORTED - -extern int* __imp__daylight_dll; -extern long* __imp__timezone_dll; -extern char** __imp__tzname; - -#define _daylight (*__imp__daylight_dll) -#define _timezone (*__imp__timezone_dll) -#define _tzname (__imp__tzname) - -#else /* __DECLSPEC_SUPPORTED */ - -__MINGW_IMPORT int _daylight_dll; -__MINGW_IMPORT long _timezone_dll; -__MINGW_IMPORT char* _tzname[2]; +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 +#if defined(__GNUC__) && defined(__STRICT_ANSI__) + typedef int ssize_t __attribute__ ((mode (DI))); +#else + typedef __int64 ssize_t; +#endif +#else + typedef int ssize_t; +#endif +#endif -#define _daylight _daylight_dll -#define _timezone _timezone_dll +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif -#endif /* __DECLSPEC_SUPPORTED */ +#ifdef _USE_32BIT_TIME_T +#define _localtime32 localtime +#define _difftime32 difftime +#define _ctime32 ctime +#define _gmtime32 gmtime +#define _mktime32 mktime +#define _time32 time +#endif -#endif /* not __MSVCRT__ */ +#ifndef _TM_DEFINED +#define _TM_DEFINED + struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + }; +#endif -#ifndef _NO_OLDNAMES +#define CLOCKS_PER_SEC 1000 + + __MINGW_IMPORT int _daylight; + __MINGW_IMPORT long _dstbias; + __MINGW_IMPORT long _timezone; + __MINGW_IMPORT char * _tzname[2]; + _CRTIMP errno_t __cdecl _get_daylight(int *_Daylight); + _CRTIMP errno_t __cdecl _get_dstbias(long *_Daylight_savings_bias); + _CRTIMP errno_t __cdecl _get_timezone(long *_Timezone); + _CRTIMP errno_t __cdecl _get_tzname(size_t *_ReturnValue,char *_Buffer,size_t _SizeInBytes,int _Index); + char *__cdecl asctime(const struct tm *_Tm); + _CRTIMP char *__cdecl _ctime32(const __time32_t *_Time); + clock_t __cdecl clock(void); + _CRTIMP double __cdecl _difftime32(__time32_t _Time1,__time32_t _Time2); + _CRTIMP struct tm *__cdecl _gmtime32(const __time32_t *_Time); + _CRTIMP struct tm *__cdecl _localtime32(const __time32_t *_Time); + size_t __cdecl strftime(char *_Buf,size_t _SizeInBytes,const char *_Format,const struct tm *_Tm); + _CRTIMP size_t __cdecl _strftime_l(char *_Buf,size_t _Max_size,const char *_Format,const struct tm *_Tm,_locale_t _Locale); + _CRTIMP char *__cdecl _strdate(char *_Buffer); + _CRTIMP char *__cdecl _strtime(char *_Buffer); + _CRTIMP __time32_t __cdecl _time32(__time32_t *_Time); + _CRTIMP __time32_t __cdecl _mktime32(struct tm *_Tm); + _CRTIMP __time32_t __cdecl _mkgmtime32(struct tm *_Tm); +#if defined (_POSIX_) || defined(__GNUC__) + void __cdecl tzset(void); +#else + _CRTIMP void __cdecl _tzset(void); +#endif -#ifdef __MSVCRT__ +#if _INTEGRAL_MAX_BITS >= 64 + double __cdecl _difftime64(__time64_t _Time1,__time64_t _Time2); + _CRTIMP char *__cdecl _ctime64(const __time64_t *_Time); + _CRTIMP struct tm *__cdecl _gmtime64(const __time64_t *_Time); + _CRTIMP struct tm *__cdecl _localtime64(const __time64_t *_Time); + _CRTIMP __time64_t __cdecl _mktime64(struct tm *_Tm); + _CRTIMP __time64_t __cdecl _mkgmtime64(struct tm *_Tm); + _CRTIMP __time64_t __cdecl _time64(__time64_t *_Time); +#endif + unsigned __cdecl _getsystime(struct tm *_Tm); + unsigned __cdecl _setsystime(struct tm *_Tm,unsigned _MilliSec); + +#ifndef _SIZE_T_DEFINED +#define _SIZE_T_DEFINED +#ifdef _WIN64 +#if defined(__GNUC__) && defined(__STRICT_ANSI__) + typedef unsigned int size_t __attribute__ ((mode (DI))); +#else + typedef unsigned __int64 size_t; +#endif +#else + typedef unsigned long size_t; +#endif +#endif -/* These go in the oldnames import library for MSVCRT. */ -__MINGW_IMPORT int daylight; -__MINGW_IMPORT long timezone; -__MINGW_IMPORT char *tzname[2]; +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#ifdef _WIN64 +#if defined(__GNUC__) && defined(__STRICT_ANSI__) + typedef int ssize_t __attribute__ ((mode (DI))); +#else + typedef __int64 ssize_t; +#endif +#else + typedef long ssize_t; +#endif +#endif #ifndef _WTIME_DEFINED + _CRTIMP wchar_t *__cdecl _wasctime(const struct tm *_Tm); + _CRTIMP wchar_t *__cdecl _wctime32(const __time32_t *_Time); + size_t __cdecl wcsftime(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm); + _CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale); + _CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer); + _CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP wchar_t *__cdecl _wctime64(const __time64_t *_Time); +#endif -/* wide function prototypes, also declared in wchar.h */ - -wchar_t * _wasctime(const struct tm*); -wchar_t * _wctime(const time_t*); -wchar_t* _wstrdate(wchar_t*); -wchar_t* _wstrtime(wchar_t*); +#if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) +#define _INC_WTIME_INL +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime32(_Time); } +#else +__CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime64(_Time); } +#endif +#endif #define _WTIME_DEFINED -#endif /* _WTIME_DEFINED */ +#endif +#ifndef RC_INVOKED +double __cdecl difftime(time_t _Time1,time_t _Time2); +char *__cdecl ctime(const time_t *_Time); +struct tm *__cdecl gmtime(const time_t *_Time); +struct tm *__cdecl localtime(const time_t *_Time); +struct tm *__cdecl localtime_r(const time_t *_Time,struct tm *); + +time_t __cdecl mktime(struct tm *_Tm); +time_t __cdecl _mkgmtime(struct tm *_Tm); +time_t __cdecl time(time_t *_Time); + +#ifdef _USE_32BIT_TIME_T +#if 0 +__CRT_INLINE double __cdecl difftime(time_t _Time1,time_t _Time2) { return _difftime32(_Time1,_Time2); } +__CRT_INLINE char *__cdecl ctime(const time_t *_Time) { return _ctime32(_Time); } +__CRT_INLINE struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime32(_Time); } +__CRT_INLINE struct tm *__cdecl localtime(const time_t *_Time) { return _localtime32(_Time); } +__CRT_INLINE time_t __cdecl mktime(struct tm *_Tm) { return _mktime32(_Tm); } +__CRT_INLINE time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime32(_Tm); } +__CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time32(_Time); } +#endif +#else +__CRT_INLINE double __cdecl difftime(time_t _Time1,time_t _Time2) { return _difftime64(_Time1,_Time2); } +__CRT_INLINE char *__cdecl ctime(const time_t *_Time) { return _ctime64(_Time); } +__CRT_INLINE struct tm *__cdecl gmtime(const time_t *_Time) { return _gmtime64(_Time); } +__CRT_INLINE struct tm *__cdecl localtime(const time_t *_Time) { return _localtime64(_Time); } +__CRT_INLINE time_t __cdecl mktime(struct tm *_Tm) { return _mktime64(_Tm); } +__CRT_INLINE time_t __cdecl _mkgmtime(struct tm *_Tm) { return _mkgmtime64(_Tm); } +__CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); } +#endif +#endif -#else /* not __MSVCRT__ */ +#if !defined(NO_OLDNAMES) || defined(_POSIX) +#define CLK_TCK CLOCKS_PER_SEC -/* CRTDLL is royally messed up when it comes to these macros. - TODO: import and alias these via oldnames import library instead - of macros. */ + __MINGW_IMPORT int daylight; + __MINGW_IMPORT long dstbias; + __MINGW_IMPORT long timezone; + __MINGW_IMPORT char *tzname[2]; + void __cdecl tzset(void); +#endif -#define daylight _daylight -/* NOTE: timezone not defined because it would conflict with sys/timeb.h. - Also, tzname used to a be macro, but now it's in moldname. */ -__MINGW_IMPORT char *tzname[2]; +#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */ +#define _TIMEVAL_DEFINED +struct timeval { + long tv_sec; + long tv_usec; +}; +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp,uvp,cmp) ((tvp)->tv_sec cmp (uvp)->tv_sec || (tvp)->tv_sec==(uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec) +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#endif /* _TIMEVAL_DEFINED */ -#endif /* not __MSVCRT__ */ +#ifndef __STRICT_ANSI__ +#ifndef _TIMEZONE_DEFINED /* also in sys/time.h */ +#define _TIMEZONE_DEFINED +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; -#endif /* Not _NO_OLDNAMES */ + extern int __cdecl mingw_gettimeofday (struct timeval *p, struct timezone *z); +#endif +#endif /* __STRICT_ANSI__ */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* Not RC_INVOKED */ +#pragma pack(pop) + +#include <sec_api/time_s.h> + +/* Adding timespec definition. */ +#include <sys/timeb.h> -#endif /* Not _TIME_H_ */ +#endif /* End _TIME_H_ */ diff --git a/tinyc/win32/include/unistd.h b/tinyc/win32/include/unistd.h deleted file mode 100644 index 8f51f7661..000000000 --- a/tinyc/win32/include/unistd.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This file is part of the Mingw32 package. - * - * unistd.h maps (roughly) to io.h - */ - -#ifndef __STRICT_ANSI__ -#include <io.h> -#endif - diff --git a/tinyc/win32/include/vadefs.h b/tinyc/win32/include/vadefs.h new file mode 100644 index 000000000..749b0bdde --- /dev/null +++ b/tinyc/win32/include/vadefs.h @@ -0,0 +1,11 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _INC_VADEFS +#define _INC_VADEFS + +//!__TINYC__: GNUC specific stuff removed + +#endif diff --git a/tinyc/win32/include/values.h b/tinyc/win32/include/values.h index 10e16a281..1cd643cef 100644 --- a/tinyc/win32/include/values.h +++ b/tinyc/win32/include/values.h @@ -1,4 +1,4 @@ /* * TODO: Nothing here yet. Should provide UNIX compatibility constants - * comparible to those in limits.h and float.h. + * comparable to those in limits.h and float.h. */ diff --git a/tinyc/win32/include/varargs.h b/tinyc/win32/include/varargs.h deleted file mode 100644 index daee29e87..000000000 --- a/tinyc/win32/include/varargs.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _VARARGS_H -#define _VARARGS_H - -#include <stdarg.h> - -#define va_dcl -#define va_alist __va_alist -#undef va_start -#define va_start(ap) ap = __builtin_varargs_start - -#endif diff --git a/tinyc/win32/include/wchar.h b/tinyc/win32/include/wchar.h index 4ad2ab9bf..389196faf 100644 --- a/tinyc/win32/include/wchar.h +++ b/tinyc/win32/include/wchar.h @@ -1,206 +1,431 @@ -/* - * wchar.h - * - * Defines of all functions for supporting wide characters. Actually it - * just includes all those headers, which is not a good thing to do from a - * processing time point of view, but it does mean that everything will be - * in sync. - * - * This file is part of the Mingw32 package. - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.2 $ - * $Author: bellard $ - * $Date: 2005/04/17 13:14:29 $ - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_WCHAR +#define _INC_WCHAR -#ifndef _WCHAR_H_ -#define _WCHAR_H_ - -/* All the headers include this file. */ #include <_mingw.h> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <sys/types.h> +#pragma pack(push,_CRT_PACKING) -#define __need_size_t -#define __need_wint_t -#define __need_wchar_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WCHAR_MIN /* also at stdint.h */ +#define WCHAR_MIN 0 +#define WCHAR_MAX ((wchar_t) -1) /* UINT16_MAX */ +#endif -#define WCHAR_MIN 0 -#define WCHAR_MAX ((wchar_t)-1) +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST + typedef __builtin_va_list __gnuc_va_list; +#endif -#ifndef RC_INVOKED +#ifndef _VA_LIST_DEFINED +#define _VA_LIST_DEFINED + typedef __gnuc_va_list va_list; +#endif -#ifdef __cplusplus -extern "C" { +#ifndef WEOF +#define WEOF (wint_t)(0xFFFF) #endif -#ifndef __STRICT_ANSI__ +#ifndef _FILE_DEFINED + struct _iobuf { + char *_ptr; + int _cnt; + char *_base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char *_tmpfname; + }; + typedef struct _iobuf FILE; +#define _FILE_DEFINED +#endif -#ifndef _FSIZE_T_DEFINED -typedef unsigned long _fsize_t; +#ifndef _STDIO_DEFINED +#ifdef _WIN64 + _CRTIMP FILE *__cdecl __iob_func(void); +#else +#ifdef _MSVCRT_ +extern FILE _iob[]; /* A pointer to an array of FILE */ +#define __iob_func() (_iob) +#else +extern FILE (*_imp___iob)[]; /* A pointer to an array of FILE */ +#define __iob_func() (*_imp___iob) +#define _iob __iob_func() +#endif +#endif + +#define _iob __iob_func() +#endif + +#ifndef _STDSTREAM_DEFINED +#define stdin (&__iob_func()[0]) +#define stdout (&__iob_func()[1]) +#define stderr (&__iob_func()[2]) +#define _STDSTREAM_DEFINED +#endif + +#ifndef _FSIZE_T_DEFINED + typedef unsigned long _fsize_t; #define _FSIZE_T_DEFINED #endif #ifndef _WFINDDATA_T_DEFINED -struct _wfinddata_t { - unsigned attrib; - time_t time_create; /* -1 for FAT file systems */ - time_t time_access; /* -1 for FAT file systems */ - time_t time_write; - _fsize_t size; - wchar_t name[FILENAME_MAX]; /* may include spaces. */ -}; -struct _wfinddatai64_t { - unsigned attrib; - time_t time_create; - time_t time_access; - time_t time_write; - __int64 size; - wchar_t name[FILENAME_MAX]; -}; + struct _wfinddata32_t { + unsigned attrib; + __time32_t time_create; + __time32_t time_access; + __time32_t time_write; + _fsize_t size; + wchar_t name[260]; + }; + +/* #if _INTEGRAL_MAX_BITS >= 64 */ + + struct _wfinddata32i64_t { + unsigned attrib; + __time32_t time_create; + __time32_t time_access; + __time32_t time_write; + __int64 size; + wchar_t name[260]; + }; + + struct _wfinddata64i32_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + _fsize_t size; + wchar_t name[260]; + }; + + struct _wfinddata64_t { + unsigned attrib; + __time64_t time_create; + __time64_t time_access; + __time64_t time_write; + __int64 size; + wchar_t name[260]; + }; +/* #endif */ + +#ifdef _USE_32BIT_TIME_T +#define _wfinddata_t _wfinddata32_t +#define _wfinddatai64_t _wfinddata32i64_t + +#define _wfindfirst _wfindfirst32 +#define _wfindnext _wfindnext32 +#define _wfindfirsti64 _wfindfirst32i64 +#define _wfindnexti64 _wfindnext32i64 +#else +#define _wfinddata_t _wfinddata64i32_t +#define _wfinddatai64_t _wfinddata64_t + +#define _wfindfirst _wfindfirst64i32 +#define _wfindnext _wfindnext64i32 +#define _wfindfirsti64 _wfindfirst64 +#define _wfindnexti64 _wfindnext64 +#endif + #define _WFINDDATA_T_DEFINED #endif -/* Wide character versions. Also defined in io.h. */ -/* CHECK: I believe these only exist in MSVCRT, and not in CRTDLL. Also - applies to other wide character versions? */ -#if !defined (_WIO_DEFINED) -#if defined (__MSVCRT__) -int _waccess (const wchar_t*, int); -int _wchmod (const wchar_t*, int); -int _wcreat (const wchar_t*, int); -long _wfindfirst (wchar_t*, struct _wfinddata_t *); -int _wfindnext (long, struct _wfinddata_t *); -int _wunlink (const wchar_t*); -int _wopen (const wchar_t*, int, ...); -int _wsopen (const wchar_t*, int, int, ...); -wchar_t* _wmktemp (wchar_t*); -long _wfindfirsti64 (const wchar_t*, struct _wfinddatai64_t*); -int _wfindnexti64 (long, struct _wfinddatai64_t*); -#endif /* defined (__MSVCRT__) */ -#define _WIO_DEFINED -#endif /* _WIO_DEFINED */ +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif -#ifndef _WSTDIO_DEFINED -/* also in stdio.h - keep in sync */ -int fwprintf (FILE*, const wchar_t*, ...); -int wprintf (const wchar_t*, ...); -int swprintf (wchar_t*, const wchar_t*, ...); -int _snwprintf (wchar_t*, size_t, const wchar_t*, ...); -int vfwprintf (FILE*, const wchar_t*, va_list); -int vwprintf (const wchar_t*, va_list); -int vswprintf (wchar_t*, const wchar_t*, va_list); -int _vsnwprintf (wchar_t*, size_t, const wchar_t*, va_list); -int fwscanf (FILE*, const wchar_t*, ...); -int wscanf (const wchar_t*, ...); -int swscanf (const wchar_t*, const wchar_t*, ...); -wint_t fgetwc (FILE*); -wint_t fputwc (wchar_t, FILE*); -wint_t ungetwc (wchar_t, FILE*); +#ifndef _CONST_RETURN +#define _CONST_RETURN +#endif -#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ -int snwprintf(wchar_t* s, size_t n, const wchar_t* format, ...); -extern inline int vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, - va_list arg) - { return _vsnwprintf ( s, n, format, arg); } -#endif - -#ifdef __MSVCRT__ -wchar_t* fgetws (wchar_t*, int, FILE*); -int fputws (const wchar_t*, FILE*); -wint_t getwc (FILE*); -wint_t getwchar (void); -wchar_t* _getws (wchar_t*); -wint_t putwc (wint_t, FILE*); -int _putws (const wchar_t*); -wint_t putwchar (wint_t); - -FILE* _wfopen (const wchar_t*, const wchar_t*); -FILE* _wfreopen (const wchar_t*, const wchar_t*, FILE*); -FILE* _wfsopen (const wchar_t*, const wchar_t*, int); -wchar_t* _wtmpnam (wchar_t*); -wchar_t* _wtempnam (const wchar_t*, const wchar_t*); -int _wrename (const wchar_t*, const wchar_t*); -int _wremove (const wchar_t*) - -FILE* _wpopen (const wchar_t*, const wchar_t*) -void _wperror (const wchar_t*); -#endif /* __MSVCRT__ */ -#define _WSTDIO_DEFINED -#endif /* _WSTDIO_DEFINED */ +#define _WConst_return _CONST_RETURN + +#ifndef _CRT_CTYPEDATA_DEFINED +#define _CRT_CTYPEDATA_DEFINED +#ifndef _CTYPE_DISABLE_MACROS + +#ifndef __PCTYPE_FUNC +#define __PCTYPE_FUNC __pctype_func() +#ifdef _MSVCRT_ +#define __pctype_func() (_pctype) +#else +#define __pctype_func() (*_imp___pctype) +#endif +#endif + +#ifndef _pctype +#ifdef _MSVCRT_ + extern unsigned short *_pctype; +#else + extern unsigned short **_imp___pctype; +#define _pctype (*_imp___pctype) +#endif +#endif +#endif +#endif + +#ifndef _CRT_WCTYPEDATA_DEFINED +#define _CRT_WCTYPEDATA_DEFINED +#ifndef _CTYPE_DISABLE_MACROS +#ifndef _wctype +#ifdef _MSVCRT_ + extern unsigned short *_wctype; +#else + extern unsigned short **_imp___wctype; +#define _wctype (*_imp___wctype) +#endif +#endif + +#ifdef _MSVCRT_ +#define __pwctype_func() (_pwctype) +#else +#define __pwctype_func() (*_imp___pwctype) +#endif + +#ifndef _pwctype +#ifdef _MSVCRT_ + extern unsigned short *_pwctype; +#else + extern unsigned short **_imp___pwctype; +#define _pwctype (*_imp___pwctype) +#endif +#endif + +#endif +#endif + +#define _UPPER 0x1 +#define _LOWER 0x2 +#define _DIGIT 0x4 +#define _SPACE 0x8 + +#define _PUNCT 0x10 +#define _CONTROL 0x20 +#define _BLANK 0x40 +#define _HEX 0x80 + +#define _LEADBYTE 0x8000 +#define _ALPHA (0x0100|_UPPER|_LOWER) + +#ifndef _WCTYPE_DEFINED +#define _WCTYPE_DEFINED + + int __cdecl iswalpha(wint_t _C); + _CRTIMP int __cdecl _iswalpha_l(wint_t _C,_locale_t _Locale); + int __cdecl iswupper(wint_t _C); + _CRTIMP int __cdecl _iswupper_l(wint_t _C,_locale_t _Locale); + int __cdecl iswlower(wint_t _C); + _CRTIMP int __cdecl _iswlower_l(wint_t _C,_locale_t _Locale); + int __cdecl iswdigit(wint_t _C); + _CRTIMP int __cdecl _iswdigit_l(wint_t _C,_locale_t _Locale); + int __cdecl iswxdigit(wint_t _C); + _CRTIMP int __cdecl _iswxdigit_l(wint_t _C,_locale_t _Locale); + int __cdecl iswspace(wint_t _C); + _CRTIMP int __cdecl _iswspace_l(wint_t _C,_locale_t _Locale); + int __cdecl iswpunct(wint_t _C); + _CRTIMP int __cdecl _iswpunct_l(wint_t _C,_locale_t _Locale); + int __cdecl iswalnum(wint_t _C); + _CRTIMP int __cdecl _iswalnum_l(wint_t _C,_locale_t _Locale); + int __cdecl iswprint(wint_t _C); + _CRTIMP int __cdecl _iswprint_l(wint_t _C,_locale_t _Locale); + int __cdecl iswgraph(wint_t _C); + _CRTIMP int __cdecl _iswgraph_l(wint_t _C,_locale_t _Locale); + int __cdecl iswcntrl(wint_t _C); + _CRTIMP int __cdecl _iswcntrl_l(wint_t _C,_locale_t _Locale); + int __cdecl iswascii(wint_t _C); + int __cdecl isleadbyte(int _C); + _CRTIMP int __cdecl _isleadbyte_l(int _C,_locale_t _Locale); + wint_t __cdecl towupper(wint_t _C); + _CRTIMP wint_t __cdecl _towupper_l(wint_t _C,_locale_t _Locale); + wint_t __cdecl towlower(wint_t _C); + _CRTIMP wint_t __cdecl _towlower_l(wint_t _C,_locale_t _Locale); + int __cdecl iswctype(wint_t _C,wctype_t _Type); + _CRTIMP int __cdecl _iswctype_l(wint_t _C,wctype_t _Type,_locale_t _Locale); + _CRTIMP int __cdecl __iswcsymf(wint_t _C); + _CRTIMP int __cdecl _iswcsymf_l(wint_t _C,_locale_t _Locale); + _CRTIMP int __cdecl __iswcsym(wint_t _C); + _CRTIMP int __cdecl _iswcsym_l(wint_t _C,_locale_t _Locale); + int __cdecl is_wctype(wint_t _C,wctype_t _Type); +#endif #ifndef _WDIRECT_DEFINED -/* Also in direct.h */ -#ifdef __MSVCRT__ -int _wchdir (const wchar_t*); -wchar_t* _wgetcwd (wchar_t*, int); -wchar_t* _wgetdcwd (int, wchar_t*, int); -int _wmkdir (const wchar_t*); -int _wrmdir (const wchar_t*); -#endif /* __MSVCRT__ */ #define _WDIRECT_DEFINED -#endif /* _WDIRECT_DEFINED */ + + _CRTIMP wchar_t *__cdecl _wgetcwd(wchar_t *_DstBuf,int _SizeInWords); + _CRTIMP wchar_t *__cdecl _wgetdcwd(int _Drive,wchar_t *_DstBuf,int _SizeInWords); + wchar_t *__cdecl _wgetdcwd_nolock(int _Drive,wchar_t *_DstBuf,int _SizeInWords); + _CRTIMP int __cdecl _wchdir(const wchar_t *_Path); + _CRTIMP int __cdecl _wmkdir(const wchar_t *_Path); + _CRTIMP int __cdecl _wrmdir(const wchar_t *_Path); +#endif + +#ifndef _WIO_DEFINED +#define _WIO_DEFINED + + _CRTIMP int __cdecl _waccess(const wchar_t *_Filename,int _AccessMode); + _CRTIMP int __cdecl _wchmod(const wchar_t *_Filename,int _Mode); + _CRTIMP int __cdecl _wcreat(const wchar_t *_Filename,int _PermissionMode); + _CRTIMP intptr_t __cdecl _wfindfirst32(const wchar_t *_Filename,struct _wfinddata32_t *_FindData); + _CRTIMP int __cdecl _wfindnext32(intptr_t _FindHandle,struct _wfinddata32_t *_FindData); + _CRTIMP int __cdecl _wunlink(const wchar_t *_Filename); + _CRTIMP int __cdecl _wrename(const wchar_t *_NewFilename,const wchar_t *_OldFilename); + _CRTIMP wchar_t *__cdecl _wmktemp(wchar_t *_TemplateName); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP intptr_t __cdecl _wfindfirst32i64(const wchar_t *_Filename,struct _wfinddata32i64_t *_FindData); + intptr_t __cdecl _wfindfirst64i32(const wchar_t *_Filename,struct _wfinddata64i32_t *_FindData); + _CRTIMP intptr_t __cdecl _wfindfirst64(const wchar_t *_Filename,struct _wfinddata64_t *_FindData); + _CRTIMP int __cdecl _wfindnext32i64(intptr_t _FindHandle,struct _wfinddata32i64_t *_FindData); + int __cdecl _wfindnext64i32(intptr_t _FindHandle,struct _wfinddata64i32_t *_FindData); + _CRTIMP int __cdecl _wfindnext64(intptr_t _FindHandle,struct _wfinddata64_t *_FindData); +#endif + _CRTIMP errno_t __cdecl _wsopen_s(int *_FileHandle,const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionFlag); +#if !defined(__cplusplus) || !(defined(_X86_) && !defined(__x86_64)) + _CRTIMP int __cdecl _wopen(const wchar_t *_Filename,int _OpenFlag,...); + _CRTIMP int __cdecl _wsopen(const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,...); +#else + extern "C++" _CRTIMP int __cdecl _wopen(const wchar_t *_Filename,int _OpenFlag,int _PermissionMode = 0); + extern "C++" _CRTIMP int __cdecl _wsopen(const wchar_t *_Filename,int _OpenFlag,int _ShareFlag,int _PermissionMode = 0); +#endif +#endif + +#ifndef _WLOCALE_DEFINED +#define _WLOCALE_DEFINED + _CRTIMP wchar_t *__cdecl _wsetlocale(int _Category,const wchar_t *_Locale); +#endif + +#ifndef _WPROCESS_DEFINED +#define _WPROCESS_DEFINED + + _CRTIMP intptr_t __cdecl _wexecl(const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wexecle(const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wexeclp(const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wexeclpe(const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wexecv(const wchar_t *_Filename,const wchar_t *const *_ArgList); + _CRTIMP intptr_t __cdecl _wexecve(const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env); + _CRTIMP intptr_t __cdecl _wexecvp(const wchar_t *_Filename,const wchar_t *const *_ArgList); + _CRTIMP intptr_t __cdecl _wexecvpe(const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env); + _CRTIMP intptr_t __cdecl _wspawnl(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wspawnle(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wspawnlp(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wspawnlpe(int _Mode,const wchar_t *_Filename,const wchar_t *_ArgList,...); + _CRTIMP intptr_t __cdecl _wspawnv(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList); + _CRTIMP intptr_t __cdecl _wspawnve(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env); + _CRTIMP intptr_t __cdecl _wspawnvp(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList); + _CRTIMP intptr_t __cdecl _wspawnvpe(int _Mode,const wchar_t *_Filename,const wchar_t *const *_ArgList,const wchar_t *const *_Env); +#ifndef _CRT_WSYSTEM_DEFINED +#define _CRT_WSYSTEM_DEFINED + _CRTIMP int __cdecl _wsystem(const wchar_t *_Command); +#endif +#endif + +#ifndef _WCTYPE_INLINE_DEFINED +#undef _CRT_WCTYPE_NOINLINE +#if !defined(__cplusplus) || defined(_CRT_WCTYPE_NOINLINE) +#define iswalpha(_c) (iswctype(_c,_ALPHA)) +#define iswupper(_c) (iswctype(_c,_UPPER)) +#define iswlower(_c) (iswctype(_c,_LOWER)) +#define iswdigit(_c) (iswctype(_c,_DIGIT)) +#define iswxdigit(_c) (iswctype(_c,_HEX)) +#define iswspace(_c) (iswctype(_c,_SPACE)) +#define iswpunct(_c) (iswctype(_c,_PUNCT)) +#define iswalnum(_c) (iswctype(_c,_ALPHA|_DIGIT)) +#define iswprint(_c) (iswctype(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT)) +#define iswgraph(_c) (iswctype(_c,_PUNCT|_ALPHA|_DIGIT)) +#define iswcntrl(_c) (iswctype(_c,_CONTROL)) +#define iswascii(_c) ((unsigned)(_c) < 0x80) + +#define _iswalpha_l(_c,_p) (_iswctype_l(_c,_ALPHA,_p)) +#define _iswupper_l(_c,_p) (_iswctype_l(_c,_UPPER,_p)) +#define _iswlower_l(_c,_p) (_iswctype_l(_c,_LOWER,_p)) +#define _iswdigit_l(_c,_p) (_iswctype_l(_c,_DIGIT,_p)) +#define _iswxdigit_l(_c,_p) (_iswctype_l(_c,_HEX,_p)) +#define _iswspace_l(_c,_p) (_iswctype_l(_c,_SPACE,_p)) +#define _iswpunct_l(_c,_p) (_iswctype_l(_c,_PUNCT,_p)) +#define _iswalnum_l(_c,_p) (_iswctype_l(_c,_ALPHA|_DIGIT,_p)) +#define _iswprint_l(_c,_p) (_iswctype_l(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT,_p)) +#define _iswgraph_l(_c,_p) (_iswctype_l(_c,_PUNCT|_ALPHA|_DIGIT,_p)) +#define _iswcntrl_l(_c,_p) (_iswctype_l(_c,_CONTROL,_p)) +#ifndef _CTYPE_DISABLE_MACROS +#define isleadbyte(_c) (__PCTYPE_FUNC[(unsigned char)(_c)] & _LEADBYTE) +#endif +#endif +#define _WCTYPE_INLINE_DEFINED +#endif + +#if !defined(_POSIX_) || defined(__GNUC__) +#ifndef _INO_T_DEFINED +#define _INO_T_DEFINED + typedef unsigned short _ino_t; +#ifndef NO_OLDNAMES + typedef unsigned short ino_t; +#endif +#endif + +#ifndef _DEV_T_DEFINED +#define _DEV_T_DEFINED + typedef unsigned int _dev_t; +#ifndef NO_OLDNAMES + typedef unsigned int dev_t; +#endif +#endif + +#ifndef _OFF_T_DEFINED +#define _OFF_T_DEFINED +#ifndef _OFF_T_ +#define _OFF_T_ + typedef long _off_t; +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef long off_t; +#endif +#endif +#endif + +#ifndef _OFF64_T_DEFINED +#define _OFF64_T_DEFINED + typedef long long _off64_t; +#if !defined(NO_OLDNAMES) || defined(_POSIX) + typedef long long off64_t; +#endif +#endif #ifndef _STAT_DEFINED -/* - * The structure manipulated and returned by stat and fstat. - * - * NOTE: If called on a directory the values in the time fields are not only - * invalid, they will cause localtime et. al. to return NULL. And calling - * asctime with a NULL pointer causes an Invalid Page Fault. So watch it! - */ -struct _stat -{ - _dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ - _ino_t st_ino; /* Always zero ? */ - _mode_t st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - short st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - _dev_t st_rdev; /* Seems useless (not even filled in) */ - _off_t st_size; /* File size in bytes */ - time_t st_atime; /* Accessed date (always 00:00 hrs local - * on FAT) */ - time_t st_mtime; /* Modified time */ - time_t st_ctime; /* Creation time */ -}; - -struct stat -{ - _dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ - _ino_t st_ino; /* Always zero ? */ - _mode_t st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - short st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - _dev_t st_rdev; /* Seems useless (not even filled in) */ - _off_t st_size; /* File size in bytes */ - time_t st_atime; /* Accessed date (always 00:00 hrs local - * on FAT) */ - time_t st_mtime; /* Modified time */ - time_t st_ctime; /* Creation time */ -}; -#if defined (__MSVCRT__) -struct _stati64 { +#define _STAT_DEFINED + +#ifdef _USE_32BIT_TIME_T +#ifdef WIN64 +#define _fstat _fstat32 +#define _stat _stat32 +#define _wstat _wstat32 +#else +#define _fstat32 _fstat +#define _stat32 _stat +#define _wstat32 _wstat +#endif +#define _fstati64 _fstat32i64 +#define _stati64 _stat32i64 +#define _wstati64 _wstat32i64 +#else +#define _fstat _fstat64i32 +#define _fstati64 _fstat64 +#define _stat _stat64i32 +#define _stati64 _stat64 +#define _wstat _wstat64i32 +#define _wstati64 _wstat64 +#endif + + struct _stat32 { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; @@ -208,111 +433,441 @@ struct _stati64 { short st_uid; short st_gid; _dev_t st_rdev; - __int64 st_size; + _off_t st_size; + __time32_t st_atime; + __time32_t st_mtime; + __time32_t st_ctime; + }; + +#ifndef NO_OLDNAMES + struct stat { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + _off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; - }; -#endif /* __MSVCRT__ */ -#define _STAT_DEFINED -#endif /* _STAT_DEFINED */ - -#if !defined ( _WSTAT_DEFINED) -/* also declared in sys/stat.h */ -#if defined __MSVCRT__ -int _wstat (const wchar_t*, struct _stat*); -int _wstati64 (const wchar_t*, struct _stati64*); -#endif /* __MSVCRT__ */ + }; +#endif + +#if _INTEGRAL_MAX_BITS >= 64 + + struct _stat32i64 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time32_t st_atime; + __time32_t st_mtime; + __time32_t st_ctime; + }; + + struct _stat64i32 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + _off_t st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; + }; + + struct _stat64 { + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + __int64 st_size; + __time64_t st_atime; + __time64_t st_mtime; + __time64_t st_ctime; + }; +#endif + +#define __stat64 _stat64 + +#endif + +#ifndef _WSTAT_DEFINED #define _WSTAT_DEFINED -#endif /* ! _WSTAT_DEFIND */ -#ifndef _WTIME_DEFINED -#ifdef __MSVCRT__ -/* wide function prototypes, also declared in time.h */ -wchar_t* _wasctime (const struct tm*); -wchar_t* _wctime (const time_t*); -wchar_t* _wstrdate (wchar_t*); -wchar_t* _wstrtime (wchar_t*); -#endif /* __MSVCRT__ */ -size_t wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*); -#define _WTIME_DEFINED -#endif /* _WTIME_DEFINED */ + _CRTIMP int __cdecl _wstat32(const wchar_t *_Name,struct _stat32 *_Stat); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP int __cdecl _wstat32i64(const wchar_t *_Name,struct _stat32i64 *_Stat); + int __cdecl _wstat64i32(const wchar_t *_Name,struct _stat64i32 *_Stat); + _CRTIMP int __cdecl _wstat64(const wchar_t *_Name,struct _stat64 *_Stat); +#endif +#endif +#endif -#ifndef _WLOCALE_DEFINED /* also declared in locale.h */ -wchar_t* _wsetlocale (int, const wchar_t*); -#define _WLOCALE_DEFINED +#ifndef _WCONIO_DEFINED +#define _WCONIO_DEFINED + +#ifndef WEOF +#define WEOF (wint_t)(0xFFFF) +#endif + + _CRTIMP wchar_t *_cgetws(wchar_t *_Buffer); + _CRTIMP wint_t __cdecl _getwch(void); + _CRTIMP wint_t __cdecl _getwche(void); + _CRTIMP wint_t __cdecl _putwch(wchar_t _WCh); + _CRTIMP wint_t __cdecl _ungetwch(wint_t _WCh); + _CRTIMP int __cdecl _cputws(const wchar_t *_String); + _CRTIMP int __cdecl _cwprintf(const wchar_t *_Format,...); + _CRTIMP int __cdecl _cwscanf(const wchar_t *_Format,...); + _CRTIMP int __cdecl _cwscanf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _cwprintf_p(const wchar_t *_Format,...); + _CRTIMP int __cdecl _vcwprintf_p(const wchar_t *_Format,va_list _ArgList); + + _CRTIMP int __cdecl _cwprintf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _cwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vcwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + wint_t __cdecl _putwch_nolock(wchar_t _WCh); + wint_t __cdecl _getwch_nolock(void); + wint_t __cdecl _getwche_nolock(void); + wint_t __cdecl _ungetwch_nolock(wint_t _WCh); +#endif + +#ifndef _WSTDIO_DEFINED +#define _WSTDIO_DEFINED + +#ifndef WEOF +#define WEOF (wint_t)(0xFFFF) +#endif + +#ifdef _POSIX_ + _CRTIMP FILE *__cdecl _wfsopen(const wchar_t *_Filename,const wchar_t *_Mode); +#else + _CRTIMP FILE *__cdecl _wfsopen(const wchar_t *_Filename,const wchar_t *_Mode,int _ShFlag); +#endif + + wint_t __cdecl fgetwc(FILE *_File); + _CRTIMP wint_t __cdecl _fgetwchar(void); + wint_t __cdecl fputwc(wchar_t _Ch,FILE *_File); + _CRTIMP wint_t __cdecl _fputwchar(wchar_t _Ch); + wint_t __cdecl getwc(FILE *_File); + wint_t __cdecl getwchar(void); + wint_t __cdecl putwc(wchar_t _Ch,FILE *_File); + wint_t __cdecl putwchar(wchar_t _Ch); + wint_t __cdecl ungetwc(wint_t _Ch,FILE *_File); + wchar_t *__cdecl fgetws(wchar_t *_Dst,int _SizeInWords,FILE *_File); + int __cdecl fputws(const wchar_t *_Str,FILE *_File); + _CRTIMP wchar_t *__cdecl _getws(wchar_t *_String); + _CRTIMP int __cdecl _putws(const wchar_t *_Str); + int __cdecl fwprintf(FILE *_File,const wchar_t *_Format,...); + int __cdecl wprintf(const wchar_t *_Format,...); + _CRTIMP int __cdecl _scwprintf(const wchar_t *_Format,...); + int __cdecl vfwprintf(FILE *_File,const wchar_t *_Format,va_list _ArgList); + int __cdecl vwprintf(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl swprintf(wchar_t*, const wchar_t*, ...); + _CRTIMP int __cdecl vswprintf(wchar_t*, const wchar_t*,va_list); + _CRTIMP int __cdecl _swprintf_c(wchar_t *_DstBuf,size_t _SizeInWords,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vswprintf_c(wchar_t *_DstBuf,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _snwprintf(wchar_t *_Dest,size_t _Count,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vsnwprintf(wchar_t *_Dest,size_t _Count,const wchar_t *_Format,va_list _Args); +#ifndef __NO_ISOCEXT /* externs in libmingwex.a */ + int __cdecl snwprintf (wchar_t *s, size_t n, const wchar_t * format, ...); + __CRT_INLINE int __cdecl vsnwprintf (wchar_t *s, size_t n, const wchar_t *format, va_list arg) { return _vsnwprintf(s,n,format,arg); } + int __cdecl vwscanf (const wchar_t *, va_list); + int __cdecl vfwscanf (FILE *,const wchar_t *,va_list); + int __cdecl vswscanf (const wchar_t *,const wchar_t *,va_list); +#endif + _CRTIMP int __cdecl _fwprintf_p(FILE *_File,const wchar_t *_Format,...); + _CRTIMP int __cdecl _wprintf_p(const wchar_t *_Format,...); + _CRTIMP int __cdecl _vfwprintf_p(FILE *_File,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _vwprintf_p(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _swprintf_p(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vswprintf_p(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _scwprintf_p(const wchar_t *_Format,...); + _CRTIMP int __cdecl _vscwprintf_p(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _wprintf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _wprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _fwprintf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _fwprintf_p_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vfwprintf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vfwprintf_p_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _swprintf_c_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _swprintf_p_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vswprintf_c_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _vswprintf_p_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _scwprintf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _scwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vscwprintf_p_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _snwprintf_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _vsnwprintf_l(wchar_t *_DstBuf,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + _CRTIMP int __cdecl _swprintf(wchar_t *_Dest,const wchar_t *_Format,...); + _CRTIMP int __cdecl _vswprintf(wchar_t *_Dest,const wchar_t *_Format,va_list _Args); + _CRTIMP int __cdecl __swprintf_l(wchar_t *_Dest,const wchar_t *_Format,_locale_t _Plocinfo,...); + _CRTIMP int __cdecl __vswprintf_l(wchar_t *_Dest,const wchar_t *_Format,_locale_t _Plocinfo,va_list _Args); +#ifndef RC_INVOKED +#include <vadefs.h> +#endif + +#ifdef _CRT_NON_CONFORMING_SWPRINTFS +#ifndef __cplusplus +#define swprintf _swprintf +#define vswprintf _vswprintf +#define _swprintf_l __swprintf_l +#define _vswprintf_l __vswprintf_l +#endif +#endif + + _CRTIMP wchar_t *__cdecl _wtempnam(const wchar_t *_Directory,const wchar_t *_FilePrefix); + _CRTIMP int __cdecl _vscwprintf(const wchar_t *_Format,va_list _ArgList); + _CRTIMP int __cdecl _vscwprintf_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList); + int __cdecl fwscanf(FILE *_File,const wchar_t *_Format,...); + _CRTIMP int __cdecl _fwscanf_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...); + int __cdecl swscanf(const wchar_t *_Src,const wchar_t *_Format,...); + _CRTIMP int __cdecl _swscanf_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP int __cdecl _snwscanf(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...); + _CRTIMP int __cdecl _snwscanf_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...); + int __cdecl wscanf(const wchar_t *_Format,...); + _CRTIMP int __cdecl _wscanf_l(const wchar_t *_Format,_locale_t _Locale,...); + _CRTIMP FILE *__cdecl _wfdopen(int _FileHandle ,const wchar_t *_Mode); + _CRTIMP FILE *__cdecl _wfopen(const wchar_t *_Filename,const wchar_t *_Mode); + _CRTIMP FILE *__cdecl _wfreopen(const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile); + +#ifndef _CRT_WPERROR_DEFINED +#define _CRT_WPERROR_DEFINED + _CRTIMP void __cdecl _wperror(const wchar_t *_ErrMsg); +#endif + _CRTIMP FILE *__cdecl _wpopen(const wchar_t *_Command,const wchar_t *_Mode); +#if !defined(NO_OLDNAMES) && !defined(wpopen) +#define wpopen _wpopen +#endif + _CRTIMP int __cdecl _wremove(const wchar_t *_Filename); + _CRTIMP wchar_t *__cdecl _wtmpnam(wchar_t *_Buffer); + _CRTIMP wint_t __cdecl _fgetwc_nolock(FILE *_File); + _CRTIMP wint_t __cdecl _fputwc_nolock(wchar_t _Ch,FILE *_File); + _CRTIMP wint_t __cdecl _ungetwc_nolock(wint_t _Ch,FILE *_File); + +#undef _CRT_GETPUTWCHAR_NOINLINE + +#if !defined(__cplusplus) || defined(_CRT_GETPUTWCHAR_NOINLINE) +#define getwchar() fgetwc(stdin) +#define putwchar(_c) fputwc((_c),stdout) +#else + __CRT_INLINE wint_t __cdecl getwchar() {return (fgetwc(stdin)); } + __CRT_INLINE wint_t __cdecl putwchar(wchar_t _C) {return (fputwc(_C,stdout)); } +#endif + +#define getwc(_stm) fgetwc(_stm) +#define putwc(_c,_stm) fputwc(_c,_stm) +#define _putwc_nolock(_c,_stm) _fputwc_nolock(_c,_stm) +#define _getwc_nolock(_c) _fgetwc_nolock(_c) #endif -#ifndef _WSTDLIB_DEFINED /* also declared in stdlib.h */ -long wcstol (const wchar_t*, wchar_t**, int); -unsigned long wcstoul (const wchar_t*, wchar_t**, int); -double wcstod (const wchar_t*, wchar_t**); -#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */ -extern __inline__ float wcstof( const wchar_t *nptr, wchar_t **endptr) -{ return (wcstod(nptr, endptr)); } +#ifndef _WSTDLIB_DEFINED +#define _WSTDLIB_DEFINED + + _CRTIMP wchar_t *__cdecl _itow(int _Value,wchar_t *_Dest,int _Radix); + _CRTIMP wchar_t *__cdecl _ltow(long _Value,wchar_t *_Dest,int _Radix); + _CRTIMP wchar_t *__cdecl _ultow(unsigned long _Value,wchar_t *_Dest,int _Radix); + double __cdecl wcstod(const wchar_t *_Str,wchar_t **_EndPtr); + _CRTIMP double __cdecl _wcstod_l(const wchar_t *_Str,wchar_t **_EndPtr,_locale_t _Locale); + float __cdecl wcstof( const wchar_t *nptr, wchar_t **endptr); +#if !defined __NO_ISOCEXT /* in libmingwex.a */ + float __cdecl wcstof (const wchar_t * __restrict__, wchar_t ** __restrict__); + long double __cdecl wcstold (const wchar_t * __restrict__, wchar_t ** __restrict__); #endif /* __NO_ISOCEXT */ -#define _WSTDLIB_DEFINED + long __cdecl wcstol(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix); + _CRTIMP long __cdecl _wcstol_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale); + unsigned long __cdecl wcstoul(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix); + _CRTIMP unsigned long __cdecl _wcstoul_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale); + _CRTIMP wchar_t *__cdecl _wgetenv(const wchar_t *_VarName); +#ifndef _CRT_WSYSTEM_DEFINED +#define _CRT_WSYSTEM_DEFINED + _CRTIMP int __cdecl _wsystem(const wchar_t *_Command); +#endif + _CRTIMP double __cdecl _wtof(const wchar_t *_Str); + _CRTIMP double __cdecl _wtof_l(const wchar_t *_Str,_locale_t _Locale); + _CRTIMP int __cdecl _wtoi(const wchar_t *_Str); + _CRTIMP int __cdecl _wtoi_l(const wchar_t *_Str,_locale_t _Locale); + _CRTIMP long __cdecl _wtol(const wchar_t *_Str); + _CRTIMP long __cdecl _wtol_l(const wchar_t *_Str,_locale_t _Locale); + +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP wchar_t *__cdecl _i64tow(__int64 _Val,wchar_t *_DstBuf,int _Radix); + _CRTIMP wchar_t *__cdecl _ui64tow(unsigned __int64 _Val,wchar_t *_DstBuf,int _Radix); + _CRTIMP __int64 __cdecl _wtoi64(const wchar_t *_Str); + _CRTIMP __int64 __cdecl _wtoi64_l(const wchar_t *_Str,_locale_t _Locale); + _CRTIMP __int64 __cdecl _wcstoi64(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix); + _CRTIMP __int64 __cdecl _wcstoi64_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale); + _CRTIMP unsigned __int64 __cdecl _wcstoui64(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix); + _CRTIMP unsigned __int64 __cdecl _wcstoui64_l(const wchar_t *_Str,wchar_t **_EndPtr,int _Radix,_locale_t _Locale); +#endif #endif +#ifndef _POSIX_ +#ifndef _WSTDLIBP_DEFINED +#define _WSTDLIBP_DEFINED + _CRTIMP wchar_t *__cdecl _wfullpath(wchar_t *_FullPath,const wchar_t *_Path,size_t _SizeInWords); + _CRTIMP void __cdecl _wmakepath(wchar_t *_ResultPath,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext); +#ifndef _CRT_WPERROR_DEFINED +#define _CRT_WPERROR_DEFINED + _CRTIMP void __cdecl _wperror(const wchar_t *_ErrMsg); +#endif + _CRTIMP int __cdecl _wputenv(const wchar_t *_EnvString); + _CRTIMP void __cdecl _wsearchenv(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath); + _CRTIMP void __cdecl _wsplitpath(const wchar_t *_FullPath,wchar_t *_Drive,wchar_t *_Dir,wchar_t *_Filename,wchar_t *_Ext); +#endif +#endif -#ifndef _NO_OLDNAMES +#ifndef _WSTRING_DEFINED +#define _WSTRING_DEFINED + _CRTIMP wchar_t *__cdecl _wcsdup(const wchar_t *_Str); + wchar_t *__cdecl wcscat(wchar_t *_Dest,const wchar_t *_Source); + _CONST_RETURN wchar_t *__cdecl wcschr(const wchar_t *_Str,wchar_t _Ch); + int __cdecl wcscmp(const wchar_t *_Str1,const wchar_t *_Str2); + wchar_t *__cdecl wcscpy(wchar_t *_Dest,const wchar_t *_Source); + size_t __cdecl wcscspn(const wchar_t *_Str,const wchar_t *_Control); + size_t __cdecl wcslen(const wchar_t *_Str); + size_t __cdecl wcsnlen(const wchar_t *_Src,size_t _MaxCount); + wchar_t *__cdecl wcsncat(wchar_t *_Dest,const wchar_t *_Source,size_t _Count); + int __cdecl wcsncmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + wchar_t *__cdecl wcsncpy(wchar_t *_Dest,const wchar_t *_Source,size_t _Count); + _CONST_RETURN wchar_t *__cdecl wcspbrk(const wchar_t *_Str,const wchar_t *_Control); + _CONST_RETURN wchar_t *__cdecl wcsrchr(const wchar_t *_Str,wchar_t _Ch); + size_t __cdecl wcsspn(const wchar_t *_Str,const wchar_t *_Control); + _CONST_RETURN wchar_t *__cdecl wcsstr(const wchar_t *_Str,const wchar_t *_SubStr); + wchar_t *__cdecl wcstok(wchar_t *_Str,const wchar_t *_Delim); + _CRTIMP wchar_t *__cdecl _wcserror(int _ErrNum); + _CRTIMP wchar_t *__cdecl __wcserror(const wchar_t *_Str); + _CRTIMP int __cdecl _wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2); + _CRTIMP int __cdecl _wcsicmp_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _wcsnicmp_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP wchar_t *__cdecl _wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount); + _CRTIMP wchar_t *__cdecl _wcsrev(wchar_t *_Str); + _CRTIMP wchar_t *__cdecl _wcsset(wchar_t *_Str,wchar_t _Val); + _CRTIMP wchar_t *__cdecl _wcslwr(wchar_t *_String); + _CRTIMP wchar_t *_wcslwr_l(wchar_t *_String,_locale_t _Locale); + _CRTIMP wchar_t *__cdecl _wcsupr(wchar_t *_String); + _CRTIMP wchar_t *_wcsupr_l(wchar_t *_String,_locale_t _Locale); + size_t __cdecl wcsxfrm(wchar_t *_Dst,const wchar_t *_Src,size_t _MaxCount); + _CRTIMP size_t __cdecl _wcsxfrm_l(wchar_t *_Dst,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale); + int __cdecl wcscoll(const wchar_t *_Str1,const wchar_t *_Str2); + _CRTIMP int __cdecl _wcscoll_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2); + _CRTIMP int __cdecl _wcsicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,_locale_t _Locale); + _CRTIMP int __cdecl _wcsncoll(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _wcsncoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale); + _CRTIMP int __cdecl _wcsnicoll(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + _CRTIMP int __cdecl _wcsnicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale); + +#ifndef NO_OLDNAMES + wchar_t *__cdecl wcsdup(const wchar_t *_Str); +#define wcswcs wcsstr + int __cdecl wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2); + int __cdecl wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + wchar_t *__cdecl wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount); + wchar_t *__cdecl wcsrev(wchar_t *_Str); + wchar_t *__cdecl wcsset(wchar_t *_Str,wchar_t _Val); + wchar_t *__cdecl wcslwr(wchar_t *_Str); + wchar_t *__cdecl wcsupr(wchar_t *_Str); + int __cdecl wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2); +#endif +#endif -/* Wide character versions. Also declared in io.h. */ -/* CHECK: Are these in the oldnames??? NO! */ -#if (0) -int waccess (const wchar_t *, int); -int wchmod (const wchar_t *, int); -int wcreat (const wchar_t *, int); -long wfindfirst (wchar_t *, struct _wfinddata_t *); -int wfindnext (long, struct _wfinddata_t *); -int wunlink (const wchar_t *); -int wrename (const wchar_t *, const wchar_t *); -int wremove (const wchar_t *); -int wopen (const wchar_t *, int, ...); -int wsopen (const wchar_t *, int, int, ...); -wchar_t* wmktemp (wchar_t *); +#ifndef _TM_DEFINED +#define _TM_DEFINED + struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + }; #endif -#endif /* _NO_OLDNAMES */ -#endif /* not __STRICT_ANSI__ */ +#ifndef _WTIME_DEFINED +#define _WTIME_DEFINED -/* These are resolved by -lmsvcp60 */ -/* If you don't have msvcp60.dll in your windows system directory, you can - easily obtain it with a search from your favorite search engine. */ -typedef int mbstate_t; -typedef wchar_t _Wint_t; + _CRTIMP wchar_t *__cdecl _wasctime(const struct tm *_Tm); + _CRTIMP wchar_t *__cdecl _wctime32(const __time32_t *_Time); + size_t __cdecl wcsftime(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm); + _CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale); + _CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer); + _CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer); +#if _INTEGRAL_MAX_BITS >= 64 + _CRTIMP wchar_t *__cdecl _wctime64(const __time64_t *_Time); +#endif -wint_t btowc(int); -size_t mbrlen(const char *, size_t, mbstate_t *); -size_t mbrtowc(wchar_t *, const char *, size_t, mbstate_t *); -size_t mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *); +#if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL) +#define _INC_WTIME_INL +#ifdef _USE_32BIT_TIME_T +__CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime32(_Time); } +#else +__CRT_INLINE wchar_t *__cdecl _wctime(const time_t *_Time) { return _wctime64(_Time); } +#endif +#endif +#endif -size_t wcrtomb(char *, wchar_t, mbstate_t *); -size_t wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *); -int wctob(wint_t); + typedef int mbstate_t; + typedef wchar_t _Wint_t; -#ifndef __NO_ISOCEXT /* these need static lib libmingwex.a */ -extern inline int fwide(FILE* stream, int mode) {return -1;} /* limited to byte orientation */ -extern inline int mbsinit(const mbstate_t* ps) {return 1;} -wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n); -wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n); -int wmemcmp(const wchar_t* s1, const wchar_t * s2, size_t n); -wchar_t* wmemcpy(wchar_t* __restrict__ s1, const wchar_t* __restrict__ s2, - size_t n); -wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n); -long long wcstoll(const wchar_t* __restrict__ nptr, - wchar_t** __restrict__ endptr, int base); -unsigned long long wcstoull(const wchar_t* __restrict__ nptr, - wchar_t ** __restrict__ endptr, int base); + wint_t __cdecl btowc(int); + size_t __cdecl mbrlen(const char *_Ch,size_t _SizeInBytes,mbstate_t *_State); + size_t __cdecl mbrtowc(wchar_t *_DstCh,const char *_SrcCh,size_t _SizeInBytes,mbstate_t *_State); + size_t __cdecl mbsrtowcs(wchar_t *_Dest,const char **_PSrc,size_t _Count,mbstate_t *_State); + size_t __cdecl wcrtomb(char *_Dest,wchar_t _Source,mbstate_t *_State); + size_t __cdecl wcsrtombs(char *_Dest,const wchar_t **_PSource,size_t _Count,mbstate_t *_State); + int __cdecl wctob(wint_t _WCh); +#ifndef __NO_ISOCEXT /* these need static lib libmingwex.a */ + wchar_t *__cdecl wmemset(wchar_t *s, wchar_t c, size_t n); + _CONST_RETURN wchar_t *__cdecl wmemchr(const wchar_t *s, wchar_t c, size_t n); + int wmemcmp(const wchar_t *s1, const wchar_t *s2,size_t n); + wchar_t *__cdecl wmemcpy(wchar_t *s1,const wchar_t *s2,size_t n); + wchar_t *__cdecl wmemmove(wchar_t *s1, const wchar_t *s2, size_t n); + long long __cdecl wcstoll(const wchar_t *nptr,wchar_t **endptr, int base); + unsigned long long __cdecl wcstoull(const wchar_t *nptr,wchar_t **endptr, int base); #endif /* __NO_ISOCEXT */ - + void *__cdecl memmove(void *_Dst,const void *_Src,size_t _MaxCount); + void *__cdecl memcpy(void *_Dst,const void *_Src,size_t _MaxCount); + __CRT_INLINE int __cdecl fwide(FILE *_F,int _M) { (void)_F; return (_M); } + __CRT_INLINE int __cdecl mbsinit(const mbstate_t *_P) { return (!_P || *_P==0); } + __CRT_INLINE _CONST_RETURN wchar_t *__cdecl wmemchr(const wchar_t *_S,wchar_t _C,size_t _N) { for (;0<_N;++_S,--_N) if (*_S==_C) return (_CONST_RETURN wchar_t *)(_S); return (0); } + __CRT_INLINE int __cdecl wmemcmp(const wchar_t *_S1,const wchar_t *_S2,size_t _N) { for (; 0 < _N; ++_S1,++_S2,--_N) if (*_S1!=*_S2) return (*_S1 < *_S2 ? -1 : +1); return (0); } + __CRT_INLINE wchar_t *__cdecl wmemcpy(wchar_t *_S1,const wchar_t *_S2,size_t _N) { return (wchar_t *)memcpy(_S1,_S2,_N*sizeof(wchar_t)); } + __CRT_INLINE wchar_t *__cdecl wmemmove(wchar_t *_S1,const wchar_t *_S2,size_t _N) { return (wchar_t *)memmove(_S1,_S2,_N*sizeof(wchar_t)); } + __CRT_INLINE wchar_t *__cdecl wmemset(wchar_t *_S,wchar_t _C,size_t _N) { + wchar_t *_Su = _S; + for (;0<_N;++_Su,--_N) { + *_Su = _C; + } + return (_S); + } #ifdef __cplusplus -} /* end of extern "C" */ +} #endif -#endif /* Not RC_INVOKED */ - -#endif /* not _WCHAR_H_ */ +#pragma pack(pop) +#include <sec_api/wchar_s.h> +#endif diff --git a/tinyc/win32/include/wctype.h b/tinyc/win32/include/wctype.h index 1fb00fb3c..a44cb384a 100644 --- a/tinyc/win32/include/wctype.h +++ b/tinyc/win32/include/wctype.h @@ -1,127 +1,172 @@ -/* - * wctype.h - * - * Functions for testing wide character types and converting characters. - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Mumit Khan <khan@xraylith.wisc.edu> - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. */ +#ifndef _INC_WCTYPE +#define _INC_WCTYPE -#ifndef _WCTYPE_H_ -#define _WCTYPE_H_ +#ifndef _WIN32 +#error Only Win32 target is supported! +#endif -/* All the headers include this file. */ #include <_mingw.h> -#define __need_wchar_t -#define __need_wint_t -#ifndef RC_INVOKED -#include <stddef.h> -#endif /* Not RC_INVOKED */ - -/* - * The following flags are used to tell iswctype and _isctype what character - * types you are looking for. - */ -#define _UPPER 0x0001 -#define _LOWER 0x0002 -#define _DIGIT 0x0004 -#define _SPACE 0x0008 -#define _PUNCT 0x0010 -#define _CONTROL 0x0020 -#define _BLANK 0x0040 -#define _HEX 0x0080 -#define _LEADBYTE 0x8000 - -#define _ALPHA 0x0103 - -#ifndef RC_INVOKED +#pragma pack(push,_CRT_PACKING) #ifdef __cplusplus extern "C" { #endif -#ifndef WEOF -#define WEOF (wchar_t)(0xFFFF) +#ifndef _CRTIMP +#define _CRTIMP __declspec(dllimport) +#endif + +#ifndef _WCHAR_T_DEFINED + typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED #endif #ifndef _WCTYPE_T_DEFINED -typedef wchar_t wctype_t; + typedef unsigned short wint_t; + typedef unsigned short wctype_t; #define _WCTYPE_T_DEFINED #endif -/* Wide character equivalents - also in ctype.h */ -int iswalnum(wint_t); -int iswalpha(wint_t); -int iswascii(wint_t); -int iswcntrl(wint_t); -int iswctype(wint_t, wctype_t); -int is_wctype(wint_t, wctype_t); /* Obsolete! */ -int iswdigit(wint_t); -int iswgraph(wint_t); -int iswlower(wint_t); -int iswprint(wint_t); -int iswpunct(wint_t); -int iswspace(wint_t); -int iswupper(wint_t); -int iswxdigit(wint_t); - -wchar_t towlower(wchar_t); -wchar_t towupper(wchar_t); - -int isleadbyte (int); - -/* Also in ctype.h */ - -__MINGW_IMPORT unsigned short _ctype[]; -#ifdef __MSVCRT__ -__MINGW_IMPORT unsigned short* _pctype; +#ifndef WEOF +#define WEOF (wint_t)(0xFFFF) +#endif + +#ifndef _CRT_CTYPEDATA_DEFINED +#define _CRT_CTYPEDATA_DEFINED +#ifndef _CTYPE_DISABLE_MACROS + +#ifndef __PCTYPE_FUNC +#define __PCTYPE_FUNC __pctype_func() +#ifdef _MSVCRT_ +#define __pctype_func() (_pctype) #else -__MINGW_IMPORT unsigned short* _pctype_dll; -#define _pctype _pctype_dll -#endif - -#if !(defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED)) -#define __WCTYPE_INLINES_DEFINED -extern inline int iswalnum(wint_t wc) {return (iswctype(wc,_ALPHA|_DIGIT));} -extern inline int iswalpha(wint_t wc) {return (iswctype(wc,_ALPHA));} -extern inline int iswascii(wint_t wc) {return (((unsigned)wc & 0x7F) ==0);} -extern inline int iswcntrl(wint_t wc) {return (iswctype(wc,_CONTROL));} -extern inline int iswdigit(wint_t wc) {return (iswctype(wc,_DIGIT));} -extern inline int iswgraph(wint_t wc) {return (iswctype(wc,_PUNCT|_ALPHA|_DIGIT));} -extern inline int iswlower(wint_t wc) {return (iswctype(wc,_LOWER));} -extern inline int iswprint(wint_t wc) {return (iswctype(wc,_BLANK|_PUNCT|_ALPHA|_DIGIT));} -extern inline int iswpunct(wint_t wc) {return (iswctype(wc,_PUNCT));} -extern inline int iswspace(wint_t wc) {return (iswctype(wc,_SPACE));} -extern inline int iswupper(wint_t wc) {return (iswctype(wc,_UPPER));} -extern inline int iswxdigit(wint_t wc) {return (iswctype(wc,_HEX));} -extern inline int isleadbyte(int c) {return (_pctype[(unsigned char)(c)] & _LEADBYTE);} -#endif /* !(defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED)) */ - - -typedef wchar_t wctrans_t; -wint_t towctrans(wint_t, wctrans_t); -wctrans_t wctrans(const char*); -wctype_t wctype(const char*); +#define __pctype_func() (*_imp___pctype) +#endif +#endif -#ifdef __cplusplus -} +#ifndef _pctype +#ifdef _MSVCRT_ + extern unsigned short *_pctype; +#else + extern unsigned short **_imp___pctype; +#define _pctype (*_imp___pctype) +#endif +#endif + +#endif #endif -#endif /* Not RC_INVOKED */ +#ifndef _CRT_WCTYPEDATA_DEFINED +#define _CRT_WCTYPEDATA_DEFINED +#ifndef _CTYPE_DISABLE_MACROS +#ifndef _wctype +#ifdef _MSVCRT_ + extern unsigned short *_wctype; +#else + extern unsigned short **_imp___wctype; +#define _wctype (*_imp___wctype) +#endif +#endif -#endif /* Not _WCTYPE_H_ */ +#ifndef _pwctype +#ifdef _MSVCRT_ + extern unsigned short *_pwctype; +#else + extern unsigned short **_imp___pwctype; +#define _pwctype (*_imp___pwctype) +#define __pwctype_func() (*_imp___pwctype) +#endif +#endif +#endif +#endif + +#define _UPPER 0x1 +#define _LOWER 0x2 +#define _DIGIT 0x4 +#define _SPACE 0x8 + +#define _PUNCT 0x10 +#define _CONTROL 0x20 +#define _BLANK 0x40 +#define _HEX 0x80 + +#define _LEADBYTE 0x8000 +#define _ALPHA (0x0100|_UPPER|_LOWER) + +#ifndef _WCTYPE_DEFINED +#define _WCTYPE_DEFINED + + int __cdecl iswalpha(wint_t); + int __cdecl iswupper(wint_t); + int __cdecl iswlower(wint_t); + int __cdecl iswdigit(wint_t); + int __cdecl iswxdigit(wint_t); + int __cdecl iswspace(wint_t); + int __cdecl iswpunct(wint_t); + int __cdecl iswalnum(wint_t); + int __cdecl iswprint(wint_t); + int __cdecl iswgraph(wint_t); + int __cdecl iswcntrl(wint_t); + int __cdecl iswascii(wint_t); + int __cdecl isleadbyte(int); + wint_t __cdecl towupper(wint_t); + wint_t __cdecl towlower(wint_t); + int __cdecl iswctype(wint_t,wctype_t); + _CRTIMP int __cdecl __iswcsymf(wint_t); + _CRTIMP int __cdecl __iswcsym(wint_t); + int __cdecl is_wctype(wint_t,wctype_t); +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES) +int __cdecl isblank(int _C); +#endif +#endif +#ifndef _WCTYPE_INLINE_DEFINED +#define _WCTYPE_INLINE_DEFINED +#ifndef __cplusplus +#define iswalpha(_c) (iswctype(_c,_ALPHA)) +#define iswupper(_c) (iswctype(_c,_UPPER)) +#define iswlower(_c) (iswctype(_c,_LOWER)) +#define iswdigit(_c) (iswctype(_c,_DIGIT)) +#define iswxdigit(_c) (iswctype(_c,_HEX)) +#define iswspace(_c) (iswctype(_c,_SPACE)) +#define iswpunct(_c) (iswctype(_c,_PUNCT)) +#define iswalnum(_c) (iswctype(_c,_ALPHA|_DIGIT)) +#define iswprint(_c) (iswctype(_c,_BLANK|_PUNCT|_ALPHA|_DIGIT)) +#define iswgraph(_c) (iswctype(_c,_PUNCT|_ALPHA|_DIGIT)) +#define iswcntrl(_c) (iswctype(_c,_CONTROL)) +#define iswascii(_c) ((unsigned)(_c) < 0x80) +#define isleadbyte(c) (__pctype_func()[(unsigned char)(c)] & _LEADBYTE) +#else + __CRT_INLINE int __cdecl iswalpha(wint_t _C) {return (iswctype(_C,_ALPHA)); } + __CRT_INLINE int __cdecl iswupper(wint_t _C) {return (iswctype(_C,_UPPER)); } + __CRT_INLINE int __cdecl iswlower(wint_t _C) {return (iswctype(_C,_LOWER)); } + __CRT_INLINE int __cdecl iswdigit(wint_t _C) {return (iswctype(_C,_DIGIT)); } + __CRT_INLINE int __cdecl iswxdigit(wint_t _C) {return (iswctype(_C,_HEX)); } + __CRT_INLINE int __cdecl iswspace(wint_t _C) {return (iswctype(_C,_SPACE)); } + __CRT_INLINE int __cdecl iswpunct(wint_t _C) {return (iswctype(_C,_PUNCT)); } + __CRT_INLINE int __cdecl iswalnum(wint_t _C) {return (iswctype(_C,_ALPHA|_DIGIT)); } + __CRT_INLINE int __cdecl iswprint(wint_t _C) {return (iswctype(_C,_BLANK|_PUNCT|_ALPHA|_DIGIT)); } + __CRT_INLINE int __cdecl iswgraph(wint_t _C) {return (iswctype(_C,_PUNCT|_ALPHA|_DIGIT)); } + __CRT_INLINE int __cdecl iswcntrl(wint_t _C) {return (iswctype(_C,_CONTROL)); } + __CRT_INLINE int __cdecl iswascii(wint_t _C) {return ((unsigned)(_C) < 0x80); } + __CRT_INLINE int __cdecl isleadbyte(int _C) {return (__pctype_func()[(unsigned char)(_C)] & _LEADBYTE); } +#endif +#endif + + typedef wchar_t wctrans_t; + wint_t __cdecl towctrans(wint_t,wctrans_t); + wctrans_t __cdecl wctrans(const char *); + wctype_t __cdecl wctype(const char *); + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) +#endif diff --git a/tinyc/win32/include/winapi/basetsd.h b/tinyc/win32/include/winapi/basetsd.h index d9c375dd9..47d78c4c3 100644 --- a/tinyc/win32/include/winapi/basetsd.h +++ b/tinyc/win32/include/winapi/basetsd.h @@ -1,119 +1,149 @@ -#ifndef _BASETSD_H -#define _BASETSD_H -#if __GNUC__ >=3 -#pragma GCC system_header +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _BASETSD_H_ +#define _BASETSD_H_ + +#if (defined(__x86_64) || defined(__ia64__)) && !defined(RC_INVOKED) +typedef unsigned __int64 POINTER_64_INT; +#else +typedef unsigned long POINTER_64_INT; #endif -#ifdef __GNUC__ -#ifndef __int64 -#define __int64 long long +#define POINTER_32 +#define POINTER_64 +#define FIRMWARE_PTR + +#ifdef __cplusplus +extern "C" { +#endif + + typedef signed char INT8,*PINT8; + typedef signed short INT16,*PINT16; + typedef signed int INT32,*PINT32; + typedef signed __int64 INT64,*PINT64; + typedef unsigned char UINT8,*PUINT8; + typedef unsigned short UINT16,*PUINT16; + typedef unsigned int UINT32,*PUINT32; + typedef unsigned __int64 UINT64,*PUINT64; + typedef signed int LONG32,*PLONG32; + typedef unsigned int ULONG32,*PULONG32; + typedef unsigned int DWORD32,*PDWORD32; + +#ifndef _W64 +#define _W64 #endif + +#ifdef _WIN64 + typedef __int64 INT_PTR,*PINT_PTR; + typedef unsigned __int64 UINT_PTR,*PUINT_PTR; + typedef __int64 LONG_PTR,*PLONG_PTR; + typedef unsigned __int64 ULONG_PTR,*PULONG_PTR; +#define __int3264 __int64 +#else + typedef int INT_PTR,*PINT_PTR; + typedef unsigned int UINT_PTR,*PUINT_PTR; + typedef long LONG_PTR,*PLONG_PTR; + typedef unsigned long ULONG_PTR,*PULONG_PTR; +#define __int3264 __int32 #endif -#if defined(_WIN64) -#define __int3264 __int64 -#define ADDRESS_TAG_BIT 0x40000000000UI64 -#else /* !_WIN64 */ -#define __int3264 __int32 +#ifdef _WIN64 +#define ADDRESS_TAG_BIT 0x40000000000ULL + typedef __int64 SHANDLE_PTR; + typedef unsigned __int64 HANDLE_PTR; + typedef unsigned int UHALF_PTR,*PUHALF_PTR; + typedef int HALF_PTR,*PHALF_PTR; + + static __inline unsigned long HandleToULong(const void *h) { return((unsigned long) (ULONG_PTR) h); } + static __inline long HandleToLong(const void *h) { return((long) (LONG_PTR) h); } + static __inline void *ULongToHandle(const unsigned long h) { return((void *) (UINT_PTR) h); } + static __inline void *LongToHandle(const long h) { return((void *) (INT_PTR) h); } + static __inline unsigned long PtrToUlong(const void *p) { return((unsigned long) (ULONG_PTR) p); } + static __inline unsigned int PtrToUint(const void *p) { return((unsigned int) (UINT_PTR) p); } + static __inline unsigned short PtrToUshort(const void *p) { return((unsigned short) (unsigned long) (ULONG_PTR) p); } + static __inline long PtrToLong(const void *p) { return((long) (LONG_PTR) p); } + static __inline int PtrToInt(const void *p) { return((int) (INT_PTR) p); } + static __inline short PtrToShort(const void *p) { return((short) (long) (LONG_PTR) p); } + static __inline void *IntToPtr(const int i) { return((void *)(INT_PTR)i); } + static __inline void *UIntToPtr(const unsigned int ui) { return((void *)(UINT_PTR)ui); } + static __inline void *LongToPtr(const long l) { return((void *)(LONG_PTR)l); } + static __inline void *ULongToPtr(const unsigned long ul) { return((void *)(ULONG_PTR)ul); } + +#define PtrToPtr64(p) ((void *) p) +#define Ptr64ToPtr(p) ((void *) p) +#define HandleToHandle64(h) (PtrToPtr64(h)) +#define Handle64ToHandle(h) (Ptr64ToPtr(h)) + + static __inline void *Ptr32ToPtr(const void *p) { return (void *)p; } + static __inline void *Handle32ToHandle(const void *h) { return((void *) h); } + static __inline void *PtrToPtr32(const void *p) { return((void *) (ULONG_PTR) p); } + +#define HandleToHandle32(h) (PtrToPtr32(h)) +#else + #define ADDRESS_TAG_BIT 0x80000000UL -#define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) ) -#define HandleToLong( h ) ((LONG)(LONG_PTR) (h) ) -#define LongToHandle( h) ((HANDLE)(LONG_PTR) (h)) -#define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) ) -#define PtrToLong( p ) ((LONG)(LONG_PTR) (p) ) -#define PtrToUint( p ) ((UINT)(UINT_PTR) (p) ) -#define PtrToInt( p ) ((INT)(INT_PTR) (p) ) -#define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) ) -#define PtrToShort( p ) ((short)(LONG_PTR)(p) ) -#define IntToPtr( i ) ((VOID*)(INT_PTR)((int)i)) -#define UIntToPtr( ui ) ((VOID*)(UINT_PTR)((unsigned int)ui)) -#define LongToPtr( l ) ((VOID*)(LONG_PTR)((long)l)) -#define ULongToPtr( ul ) ((VOID*)(ULONG_PTR)((unsigned long)ul)) -#endif /* !_WIN64 */ + typedef unsigned short UHALF_PTR,*PUHALF_PTR; + typedef short HALF_PTR,*PHALF_PTR; + typedef long SHANDLE_PTR; + typedef unsigned long HANDLE_PTR; + +#define HandleToULong(h) ((ULONG)(ULONG_PTR)(h)) +#define HandleToLong(h) ((LONG)(LONG_PTR) (h)) +#define ULongToHandle(ul) ((HANDLE)(ULONG_PTR) (ul)) +#define LongToHandle(h) ((HANDLE)(LONG_PTR) (h)) +#define PtrToUlong(p) ((ULONG)(ULONG_PTR) (p)) +#define PtrToLong(p) ((LONG)(LONG_PTR) (p)) +#define PtrToUint(p) ((UINT)(UINT_PTR) (p)) +#define PtrToInt(p) ((INT)(INT_PTR) (p)) +#define PtrToUshort(p) ((unsigned short)(ULONG_PTR)(p)) +#define PtrToShort(p) ((short)(LONG_PTR)(p)) +#define IntToPtr(i) ((VOID *)(INT_PTR)((int)i)) +#define UIntToPtr(ui) ((VOID *)(UINT_PTR)((unsigned int)ui)) +#define LongToPtr(l) ((VOID *)(LONG_PTR)((long)l)) +#define ULongToPtr(ul) ((VOID *)(ULONG_PTR)((unsigned long)ul)) + + static __inline void *PtrToPtr64(const void *p) { return((void *) (ULONG_PTR)p); } + static __inline void *Ptr64ToPtr(const void *p) { return((void *) (ULONG_PTR) p); } + static __inline void *HandleToHandle64(const void *h) { return((void *) h); } + static __inline void *Handle64ToHandle(const void *h) { return((void *) (ULONG_PTR) h); } + +#define Ptr32ToPtr(p) ((void *) p) +#define Handle32ToHandle(h) (Ptr32ToPtr(h)) +#define PtrToPtr32(p) ((void *) p) +#define HandleToHandle32(h) (PtrToPtr32(h)) +#endif + +#define HandleToUlong(h) HandleToULong(h) +#define UlongToHandle(ul) ULongToHandle(ul) #define UlongToPtr(ul) ULongToPtr(ul) #define UintToPtr(ui) UIntToPtr(ui) -#define MAXUINT_PTR (~((UINT_PTR)0)) -#define MAXINT_PTR ((INT_PTR)(MAXUINT_PTR >> 1)) -#define MININT_PTR (~MAXINT_PTR) + +#define MAXUINT_PTR (~((UINT_PTR)0)) +#define MAXINT_PTR ((INT_PTR)(MAXUINT_PTR >> 1)) +#define MININT_PTR (~MAXINT_PTR) + #define MAXULONG_PTR (~((ULONG_PTR)0)) -#define MAXLONG_PTR ((LONG_PTR)(MAXULONG_PTR >> 1)) -#define MINLONG_PTR (~MAXLONG_PTR) +#define MAXLONG_PTR ((LONG_PTR)(MAXULONG_PTR >> 1)) +#define MINLONG_PTR (~MAXLONG_PTR) + #define MAXUHALF_PTR ((UHALF_PTR)~0) -#define MAXHALF_PTR ((HALF_PTR)(MAXUHALF_PTR >> 1)) -#define MINHALF_PTR (~MAXHALF_PTR) +#define MAXHALF_PTR ((HALF_PTR)(MAXUHALF_PTR >> 1)) +#define MINHALF_PTR (~MAXHALF_PTR) + + typedef ULONG_PTR SIZE_T,*PSIZE_T; + typedef LONG_PTR SSIZE_T,*PSSIZE_T; + typedef ULONG_PTR DWORD_PTR,*PDWORD_PTR; + typedef __int64 LONG64,*PLONG64; + typedef unsigned __int64 ULONG64,*PULONG64; + typedef unsigned __int64 DWORD64,*PDWORD64; + typedef ULONG_PTR KAFFINITY; + typedef KAFFINITY *PKAFFINITY; -#ifndef RC_INVOKED -#ifdef __cplusplus -extern "C" { -#endif -typedef int LONG32, *PLONG32; -#ifndef XFree86Server -typedef int INT32, *PINT32; -#endif /* ndef XFree86Server */ -typedef unsigned int ULONG32, *PULONG32; -typedef unsigned int DWORD32, *PDWORD32; -typedef unsigned int UINT32, *PUINT32; - -#if defined(_WIN64) -typedef __int64 INT_PTR, *PINT_PTR; -typedef unsigned __int64 UINT_PTR, *PUINT_PTR; -typedef __int64 LONG_PTR, *PLONG_PTR; -typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; -typedef unsigned __int64 HANDLE_PTR; -typedef unsigned int UHALF_PTR, *PUHALF_PTR; -typedef int HALF_PTR, *PHALF_PTR; - -#if 0 /* TODO when WIN64 is here */ -inline unsigned long HandleToUlong(const void* h ) - { return((unsigned long) h ); } -inline long HandleToLong( const void* h ) - { return((long) h ); } -inline void* LongToHandle( const long h ) - { return((void*) (INT_PTR) h ); } -inline unsigned long PtrToUlong( const void* p) - { return((unsigned long) p ); } -inline unsigned int PtrToUint( const void* p ) - { return((unsigned int) p ); } -inline unsigned short PtrToUshort( const void* p ) - { return((unsigned short) p ); } -inline long PtrToLong( const void* p ) - { return((long) p ); } -inline int PtrToInt( const void* p ) - { return((int) p ); } -inline short PtrToShort( const void* p ) - { return((short) p ); } -inline void* IntToPtr( const int i ) - { return( (void*)(INT_PTR)i ); } -inline void* UIntToPtr(const unsigned int ui) - { return( (void*)(UINT_PTR)ui ); } -inline void* LongToPtr( const long l ) - { return( (void*)(LONG_PTR)l ); } -inline void* ULongToPtr( const unsigned long ul ) - { return( (void*)(ULONG_PTR)ul ); } -#endif /* 0_ */ - -#else /* !_WIN64 */ -typedef int INT_PTR, *PINT_PTR; -typedef unsigned int UINT_PTR, *PUINT_PTR; -typedef long LONG_PTR, *PLONG_PTR; -typedef unsigned long ULONG_PTR, *PULONG_PTR; -typedef unsigned short UHALF_PTR, *PUHALF_PTR; -typedef short HALF_PTR, *PHALF_PTR; -typedef unsigned long HANDLE_PTR; -#endif /* !_WIN64 */ - -typedef ULONG_PTR SIZE_T, *PSIZE_T; -typedef LONG_PTR SSIZE_T, *PSSIZE_T; -typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; -typedef __int64 LONG64, *PLONG64; -typedef __int64 INT64, *PINT64; -typedef unsigned __int64 ULONG64, *PULONG64; -typedef unsigned __int64 DWORD64, *PDWORD64; -typedef unsigned __int64 UINT64, *PUINT64; #ifdef __cplusplus } #endif -#endif /* !RC_INVOKED */ - -#endif /* _BASETSD_H */ +#endif diff --git a/tinyc/win32/include/winapi/basetyps.h b/tinyc/win32/include/winapi/basetyps.h index e1e36501b..376665e79 100644 --- a/tinyc/win32/include/winapi/basetyps.h +++ b/tinyc/win32/include/winapi/basetyps.h @@ -1,144 +1,85 @@ -#ifndef _BASETYPS_H -#define _BASETYPS_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#if !defined(_BASETYPS_H_) +#define _BASETYPS_H_ -#ifndef __OBJC__ #ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C extern -#endif /* __cplusplus */ -#define STDMETHODCALLTYPE __stdcall -#define STDMETHODVCALLTYPE __cdecl -#define STDAPICALLTYPE __stdcall -#define STDAPIVCALLTYPE __cdecl -#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE -#define STDAPI_(t) EXTERN_C t STDAPICALLTYPE -#define STDMETHODIMP HRESULT STDMETHODCALLTYPE -#define STDMETHODIMP_(t) t STDMETHODCALLTYPE -#define STDAPIV EXTERN_C HRESULT STDAPIVCALLTYPE -#define STDAPIV_(t) EXTERN_C t STDAPIVCALLTYPE -#define STDMETHODIMPV HRESULT STDMETHODVCALLTYPE -#define STDMETHODIMPV_(t) t STDMETHODVCALLTYPE -#define interface struct -#if defined(__cplusplus) && !defined(CINTERFACE) -#define STDMETHOD(m) virtual HRESULT STDMETHODCALLTYPE m -#define STDMETHOD_(t,m) virtual t STDMETHODCALLTYPE m -#define PURE =0 -#define THIS_ -#define THIS void -/* - __attribute__((com_interface)) is obsolete in __GNUC__ >= 3 - g++ vtables are now COM-compatible by default -*/ -#if defined(__GNUC__) && __GNUC__ < 3 && !defined(NOCOMATTRIBUTE) -#define DECLARE_INTERFACE(i) interface __attribute__((com_interface)) i -#define DECLARE_INTERFACE_(i,b) interface __attribute__((com_interface)) i : public b -#else -#define DECLARE_INTERFACE(i) interface i -#define DECLARE_INTERFACE_(i,b) interface i : public b -#endif -#else -#define STDMETHOD(m) HRESULT(STDMETHODCALLTYPE *m) -#define STDMETHOD_(t,m) t(STDMETHODCALLTYPE *m) -#define PURE -#define THIS_ INTERFACE *, -#define THIS INTERFACE * -#ifndef CONST_VTABLE -#define CONST_VTABLE #endif -#define DECLARE_INTERFACE(i) \ -typedef interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; } i; \ -typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \ -CONST_VTABLE struct i##Vtbl -#define DECLARE_INTERFACE_(i,b) DECLARE_INTERFACE(i) -#endif -#define BEGIN_INTERFACE -#define END_INTERFACE -#define FWD_DECL(i) typedef interface i i +#define STDMETHODCALLTYPE WINAPI +#define STDMETHODVCALLTYPE __cdecl + +#define STDAPICALLTYPE WINAPI +#define STDAPIVCALLTYPE __cdecl + +#define STDAPI EXTERN_C HRESULT WINAPI +#define STDAPI_(type) EXTERN_C type WINAPI + +#define STDMETHODIMP HRESULT WINAPI +#define STDMETHODIMP_(type) type WINAPI + +#define STDAPIV EXTERN_C HRESULT STDAPIVCALLTYPE +#define STDAPIV_(type) EXTERN_C type STDAPIVCALLTYPE + +#define STDMETHODIMPV HRESULT STDMETHODVCALLTYPE +#define STDMETHODIMPV_(type) type STDMETHODVCALLTYPE + #if defined(__cplusplus) && !defined(CINTERFACE) -#define IENUM_THIS(T) -#define IENUM_THIS_(T) + +#define __STRUCT__ struct +#define STDMETHOD(method) virtual HRESULT WINAPI method +#define STDMETHOD_(type,method) virtual type WINAPI method +#define STDMETHODV(method) virtual HRESULT STDMETHODVCALLTYPE method +#define STDMETHODV_(type,method) virtual type STDMETHODVCALLTYPE method +#define PURE = 0 +#define THIS_ +#define THIS void +#define DECLARE_INTERFACE(iface) __STRUCT__ iface +#define DECLARE_INTERFACE_(iface,baseiface) __STRUCT__ iface : public baseiface #else -#define IENUM_THIS(T) T* -#define IENUM_THIS_(T) T*, -#endif -#define DECLARE_ENUMERATOR_(I,T) \ -DECLARE_INTERFACE_(I,IUnknown) \ -{ \ - STDMETHOD(QueryInterface)(IENUM_THIS_(I) REFIID,PVOID*) PURE; \ - STDMETHOD_(ULONG,AddRef)(IENUM_THIS(I)) PURE; \ - STDMETHOD_(ULONG,Release)(IENUM_THIS(I)) PURE; \ - STDMETHOD(Next)(IENUM_THIS_(I) ULONG,T*,ULONG*) PURE; \ - STDMETHOD(Skip)(IENUM_THIS_(I) ULONG) PURE; \ - STDMETHOD(Reset)(IENUM_THIS(I)) PURE; \ - STDMETHOD(Clone)(IENUM_THIS_(I) I**) PURE; \ -} -#define DECLARE_ENUMERATOR(T) DECLARE_ENUMERATOR_(IEnum##T,T) -#endif /* __OBJC__ */ +#ifndef __OBJC__ +#define interface struct +#endif -#ifndef _GUID_DEFINED /* also defined in winnt.h */ -#define _GUID_DEFINED -typedef struct _GUID -{ - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} GUID,*REFGUID,*LPGUID; -#endif /* _GUID_DEFINED */ -#ifndef UUID_DEFINED -#define UUID_DEFINED -typedef GUID UUID; -#endif /* UUID_DEFINED */ -typedef GUID IID; -typedef GUID CLSID; -typedef CLSID *LPCLSID; -typedef IID *LPIID; -typedef IID *REFIID; -typedef CLSID *REFCLSID; -typedef GUID FMTID; -typedef FMTID *REFFMTID; -typedef unsigned long error_status_t; -#define uuid_t UUID -typedef unsigned long PROPID; +#define STDMETHOD(method) HRESULT (WINAPI *method) +#define STDMETHOD_(type,method) type (WINAPI *method) +#define STDMETHODV(method) HRESULT (STDMETHODVCALLTYPE *method) +#define STDMETHODV_(type,method) type (STDMETHODVCALLTYPE *method) -#ifndef _REFGUID_DEFINED -#if defined (__cplusplus) && !defined (CINTERFACE) -#define REFGUID const GUID& -#define REFIID const IID& -#define REFCLSID const CLSID& +#define PURE +#define THIS_ INTERFACE *This, +#define THIS INTERFACE *This +#ifdef CONST_VTABLE +#define DECLARE_INTERFACE(iface) typedef struct iface { \ + const struct iface##Vtbl *lpVtbl; } iface; \ + typedef const struct iface##Vtbl iface##Vtbl; \ + const struct iface##Vtbl #else -#define REFGUID const GUID* const -#define REFIID const IID* const -#define REFCLSID const CLSID* const +#define DECLARE_INTERFACE(iface) typedef struct iface { \ + struct iface##Vtbl *lpVtbl; \ + } iface; \ + typedef struct iface##Vtbl iface##Vtbl; \ + struct iface##Vtbl #endif -#define _REFGUID_DEFINED -#define _REFGIID_DEFINED -#define _REFCLSID_DEFINED +#define DECLARE_INTERFACE_(iface,baseiface) DECLARE_INTERFACE(iface) #endif -#ifndef GUID_SECTION -#define GUID_SECTION ".text" -#endif -#ifdef __GNUC__ -#define GUID_SECT __attribute__ ((section (GUID_SECTION))) -#else -#define GUID_SECT -#endif -#if !defined(INITGUID) || (defined(INITGUID) && defined(__cplusplus)) -#define GUID_EXT EXTERN_C -#else -#define GUID_EXT + +#include <guiddef.h> + +#ifndef _ERROR_STATUS_T_DEFINED +#define _ERROR_STATUS_T_DEFINED +typedef unsigned long error_status_t; #endif -#ifdef INITGUID -#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} -#define DEFINE_OLEGUID(n,l,w1,w2) DEFINE_GUID(n,l,w1,w2,0xC0,0,0,0,0,0,0,0x46) -#else -#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n -#define DEFINE_OLEGUID(n,l,w1,w2) DEFINE_GUID(n,l,w1,w2,0xC0,0,0,0,0,0,0,0x46) + +#ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED #endif #endif diff --git a/tinyc/win32/include/winapi/guiddef.h b/tinyc/win32/include/winapi/guiddef.h new file mode 100644 index 000000000..4e7909a97 --- /dev/null +++ b/tinyc/win32/include/winapi/guiddef.h @@ -0,0 +1,156 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef GUID_DEFINED +#define GUID_DEFINED +typedef struct _GUID { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8 ]; +} GUID; +#endif + +#ifndef UUID_DEFINED +#define UUID_DEFINED +typedef GUID UUID; +#endif + +#ifndef FAR +#define FAR +#endif + +#ifndef DECLSPEC_SELECTANY +#define DECLSPEC_SELECTANY __declspec(selectany) +#endif + +#ifndef EXTERN_C +#ifdef __cplusplus +#define EXTERN_C extern "C" +#else +#define EXTERN_C extern +#endif +#endif + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#ifdef INITGUID +#ifdef __cplusplus +#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) EXTERN_C const GUID DECLSPEC_SELECTANY name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } } +#else +#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID DECLSPEC_SELECTANY name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } } +#endif +#else +#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) EXTERN_C const GUID name +#endif + +#define DEFINE_OLEGUID(name,l,w1,w2) DEFINE_GUID(name,l,w1,w2,0xC0,0,0,0,0,0,0,0x46) + +#ifndef _GUIDDEF_H_ +#define _GUIDDEF_H_ + +#ifndef __LPGUID_DEFINED__ +#define __LPGUID_DEFINED__ +typedef GUID *LPGUID; +#endif + +#ifndef __LPCGUID_DEFINED__ +#define __LPCGUID_DEFINED__ +typedef const GUID *LPCGUID; +#endif + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef GUID IID; +typedef IID *LPIID; +#define IID_NULL GUID_NULL +#define IsEqualIID(riid1,riid2) IsEqualGUID(riid1,riid2) +typedef GUID CLSID; +typedef CLSID *LPCLSID; +#define CLSID_NULL GUID_NULL +#define IsEqualCLSID(rclsid1,rclsid2) IsEqualGUID(rclsid1,rclsid2) +typedef GUID FMTID; +typedef FMTID *LPFMTID; +#define FMTID_NULL GUID_NULL +#define IsEqualFMTID(rfmtid1,rfmtid2) IsEqualGUID(rfmtid1,rfmtid2) + +#ifdef __midl_proxy +#define __MIDL_CONST +#else +#define __MIDL_CONST const +#endif + +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#ifdef __cplusplus +#define REFGUID const GUID & +#else +#define REFGUID const GUID *__MIDL_CONST +#endif +#endif + +#ifndef _REFIID_DEFINED +#define _REFIID_DEFINED +#ifdef __cplusplus +#define REFIID const IID & +#else +#define REFIID const IID *__MIDL_CONST +#endif +#endif + +#ifndef _REFCLSID_DEFINED +#define _REFCLSID_DEFINED +#ifdef __cplusplus +#define REFCLSID const IID & +#else +#define REFCLSID const IID *__MIDL_CONST +#endif +#endif + +#ifndef _REFFMTID_DEFINED +#define _REFFMTID_DEFINED +#ifdef __cplusplus +#define REFFMTID const IID & +#else +#define REFFMTID const IID *__MIDL_CONST +#endif +#endif +#endif + +#ifndef _SYS_GUID_OPERATORS_ +#define _SYS_GUID_OPERATORS_ +#include <string.h> + +#ifdef __cplusplus +__inline int InlineIsEqualGUID(REFGUID rguid1,REFGUID rguid2) { + return (((unsigned long *) &rguid1)[0]==((unsigned long *) &rguid2)[0] && ((unsigned long *) &rguid1)[1]==((unsigned long *) &rguid2)[1] && + ((unsigned long *) &rguid1)[2]==((unsigned long *) &rguid2)[2] && ((unsigned long *) &rguid1)[3]==((unsigned long *) &rguid2)[3]); +} +__inline int IsEqualGUID(REFGUID rguid1,REFGUID rguid2) { return !memcmp(&rguid1,&rguid2,sizeof(GUID)); } +#else +#define InlineIsEqualGUID(rguid1,rguid2) (((unsigned long *) rguid1)[0]==((unsigned long *) rguid2)[0] && ((unsigned long *) rguid1)[1]==((unsigned long *) rguid2)[1] && ((unsigned long *) rguid1)[2]==((unsigned long *) rguid2)[2] && ((unsigned long *) rguid1)[3]==((unsigned long *) rguid2)[3]) +#define IsEqualGUID(rguid1,rguid2) (!memcmp(rguid1,rguid2,sizeof(GUID))) +#endif + +#ifdef __INLINE_ISEQUAL_GUID +#undef IsEqualGUID +#define IsEqualGUID(rguid1,rguid2) InlineIsEqualGUID(rguid1,rguid2) +#endif + +#define IsEqualIID(riid1,riid2) IsEqualGUID(riid1,riid2) +#define IsEqualCLSID(rclsid1,rclsid2) IsEqualGUID(rclsid1,rclsid2) + +#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_ +#define _SYS_GUID_OPERATOR_EQ_ +#ifdef __cplusplus +__inline int operator==(REFGUID guidOne,REFGUID guidOther) { return IsEqualGUID(guidOne,guidOther); } +__inline int operator!=(REFGUID guidOne,REFGUID guidOther) { return !(guidOne==guidOther); } +#endif +#endif +#endif +#endif diff --git a/tinyc/win32/include/winapi/poppack.h b/tinyc/win32/include/winapi/poppack.h new file mode 100644 index 000000000..b08cba222 --- /dev/null +++ b/tinyc/win32/include/winapi/poppack.h @@ -0,0 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#if !(defined(lint) || defined(RC_INVOKED)) +#pragma pack(pop) +#endif diff --git a/tinyc/win32/include/winapi/pshpack1.h b/tinyc/win32/include/winapi/pshpack1.h new file mode 100644 index 000000000..d18d9e856 --- /dev/null +++ b/tinyc/win32/include/winapi/pshpack1.h @@ -0,0 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#if !(defined(lint) || defined(RC_INVOKED)) +#pragma pack(push,1) +#endif diff --git a/tinyc/win32/include/winapi/pshpack2.h b/tinyc/win32/include/winapi/pshpack2.h new file mode 100644 index 000000000..7de16fd39 --- /dev/null +++ b/tinyc/win32/include/winapi/pshpack2.h @@ -0,0 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#if !(defined(lint) || defined(RC_INVOKED)) +#pragma pack(push,2) +#endif diff --git a/tinyc/win32/include/winapi/pshpack4.h b/tinyc/win32/include/winapi/pshpack4.h new file mode 100644 index 000000000..1c8e61d7d --- /dev/null +++ b/tinyc/win32/include/winapi/pshpack4.h @@ -0,0 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#if !(defined(lint) || defined(RC_INVOKED)) +#pragma pack(push,4) +#endif diff --git a/tinyc/win32/include/winapi/pshpack8.h b/tinyc/win32/include/winapi/pshpack8.h new file mode 100644 index 000000000..70a3c7f7c --- /dev/null +++ b/tinyc/win32/include/winapi/pshpack8.h @@ -0,0 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#if !(defined(lint) || defined(RC_INVOKED)) +#pragma pack(push,8) +#endif diff --git a/tinyc/win32/include/winapi/winbase.h b/tinyc/win32/include/winapi/winbase.h index b3fab6c3d..4a38006ef 100644 --- a/tinyc/win32/include/winapi/winbase.h +++ b/tinyc/win32/include/winapi/winbase.h @@ -1,1852 +1,2951 @@ -#ifndef _WINBASE_H -#define _WINBASE_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINBASE_ +#define _WINBASE_ +#define WINADVAPI DECLSPEC_IMPORT #define WINBASEAPI DECLSPEC_IMPORT +#define ZAWPROXYAPI DECLSPEC_IMPORT + #ifdef __cplusplus extern "C" { #endif -#define SP_SERIALCOMM 1 -#define PST_UNSPECIFIED 0 -#define PST_RS232 1 -#define PST_PARALLELPORT 2 -#define PST_RS422 3 -#define PST_RS423 4 -#define PST_RS449 5 -#define PST_MODEM 6 -#define PST_FAX 0x21 -#define PST_SCANNER 0x22 -#define PST_NETWORK_BRIDGE 0x100 -#define PST_LAT 0x101 -#define PST_TCPIP_TELNET 0x102 -#define PST_X25 0x103 -#define BAUD_075 1 -#define BAUD_110 2 -#define BAUD_134_5 4 -#define BAUD_150 8 -#define BAUD_300 16 -#define BAUD_600 32 -#define BAUD_1200 64 -#define BAUD_1800 128 -#define BAUD_2400 256 -#define BAUD_4800 512 -#define BAUD_7200 1024 -#define BAUD_9600 2048 -#define BAUD_14400 4096 -#define BAUD_19200 8192 -#define BAUD_38400 16384 -#define BAUD_56K 32768 -#define BAUD_128K 65536 -#define BAUD_115200 131072 -#define BAUD_57600 262144 -#define BAUD_USER 0x10000000 -#define PCF_DTRDSR 1 -#define PCF_RTSCTS 2 -#define PCF_RLSD 4 -#define PCF_PARITY_CHECK 8 -#define PCF_XONXOFF 16 -#define PCF_SETXCHAR 32 -#define PCF_TOTALTIMEOUTS 64 -#define PCF_INTTIMEOUTS 128 -#define PCF_SPECIALCHARS 256 -#define PCF_16BITMODE 512 -#define SP_PARITY 1 -#define SP_BAUD 2 -#define SP_DATABITS 4 -#define SP_STOPBITS 8 -#define SP_HANDSHAKING 16 -#define SP_PARITY_CHECK 32 -#define SP_RLSD 64 -#define DATABITS_5 1 -#define DATABITS_6 2 -#define DATABITS_7 4 -#define DATABITS_8 8 -#define DATABITS_16 16 -#define DATABITS_16X 32 -#define STOPBITS_10 1 -#define STOPBITS_15 2 -#define STOPBITS_20 4 -#define PARITY_NONE 256 -#define PARITY_ODD 512 -#define PARITY_EVEN 1024 -#define PARITY_MARK 2048 -#define PARITY_SPACE 4096 -#define EXCEPTION_DEBUG_EVENT 1 -#define CREATE_THREAD_DEBUG_EVENT 2 -#define CREATE_PROCESS_DEBUG_EVENT 3 -#define EXIT_THREAD_DEBUG_EVENT 4 -#define EXIT_PROCESS_DEBUG_EVENT 5 -#define LOAD_DLL_DEBUG_EVENT 6 -#define UNLOAD_DLL_DEBUG_EVENT 7 -#define OUTPUT_DEBUG_STRING_EVENT 8 -#define RIP_EVENT 9 -#define HFILE_ERROR ((HFILE)-1) -#define FILE_BEGIN 0 -#define FILE_CURRENT 1 -#define FILE_END 2 -#define INVALID_SET_FILE_POINTER ((DWORD)-1) -#define OF_READ 0 -#define OF_READWRITE 2 -#define OF_WRITE 1 -#define OF_SHARE_COMPAT 0 -#define OF_SHARE_DENY_NONE 64 -#define OF_SHARE_DENY_READ 48 -#define OF_SHARE_DENY_WRITE 32 -#define OF_SHARE_EXCLUSIVE 16 -#define OF_CANCEL 2048 -#define OF_CREATE 4096 -#define OF_DELETE 512 -#define OF_EXIST 16384 -#define OF_PARSE 256 -#define OF_PROMPT 8192 -#define OF_REOPEN 32768 -#define OF_VERIFY 1024 -#define NMPWAIT_NOWAIT 1 -#define NMPWAIT_WAIT_FOREVER (-1) -#define NMPWAIT_USE_DEFAULT_WAIT 0 -#define CE_BREAK 16 -#define CE_DNS 2048 -#define CE_FRAME 8 -#define CE_IOE 1024 -#define CE_MODE 32768 -#define CE_OOP 4096 -#define CE_OVERRUN 2 -#define CE_PTO 512 -#define CE_RXOVER 1 -#define CE_RXPARITY 4 -#define CE_TXFULL 256 -#define PROGRESS_CONTINUE 0 -#define PROGRESS_CANCEL 1 -#define PROGRESS_STOP 2 -#define PROGRESS_QUIET 3 -#define CALLBACK_CHUNK_FINISHED 0 -#define CALLBACK_STREAM_SWITCH 1 -#define COPY_FILE_FAIL_IF_EXISTS 1 -#define COPY_FILE_RESTARTABLE 2 -#define OFS_MAXPATHNAME 128 -#define DUPLICATE_CLOSE_SOURCE 1 -#define DUPLICATE_SAME_ACCESS 2 -#define FILE_MAP_ALL_ACCESS 0xf001f -#define FILE_MAP_READ 4 -#define FILE_MAP_WRITE 2 -#define FILE_MAP_COPY 1 -#define MUTEX_ALL_ACCESS 0x1f0001 -#define MUTEX_MODIFY_STATE 1 -#define SEMAPHORE_ALL_ACCESS 0x1f0003 -#define SEMAPHORE_MODIFY_STATE 2 -#define EVENT_ALL_ACCESS 0x1f0003 -#define EVENT_MODIFY_STATE 2 -#define PIPE_ACCESS_DUPLEX 3 -#define PIPE_ACCESS_INBOUND 1 -#define PIPE_ACCESS_OUTBOUND 2 -#define PIPE_TYPE_BYTE 0 -#define PIPE_TYPE_MESSAGE 4 -#define PIPE_READMODE_BYTE 0 -#define PIPE_READMODE_MESSAGE 2 -#define PIPE_WAIT 0 -#define PIPE_NOWAIT 1 -#define PIPE_CLIENT_END 0 -#define PIPE_SERVER_END 1 +#define DefineHandleTable(w) ((w),TRUE) +#define LimitEmsPages(dw) +#define SetSwapAreaSize(w) (w) +#define LockSegment(w) GlobalFix((HANDLE)(w)) +#define UnlockSegment(w) GlobalUnfix((HANDLE)(w)) +#define GetCurrentTime() GetTickCount() + +#define Yield() + +#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) +#define INVALID_FILE_SIZE ((DWORD)0xffffffff) +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + +#define FILE_BEGIN 0 +#define FILE_CURRENT 1 +#define FILE_END 2 + +#define TIME_ZONE_ID_INVALID ((DWORD)0xffffffff) + +#define WAIT_FAILED ((DWORD)0xffffffff) +#define WAIT_OBJECT_0 ((STATUS_WAIT_0) + 0) +#define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0) + 0) +#define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0) + 0) +#define WAIT_IO_COMPLETION STATUS_USER_APC +#define STILL_ACTIVE STATUS_PENDING +#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION +#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT +#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT +#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP +#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED +#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND +#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO +#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT +#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION +#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW +#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK +#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW +#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO +#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW +#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION +#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR +#define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION +#define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION +#define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW +#define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION +#define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION +#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE +#define EXCEPTION_POSSIBLE_DEADLOCK STATUS_POSSIBLE_DEADLOCK +#define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT +#define MoveMemory RtlMoveMemory +#define CopyMemory RtlCopyMemory +#define FillMemory RtlFillMemory +#define ZeroMemory RtlZeroMemory +#define SecureZeroMemory RtlSecureZeroMemory + +#define FILE_FLAG_WRITE_THROUGH 0x80000000 +#define FILE_FLAG_OVERLAPPED 0x40000000 +#define FILE_FLAG_NO_BUFFERING 0x20000000 +#define FILE_FLAG_RANDOM_ACCESS 0x10000000 +#define FILE_FLAG_SEQUENTIAL_SCAN 0x8000000 +#define FILE_FLAG_DELETE_ON_CLOSE 0x4000000 +#define FILE_FLAG_BACKUP_SEMANTICS 0x2000000 +#define FILE_FLAG_POSIX_SEMANTICS 0x1000000 +#define FILE_FLAG_OPEN_REPARSE_POINT 0x200000 +#define FILE_FLAG_OPEN_NO_RECALL 0x100000 +#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x80000 + +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define OPEN_ALWAYS 4 +#define TRUNCATE_EXISTING 5 + +#define PROGRESS_CONTINUE 0 +#define PROGRESS_CANCEL 1 +#define PROGRESS_STOP 2 +#define PROGRESS_QUIET 3 + +#define CALLBACK_CHUNK_FINISHED 0x0 +#define CALLBACK_STREAM_SWITCH 0x1 + +#define COPY_FILE_FAIL_IF_EXISTS 0x1 +#define COPY_FILE_RESTARTABLE 0x2 +#define COPY_FILE_OPEN_SOURCE_FOR_WRITE 0x4 +#define COPY_FILE_ALLOW_DECRYPTED_DESTINATION 0x8 + +#define REPLACEFILE_WRITE_THROUGH 0x1 +#define REPLACEFILE_IGNORE_MERGE_ERRORS 0x2 + +#define PIPE_ACCESS_INBOUND 0x1 +#define PIPE_ACCESS_OUTBOUND 0x2 +#define PIPE_ACCESS_DUPLEX 0x3 + +#define PIPE_CLIENT_END 0x0 +#define PIPE_SERVER_END 0x1 + +#define PIPE_WAIT 0x0 +#define PIPE_NOWAIT 0x1 +#define PIPE_READMODE_BYTE 0x0 +#define PIPE_READMODE_MESSAGE 0x2 +#define PIPE_TYPE_BYTE 0x0 +#define PIPE_TYPE_MESSAGE 0x4 + #define PIPE_UNLIMITED_INSTANCES 255 -#define CREATE_DEFAULT_ERROR_MODE 67108864 -#define DEBUG_PROCESS 1 -#define DEBUG_ONLY_THIS_PROCESS 2 -#define CREATE_SUSPENDED 4 -#define DETACHED_PROCESS 8 -#define CREATE_NEW_CONSOLE 16 -#define NORMAL_PRIORITY_CLASS 32 -#define IDLE_PRIORITY_CLASS 64 -#define HIGH_PRIORITY_CLASS 128 -#define REALTIME_PRIORITY_CLASS 256 -#define CREATE_NEW_PROCESS_GROUP 512 -#define CREATE_UNICODE_ENVIRONMENT 1024 -#define CREATE_SEPARATE_WOW_VDM 2048 -#define CREATE_SHARED_WOW_VDM 4096 -#define CREATE_FORCEDOS 8192 + +#define SECURITY_ANONYMOUS (SecurityAnonymous << 16) +#define SECURITY_IDENTIFICATION (SecurityIdentification << 16) +#define SECURITY_IMPERSONATION (SecurityImpersonation << 16) +#define SECURITY_DELEGATION (SecurityDelegation << 16) + +#define SECURITY_CONTEXT_TRACKING 0x40000 +#define SECURITY_EFFECTIVE_ONLY 0x80000 + +#define SECURITY_SQOS_PRESENT 0x100000 +#define SECURITY_VALID_SQOS_FLAGS 0x1f0000 + + typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + }; + PVOID Pointer; + }; + HANDLE hEvent; + } OVERLAPPED,*LPOVERLAPPED; + + typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + LPVOID lpSecurityDescriptor; + WINBOOL bInheritHandle; + } SECURITY_ATTRIBUTES,*PSECURITY_ATTRIBUTES,*LPSECURITY_ATTRIBUTES; + + typedef struct _PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + } PROCESS_INFORMATION,*PPROCESS_INFORMATION,*LPPROCESS_INFORMATION; + +#ifndef _FILETIME_ +#define _FILETIME_ + typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } FILETIME,*PFILETIME,*LPFILETIME; +#endif + + typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME,*PSYSTEMTIME,*LPSYSTEMTIME; + + typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); + typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; + typedef VOID (WINAPI *PFIBER_START_ROUTINE)(LPVOID lpFiberParameter); + typedef PFIBER_START_ROUTINE LPFIBER_START_ROUTINE; + + typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; + typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION; + typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION; + typedef RTL_CRITICAL_SECTION_DEBUG CRITICAL_SECTION_DEBUG; + typedef PRTL_CRITICAL_SECTION_DEBUG PCRITICAL_SECTION_DEBUG; + typedef PRTL_CRITICAL_SECTION_DEBUG LPCRITICAL_SECTION_DEBUG; + + WINBASEAPI PVOID WINAPI EncodePointer(PVOID Ptr); + WINBASEAPI PVOID WINAPI DecodePointer(PVOID Ptr); + WINBASEAPI PVOID WINAPI EncodeSystemPointer(PVOID Ptr); + WINBASEAPI PVOID WINAPI DecodeSystemPointer(PVOID Ptr); + +#ifdef I_X86_ + typedef PLDT_ENTRY LPLDT_ENTRY; +#else + typedef LPVOID LPLDT_ENTRY; +#endif + +#define MUTEX_MODIFY_STATE MUTANT_QUERY_STATE +#define MUTEX_ALL_ACCESS MUTANT_ALL_ACCESS + +#define SP_SERIALCOMM ((DWORD)0x1) + +#define PST_UNSPECIFIED ((DWORD)0x0) +#define PST_RS232 ((DWORD)0x1) +#define PST_PARALLELPORT ((DWORD)0x2) +#define PST_RS422 ((DWORD)0x3) +#define PST_RS423 ((DWORD)0x4) +#define PST_RS449 ((DWORD)0x5) +#define PST_MODEM ((DWORD)0x6) +#define PST_FAX ((DWORD)0x21) +#define PST_SCANNER ((DWORD)0x22) +#define PST_NETWORK_BRIDGE ((DWORD)0x100) +#define PST_LAT ((DWORD)0x101) +#define PST_TCPIP_TELNET ((DWORD)0x102) +#define PST_X25 ((DWORD)0x103) + +#define PCF_DTRDSR ((DWORD)0x1) +#define PCF_RTSCTS ((DWORD)0x2) +#define PCF_RLSD ((DWORD)0x4) +#define PCF_PARITY_CHECK ((DWORD)0x8) +#define PCF_XONXOFF ((DWORD)0x10) +#define PCF_SETXCHAR ((DWORD)0x20) +#define PCF_TOTALTIMEOUTS ((DWORD)0x40) +#define PCF_INTTIMEOUTS ((DWORD)0x80) +#define PCF_SPECIALCHARS ((DWORD)0x100) +#define PCF_16BITMODE ((DWORD)0x200) + +#define SP_PARITY ((DWORD)0x1) +#define SP_BAUD ((DWORD)0x2) +#define SP_DATABITS ((DWORD)0x4) +#define SP_STOPBITS ((DWORD)0x8) +#define SP_HANDSHAKING ((DWORD)0x10) +#define SP_PARITY_CHECK ((DWORD)0x20) +#define SP_RLSD ((DWORD)0x40) + +#define BAUD_075 ((DWORD)0x1) +#define BAUD_110 ((DWORD)0x2) +#define BAUD_134_5 ((DWORD)0x4) +#define BAUD_150 ((DWORD)0x8) +#define BAUD_300 ((DWORD)0x10) +#define BAUD_600 ((DWORD)0x20) +#define BAUD_1200 ((DWORD)0x40) +#define BAUD_1800 ((DWORD)0x80) +#define BAUD_2400 ((DWORD)0x100) +#define BAUD_4800 ((DWORD)0x200) +#define BAUD_7200 ((DWORD)0x400) +#define BAUD_9600 ((DWORD)0x800) +#define BAUD_14400 ((DWORD)0x1000) +#define BAUD_19200 ((DWORD)0x2000) +#define BAUD_38400 ((DWORD)0x4000) +#define BAUD_56K ((DWORD)0x8000) +#define BAUD_128K ((DWORD)0x10000) +#define BAUD_115200 ((DWORD)0x20000) +#define BAUD_57600 ((DWORD)0x40000) +#define BAUD_USER ((DWORD)0x10000000) + +#define DATABITS_5 ((WORD)0x1) +#define DATABITS_6 ((WORD)0x2) +#define DATABITS_7 ((WORD)0x4) +#define DATABITS_8 ((WORD)0x8) +#define DATABITS_16 ((WORD)0x10) +#define DATABITS_16X ((WORD)0x20) + +#define STOPBITS_10 ((WORD)0x1) +#define STOPBITS_15 ((WORD)0x2) +#define STOPBITS_20 ((WORD)0x4) +#define PARITY_NONE ((WORD)0x100) +#define PARITY_ODD ((WORD)0x200) +#define PARITY_EVEN ((WORD)0x400) +#define PARITY_MARK ((WORD)0x800) +#define PARITY_SPACE ((WORD)0x1000) + + typedef struct _COMMPROP { + WORD wPacketLength; + WORD wPacketVersion; + DWORD dwServiceMask; + DWORD dwReserved1; + DWORD dwMaxTxQueue; + DWORD dwMaxRxQueue; + DWORD dwMaxBaud; + DWORD dwProvSubType; + DWORD dwProvCapabilities; + DWORD dwSettableParams; + DWORD dwSettableBaud; + WORD wSettableData; + WORD wSettableStopParity; + DWORD dwCurrentTxQueue; + DWORD dwCurrentRxQueue; + DWORD dwProvSpec1; + DWORD dwProvSpec2; + WCHAR wcProvChar[1]; + } COMMPROP,*LPCOMMPROP; + +#define COMMPROP_INITIALIZED ((DWORD)0xE73CF52E) + + typedef struct _COMSTAT { + DWORD fCtsHold : 1; + DWORD fDsrHold : 1; + DWORD fRlsdHold : 1; + DWORD fXoffHold : 1; + DWORD fXoffSent : 1; + DWORD fEof : 1; + DWORD fTxim : 1; + DWORD fReserved : 25; + DWORD cbInQue; + DWORD cbOutQue; + } COMSTAT,*LPCOMSTAT; + +#define DTR_CONTROL_DISABLE 0x0 +#define DTR_CONTROL_ENABLE 0x1 +#define DTR_CONTROL_HANDSHAKE 0x2 + +#define RTS_CONTROL_DISABLE 0x0 +#define RTS_CONTROL_ENABLE 0x1 +#define RTS_CONTROL_HANDSHAKE 0x2 +#define RTS_CONTROL_TOGGLE 0x3 + + typedef struct _DCB { + DWORD DCBlength; + DWORD BaudRate; + DWORD fBinary: 1; + DWORD fParity: 1; + DWORD fOutxCtsFlow:1; + DWORD fOutxDsrFlow:1; + DWORD fDtrControl:2; + DWORD fDsrSensitivity:1; + DWORD fTXContinueOnXoff: 1; + DWORD fOutX: 1; + DWORD fInX: 1; + DWORD fErrorChar: 1; + DWORD fNull: 1; + DWORD fRtsControl:2; + DWORD fAbortOnError:1; + DWORD fDummy2:17; + WORD wReserved; + WORD XonLim; + WORD XoffLim; + BYTE ByteSize; + BYTE Parity; + BYTE StopBits; + char XonChar; + char XoffChar; + char ErrorChar; + char EofChar; + char EvtChar; + WORD wReserved1; + } DCB,*LPDCB; + + typedef struct _COMMTIMEOUTS { + DWORD ReadIntervalTimeout; + DWORD ReadTotalTimeoutMultiplier; + DWORD ReadTotalTimeoutConstant; + DWORD WriteTotalTimeoutMultiplier; + DWORD WriteTotalTimeoutConstant; + } COMMTIMEOUTS,*LPCOMMTIMEOUTS; + + typedef struct _COMMCONFIG { + DWORD dwSize; + WORD wVersion; + WORD wReserved; + DCB dcb; + DWORD dwProviderSubType; + DWORD dwProviderOffset; + DWORD dwProviderSize; + WCHAR wcProviderData[1]; + } COMMCONFIG,*LPCOMMCONFIG; + + typedef struct _SYSTEM_INFO { + union { + DWORD dwOemId; + struct { + WORD wProcessorArchitecture; + WORD wReserved; + }; + }; + DWORD dwPageSize; + LPVOID lpMinimumApplicationAddress; + LPVOID lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; + } SYSTEM_INFO,*LPSYSTEM_INFO; + +#define FreeModule(hLibModule) FreeLibrary((hLibModule)) +#define MakeProcInstance(lpProc,hInstance) (lpProc) +#define FreeProcInstance(lpProc) (lpProc) + +#define GMEM_FIXED 0x0 +#define GMEM_MOVEABLE 0x2 +#define GMEM_NOCOMPACT 0x10 +#define GMEM_NODISCARD 0x20 +#define GMEM_ZEROINIT 0x40 +#define GMEM_MODIFY 0x80 +#define GMEM_DISCARDABLE 0x100 +#define GMEM_NOT_BANKED 0x1000 +#define GMEM_SHARE 0x2000 +#define GMEM_DDESHARE 0x2000 +#define GMEM_NOTIFY 0x4000 +#define GMEM_LOWER GMEM_NOT_BANKED +#define GMEM_VALID_FLAGS 0x7F72 +#define GMEM_INVALID_HANDLE 0x8000 + +#define GHND (GMEM_MOVEABLE | GMEM_ZEROINIT) +#define GPTR (GMEM_FIXED | GMEM_ZEROINIT) + +#define GlobalLRUNewest(h) ((HANDLE)(h)) +#define GlobalLRUOldest(h) ((HANDLE)(h)) +#define GlobalDiscard(h) GlobalReAlloc((h),0,GMEM_MOVEABLE) + +#define GMEM_DISCARDED 0x4000 +#define GMEM_LOCKCOUNT 0xff + + typedef struct _MEMORYSTATUS { + DWORD dwLength; + DWORD dwMemoryLoad; + SIZE_T dwTotalPhys; + SIZE_T dwAvailPhys; + SIZE_T dwTotalPageFile; + SIZE_T dwAvailPageFile; + SIZE_T dwTotalVirtual; + SIZE_T dwAvailVirtual; + } MEMORYSTATUS,*LPMEMORYSTATUS; + +#define LMEM_FIXED 0x0 +#define LMEM_MOVEABLE 0x2 +#define LMEM_NOCOMPACT 0x10 +#define LMEM_NODISCARD 0x20 +#define LMEM_ZEROINIT 0x40 +#define LMEM_MODIFY 0x80 +#define LMEM_DISCARDABLE 0xf00 +#define LMEM_VALID_FLAGS 0xf72 +#define LMEM_INVALID_HANDLE 0x8000 + +#define LHND (LMEM_MOVEABLE | LMEM_ZEROINIT) +#define LPTR (LMEM_FIXED | LMEM_ZEROINIT) + +#define NONZEROLHND (LMEM_MOVEABLE) +#define NONZEROLPTR (LMEM_FIXED) + +#define LocalDiscard(h) LocalReAlloc((h),0,LMEM_MOVEABLE) + +#define LMEM_DISCARDED 0x4000 +#define LMEM_LOCKCOUNT 0xff + +#define DEBUG_PROCESS 0x1 +#define DEBUG_ONLY_THIS_PROCESS 0x2 +#define CREATE_SUSPENDED 0x4 +#define DETACHED_PROCESS 0x8 +#define CREATE_NEW_CONSOLE 0x10 +#define NORMAL_PRIORITY_CLASS 0x20 +#define IDLE_PRIORITY_CLASS 0x40 +#define HIGH_PRIORITY_CLASS 0x80 +#define REALTIME_PRIORITY_CLASS 0x100 +#define CREATE_NEW_PROCESS_GROUP 0x200 +#define CREATE_UNICODE_ENVIRONMENT 0x400 +#define CREATE_SEPARATE_WOW_VDM 0x800 +#define CREATE_SHARED_WOW_VDM 0x1000 +#define CREATE_FORCEDOS 0x2000 +#define BELOW_NORMAL_PRIORITY_CLASS 0x4000 +#define ABOVE_NORMAL_PRIORITY_CLASS 0x8000 +#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x10000 + +#define CREATE_BREAKAWAY_FROM_JOB 0x1000000 +#define CREATE_PRESERVE_CODE_AUTHZ_LEVEL 0x2000000 + +#define CREATE_DEFAULT_ERROR_MODE 0x4000000 #define CREATE_NO_WINDOW 0x8000000 -#define CONSOLE_TEXTMODE_BUFFER 1 -#define CREATE_NEW 1 -#define CREATE_ALWAYS 2 -#define OPEN_EXISTING 3 -#define OPEN_ALWAYS 4 -#define TRUNCATE_EXISTING 5 -#define FILE_FLAG_WRITE_THROUGH 0x80000000 -#define FILE_FLAG_OVERLAPPED 1073741824 -#define FILE_FLAG_NO_BUFFERING 536870912 -#define FILE_FLAG_RANDOM_ACCESS 268435456 -#define FILE_FLAG_SEQUENTIAL_SCAN 134217728 -#define FILE_FLAG_DELETE_ON_CLOSE 67108864 -#define FILE_FLAG_BACKUP_SEMANTICS 33554432 -#define FILE_FLAG_POSIX_SEMANTICS 16777216 -#define FILE_FLAG_OPEN_REPARSE_POINT 2097152 -#define FILE_FLAG_OPEN_NO_RECALL 1048576 -#define CLRDTR 6 -#define CLRRTS 4 -#define SETDTR 5 -#define SETRTS 3 + +#define PROFILE_USER 0x10000000 +#define PROFILE_KERNEL 0x20000000 +#define PROFILE_SERVER 0x40000000 + +#define CREATE_IGNORE_SYSTEM_DEFAULT 0x80000000 + +#define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN +#define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1) +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX +#define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1) +#define THREAD_PRIORITY_ERROR_RETURN (MAXLONG) + +#define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT +#define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE + +#define EXCEPTION_DEBUG_EVENT 1 +#define CREATE_THREAD_DEBUG_EVENT 2 +#define CREATE_PROCESS_DEBUG_EVENT 3 +#define EXIT_THREAD_DEBUG_EVENT 4 +#define EXIT_PROCESS_DEBUG_EVENT 5 +#define LOAD_DLL_DEBUG_EVENT 6 +#define UNLOAD_DLL_DEBUG_EVENT 7 +#define OUTPUT_DEBUG_STRING_EVENT 8 +#define RIP_EVENT 9 + + typedef struct _EXCEPTION_DEBUG_INFO { + EXCEPTION_RECORD ExceptionRecord; + DWORD dwFirstChance; + } EXCEPTION_DEBUG_INFO,*LPEXCEPTION_DEBUG_INFO; + + typedef struct _CREATE_THREAD_DEBUG_INFO { + HANDLE hThread; + LPVOID lpThreadLocalBase; + LPTHREAD_START_ROUTINE lpStartAddress; + } CREATE_THREAD_DEBUG_INFO,*LPCREATE_THREAD_DEBUG_INFO; + + typedef struct _CREATE_PROCESS_DEBUG_INFO { + HANDLE hFile; + HANDLE hProcess; + HANDLE hThread; + LPVOID lpBaseOfImage; + DWORD dwDebugInfoFileOffset; + DWORD nDebugInfoSize; + LPVOID lpThreadLocalBase; + LPTHREAD_START_ROUTINE lpStartAddress; + LPVOID lpImageName; + WORD fUnicode; + } CREATE_PROCESS_DEBUG_INFO,*LPCREATE_PROCESS_DEBUG_INFO; + + typedef struct _EXIT_THREAD_DEBUG_INFO { + DWORD dwExitCode; + } EXIT_THREAD_DEBUG_INFO,*LPEXIT_THREAD_DEBUG_INFO; + + typedef struct _EXIT_PROCESS_DEBUG_INFO { + DWORD dwExitCode; + } EXIT_PROCESS_DEBUG_INFO,*LPEXIT_PROCESS_DEBUG_INFO; + + typedef struct _LOAD_DLL_DEBUG_INFO { + HANDLE hFile; + LPVOID lpBaseOfDll; + DWORD dwDebugInfoFileOffset; + DWORD nDebugInfoSize; + LPVOID lpImageName; + WORD fUnicode; + } LOAD_DLL_DEBUG_INFO,*LPLOAD_DLL_DEBUG_INFO; + + typedef struct _UNLOAD_DLL_DEBUG_INFO { + LPVOID lpBaseOfDll; + } UNLOAD_DLL_DEBUG_INFO,*LPUNLOAD_DLL_DEBUG_INFO; + + typedef struct _OUTPUT_DEBUG_STRING_INFO { + LPSTR lpDebugStringData; + WORD fUnicode; + WORD nDebugStringLength; + } OUTPUT_DEBUG_STRING_INFO,*LPOUTPUT_DEBUG_STRING_INFO; + + typedef struct _RIP_INFO { + DWORD dwError; + DWORD dwType; + } RIP_INFO,*LPRIP_INFO; + + typedef struct _DEBUG_EVENT { + DWORD dwDebugEventCode; + DWORD dwProcessId; + DWORD dwThreadId; + union { + EXCEPTION_DEBUG_INFO Exception; + CREATE_THREAD_DEBUG_INFO CreateThread; + CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; + EXIT_THREAD_DEBUG_INFO ExitThread; + EXIT_PROCESS_DEBUG_INFO ExitProcess; + LOAD_DLL_DEBUG_INFO LoadDll; + UNLOAD_DLL_DEBUG_INFO UnloadDll; + OUTPUT_DEBUG_STRING_INFO DebugString; + RIP_INFO RipInfo; + } u; + } DEBUG_EVENT,*LPDEBUG_EVENT; + + typedef PCONTEXT LPCONTEXT; + typedef PEXCEPTION_RECORD LPEXCEPTION_RECORD; + typedef PEXCEPTION_POINTERS LPEXCEPTION_POINTERS; + +#define DRIVE_UNKNOWN 0 +#define DRIVE_NO_ROOT_DIR 1 +#define DRIVE_REMOVABLE 2 +#define DRIVE_FIXED 3 +#define DRIVE_REMOTE 4 +#define DRIVE_CDROM 5 +#define DRIVE_RAMDISK 6 + +#define GetFreeSpace(w) (0x100000L) +#define FILE_TYPE_UNKNOWN 0x0 +#define FILE_TYPE_DISK 0x1 +#define FILE_TYPE_CHAR 0x2 +#define FILE_TYPE_PIPE 0x3 +#define FILE_TYPE_REMOTE 0x8000 + +#define STD_INPUT_HANDLE ((DWORD)-10) +#define STD_OUTPUT_HANDLE ((DWORD)-11) +#define STD_ERROR_HANDLE ((DWORD)-12) + +#define NOPARITY 0 +#define ODDPARITY 1 +#define EVENPARITY 2 +#define MARKPARITY 3 +#define SPACEPARITY 4 + +#define ONESTOPBIT 0 +#define ONE5STOPBITS 1 +#define TWOSTOPBITS 2 + +#define IGNORE 0 +#define INFINITE 0xffffffff + +#define CBR_110 110 +#define CBR_300 300 +#define CBR_600 600 +#define CBR_1200 1200 +#define CBR_2400 2400 +#define CBR_4800 4800 +#define CBR_9600 9600 +#define CBR_14400 14400 +#define CBR_19200 19200 +#define CBR_38400 38400 +#define CBR_56000 56000 +#define CBR_57600 57600 +#define CBR_115200 115200 +#define CBR_128000 128000 +#define CBR_256000 256000 + +#define CE_RXOVER 0x1 +#define CE_OVERRUN 0x2 +#define CE_RXPARITY 0x4 +#define CE_FRAME 0x8 +#define CE_BREAK 0x10 +#define CE_TXFULL 0x100 +#define CE_PTO 0x200 +#define CE_IOE 0x400 +#define CE_DNS 0x800 +#define CE_OOP 0x1000 +#define CE_MODE 0x8000 + +#define IE_BADID (-1) +#define IE_OPEN (-2) +#define IE_NOPEN (-3) +#define IE_MEMORY (-4) +#define IE_DEFAULT (-5) +#define IE_HARDWARE (-10) +#define IE_BYTESIZE (-11) +#define IE_BAUDRATE (-12) + +#define EV_RXCHAR 0x1 +#define EV_RXFLAG 0x2 +#define EV_TXEMPTY 0x4 +#define EV_CTS 0x8 +#define EV_DSR 0x10 +#define EV_RLSD 0x20 +#define EV_BREAK 0x40 +#define EV_ERR 0x80 +#define EV_RING 0x100 +#define EV_PERR 0x200 +#define EV_RX80FULL 0x400 +#define EV_EVENT1 0x800 +#define EV_EVENT2 0x1000 + #define SETXOFF 1 #define SETXON 2 +#define SETRTS 3 +#define CLRRTS 4 +#define SETDTR 5 +#define CLRDTR 6 +#define RESETDEV 7 #define SETBREAK 8 #define CLRBREAK 9 -#define STILL_ACTIVE 0x103 -#define FIND_FIRST_EX_CASE_SENSITIVE 1 + +#define PURGE_TXABORT 0x1 +#define PURGE_RXABORT 0x2 +#define PURGE_TXCLEAR 0x4 +#define PURGE_RXCLEAR 0x8 + +#define LPTx 0x80 + +#define MS_CTS_ON ((DWORD)0x10) +#define MS_DSR_ON ((DWORD)0x20) +#define MS_RING_ON ((DWORD)0x40) +#define MS_RLSD_ON ((DWORD)0x80) + +#define S_QUEUEEMPTY 0 +#define S_THRESHOLD 1 +#define S_ALLTHRESHOLD 2 + +#define S_NORMAL 0 +#define S_LEGATO 1 +#define S_STACCATO 2 + +#define S_PERIOD512 0 +#define S_PERIOD1024 1 +#define S_PERIOD2048 2 +#define S_PERIODVOICE 3 +#define S_WHITE512 4 +#define S_WHITE1024 5 +#define S_WHITE2048 6 +#define S_WHITEVOICE 7 + +#define S_SERDVNA (-1) +#define S_SEROFM (-2) +#define S_SERMACT (-3) +#define S_SERQFUL (-4) +#define S_SERBDNT (-5) +#define S_SERDLN (-6) +#define S_SERDCC (-7) +#define S_SERDTP (-8) +#define S_SERDVL (-9) +#define S_SERDMD (-10) +#define S_SERDSH (-11) +#define S_SERDPT (-12) +#define S_SERDFQ (-13) +#define S_SERDDR (-14) +#define S_SERDSR (-15) +#define S_SERDST (-16) + +#define NMPWAIT_WAIT_FOREVER 0xffffffff +#define NMPWAIT_NOWAIT 0x1 +#define NMPWAIT_USE_DEFAULT_WAIT 0x0 + +#define FS_CASE_IS_PRESERVED FILE_CASE_PRESERVED_NAMES +#define FS_CASE_SENSITIVE FILE_CASE_SENSITIVE_SEARCH +#define FS_UNICODE_STORED_ON_DISK FILE_UNICODE_ON_DISK +#define FS_PERSISTENT_ACLS FILE_PERSISTENT_ACLS +#define FS_VOL_IS_COMPRESSED FILE_VOLUME_IS_COMPRESSED +#define FS_FILE_COMPRESSION FILE_FILE_COMPRESSION +#define FS_FILE_ENCRYPTION FILE_SUPPORTS_ENCRYPTION + +#define FILE_MAP_COPY SECTION_QUERY +#define FILE_MAP_WRITE SECTION_MAP_WRITE +#define FILE_MAP_READ SECTION_MAP_READ +#define FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS +#define FILE_MAP_EXECUTE SECTION_MAP_EXECUTE_EXPLICIT + +#define OF_READ 0x0 +#define OF_WRITE 0x1 +#define OF_READWRITE 0x2 +#define OF_SHARE_COMPAT 0x0 +#define OF_SHARE_EXCLUSIVE 0x10 +#define OF_SHARE_DENY_WRITE 0x20 +#define OF_SHARE_DENY_READ 0x30 +#define OF_SHARE_DENY_NONE 0x40 +#define OF_PARSE 0x100 +#define OF_DELETE 0x200 +#define OF_VERIFY 0x400 +#define OF_CANCEL 0x800 +#define OF_CREATE 0x1000 +#define OF_PROMPT 0x2000 +#define OF_EXIST 0x4000 +#define OF_REOPEN 0x8000 + +#define OFS_MAXPATHNAME 128 + typedef struct _OFSTRUCT { + BYTE cBytes; + BYTE fFixedDisk; + WORD nErrCode; + WORD Reserved1; + WORD Reserved2; + CHAR szPathName[OFS_MAXPATHNAME]; + } OFSTRUCT,*LPOFSTRUCT,*POFSTRUCT; + +#ifndef NOWINBASEINTERLOCK + +#ifndef _NTOS_ + +#if defined(__ia64__) && !defined(RC_INVOKED) + +#define InterlockedIncrement _InterlockedIncrement +#define InterlockedIncrementAcquire _InterlockedIncrement_acq +#define InterlockedIncrementRelease _InterlockedIncrement_rel +#define InterlockedDecrement _InterlockedDecrement +#define InterlockedDecrementAcquire _InterlockedDecrement_acq +#define InterlockedDecrementRelease _InterlockedDecrement_rel +#define InterlockedExchange _InterlockedExchange +#define InterlockedExchangeAdd _InterlockedExchangeAdd +#define InterlockedCompareExchange _InterlockedCompareExchange +#define InterlockedCompareExchangeAcquire _InterlockedCompareExchange_acq +#define InterlockedCompareExchangeRelease _InterlockedCompareExchange_rel +#define InterlockedExchangePointer _InterlockedExchangePointer +#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer +#define InterlockedCompareExchangePointerRelease _InterlockedCompareExchangePointer_rel +#define InterlockedCompareExchangePointerAcquire _InterlockedCompareExchangePointer_acq + +#define InterlockedIncrement64 _InterlockedIncrement64 +#define InterlockedDecrement64 _InterlockedDecrement64 +#define InterlockedExchange64 _InterlockedExchange64 +#define InterlockedExchangeAcquire64 _InterlockedExchange64_acq +#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64 +#define InterlockedCompareExchange64 _InterlockedCompareExchange64 +#define InterlockedCompareExchangeAcquire64 _InterlockedCompareExchange64_acq +#define InterlockedCompareExchangeRelease64 _InterlockedCompareExchange64_rel + + LONGLONG __cdecl InterlockedIncrement64(LONGLONG volatile *Addend); + LONGLONG __cdecl InterlockedDecrement64(LONGLONG volatile *Addend); + LONG __cdecl InterlockedIncrementAcquire(LONG volatile *Addend); + LONG __cdecl InterlockedDecrementAcquire(LONG volatile *Addend); + LONG __cdecl InterlockedIncrementRelease(LONG volatile *Addend); + LONG __cdecl InterlockedDecrementRelease(LONG volatile *Addend); + LONGLONG __cdecl InterlockedExchange64 (LONGLONG volatile *Target,LONGLONG Value); + LONGLONG __cdecl InterlockedExchangeAcquire64 (LONGLONG volatile *Target,LONGLONG Value); + LONGLONG __cdecl InterlockedExchangeAdd64 (LONGLONG volatile *Addend,LONGLONG Value); + LONGLONG __cdecl InterlockedCompareExchange64 (LONGLONG volatile *Destination,LONGLONG ExChange,LONGLONG Comperand); + LONGLONG __cdecl InterlockedCompareExchangeAcquire64 (LONGLONG volatile *Destination,LONGLONG ExChange,LONGLONG Comperand); + LONGLONG __cdecl InterlockedCompareExchangeRelease64 (LONGLONG volatile *Destination,LONGLONG ExChange,LONGLONG Comperand); + LONG __cdecl InterlockedIncrement(LONG volatile *lpAddend); + LONG __cdecl InterlockedDecrement(LONG volatile *lpAddend); + LONG __cdecl InterlockedExchange(LONG volatile *Target,LONG Value); + LONG __cdecl InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); + LONG __cdecl InterlockedCompareExchange(LONG volatile *Destination,LONG ExChange,LONG Comperand); + LONG __cdecl InterlockedCompareExchangeRelease(LONG volatile *Destination,LONG ExChange,LONG Comperand); + LONG __cdecl InterlockedCompareExchangeAcquire(LONG volatile *Destination,LONG ExChange,LONG Comperand); + PVOID __cdecl InterlockedExchangePointer(PVOID volatile *Target,PVOID Value); + PVOID __cdecl InterlockedCompareExchangePointer(PVOID volatile *Destination,PVOID ExChange,PVOID Comperand); + PVOID __cdecl InterlockedCompareExchangePointerAcquire(PVOID volatile *Destination,PVOID Exchange,PVOID Comperand); + PVOID __cdecl InterlockedCompareExchangePointerRelease(PVOID volatile *Destination,PVOID Exchange,PVOID Comperand); + +#ifndef InterlockedAnd +#define InterlockedAnd InterlockedAnd_Inline + __CRT_INLINE LONG InterlockedAnd_Inline(LONG volatile *Target,LONG Set) { + LONG i; + LONG j; + j = *Target; + do { + i = j; + j = InterlockedCompareExchange(Target,i & Set,i); + } while(i!=j); + return j; + } +#endif + +#ifndef InterlockedOr +#define InterlockedOr InterlockedOr_Inline + + __CRT_INLINE LONG InterlockedOr_Inline(LONG volatile *Target,LONG Set) { + LONG i; + LONG j; + j = *Target; + do { + i = j; + j = InterlockedCompareExchange(Target,i | Set,i); + } while(i!=j); + return j; + } +#endif + +#ifndef InterlockedXor +#define InterlockedXor InterlockedXor_Inline + + __CRT_INLINE LONG InterlockedXor_Inline(LONG volatile *Target,LONG Set) { + LONG i; + LONG j; + j = *Target; + do { + i = j; + j = InterlockedCompareExchange(Target,i ^ Set,i); + } while(i!=j); + return j; + } +#endif + +#ifndef !defined (InterlockedAnd64) +#define InterlockedAnd64 InterlockedAnd64_Inline + + __CRT_INLINE LONGLONG InterlockedAnd64_Inline (LONGLONG volatile *Destination,LONGLONG Value) { + LONGLONG Old; + do { + Old = *Destination; + } while(InterlockedCompareExchange64(Destination,Old & Value,Old)!=Old); + return Old; + } +#endif + +#ifndef InterlockedOr64 +#define InterlockedOr64 InterlockedOr64_Inline + + __CRT_INLINE LONGLONG InterlockedOr64_Inline (LONGLONG volatile *Destination,LONGLONG Value) { + LONGLONG Old; + do { + Old = *Destination; + } while(InterlockedCompareExchange64(Destination,Old | Value,Old)!=Old); + return Old; + } +#endif + +#ifndef InterlockedXor64 +#define InterlockedXor64 InterlockedXor64_Inline + + __CRT_INLINE LONGLONG InterlockedXor64_Inline (LONGLONG volatile *Destination,LONGLONG Value) { + LONGLONG Old; + do { + Old = *Destination; + } while(InterlockedCompareExchange64(Destination,Old ^ Value,Old)!=Old); + return Old; + } +#endif + +#ifndef InterlockedBitTestAndSet +#define InterlockedBitTestAndSet InterlockedBitTestAndSet_Inline + + __CRT_INLINE BOOLEAN InterlockedBitTestAndSet_Inline(LONG *Base,LONG Bit) { + LONG tBit; + tBit = 1<<(Bit & (sizeof (*Base)*8-1)); + return (BOOLEAN)((InterlockedOr(&Base[Bit/(sizeof(*Base)*8)],tBit)&tBit)!=0); + } +#endif + +#ifndef InterlockedBitTestAndReset +#define InterlockedBitTestAndReset InterlockedBitTestAndReset_Inline + + __CRT_INLINE BOOLEAN InterlockedBitTestAndReset_Inline(LONG *Base,LONG Bit) { + LONG tBit; + tBit = 1<<(Bit & (sizeof (*Base)*8-1)); + return (BOOLEAN)((InterlockedAnd(&Base[Bit/(sizeof(*Base)*8)],~tBit)&tBit)!=0); + } +#endif + +#ifndef InterlockedBitTestAndComplement +#define InterlockedBitTestAndComplement InterlockedBitTestAndComplement_Inline + + __CRT_INLINE BOOLEAN InterlockedBitTestAndComplement_Inline(LONG *Base,LONG Bit) { + LONG tBit; + tBit = 1<<(Bit & (sizeof (*Base)*8-1)); + return (BOOLEAN)((InterlockedXor(&Base[Bit/(sizeof(*Base)*8)],tBit)&tBit)!=0); + } +#endif +#elif defined(__x86_64) && !defined(RC_INVOKED) + +#define InterlockedIncrement _InterlockedIncrement +#define InterlockedIncrementAcquire InterlockedIncrement +#define InterlockedIncrementRelease InterlockedIncrement +#define InterlockedDecrement _InterlockedDecrement +#define InterlockedDecrementAcquire InterlockedDecrement +#define InterlockedDecrementRelease InterlockedDecrement +#define InterlockedExchange _InterlockedExchange +#define InterlockedExchangeAdd _InterlockedExchangeAdd +#define InterlockedCompareExchange _InterlockedCompareExchange +#define InterlockedCompareExchangeAcquire InterlockedCompareExchange +#define InterlockedCompareExchangeRelease InterlockedCompareExchange +#define InterlockedExchangePointer _InterlockedExchangePointer +#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer +#define InterlockedCompareExchangePointerAcquire _InterlockedCompareExchangePointer +#define InterlockedCompareExchangePointerRelease _InterlockedCompareExchangePointer +#define InterlockedAnd64 _InterlockedAnd64 +#define InterlockedOr64 _InterlockedOr64 +#define InterlockedXor64 _InterlockedXor64 +#define InterlockedIncrement64 _InterlockedIncrement64 +#define InterlockedDecrement64 _InterlockedDecrement64 +#define InterlockedExchange64 _InterlockedExchange64 +#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64 +#define InterlockedCompareExchange64 _InterlockedCompareExchange64 +#define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64 +#define InterlockedCompareExchangeRelease64 InterlockedCompareExchange64 + + LONG InterlockedIncrement(LONG volatile *Addend); + LONG InterlockedDecrement(LONG volatile *Addend); + LONG InterlockedExchange(LONG volatile *Target,LONG Value); + LONG InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); + LONG InterlockedCompareExchange(LONG volatile *Destination,LONG ExChange,LONG Comperand); + PVOID InterlockedCompareExchangePointer(PVOID volatile *Destination,PVOID Exchange,PVOID Comperand); + PVOID InterlockedExchangePointer(PVOID volatile *Target,PVOID Value); + LONG64 InterlockedAnd64(LONG64 volatile *Destination,LONG64 Value); + LONG64 InterlockedOr64(LONG64 volatile *Destination,LONG64 Value); + LONG64 InterlockedXor64(LONG64 volatile *Destination,LONG64 Value); + LONG64 InterlockedIncrement64(LONG64 volatile *Addend); + LONG64 InterlockedDecrement64(LONG64 volatile *Addend); + LONG64 InterlockedExchange64(LONG64 volatile *Target,LONG64 Value); + LONG64 InterlockedExchangeAdd64(LONG64 volatile *Addend,LONG64 Value); + LONG64 InterlockedCompareExchange64(LONG64 volatile *Destination,LONG64 ExChange,LONG64 Comperand); +#else + LONG WINAPI InterlockedIncrement(LONG volatile *lpAddend); + LONG WINAPI InterlockedDecrement(LONG volatile *lpAddend); + LONG WINAPI InterlockedExchange(LONG volatile *Target,LONG Value); + +#define InterlockedExchangePointer(Target,Value) (PVOID)InterlockedExchange((PLONG)(Target),(LONG)(Value)) + + LONG WINAPI InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); + LONG WINAPI InterlockedCompareExchange(LONG volatile *Destination,LONG Exchange,LONG Comperand); + LONGLONG WINAPI InterlockedCompareExchange64(LONGLONG volatile *Destination,LONGLONG Exchange,LONGLONG Comperand); + + __CRT_INLINE LONGLONG InterlockedAnd64 (LONGLONG volatile *Destination,LONGLONG Value) { + LONGLONG Old; + do { + Old = *Destination; + } while(InterlockedCompareExchange64(Destination,Old & Value,Old)!=Old); + return Old; + } + + __CRT_INLINE LONGLONG InterlockedOr64 (LONGLONG volatile *Destination,LONGLONG Value) { + LONGLONG Old; + do { + Old = *Destination; + } while(InterlockedCompareExchange64(Destination,Old | Value,Old)!=Old); + return Old; + } + + __CRT_INLINE LONGLONG InterlockedXor64 (LONGLONG volatile *Destination,LONGLONG Value) { + LONGLONG Old; + do { + Old = *Destination; + } while(InterlockedCompareExchange64(Destination,Old ^ Value,Old)!=Old); + + return Old; + } + + __CRT_INLINE LONGLONG InterlockedIncrement64(LONGLONG volatile *Addend) { + LONGLONG Old; + do { + Old = *Addend; + } while(InterlockedCompareExchange64(Addend,Old + 1,Old)!=Old); + return Old + 1; + } + + __CRT_INLINE LONGLONG InterlockedDecrement64(LONGLONG volatile *Addend) { + LONGLONG Old; + do { + Old = *Addend; + } while(InterlockedCompareExchange64(Addend,Old - 1,Old)!=Old); + return Old - 1; + } + + __CRT_INLINE LONGLONG InterlockedExchange64(LONGLONG volatile *Target,LONGLONG Value) { + LONGLONG Old; + do { + Old = *Target; + } while(InterlockedCompareExchange64(Target,Value,Old)!=Old); + return Old; + } + + __CRT_INLINE LONGLONG InterlockedExchangeAdd64(LONGLONG volatile *Addend,LONGLONG Value) { + LONGLONG Old; + do { + Old = *Addend; + } while(InterlockedCompareExchange64(Addend,Old + Value,Old)!=Old); + return Old; + } + +#ifdef __cplusplus + __CRT_INLINE PVOID __cdecl __InlineInterlockedCompareExchangePointer(PVOID volatile *Destination,PVOID ExChange,PVOID Comperand) { + return((PVOID)(LONG_PTR)InterlockedCompareExchange((LONG volatile *)Destination,(LONG)(LONG_PTR)ExChange,(LONG)(LONG_PTR)Comperand)); + } +#define InterlockedCompareExchangePointer __InlineInterlockedCompareExchangePointer +#else +#define InterlockedCompareExchangePointer(Destination,ExChange,Comperand)(PVOID)(LONG_PTR)InterlockedCompareExchange((LONG volatile *)(Destination),(LONG)(LONG_PTR)(ExChange),(LONG)(LONG_PTR)(Comperand)) +#endif + +#define InterlockedIncrementAcquire InterlockedIncrement +#define InterlockedIncrementRelease InterlockedIncrement +#define InterlockedDecrementAcquire InterlockedDecrement +#define InterlockedDecrementRelease InterlockedDecrement +#define InterlockedIncrementAcquire InterlockedIncrement +#define InterlockedIncrementRelease InterlockedIncrement +#define InterlockedCompareExchangeAcquire InterlockedCompareExchange +#define InterlockedCompareExchangeRelease InterlockedCompareExchange +#define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64 +#define InterlockedCompareExchangeRelease64 InterlockedCompareExchange64 +#define InterlockedCompareExchangePointerAcquire InterlockedCompareExchangePointer +#define InterlockedCompareExchangePointerRelease InterlockedCompareExchangePointer +#endif + +#if defined(_SLIST_HEADER_) && !defined(_NTOSP_) + WINBASEAPI VOID WINAPI InitializeSListHead(PSLIST_HEADER ListHead); + WINBASEAPI PSLIST_ENTRY WINAPI InterlockedPopEntrySList(PSLIST_HEADER ListHead); + WINBASEAPI PSLIST_ENTRY WINAPI InterlockedPushEntrySList(PSLIST_HEADER ListHead,PSLIST_ENTRY ListEntry); + WINBASEAPI PSLIST_ENTRY WINAPI InterlockedFlushSList(PSLIST_HEADER ListHead); + WINBASEAPI USHORT WINAPI QueryDepthSList(PSLIST_HEADER ListHead); +#endif +#endif +#endif + + WINBASEAPI WINBOOL WINAPI FreeResource(HGLOBAL hResData); + WINBASEAPI LPVOID WINAPI LockResource(HGLOBAL hResData); + +#define UnlockResource(hResData) ((hResData),0) +#define MAXINTATOM 0xC000 +#define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i))) +#define INVALID_ATOM ((ATOM)0) + + int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd); + WINBASEAPI WINBOOL WINAPI FreeLibrary(HMODULE hLibModule); + WINBASEAPI DECLSPEC_NORETURN VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule,DWORD dwExitCode); + WINBASEAPI WINBOOL WINAPI DisableThreadLibraryCalls(HMODULE hLibModule); + WINBASEAPI FARPROC WINAPI GetProcAddress(HMODULE hModule,LPCSTR lpProcName); + WINBASEAPI DWORD WINAPI GetVersion(VOID); + WINBASEAPI HGLOBAL WINAPI GlobalAlloc(UINT uFlags,SIZE_T dwBytes); + WINBASEAPI HGLOBAL WINAPI GlobalReAlloc(HGLOBAL hMem,SIZE_T dwBytes,UINT uFlags); + WINBASEAPI SIZE_T WINAPI GlobalSize(HGLOBAL hMem); + WINBASEAPI UINT WINAPI GlobalFlags(HGLOBAL hMem); + WINBASEAPI LPVOID WINAPI GlobalLock(HGLOBAL hMem); + WINBASEAPI HGLOBAL WINAPI GlobalHandle(LPCVOID pMem); + WINBASEAPI WINBOOL WINAPI GlobalUnlock(HGLOBAL hMem); + WINBASEAPI HGLOBAL WINAPI GlobalFree(HGLOBAL hMem); + WINBASEAPI SIZE_T WINAPI GlobalCompact(DWORD dwMinFree); + WINBASEAPI VOID WINAPI GlobalFix(HGLOBAL hMem); + WINBASEAPI VOID WINAPI GlobalUnfix(HGLOBAL hMem); + WINBASEAPI LPVOID WINAPI GlobalWire(HGLOBAL hMem); + WINBASEAPI WINBOOL WINAPI GlobalUnWire(HGLOBAL hMem); + WINBASEAPI VOID WINAPI GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer); + + typedef struct _MEMORYSTATUSEX { + DWORD dwLength; + DWORD dwMemoryLoad; + DWORDLONG ullTotalPhys; + DWORDLONG ullAvailPhys; + DWORDLONG ullTotalPageFile; + DWORDLONG ullAvailPageFile; + DWORDLONG ullTotalVirtual; + DWORDLONG ullAvailVirtual; + DWORDLONG ullAvailExtendedVirtual; + } MEMORYSTATUSEX,*LPMEMORYSTATUSEX; + + WINBASEAPI WINBOOL WINAPI GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer); + WINBASEAPI HLOCAL WINAPI LocalAlloc(UINT uFlags,SIZE_T uBytes); + WINBASEAPI HLOCAL WINAPI LocalReAlloc(HLOCAL hMem,SIZE_T uBytes,UINT uFlags); + WINBASEAPI LPVOID WINAPI LocalLock(HLOCAL hMem); + WINBASEAPI HLOCAL WINAPI LocalHandle(LPCVOID pMem); + WINBASEAPI WINBOOL WINAPI LocalUnlock(HLOCAL hMem); + WINBASEAPI SIZE_T WINAPI LocalSize(HLOCAL hMem); + WINBASEAPI UINT WINAPI LocalFlags(HLOCAL hMem); + WINBASEAPI HLOCAL WINAPI LocalFree(HLOCAL hMem); + WINBASEAPI SIZE_T WINAPI LocalShrink(HLOCAL hMem,UINT cbNewSize); + WINBASEAPI SIZE_T WINAPI LocalCompact(UINT uMinFree); + WINBASEAPI WINBOOL WINAPI FlushInstructionCache(HANDLE hProcess,LPCVOID lpBaseAddress,SIZE_T dwSize); + WINBASEAPI LPVOID WINAPI VirtualAlloc(LPVOID lpAddress,SIZE_T dwSize,DWORD flAllocationType,DWORD flProtect); + WINBASEAPI WINBOOL WINAPI VirtualFree(LPVOID lpAddress,SIZE_T dwSize,DWORD dwFreeType); + WINBASEAPI WINBOOL WINAPI VirtualProtect(LPVOID lpAddress,SIZE_T dwSize,DWORD flNewProtect,PDWORD lpflOldProtect); + WINBASEAPI SIZE_T WINAPI VirtualQuery(LPCVOID lpAddress,PMEMORY_BASIC_INFORMATION lpBuffer,SIZE_T dwLength); + WINBASEAPI LPVOID WINAPI VirtualAllocEx(HANDLE hProcess,LPVOID lpAddress,SIZE_T dwSize,DWORD flAllocationType,DWORD flProtect); + WINBASEAPI UINT WINAPI GetWriteWatch(DWORD dwFlags,PVOID lpBaseAddress,SIZE_T dwRegionSize,PVOID *lpAddresses,ULONG_PTR *lpdwCount,PULONG lpdwGranularity); + WINBASEAPI UINT WINAPI ResetWriteWatch(LPVOID lpBaseAddress,SIZE_T dwRegionSize); + WINBASEAPI SIZE_T WINAPI GetLargePageMinimum(VOID); + WINBASEAPI UINT WINAPI EnumSystemFirmwareTables(DWORD FirmwareTableProviderSignature,PVOID pFirmwareTableEnumBuffer,DWORD BufferSize); + WINBASEAPI UINT WINAPI GetSystemFirmwareTable(DWORD FirmwareTableProviderSignature,DWORD FirmwareTableID,PVOID pFirmwareTableBuffer,DWORD BufferSize); + WINBASEAPI WINBOOL WINAPI VirtualFreeEx(HANDLE hProcess,LPVOID lpAddress,SIZE_T dwSize,DWORD dwFreeType); + WINBASEAPI WINBOOL WINAPI VirtualProtectEx(HANDLE hProcess,LPVOID lpAddress,SIZE_T dwSize,DWORD flNewProtect,PDWORD lpflOldProtect); + WINBASEAPI SIZE_T WINAPI VirtualQueryEx(HANDLE hProcess,LPCVOID lpAddress,PMEMORY_BASIC_INFORMATION lpBuffer,SIZE_T dwLength); + WINBASEAPI HANDLE WINAPI HeapCreate(DWORD flOptions,SIZE_T dwInitialSize,SIZE_T dwMaximumSize); + WINBASEAPI WINBOOL WINAPI HeapDestroy(HANDLE hHeap); + WINBASEAPI LPVOID WINAPI HeapAlloc(HANDLE hHeap,DWORD dwFlags,SIZE_T dwBytes); + WINBASEAPI LPVOID WINAPI HeapReAlloc(HANDLE hHeap,DWORD dwFlags,LPVOID lpMem,SIZE_T dwBytes); + WINBASEAPI WINBOOL WINAPI HeapFree(HANDLE hHeap,DWORD dwFlags,LPVOID lpMem); + WINBASEAPI SIZE_T WINAPI HeapSize(HANDLE hHeap,DWORD dwFlags,LPCVOID lpMem); + WINBASEAPI WINBOOL WINAPI HeapValidate(HANDLE hHeap,DWORD dwFlags,LPCVOID lpMem); + WINBASEAPI SIZE_T WINAPI HeapCompact(HANDLE hHeap,DWORD dwFlags); + WINBASEAPI HANDLE WINAPI GetProcessHeap(VOID); + WINBASEAPI DWORD WINAPI GetProcessHeaps(DWORD NumberOfHeaps,PHANDLE ProcessHeaps); + + typedef struct _PROCESS_HEAP_ENTRY { + PVOID lpData; + DWORD cbData; + BYTE cbOverhead; + BYTE iRegionIndex; + WORD wFlags; + union { + struct { + HANDLE hMem; + DWORD dwReserved[3]; + } Block; + struct { + DWORD dwCommittedSize; + DWORD dwUnCommittedSize; + LPVOID lpFirstBlock; + LPVOID lpLastBlock; + } Region; + }; + } PROCESS_HEAP_ENTRY,*LPPROCESS_HEAP_ENTRY,*PPROCESS_HEAP_ENTRY; + +#define PROCESS_HEAP_REGION 0x1 +#define PROCESS_HEAP_UNCOMMITTED_RANGE 0x2 +#define PROCESS_HEAP_ENTRY_BUSY 0x4 +#define PROCESS_HEAP_ENTRY_MOVEABLE 0x10 +#define PROCESS_HEAP_ENTRY_DDESHARE 0x20 + + WINBASEAPI WINBOOL WINAPI HeapLock(HANDLE hHeap); + WINBASEAPI WINBOOL WINAPI HeapUnlock(HANDLE hHeap); + WINBASEAPI WINBOOL WINAPI HeapWalk(HANDLE hHeap,LPPROCESS_HEAP_ENTRY lpEntry); + WINBASEAPI WINBOOL WINAPI HeapSetInformation(HANDLE HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,PVOID HeapInformation,SIZE_T HeapInformationLength); + WINBASEAPI WINBOOL WINAPI HeapQueryInformation(HANDLE HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,PVOID HeapInformation,SIZE_T HeapInformationLength,PSIZE_T ReturnLength); + #define SCS_32BIT_BINARY 0 #define SCS_DOS_BINARY 1 -#define SCS_OS216_BINARY 5 +#define SCS_WOW_BINARY 2 #define SCS_PIF_BINARY 3 #define SCS_POSIX_BINARY 4 -#define SCS_WOW_BINARY 2 -#define MAX_COMPUTERNAME_LENGTH 15 -#define HW_PROFILE_GUIDLEN 39 -#define MAX_PROFILE_LEN 80 -#define DOCKINFO_UNDOCKED 1 -#define DOCKINFO_DOCKED 2 -#define DOCKINFO_USER_SUPPLIED 4 -#define DOCKINFO_USER_UNDOCKED (DOCKINFO_USER_SUPPLIED|DOCKINFO_UNDOCKED) -#define DOCKINFO_USER_DOCKED (DOCKINFO_USER_SUPPLIED|DOCKINFO_DOCKED) -#define DRIVE_REMOVABLE 2 -#define DRIVE_FIXED 3 -#define DRIVE_REMOTE 4 -#define DRIVE_CDROM 5 -#define DRIVE_RAMDISK 6 -#define DRIVE_UNKNOWN 0 -#define DRIVE_NO_ROOT_DIR 1 -#define FILE_TYPE_UNKNOWN 0 -#define FILE_TYPE_DISK 1 -#define FILE_TYPE_CHAR 2 -#define FILE_TYPE_PIPE 3 -#define FILE_TYPE_REMOTE 0x8000 -#define HANDLE_FLAG_INHERIT 1 -#define HANDLE_FLAG_PROTECT_FROM_CLOSE 2 -#define STD_INPUT_HANDLE (DWORD)(0xfffffff6) -#define STD_OUTPUT_HANDLE (DWORD)(0xfffffff5) -#define STD_ERROR_HANDLE (DWORD)(0xfffffff4) -#define INVALID_HANDLE_VALUE (HANDLE)(-1) +#define SCS_OS216_BINARY 5 +#define SCS_64BIT_BINARY 6 + +#ifdef UNICODE +#define GetBinaryType GetBinaryTypeW +#define GetShortPathName GetShortPathNameW +#define GetLongPathName GetLongPathNameW +#define GetEnvironmentStrings GetEnvironmentStringsW +#define SetEnvironmentStrings SetEnvironmentStringsW +#define FreeEnvironmentStrings FreeEnvironmentStringsW +#else +#define GetBinaryType GetBinaryTypeA +#define GetShortPathName GetShortPathNameA +#define GetLongPathName GetLongPathNameA +#define GetEnvironmentStringsA GetEnvironmentStrings +#define SetEnvironmentStrings SetEnvironmentStringsA +#define FreeEnvironmentStrings FreeEnvironmentStringsA +#endif + +#ifdef _WIN64 +#define SCS_THIS_PLATFORM_BINARY SCS_64BIT_BINARY +#else +#define SCS_THIS_PLATFORM_BINARY SCS_32BIT_BINARY +#endif + + WINBASEAPI WINBOOL WINAPI GetBinaryTypeA(LPCSTR lpApplicationName,LPDWORD lpBinaryType); + WINBASEAPI WINBOOL WINAPI GetBinaryTypeW(LPCWSTR lpApplicationName,LPDWORD lpBinaryType); + WINBASEAPI DWORD WINAPI GetShortPathNameA(LPCSTR lpszLongPath,LPSTR lpszShortPath,DWORD cchBuffer); + WINBASEAPI DWORD WINAPI GetShortPathNameW(LPCWSTR lpszLongPath,LPWSTR lpszShortPath,DWORD cchBuffer); + WINBASEAPI DWORD WINAPI GetLongPathNameA(LPCSTR lpszShortPath,LPSTR lpszLongPath,DWORD cchBuffer); + WINBASEAPI DWORD WINAPI GetLongPathNameW(LPCWSTR lpszShortPath,LPWSTR lpszLongPath,DWORD cchBuffer); + WINBASEAPI WINBOOL WINAPI GetProcessAffinityMask(HANDLE hProcess,PDWORD_PTR lpProcessAffinityMask,PDWORD_PTR lpSystemAffinityMask); + WINBASEAPI WINBOOL WINAPI SetProcessAffinityMask(HANDLE hProcess,DWORD_PTR dwProcessAffinityMask); + WINBASEAPI WINBOOL WINAPI GetProcessHandleCount(HANDLE hProcess,PDWORD pdwHandleCount); + WINBASEAPI WINBOOL WINAPI GetProcessTimes(HANDLE hProcess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime); + WINBASEAPI WINBOOL WINAPI GetProcessIoCounters(HANDLE hProcess,PIO_COUNTERS lpIoCounters); + WINBASEAPI WINBOOL WINAPI GetProcessWorkingSetSize(HANDLE hProcess,PSIZE_T lpMinimumWorkingSetSize,PSIZE_T lpMaximumWorkingSetSize); + WINBASEAPI WINBOOL WINAPI GetProcessWorkingSetSizeEx(HANDLE hProcess,PSIZE_T lpMinimumWorkingSetSize,PSIZE_T lpMaximumWorkingSetSize,PDWORD Flags); + WINBASEAPI WINBOOL WINAPI SetProcessWorkingSetSize(HANDLE hProcess,SIZE_T dwMinimumWorkingSetSize,SIZE_T dwMaximumWorkingSetSize); + WINBASEAPI WINBOOL WINAPI SetProcessWorkingSetSizeEx(HANDLE hProcess,SIZE_T dwMinimumWorkingSetSize,SIZE_T dwMaximumWorkingSetSize,DWORD Flags); + WINBASEAPI HANDLE WINAPI OpenProcess(DWORD dwDesiredAccess,WINBOOL bInheritHandle,DWORD dwProcessId); + WINBASEAPI HANDLE WINAPI GetCurrentProcess(VOID); + WINBASEAPI DWORD WINAPI GetCurrentProcessId(VOID); + WINBASEAPI DECLSPEC_NORETURN VOID WINAPI ExitProcess(UINT uExitCode); + WINBASEAPI WINBOOL WINAPI TerminateProcess(HANDLE hProcess,UINT uExitCode); + WINBASEAPI WINBOOL WINAPI GetExitCodeProcess(HANDLE hProcess,LPDWORD lpExitCode); + WINBASEAPI VOID WINAPI FatalExit(int ExitCode); + /* WINBASEAPI LPCH WINAPI GetEnvironmentStrings(VOID); */ + WINBASEAPI LPWCH WINAPI GetEnvironmentStringsW(VOID); + WINBASEAPI WINBOOL WINAPI SetEnvironmentStringsA(LPCH NewEnvironment); + WINBASEAPI WINBOOL WINAPI SetEnvironmentStringsW(LPWCH NewEnvironment); + WINBASEAPI WINBOOL WINAPI FreeEnvironmentStringsA(LPCH); + WINBASEAPI WINBOOL WINAPI FreeEnvironmentStringsW(LPWCH); + WINBASEAPI VOID WINAPI RaiseException(DWORD dwExceptionCode,DWORD dwExceptionFlags,DWORD nNumberOfArguments,CONST ULONG_PTR *lpArguments); + WINBASEAPI LONG WINAPI UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo); + + typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(struct _EXCEPTION_POINTERS *ExceptionInfo); + typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER; + + WINBASEAPI LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter); + +#define FIBER_FLAG_FLOAT_SWITCH 0x1 + + WINBASEAPI LPVOID WINAPI CreateFiber(SIZE_T dwStackSize,LPFIBER_START_ROUTINE lpStartAddress,LPVOID lpParameter); + WINBASEAPI LPVOID WINAPI CreateFiberEx(SIZE_T dwStackCommitSize,SIZE_T dwStackReserveSize,DWORD dwFlags,LPFIBER_START_ROUTINE lpStartAddress,LPVOID lpParameter); + WINBASEAPI VOID WINAPI DeleteFiber(LPVOID lpFiber); + WINBASEAPI LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter); + WINBASEAPI LPVOID WINAPI ConvertThreadToFiberEx(LPVOID lpParameter,DWORD dwFlags); + WINBASEAPI WINBOOL WINAPI ConvertFiberToThread(VOID); + WINBASEAPI VOID WINAPI SwitchToFiber(LPVOID lpFiber); + WINBASEAPI WINBOOL WINAPI SwitchToThread(VOID); + WINBASEAPI HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId); + WINBASEAPI HANDLE WINAPI CreateRemoteThread(HANDLE hProcess,LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId); + WINBASEAPI HANDLE WINAPI GetCurrentThread(VOID); + WINBASEAPI DWORD WINAPI GetCurrentThreadId(VOID); + WINBASEAPI WINBOOL WINAPI SetThreadStackGuarantee (PULONG StackSizeInBytes); + WINBASEAPI DWORD WINAPI GetProcessIdOfThread(HANDLE Thread); + WINBASEAPI DWORD WINAPI GetThreadId(HANDLE Thread); + WINBASEAPI DWORD WINAPI GetProcessId(HANDLE Process); + WINBASEAPI DWORD WINAPI GetCurrentProcessorNumber(VOID); + WINBASEAPI DWORD_PTR WINAPI SetThreadAffinityMask(HANDLE hThread,DWORD_PTR dwThreadAffinityMask); + WINBASEAPI DWORD WINAPI SetThreadIdealProcessor(HANDLE hThread,DWORD dwIdealProcessor); + WINBASEAPI WINBOOL WINAPI SetProcessPriorityBoost(HANDLE hProcess,WINBOOL bDisablePriorityBoost); + WINBASEAPI WINBOOL WINAPI GetProcessPriorityBoost(HANDLE hProcess,PBOOL pDisablePriorityBoost); + WINBASEAPI WINBOOL WINAPI RequestWakeupLatency(LATENCY_TIME latency); + WINBASEAPI WINBOOL WINAPI IsSystemResumeAutomatic(VOID); + WINBASEAPI HANDLE WINAPI OpenThread(DWORD dwDesiredAccess,WINBOOL bInheritHandle,DWORD dwThreadId); + WINBASEAPI WINBOOL WINAPI SetThreadPriority(HANDLE hThread,int nPriority); + WINBASEAPI WINBOOL WINAPI SetThreadPriorityBoost(HANDLE hThread,WINBOOL bDisablePriorityBoost); + WINBASEAPI WINBOOL WINAPI GetThreadPriorityBoost(HANDLE hThread,PBOOL pDisablePriorityBoost); + WINBASEAPI int WINAPI GetThreadPriority(HANDLE hThread); + WINBASEAPI WINBOOL WINAPI GetThreadTimes(HANDLE hThread,LPFILETIME lpCreationTime,LPFILETIME lpExitTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime); + WINBASEAPI WINBOOL WINAPI GetThreadIOPendingFlag(HANDLE hThread,PBOOL lpIOIsPending); + WINBASEAPI DECLSPEC_NORETURN VOID WINAPI ExitThread(DWORD dwExitCode); + WINBASEAPI WINBOOL WINAPI TerminateThread(HANDLE hThread,DWORD dwExitCode); + WINBASEAPI WINBOOL WINAPI GetExitCodeThread(HANDLE hThread,LPDWORD lpExitCode); + WINBASEAPI WINBOOL WINAPI GetThreadSelectorEntry(HANDLE hThread,DWORD dwSelector,LPLDT_ENTRY lpSelectorEntry); + WINBASEAPI EXECUTION_STATE WINAPI SetThreadExecutionState(EXECUTION_STATE esFlags); + WINBASEAPI DWORD WINAPI GetLastError(VOID); + WINBASEAPI VOID WINAPI SetLastError(DWORD dwErrCode); + +#ifndef RC_INVOKED +#ifdef WINBASE_DECLARE_RESTORE_LAST_ERROR + WINBASEAPI VOID WINAPI RestoreLastError(DWORD dwErrCode); + + typedef VOID (WINAPI *PRESTORE_LAST_ERROR)(DWORD); + +#define RESTORE_LAST_ERROR_NAME_A "RestoreLastError" +#define RESTORE_LAST_ERROR_NAME_W L"RestoreLastError" +#define RESTORE_LAST_ERROR_NAME TEXT("RestoreLastError") +#endif +#endif + +#define HasOverlappedIoCompleted(lpOverlapped) (((DWORD)(lpOverlapped)->Internal)!=STATUS_PENDING) + + WINBASEAPI WINBOOL WINAPI GetOverlappedResult(HANDLE hFile,LPOVERLAPPED lpOverlapped,LPDWORD lpNumberOfBytesTransferred,WINBOOL bWait); + WINBASEAPI HANDLE WINAPI CreateIoCompletionPort(HANDLE FileHandle,HANDLE ExistingCompletionPort,ULONG_PTR CompletionKey,DWORD NumberOfConcurrentThreads); + WINBASEAPI WINBOOL WINAPI GetQueuedCompletionStatus(HANDLE CompletionPort,LPDWORD lpNumberOfBytesTransferred,PULONG_PTR lpCompletionKey,LPOVERLAPPED *lpOverlapped,DWORD dwMilliseconds); + WINBASEAPI WINBOOL WINAPI PostQueuedCompletionStatus(HANDLE CompletionPort,DWORD dwNumberOfBytesTransferred,ULONG_PTR dwCompletionKey,LPOVERLAPPED lpOverlapped); + +#define SEM_FAILCRITICALERRORS 0x1 +#define SEM_NOGPFAULTERRORBOX 0x2 +#define SEM_NOALIGNMENTFAULTEXCEPT 0x4 +#define SEM_NOOPENFILEERRORBOX 0x8000 + + WINBASEAPI UINT WINAPI SetErrorMode(UINT uMode); + WINBASEAPI WINBOOL WINAPI ReadProcessMemory(HANDLE hProcess,LPCVOID lpBaseAddress,LPVOID lpBuffer,SIZE_T nSize,SIZE_T *lpNumberOfBytesRead); + WINBASEAPI WINBOOL WINAPI WriteProcessMemory(HANDLE hProcess,LPVOID lpBaseAddress,LPCVOID lpBuffer,SIZE_T nSize,SIZE_T *lpNumberOfBytesWritten); + WINBASEAPI WINBOOL WINAPI GetThreadContext(HANDLE hThread,LPCONTEXT lpContext); + WINBASEAPI WINBOOL WINAPI SetThreadContext(HANDLE hThread,CONST CONTEXT *lpContext); + WINBASEAPI DWORD WINAPI SuspendThread(HANDLE hThread); + WINBASEAPI DWORD WINAPI ResumeThread(HANDLE hThread); + + typedef VOID (WINAPI *PAPCFUNC)(ULONG_PTR dwParam); + + WINBASEAPI DWORD WINAPI QueueUserAPC(PAPCFUNC pfnAPC,HANDLE hThread,ULONG_PTR dwData); + WINBASEAPI WINBOOL WINAPI IsDebuggerPresent(VOID); + WINBASEAPI WINBOOL WINAPI CheckRemoteDebuggerPresent(HANDLE hProcess,PBOOL pbDebuggerPresent); + WINBASEAPI VOID WINAPI DebugBreak(VOID); + WINBASEAPI WINBOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT lpDebugEvent,DWORD dwMilliseconds); + WINBASEAPI WINBOOL WINAPI ContinueDebugEvent(DWORD dwProcessId,DWORD dwThreadId,DWORD dwContinueStatus); + WINBASEAPI WINBOOL WINAPI DebugActiveProcess(DWORD dwProcessId); + WINBASEAPI WINBOOL WINAPI DebugActiveProcessStop(DWORD dwProcessId); + WINBASEAPI WINBOOL WINAPI DebugSetProcessKillOnExit(WINBOOL KillOnExit); + WINBASEAPI WINBOOL WINAPI DebugBreakProcess(HANDLE Process); + WINBASEAPI VOID WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); + WINBASEAPI VOID WINAPI EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); + WINBASEAPI VOID WINAPI LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); + WINBASEAPI WINBOOL WINAPI InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection,DWORD dwSpinCount); + WINBASEAPI DWORD WINAPI SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection,DWORD dwSpinCount); + WINBASEAPI WINBOOL WINAPI TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); + WINBASEAPI VOID WINAPI DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection); + WINBASEAPI WINBOOL WINAPI SetEvent(HANDLE hEvent); + WINBASEAPI WINBOOL WINAPI ResetEvent(HANDLE hEvent); + WINBASEAPI WINBOOL WINAPI PulseEvent(HANDLE hEvent); + WINBASEAPI WINBOOL WINAPI ReleaseSemaphore(HANDLE hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount); + WINBASEAPI WINBOOL WINAPI ReleaseMutex(HANDLE hMutex); + WINBASEAPI DWORD WINAPI WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds); + WINBASEAPI DWORD WINAPI WaitForMultipleObjects(DWORD nCount,CONST HANDLE *lpHandles,WINBOOL bWaitAll,DWORD dwMilliseconds); + WINBASEAPI VOID WINAPI Sleep(DWORD dwMilliseconds); + WINBASEAPI HGLOBAL WINAPI LoadResource(HMODULE hModule,HRSRC hResInfo); + WINBASEAPI DWORD WINAPI SizeofResource(HMODULE hModule,HRSRC hResInfo); + WINBASEAPI ATOM WINAPI GlobalDeleteAtom(ATOM nAtom); + WINBASEAPI WINBOOL WINAPI InitAtomTable(DWORD nSize); + WINBASEAPI ATOM WINAPI DeleteAtom(ATOM nAtom); + WINBASEAPI UINT WINAPI SetHandleCount(UINT uNumber); + WINBASEAPI DWORD WINAPI GetLogicalDrives(VOID); + WINBASEAPI WINBOOL WINAPI LockFile(HANDLE hFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,DWORD nNumberOfBytesToLockLow,DWORD nNumberOfBytesToLockHigh); + WINBASEAPI WINBOOL WINAPI UnlockFile(HANDLE hFile,DWORD dwFileOffsetLow,DWORD dwFileOffsetHigh,DWORD nNumberOfBytesToUnlockLow,DWORD nNumberOfBytesToUnlockHigh); + WINBASEAPI WINBOOL WINAPI LockFileEx(HANDLE hFile,DWORD dwFlags,DWORD dwReserved,DWORD nNumberOfBytesToLockLow,DWORD nNumberOfBytesToLockHigh,LPOVERLAPPED lpOverlapped); + +#define LOCKFILE_FAIL_IMMEDIATELY 0x1 +#define LOCKFILE_EXCLUSIVE_LOCK 0x2 + + WINBASEAPI WINBOOL WINAPI UnlockFileEx(HANDLE hFile,DWORD dwReserved,DWORD nNumberOfBytesToUnlockLow,DWORD nNumberOfBytesToUnlockHigh,LPOVERLAPPED lpOverlapped); + + typedef struct _BY_HANDLE_FILE_INFORMATION { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD dwVolumeSerialNumber; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD nNumberOfLinks; + DWORD nFileIndexHigh; + DWORD nFileIndexLow; + } BY_HANDLE_FILE_INFORMATION,*PBY_HANDLE_FILE_INFORMATION,*LPBY_HANDLE_FILE_INFORMATION; + +#ifdef UNICODE +#define SetFileShortName SetFileShortNameW +#else +#define SetFileShortName SetFileShortNameA +#endif + + WINBASEAPI WINBOOL WINAPI GetFileInformationByHandle(HANDLE hFile,LPBY_HANDLE_FILE_INFORMATION lpFileInformation); + WINBASEAPI DWORD WINAPI GetFileType(HANDLE hFile); + WINBASEAPI DWORD WINAPI GetFileSize(HANDLE hFile,LPDWORD lpFileSizeHigh); + WINBASEAPI WINBOOL WINAPI GetFileSizeEx(HANDLE hFile,PLARGE_INTEGER lpFileSize); + WINBASEAPI HANDLE WINAPI GetStdHandle(DWORD nStdHandle); + WINBASEAPI WINBOOL WINAPI SetStdHandle(DWORD nStdHandle,HANDLE hHandle); + WINBASEAPI WINBOOL WINAPI WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped); + WINBASEAPI WINBOOL WINAPI ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped); + WINBASEAPI WINBOOL WINAPI FlushFileBuffers(HANDLE hFile); + WINBASEAPI WINBOOL WINAPI DeviceIoControl(HANDLE hDevice,DWORD dwIoControlCode,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesReturned,LPOVERLAPPED lpOverlapped); + WINBASEAPI WINBOOL WINAPI RequestDeviceWakeup(HANDLE hDevice); + WINBASEAPI WINBOOL WINAPI CancelDeviceWakeupRequest(HANDLE hDevice); + WINBASEAPI WINBOOL WINAPI GetDevicePowerState(HANDLE hDevice,WINBOOL *pfOn); + WINBASEAPI WINBOOL WINAPI SetMessageWaitingIndicator(HANDLE hMsgIndicator,ULONG ulMsgCount); + WINBASEAPI WINBOOL WINAPI SetEndOfFile(HANDLE hFile); + WINBASEAPI DWORD WINAPI SetFilePointer(HANDLE hFile,LONG lDistanceToMove,PLONG lpDistanceToMoveHigh,DWORD dwMoveMethod); + WINBASEAPI WINBOOL WINAPI SetFilePointerEx(HANDLE hFile,LARGE_INTEGER liDistanceToMove,PLARGE_INTEGER lpNewFilePointer,DWORD dwMoveMethod); + WINBASEAPI WINBOOL WINAPI FindClose(HANDLE hFindFile); + WINBASEAPI WINBOOL WINAPI GetFileTime(HANDLE hFile,LPFILETIME lpCreationTime,LPFILETIME lpLastAccessTime,LPFILETIME lpLastWriteTime); + WINBASEAPI WINBOOL WINAPI SetFileTime(HANDLE hFile,CONST FILETIME *lpCreationTime,CONST FILETIME *lpLastAccessTime,CONST FILETIME *lpLastWriteTime); + WINBASEAPI WINBOOL WINAPI SetFileValidData(HANDLE hFile,LONGLONG ValidDataLength); + WINBASEAPI WINBOOL WINAPI SetFileShortNameA(HANDLE hFile,LPCSTR lpShortName); + WINBASEAPI WINBOOL WINAPI SetFileShortNameW(HANDLE hFile,LPCWSTR lpShortName); + WINBASEAPI WINBOOL WINAPI CloseHandle(HANDLE hObject); + WINBASEAPI WINBOOL WINAPI DuplicateHandle(HANDLE hSourceProcessHandle,HANDLE hSourceHandle,HANDLE hTargetProcessHandle,LPHANDLE lpTargetHandle,DWORD dwDesiredAccess,WINBOOL bInheritHandle,DWORD dwOptions); + WINBASEAPI WINBOOL WINAPI GetHandleInformation(HANDLE hObject,LPDWORD lpdwFlags); + WINBASEAPI WINBOOL WINAPI SetHandleInformation(HANDLE hObject,DWORD dwMask,DWORD dwFlags); + +#define HANDLE_FLAG_INHERIT 0x1 +#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x2 + +#define HINSTANCE_ERROR 32 + + WINBASEAPI DWORD WINAPI LoadModule(LPCSTR lpModuleName,LPVOID lpParameterBlock); + WINBASEAPI UINT WINAPI WinExec(LPCSTR lpCmdLine,UINT uCmdShow); + WINBASEAPI WINBOOL WINAPI ClearCommBreak(HANDLE hFile); + WINBASEAPI WINBOOL WINAPI ClearCommError(HANDLE hFile,LPDWORD lpErrors,LPCOMSTAT lpStat); + WINBASEAPI WINBOOL WINAPI SetupComm(HANDLE hFile,DWORD dwInQueue,DWORD dwOutQueue); + WINBASEAPI WINBOOL WINAPI EscapeCommFunction(HANDLE hFile,DWORD dwFunc); + WINBASEAPI WINBOOL WINAPI GetCommConfig(HANDLE hCommDev,LPCOMMCONFIG lpCC,LPDWORD lpdwSize); + WINBASEAPI WINBOOL WINAPI GetCommMask(HANDLE hFile,LPDWORD lpEvtMask); + WINBASEAPI WINBOOL WINAPI GetCommProperties(HANDLE hFile,LPCOMMPROP lpCommProp); + WINBASEAPI WINBOOL WINAPI GetCommModemStatus(HANDLE hFile,LPDWORD lpModemStat); + WINBASEAPI WINBOOL WINAPI GetCommState(HANDLE hFile,LPDCB lpDCB); + WINBASEAPI WINBOOL WINAPI GetCommTimeouts(HANDLE hFile,LPCOMMTIMEOUTS lpCommTimeouts); + WINBASEAPI WINBOOL WINAPI PurgeComm(HANDLE hFile,DWORD dwFlags); + WINBASEAPI WINBOOL WINAPI SetCommBreak(HANDLE hFile); + WINBASEAPI WINBOOL WINAPI SetCommConfig(HANDLE hCommDev,LPCOMMCONFIG lpCC,DWORD dwSize); + WINBASEAPI WINBOOL WINAPI SetCommMask(HANDLE hFile,DWORD dwEvtMask); + WINBASEAPI WINBOOL WINAPI SetCommState(HANDLE hFile,LPDCB lpDCB); + WINBASEAPI WINBOOL WINAPI SetCommTimeouts(HANDLE hFile,LPCOMMTIMEOUTS lpCommTimeouts); + WINBASEAPI WINBOOL WINAPI TransmitCommChar(HANDLE hFile,char cChar); + WINBASEAPI WINBOOL WINAPI WaitCommEvent(HANDLE hFile,LPDWORD lpEvtMask,LPOVERLAPPED lpOverlapped); + WINBASEAPI DWORD WINAPI SetTapePosition(HANDLE hDevice,DWORD dwPositionMethod,DWORD dwPartition,DWORD dwOffsetLow,DWORD dwOffsetHigh,WINBOOL bImmediate); + WINBASEAPI DWORD WINAPI GetTapePosition(HANDLE hDevice,DWORD dwPositionType,LPDWORD lpdwPartition,LPDWORD lpdwOffsetLow,LPDWORD lpdwOffsetHigh); + WINBASEAPI DWORD WINAPI PrepareTape(HANDLE hDevice,DWORD dwOperation,WINBOOL bImmediate); + WINBASEAPI DWORD WINAPI EraseTape(HANDLE hDevice,DWORD dwEraseType,WINBOOL bImmediate); + WINBASEAPI DWORD WINAPI CreateTapePartition(HANDLE hDevice,DWORD dwPartitionMethod,DWORD dwCount,DWORD dwSize); + WINBASEAPI DWORD WINAPI WriteTapemark(HANDLE hDevice,DWORD dwTapemarkType,DWORD dwTapemarkCount,WINBOOL bImmediate); + WINBASEAPI DWORD WINAPI GetTapeStatus(HANDLE hDevice); + WINBASEAPI DWORD WINAPI GetTapeParameters(HANDLE hDevice,DWORD dwOperation,LPDWORD lpdwSize,LPVOID lpTapeInformation); + #define GET_TAPE_MEDIA_INFORMATION 0 #define GET_TAPE_DRIVE_INFORMATION 1 + + WINBASEAPI DWORD WINAPI SetTapeParameters(HANDLE hDevice,DWORD dwOperation,LPVOID lpTapeInformation); + #define SET_TAPE_MEDIA_INFORMATION 0 #define SET_TAPE_DRIVE_INFORMATION 1 -#define THREAD_PRIORITY_ABOVE_NORMAL 1 -#define THREAD_PRIORITY_BELOW_NORMAL (-1) -#define THREAD_PRIORITY_HIGHEST 2 -#define THREAD_PRIORITY_IDLE (-15) -#define THREAD_PRIORITY_LOWEST (-2) -#define THREAD_PRIORITY_NORMAL 0 -#define THREAD_PRIORITY_TIME_CRITICAL 15 -#define THREAD_PRIORITY_ERROR_RETURN 2147483647 -#define TIME_ZONE_ID_UNKNOWN 0 -#define TIME_ZONE_ID_STANDARD 1 -#define TIME_ZONE_ID_DAYLIGHT 2 -#define TIME_ZONE_ID_INVALID 0xFFFFFFFF -#define FS_CASE_IS_PRESERVED 2 -#define FS_CASE_SENSITIVE 1 -#define FS_UNICODE_STORED_ON_DISK 4 -#define FS_PERSISTENT_ACLS 8 -#define FS_FILE_COMPRESSION 16 -#define FS_VOL_IS_COMPRESSED 32768 -#define GMEM_FIXED 0 -#define GMEM_MOVEABLE 2 -#define GMEM_MODIFY 128 -#define GPTR 64 -#define GHND 66 -#define GMEM_DDESHARE 8192 -#define GMEM_DISCARDABLE 256 -#define GMEM_LOWER 4096 -#define GMEM_NOCOMPACT 16 -#define GMEM_NODISCARD 32 -#define GMEM_NOT_BANKED 4096 -#define GMEM_NOTIFY 16384 -#define GMEM_SHARE 8192 -#define GMEM_ZEROINIT 64 -#define GMEM_DISCARDED 16384 -#define GMEM_INVALID_HANDLE 32768 -#define GMEM_LOCKCOUNT 255 -#define STATUS_WAIT_0 0 -#define STATUS_ABANDONED_WAIT_0 0x80 -#define STATUS_USER_APC 0xC0 -#define STATUS_TIMEOUT 0x102 -#define STATUS_PENDING 0x103 -#define STATUS_SEGMENT_NOTIFICATION 0x40000005 -#define STATUS_GUARD_PAGE_VIOLATION 0x80000001 -#define STATUS_DATATYPE_MISALIGNMENT 0x80000002 -#define STATUS_BREAKPOINT 0x80000003 -#define STATUS_SINGLE_STEP 0x80000004 -#define STATUS_ACCESS_VIOLATION 0xC0000005 -#define STATUS_IN_PAGE_ERROR 0xC0000006 -#define STATUS_INVALID_HANDLE 0xC0000008L -#define STATUS_NO_MEMORY 0xC0000017 -#define STATUS_ILLEGAL_INSTRUCTION 0xC000001D -#define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025 -#define STATUS_INVALID_DISPOSITION 0xC0000026 -#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C -#define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D -#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E -#define STATUS_FLOAT_INEXACT_RESULT 0xC000008F -#define STATUS_FLOAT_INVALID_OPERATION 0xC0000090 -#define STATUS_FLOAT_OVERFLOW 0xC0000091 -#define STATUS_FLOAT_STACK_CHECK 0xC0000092 -#define STATUS_FLOAT_UNDERFLOW 0xC0000093 -#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094 -#define STATUS_INTEGER_OVERFLOW 0xC0000095 -#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096 -#define STATUS_STACK_OVERFLOW 0xC00000FD -#define STATUS_CONTROL_C_EXIT 0xC000013A -#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION -#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT -#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT -#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP -#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED -#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND -#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO -#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT -#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION -#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW -#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK -#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW -#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO -#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW -#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION -#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR -#define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION -#define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION -#define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW -#define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION -#define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION -#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE -#define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT -#define PROCESS_HEAP_REGION 1 -#define PROCESS_HEAP_UNCOMMITTED_RANGE 2 -#define PROCESS_HEAP_ENTRY_BUSY 4 -#define PROCESS_HEAP_ENTRY_MOVEABLE 16 -#define PROCESS_HEAP_ENTRY_DDESHARE 32 -#define DONT_RESOLVE_DLL_REFERENCES 1 -#define LOAD_LIBRARY_AS_DATAFILE 2 -#define LOAD_WITH_ALTERED_SEARCH_PATH 8 -#define LMEM_FIXED 0 -#define LMEM_MOVEABLE 2 -#define LMEM_NONZEROLHND 2 -#define LMEM_NONZEROLPTR 0 -#define LMEM_DISCARDABLE 3840 -#define LMEM_NOCOMPACT 16 -#define LMEM_NODISCARD 32 -#define LMEM_ZEROINIT 64 -#define LMEM_DISCARDED 16384 -#define LMEM_MODIFY 128 -#define LMEM_INVALID_HANDLE 32768 -#define LMEM_LOCKCOUNT 255 -#define LPTR 64 -#define LHND 66 -#define NONZEROLHND 2 -#define NONZEROLPTR 0 -#define LOCKFILE_FAIL_IMMEDIATELY 1 -#define LOCKFILE_EXCLUSIVE_LOCK 2 -#define LOGON32_PROVIDER_DEFAULT 0 -#define LOGON32_PROVIDER_WINNT35 1 -#define LOGON32_LOGON_INTERACTIVE 2 -#define LOGON32_LOGON_BATCH 4 -#define LOGON32_LOGON_SERVICE 5 -#define MOVEFILE_REPLACE_EXISTING 1 -#define MOVEFILE_COPY_ALLOWED 2 -#define MOVEFILE_DELAY_UNTIL_REBOOT 4 -#define MOVEFILE_WRITE_THROUGH 8 -#define MAXIMUM_WAIT_OBJECTS 64 -#define MAXIMUM_SUSPEND_COUNT 0x7F -#define WAIT_OBJECT_0 0 -#define WAIT_ABANDONED_0 128 -#define WAIT_TIMEOUT 0x102 -#define WAIT_IO_COMPLETION 0xC0 -#define WAIT_ABANDONED 128 -#define WAIT_FAILED 0xFFFFFFFF -#define PURGE_TXABORT 1 -#define PURGE_RXABORT 2 -#define PURGE_TXCLEAR 4 -#define PURGE_RXCLEAR 8 -#define EVENTLOG_FORWARDS_READ 4 -#define EVENTLOG_BACKWARDS_READ 8 -#define EVENTLOG_SEEK_READ 2 -#define EVENTLOG_SEQUENTIAL_READ 1 -#define EVENTLOG_ERROR_TYPE 1 -#define EVENTLOG_WARNING_TYPE 2 -#define EVENTLOG_INFORMATION_TYPE 4 -#define EVENTLOG_AUDIT_SUCCESS 8 -#define EVENTLOG_AUDIT_FAILURE 16 -#define FORMAT_MESSAGE_ALLOCATE_BUFFER 256 -#define FORMAT_MESSAGE_IGNORE_INSERTS 512 -#define FORMAT_MESSAGE_FROM_STRING 1024 -#define FORMAT_MESSAGE_FROM_HMODULE 2048 -#define FORMAT_MESSAGE_FROM_SYSTEM 4096 -#define FORMAT_MESSAGE_ARGUMENT_ARRAY 8192 -#define FORMAT_MESSAGE_MAX_WIDTH_MASK 255 -#define EV_BREAK 64 -#define EV_CTS 8 -#define EV_DSR 16 -#define EV_ERR 128 -#define EV_EVENT1 2048 -#define EV_EVENT2 4096 -#define EV_PERR 512 -#define EV_RING 256 -#define EV_RLSD 32 -#define EV_RX80FULL 1024 -#define EV_RXCHAR 1 -#define EV_RXFLAG 2 -#define EV_TXEMPTY 4 -#define SEM_FAILCRITICALERRORS 1 -#define SEM_NOALIGNMENTFAULTEXCEPT 4 -#define SEM_NOGPFAULTERRORBOX 2 -#define SEM_NOOPENFILEERRORBOX 32768 -#define SLE_ERROR 1 -#define SLE_MINORERROR 2 -#define SLE_WARNING 3 -#define SHUTDOWN_NORETRY 1 -#define EXCEPTION_EXECUTE_HANDLER 1 -#define EXCEPTION_CONTINUE_EXECUTION (-1) -#define EXCEPTION_CONTINUE_SEARCH 0 -#define MAXINTATOM 0xC000 -#define INVALID_ATOM ((ATOM)0) -#define IGNORE 0 -#define INFINITE 0xFFFFFFFF -#define NOPARITY 0 -#define ODDPARITY 1 -#define EVENPARITY 2 -#define MARKPARITY 3 -#define SPACEPARITY 4 -#define ONESTOPBIT 0 -#define ONE5STOPBITS 1 -#define TWOSTOPBITS 2 -#define CBR_110 110 -#define CBR_300 300 -#define CBR_600 600 -#define CBR_1200 1200 -#define CBR_2400 2400 -#define CBR_4800 4800 -#define CBR_9600 9600 -#define CBR_14400 14400 -#define CBR_19200 19200 -#define CBR_38400 38400 -#define CBR_56000 56000 -#define CBR_57600 57600 -#define CBR_115200 115200 -#define CBR_128000 128000 -#define CBR_256000 256000 -#define BACKUP_INVALID 0 -#define BACKUP_DATA 1 -#define BACKUP_EA_DATA 2 -#define BACKUP_SECURITY_DATA 3 -#define BACKUP_ALTERNATE_DATA 4 -#define BACKUP_LINK 5 -#define BACKUP_PROPERTY_DATA 6 -#define BACKUP_OBJECT_ID 7 -#define BACKUP_REPARSE_DATA 8 -#define BACKUP_SPARSE_BLOCK 9 -#define STREAM_NORMAL_ATTRIBUTE 0 -#define STREAM_MODIFIED_WHEN_READ 1 -#define STREAM_CONTAINS_SECURITY 2 -#define STREAM_CONTAINS_PROPERTIES 4 -#define STARTF_USESHOWWINDOW 1 -#define STARTF_USESIZE 2 -#define STARTF_USEPOSITION 4 -#define STARTF_USECOUNTCHARS 8 -#define STARTF_USEFILLATTRIBUTE 16 -#define STARTF_RUNFULLSCREEN 32 -#define STARTF_FORCEONFEEDBACK 64 -#define STARTF_FORCEOFFFEEDBACK 128 -#define STARTF_USESTDHANDLES 256 -#define STARTF_USEHOTKEY 512 -#define TC_NORMAL 0 -#define TC_HARDERR 1 -#define TC_GP_TRAP 2 -#define TC_SIGNAL 3 -#define AC_LINE_OFFLINE 0 -#define AC_LINE_ONLINE 1 -#define AC_LINE_BACKUP_POWER 2 -#define AC_LINE_UNKNOWN 255 -#define BATTERY_FLAG_HIGH 1 -#define BATTERY_FLAG_LOW 2 -#define BATTERY_FLAG_CRITICAL 4 -#define BATTERY_FLAG_CHARGING 8 -#define BATTERY_FLAG_NO_BATTERY 128 -#define BATTERY_FLAG_UNKNOWN 255 -#define BATTERY_PERCENTAGE_UNKNOWN 255 -#define BATTERY_LIFE_UNKNOWN 0xFFFFFFFF -#define DDD_RAW_TARGET_PATH 1 -#define DDD_REMOVE_DEFINITION 2 -#define DDD_EXACT_MATCH_ON_REMOVE 4 -#define HINSTANCE_ERROR 32 -#define MS_CTS_ON 16 -#define MS_DSR_ON 32 -#define MS_RING_ON 64 -#define MS_RLSD_ON 128 -#define PROFILE_USER 0x10000000 -#define PROFILE_KERNEL 0x20000000 -#define PROFILE_SERVER 0x40000000 -#define DTR_CONTROL_DISABLE 0 -#define DTR_CONTROL_ENABLE 1 -#define DTR_CONTROL_HANDSHAKE 2 -#define RTS_CONTROL_DISABLE 0 -#define RTS_CONTROL_ENABLE 1 -#define RTS_CONTROL_HANDSHAKE 2 -#define RTS_CONTROL_TOGGLE 3 -#define SECURITY_ANONYMOUS (SecurityAnonymous<<16) -#define SECURITY_IDENTIFICATION (SecurityIdentification<<16) -#define SECURITY_IMPERSONATION (SecurityImpersonation<<16) -#define SECURITY_DELEGATION (SecurityDelegation<<16) -#define SECURITY_CONTEXT_TRACKING 0x40000 -#define SECURITY_EFFECTIVE_ONLY 0x80000 -#define SECURITY_SQOS_PRESENT 0x100000 -#define SECURITY_VALID_SQOS_FLAGS 0x1F0000 -#define INVALID_FILE_SIZE 0xFFFFFFFF -#define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF -#ifndef RC_INVOKED -typedef struct _FILETIME { - DWORD dwLowDateTime; - DWORD dwHighDateTime; -} FILETIME,*PFILETIME,*LPFILETIME; -typedef struct _BY_HANDLE_FILE_INFORMATION { - DWORD dwFileAttributes; - FILETIME ftCreationTime; - FILETIME ftLastAccessTime; - FILETIME ftLastWriteTime; - DWORD dwVolumeSerialNumber; - DWORD nFileSizeHigh; - DWORD nFileSizeLow; - DWORD nNumberOfLinks; - DWORD nFileIndexHigh; - DWORD nFileIndexLow; -} BY_HANDLE_FILE_INFORMATION,*LPBY_HANDLE_FILE_INFORMATION; -typedef struct _DCB { - DWORD DCBlength; - DWORD BaudRate; - DWORD fBinary:1; - DWORD fParity:1; - DWORD fOutxCtsFlow:1; - DWORD fOutxDsrFlow:1; - DWORD fDtrControl:2; - DWORD fDsrSensitivity:1; - DWORD fTXContinueOnXoff:1; - DWORD fOutX:1; - DWORD fInX:1; - DWORD fErrorChar:1; - DWORD fNull:1; - DWORD fRtsControl:2; - DWORD fAbortOnError:1; - DWORD fDummy2:17; - WORD wReserved; - WORD XonLim; - WORD XoffLim; - BYTE ByteSize; - BYTE Parity; - BYTE StopBits; - char XonChar; - char XoffChar; - char ErrorChar; - char EofChar; - char EvtChar; - WORD wReserved1; -} DCB,*LPDCB; -typedef struct _COMM_CONFIG { - DWORD dwSize; - WORD wVersion; - WORD wReserved; - DCB dcb; - DWORD dwProviderSubType; - DWORD dwProviderOffset; - DWORD dwProviderSize; - WCHAR wcProviderData[1]; -} COMMCONFIG,*LPCOMMCONFIG; -typedef struct _COMMPROP { - WORD wPacketLength; - WORD wPacketVersion; - DWORD dwServiceMask; - DWORD dwReserved1; - DWORD dwMaxTxQueue; - DWORD dwMaxRxQueue; - DWORD dwMaxBaud; - DWORD dwProvSubType; - DWORD dwProvCapabilities; - DWORD dwSettableParams; - DWORD dwSettableBaud; - WORD wSettableData; - WORD wSettableStopParity; - DWORD dwCurrentTxQueue; - DWORD dwCurrentRxQueue; - DWORD dwProvSpec1; - DWORD dwProvSpec2; - WCHAR wcProvChar[1]; -} COMMPROP,*LPCOMMPROP; -typedef struct _COMMTIMEOUTS { - DWORD ReadIntervalTimeout; - DWORD ReadTotalTimeoutMultiplier; - DWORD ReadTotalTimeoutConstant; - DWORD WriteTotalTimeoutMultiplier; - DWORD WriteTotalTimeoutConstant; -} COMMTIMEOUTS,*LPCOMMTIMEOUTS; -typedef struct _COMSTAT { - DWORD fCtsHold:1; - DWORD fDsrHold:1; - DWORD fRlsdHold:1; - DWORD fXoffHold:1; - DWORD fXoffSent:1; - DWORD fEof:1; - DWORD fTxim:1; - DWORD fReserved:25; - DWORD cbInQue; - DWORD cbOutQue; -} COMSTAT,*LPCOMSTAT; -typedef DWORD (WINAPI *LPTHREAD_START_ROUTINE)(LPVOID); -typedef struct _CREATE_PROCESS_DEBUG_INFO { - HANDLE hFile; - HANDLE hProcess; - HANDLE hThread; - LPVOID lpBaseOfImage; - DWORD dwDebugInfoFileOffset; - DWORD nDebugInfoSize; - LPVOID lpThreadLocalBase; - LPTHREAD_START_ROUTINE lpStartAddress; - LPVOID lpImageName; - WORD fUnicode; -} CREATE_PROCESS_DEBUG_INFO,*LPCREATE_PROCESS_DEBUG_INFO; -typedef struct _CREATE_THREAD_DEBUG_INFO { - HANDLE hThread; - LPVOID lpThreadLocalBase; - LPTHREAD_START_ROUTINE lpStartAddress; -} CREATE_THREAD_DEBUG_INFO,*LPCREATE_THREAD_DEBUG_INFO; -typedef struct _EXCEPTION_DEBUG_INFO { - EXCEPTION_RECORD ExceptionRecord; - DWORD dwFirstChance; -} EXCEPTION_DEBUG_INFO,*LPEXCEPTION_DEBUG_INFO; -typedef struct _EXIT_THREAD_DEBUG_INFO { - DWORD dwExitCode; -} EXIT_THREAD_DEBUG_INFO,*LPEXIT_THREAD_DEBUG_INFO; -typedef struct _EXIT_PROCESS_DEBUG_INFO { - DWORD dwExitCode; -} EXIT_PROCESS_DEBUG_INFO,*LPEXIT_PROCESS_DEBUG_INFO; -typedef struct _LOAD_DLL_DEBUG_INFO { - HANDLE hFile; - LPVOID lpBaseOfDll; - DWORD dwDebugInfoFileOffset; - DWORD nDebugInfoSize; - LPVOID lpImageName; - WORD fUnicode; -} LOAD_DLL_DEBUG_INFO,*LPLOAD_DLL_DEBUG_INFO; -typedef struct _UNLOAD_DLL_DEBUG_INFO { - LPVOID lpBaseOfDll; -} UNLOAD_DLL_DEBUG_INFO,*LPUNLOAD_DLL_DEBUG_INFO; -typedef struct _OUTPUT_DEBUG_STRING_INFO { - LPSTR lpDebugStringData; - WORD fUnicode; - WORD nDebugStringLength; -} OUTPUT_DEBUG_STRING_INFO,*LPOUTPUT_DEBUG_STRING_INFO; -typedef struct _RIP_INFO { - DWORD dwError; - DWORD dwType; -} RIP_INFO,*LPRIP_INFO; -typedef struct _DEBUG_EVENT { - DWORD dwDebugEventCode; - DWORD dwProcessId; - DWORD dwThreadId; - union { - EXCEPTION_DEBUG_INFO Exception; - CREATE_THREAD_DEBUG_INFO CreateThread; - CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; - EXIT_THREAD_DEBUG_INFO ExitThread; - EXIT_PROCESS_DEBUG_INFO ExitProcess; - LOAD_DLL_DEBUG_INFO LoadDll; - UNLOAD_DLL_DEBUG_INFO UnloadDll; - OUTPUT_DEBUG_STRING_INFO DebugString; - RIP_INFO RipInfo; - } u; -} DEBUG_EVENT,*LPDEBUG_EVENT; -typedef struct _OVERLAPPED { - DWORD Internal; - DWORD InternalHigh; - DWORD Offset; - DWORD OffsetHigh; - HANDLE hEvent; -} OVERLAPPED,*POVERLAPPED,*LPOVERLAPPED; -typedef struct _STARTUPINFOA { - DWORD cb; - LPSTR lpReserved; - LPSTR lpDesktop; - LPSTR lpTitle; - DWORD dwX; - DWORD dwY; - DWORD dwXSize; - DWORD dwYSize; - DWORD dwXCountChars; - DWORD dwYCountChars; - DWORD dwFillAttribute; - DWORD dwFlags; - WORD wShowWindow; - WORD cbReserved2; - PBYTE lpReserved2; - HANDLE hStdInput; - HANDLE hStdOutput; - HANDLE hStdError; -} STARTUPINFOA,*LPSTARTUPINFOA; -typedef struct _STARTUPINFOW { - DWORD cb; - LPWSTR lpReserved; - LPWSTR lpDesktop; - LPWSTR lpTitle; - DWORD dwX; - DWORD dwY; - DWORD dwXSize; - DWORD dwYSize; - DWORD dwXCountChars; - DWORD dwYCountChars; - DWORD dwFillAttribute; - DWORD dwFlags; - WORD wShowWindow; - WORD cbReserved2; - PBYTE lpReserved2; - HANDLE hStdInput; - HANDLE hStdOutput; - HANDLE hStdError; -} STARTUPINFOW,*LPSTARTUPINFOW; -typedef struct _PROCESS_INFORMATION { - HANDLE hProcess; - HANDLE hThread; - DWORD dwProcessId; - DWORD dwThreadId; -} PROCESS_INFORMATION,*LPPROCESS_INFORMATION; -typedef struct _CRITICAL_SECTION_DEBUG { - WORD Type; - WORD CreatorBackTraceIndex; - struct _CRITICAL_SECTION *CriticalSection; - LIST_ENTRY ProcessLocksList; - DWORD EntryCount; - DWORD ContentionCount; - DWORD Spare [2]; -} CRITICAL_SECTION_DEBUG,*PCRITICAL_SECTION_DEBUG; -typedef struct _CRITICAL_SECTION { - PCRITICAL_SECTION_DEBUG DebugInfo; - LONG LockCount; - LONG RecursionCount; - HANDLE OwningThread; - HANDLE LockSemaphore; - DWORD SpinCount; -} CRITICAL_SECTION,*PCRITICAL_SECTION,*LPCRITICAL_SECTION; -typedef struct _SYSTEMTIME { - WORD wYear; - WORD wMonth; - WORD wDayOfWeek; - WORD wDay; - WORD wHour; - WORD wMinute; - WORD wSecond; - WORD wMilliseconds; -} SYSTEMTIME,*LPSYSTEMTIME; -typedef struct _WIN32_FILE_ATTRIBUTE_DATA { - DWORD dwFileAttributes; - FILETIME ftCreationTime; - FILETIME ftLastAccessTime; - FILETIME ftLastWriteTime; - DWORD nFileSizeHigh; - DWORD nFileSizeLow; -} WIN32_FILE_ATTRIBUTE_DATA,*LPWIN32_FILE_ATTRIBUTE_DATA; -typedef struct _WIN32_FIND_DATAA { - DWORD dwFileAttributes; - FILETIME ftCreationTime; - FILETIME ftLastAccessTime; - FILETIME ftLastWriteTime; - DWORD nFileSizeHigh; - DWORD nFileSizeLow; - DWORD dwReserved0; - DWORD dwReserved1; - CHAR cFileName[MAX_PATH]; - CHAR cAlternateFileName[14]; -} WIN32_FIND_DATAA,*LPWIN32_FIND_DATAA; -typedef struct _WIN32_FIND_DATAW { - DWORD dwFileAttributes; - FILETIME ftCreationTime; - FILETIME ftLastAccessTime; - FILETIME ftLastWriteTime; - DWORD nFileSizeHigh; - DWORD nFileSizeLow; - DWORD dwReserved0; - DWORD dwReserved1; - WCHAR cFileName[MAX_PATH]; - WCHAR cAlternateFileName[14]; -} WIN32_FIND_DATAW,*LPWIN32_FIND_DATAW; -typedef struct _WIN32_STREAM_ID { - DWORD dwStreamId; - DWORD dwStreamAttributes; - LARGE_INTEGER Size; - DWORD dwStreamNameSize; - WCHAR cStreamName[ANYSIZE_ARRAY]; -} WIN32_STREAM_ID; -typedef enum _FINDEX_INFO_LEVELS { - FindExInfoStandard, - FindExInfoMaxInfoLevel -} FINDEX_INFO_LEVELS; -typedef enum _FINDEX_SEARCH_OPS { - FindExSearchNameMatch, - FindExSearchLimitToDirectories, - FindExSearchLimitToDevices, - FindExSearchMaxSearchOp -} FINDEX_SEARCH_OPS; -typedef enum _ACL_INFORMATION_CLASS { - AclRevisionInformation=1, - AclSizeInformation -} ACL_INFORMATION_CLASS; -typedef struct tagHW_PROFILE_INFOA { - DWORD dwDockInfo; - CHAR szHwProfileGuid[HW_PROFILE_GUIDLEN]; - CHAR szHwProfileName[MAX_PROFILE_LEN]; -} HW_PROFILE_INFOA,*LPHW_PROFILE_INFOA; -typedef struct tagHW_PROFILE_INFOW { - DWORD dwDockInfo; - WCHAR szHwProfileGuid[HW_PROFILE_GUIDLEN]; - WCHAR szHwProfileName[MAX_PROFILE_LEN]; -} HW_PROFILE_INFOW,*LPHW_PROFILE_INFOW; -typedef enum _GET_FILEEX_INFO_LEVELS { - GetFileExInfoStandard, - GetFileExMaxInfoLevel -} GET_FILEEX_INFO_LEVELS; -typedef struct _SYSTEM_INFO { - _ANONYMOUS_UNION union { - DWORD dwOemId; - _ANONYMOUS_STRUCT struct { - WORD wProcessorArchitecture; - WORD wReserved; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME; - DWORD dwPageSize; - PVOID lpMinimumApplicationAddress; - PVOID lpMaximumApplicationAddress; - DWORD dwActiveProcessorMask; - DWORD dwNumberOfProcessors; - DWORD dwProcessorType; - DWORD dwAllocationGranularity; - WORD wProcessorLevel; - WORD wProcessorRevision; -} SYSTEM_INFO,*LPSYSTEM_INFO; -typedef struct _SYSTEM_POWER_STATUS { - BYTE ACLineStatus; - BYTE BatteryFlag; - BYTE BatteryLifePercent; - BYTE Reserved1; - DWORD BatteryLifeTime; - DWORD BatteryFullLifeTime; -} SYSTEM_POWER_STATUS,*LPSYSTEM_POWER_STATUS; -typedef struct _TIME_ZONE_INFORMATION { - LONG Bias; - WCHAR StandardName[32]; - SYSTEMTIME StandardDate; - LONG StandardBias; - WCHAR DaylightName[32]; - SYSTEMTIME DaylightDate; - LONG DaylightBias; -} TIME_ZONE_INFORMATION,*LPTIME_ZONE_INFORMATION; -typedef struct _MEMORYSTATUS { - DWORD dwLength; - DWORD dwMemoryLoad; - DWORD dwTotalPhys; - DWORD dwAvailPhys; - DWORD dwTotalPageFile; - DWORD dwAvailPageFile; - DWORD dwTotalVirtual; - DWORD dwAvailVirtual; -} MEMORYSTATUS,*LPMEMORYSTATUS; -typedef struct _LDT_ENTRY { - WORD LimitLow; - WORD BaseLow; - union { - struct { - BYTE BaseMid; - BYTE Flags1; - BYTE Flags2; - BYTE BaseHi; - } Bytes; - struct { - DWORD BaseMid:8; - DWORD Type:5; - DWORD Dpl:2; - DWORD Pres:1; - DWORD LimitHi:4; - DWORD Sys:1; - DWORD Reserved_0:1; - DWORD Default_Big:1; - DWORD Granularity:1; - DWORD BaseHi:8; - } Bits; - } HighWord; -} LDT_ENTRY,*PLDT_ENTRY,*LPLDT_ENTRY; -typedef struct _PROCESS_HEAP_ENTRY { - PVOID lpData; - DWORD cbData; - BYTE cbOverhead; - BYTE iRegionIndex; - WORD wFlags; - _ANONYMOUS_UNION union { - struct { - HANDLE hMem; - DWORD dwReserved[3]; - } Block; - struct { - DWORD dwCommittedSize; - DWORD dwUnCommittedSize; - LPVOID lpFirstBlock; - LPVOID lpLastBlock; - } Region; - } DUMMYUNIONNAME; -} PROCESS_HEAP_ENTRY,*LPPROCESS_HEAP_ENTRY; -typedef struct _OFSTRUCT { - BYTE cBytes; - BYTE fFixedDisk; - WORD nErrCode; - WORD Reserved1; - WORD Reserved2; - CHAR szPathName[OFS_MAXPATHNAME]; -} OFSTRUCT,*LPOFSTRUCT,*POFSTRUCT; -typedef struct _WIN_CERTIFICATE { - DWORD dwLength; - WORD wRevision; - WORD wCertificateType; - BYTE bCertificate[1]; -} WIN_CERTIFICATE, *LPWIN_CERTIFICATE; - -typedef DWORD(WINAPI *LPPROGRESS_ROUTINE)(LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,DWORD,DWORD,HANDLE,HANDLE,LPVOID); -typedef void(WINAPI *LPFIBER_START_ROUTINE)(PVOID); -typedef BOOL(CALLBACK *ENUMRESLANGPROC)(HMODULE,LPCTSTR,LPCTSTR,WORD,LONG); -typedef BOOL(CALLBACK *ENUMRESNAMEPROC)(HMODULE,LPCTSTR,LPTSTR,LONG); -typedef BOOL(CALLBACK *ENUMRESTYPEPROC)(HMODULE,LPTSTR,LONG); -typedef void(CALLBACK *LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD,DWORD,LPOVERLAPPED); -typedef LONG(CALLBACK *PTOP_LEVEL_EXCEPTION_FILTER)(LPEXCEPTION_POINTERS); -typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER; -typedef void(APIENTRY *PAPCFUNC)(DWORD); -typedef void(CALLBACK *PTIMERAPCROUTINE)(PVOID,DWORD,DWORD); -#define MAKEINTATOM(i) (LPTSTR)((DWORD)((WORD)(i))) -/* Functions */ -#ifndef UNDER_CE -int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPSTR,int); + WINBASEAPI WINBOOL WINAPI Beep(DWORD dwFreq,DWORD dwDuration); + WINBASEAPI int WINAPI MulDiv(int nNumber,int nNumerator,int nDenominator); + WINBASEAPI VOID WINAPI GetSystemTime(LPSYSTEMTIME lpSystemTime); + WINBASEAPI VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime); + WINBASEAPI WINBOOL WINAPI SetSystemTime(CONST SYSTEMTIME *lpSystemTime); + WINBASEAPI VOID WINAPI GetLocalTime(LPSYSTEMTIME lpSystemTime); + WINBASEAPI WINBOOL WINAPI SetLocalTime(CONST SYSTEMTIME *lpSystemTime); + WINBASEAPI VOID WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo); + WINBASEAPI WINBOOL WINAPI SetSystemFileCacheSize(SIZE_T MinimumFileCacheSize,SIZE_T MaximumFileCacheSize,DWORD Flags); + WINBASEAPI WINBOOL WINAPI GetSystemFileCacheSize(PSIZE_T lpMinimumFileCacheSize,PSIZE_T lpMaximumFileCacheSize,PDWORD lpFlags); + WINBASEAPI WINBOOL WINAPI GetSystemRegistryQuota(PDWORD pdwQuotaAllowed,PDWORD pdwQuotaUsed); + WINBOOL WINAPI GetSystemTimes(LPFILETIME lpIdleTime,LPFILETIME lpKernelTime,LPFILETIME lpUserTime); + WINBASEAPI VOID WINAPI GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo); + WINBASEAPI WINBOOL WINAPI IsProcessorFeaturePresent(DWORD ProcessorFeature); + + typedef struct _TIME_ZONE_INFORMATION { + LONG Bias; + WCHAR StandardName[32]; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR DaylightName[32]; + SYSTEMTIME DaylightDate; + LONG DaylightBias; + } TIME_ZONE_INFORMATION,*PTIME_ZONE_INFORMATION,*LPTIME_ZONE_INFORMATION; + +#ifdef UNICODE +#define FormatMessage FormatMessageW #else -int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPWSTR,int); -#endif -int APIENTRY wWinMain(HINSTANCE,HINSTANCE,LPWSTR,int); -long WINAPI _hread(HFILE,LPVOID,long); -long WINAPI _hwrite(HFILE,LPCSTR,long); -HFILE WINAPI _lclose(HFILE); -HFILE WINAPI _lcreat(LPCSTR,int); -LONG WINAPI _llseek(HFILE,LONG,int); -HFILE WINAPI _lopen(LPCSTR,int); -UINT WINAPI _lread(HFILE,LPVOID,UINT); -UINT WINAPI _lwrite(HFILE,LPCSTR,UINT); -#define AbnormalTermination() FALSE -BOOL WINAPI AccessCheck(PSECURITY_DESCRIPTOR,HANDLE,DWORD,PGENERIC_MAPPING,PPRIVILEGE_SET,PDWORD,PDWORD,PBOOL); -BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR,LPVOID,LPSTR,LPSTR,PSECURITY_DESCRIPTOR,DWORD,PGENERIC_MAPPING,BOOL,PDWORD,PBOOL,PBOOL); -BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR,LPVOID,LPWSTR,LPWSTR,PSECURITY_DESCRIPTOR,DWORD,PGENERIC_MAPPING,BOOL,PDWORD,PBOOL,PBOOL); -BOOL WINAPI AddAccessAllowedAce(PACL,DWORD,DWORD,PSID); -BOOL WINAPI AddAccessDeniedAce(PACL,DWORD,DWORD,PSID); -BOOL WINAPI AddAce(PACL,DWORD,DWORD,PVOID,DWORD); -ATOM WINAPI AddAtomA(LPCSTR); -ATOM WINAPI AddAtomW(LPCWSTR); -BOOL WINAPI AddAuditAccessAce(PACL,DWORD,DWORD,PSID,BOOL,BOOL); -BOOL WINAPI AdjustTokenGroups(HANDLE,BOOL,PTOKEN_GROUPS,DWORD,PTOKEN_GROUPS,PDWORD); -BOOL WINAPI AdjustTokenPrivileges(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD); -BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID*); -BOOL WINAPI AllocateLocallyUniqueId(PLUID); -BOOL WINAPI AreAllAccessesGranted(DWORD,DWORD); -BOOL WINAPI AreAnyAccessesGranted(DWORD,DWORD); -BOOL WINAPI AreFileApisANSI(void); -BOOL WINAPI BackupEventLogA(HANDLE,LPCSTR); -BOOL WINAPI BackupEventLogW(HANDLE,LPCWSTR); -BOOL WINAPI BackupRead(HANDLE,PBYTE,DWORD,PDWORD,BOOL,BOOL,PVOID); -BOOL WINAPI BackupSeek(HANDLE,DWORD,DWORD,PDWORD,PDWORD,PVOID); -BOOL WINAPI BackupWrite(HANDLE,PBYTE,DWORD,PDWORD,BOOL,BOOL,PVOID); -BOOL WINAPI Beep(DWORD,DWORD); -HANDLE WINAPI BeginUpdateResourceA(LPCSTR,BOOL); -HANDLE WINAPI BeginUpdateResourceW(LPCWSTR,BOOL); -BOOL WINAPI BuildCommDCBA(LPCSTR,LPDCB); -BOOL WINAPI BuildCommDCBW(LPCWSTR,LPDCB); -BOOL WINAPI BuildCommDCBAndTimeoutsA(LPCSTR,LPDCB,LPCOMMTIMEOUTS); -BOOL WINAPI BuildCommDCBAndTimeoutsW(LPCWSTR,LPDCB,LPCOMMTIMEOUTS); -BOOL WINAPI CallNamedPipeA(LPCSTR,PVOID,DWORD,PVOID,DWORD,PDWORD,DWORD); -BOOL WINAPI CallNamedPipeW(LPCWSTR,PVOID,DWORD,PVOID,DWORD,PDWORD,DWORD); -BOOL WINAPI CancelIo(HANDLE); -BOOL WINAPI CancelWaitableTimer(HANDLE); -BOOL WINAPI ClearCommBreak(HANDLE); -BOOL WINAPI ClearCommError(HANDLE,PDWORD,LPCOMSTAT); -BOOL WINAPI ClearEventLogA(HANDLE,LPCSTR); -BOOL WINAPI ClearEventLogW(HANDLE,LPCWSTR); -BOOL WINAPI CloseEventLog(HANDLE); -BOOL WINAPI CloseHandle(HANDLE); -BOOL WINAPI CommConfigDialogA(LPCSTR,HWND,LPCOMMCONFIG); -BOOL WINAPI CommConfigDialogW(LPCWSTR,HWND,LPCOMMCONFIG); -LONG WINAPI CompareFileTime(CONST FILETIME*,CONST FILETIME*); -BOOL WINAPI ConnectNamedPipe(HANDLE,LPOVERLAPPED); -BOOL WINAPI ContinueDebugEvent(DWORD,DWORD,DWORD); -PVOID WINAPI ConvertThreadToFiber(PVOID); -BOOL WINAPI CopyFileA(LPCSTR,LPCSTR,BOOL); -BOOL WINAPI CopyFileW(LPCWSTR,LPCWSTR,BOOL); -BOOL WINAPI CopyFileExA(LPCSTR,LPCSTR,LPPROGRESS_ROUTINE,LPVOID,LPBOOL,DWORD); -BOOL WINAPI CopyFileExW(LPCWSTR,LPCWSTR,LPPROGRESS_ROUTINE,LPVOID,LPBOOL,DWORD); -#define RtlMoveMemory memmove -#define RtlCopyMemory memcpy -#define RtlFillMemory(d,l,f) memset((d), (f), (l)) -#define RtlZeroMemory(d,l) RtlFillMemory((d),(l),0) -#define MoveMemory RtlMoveMemory -#define CopyMemory RtlCopyMemory -#define FillMemory RtlFillMemory -#define ZeroMemory RtlZeroMemory -BOOL WINAPI CopySid(DWORD,PSID,PSID); -BOOL WINAPI CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES); -BOOL WINAPI CreateDirectoryW(LPCWSTR,LPSECURITY_ATTRIBUTES); -BOOL WINAPI CreateDirectoryExA(LPCSTR,LPCSTR,LPSECURITY_ATTRIBUTES); -BOOL WINAPI CreateDirectoryExW(LPCWSTR,LPCWSTR,LPSECURITY_ATTRIBUTES); -HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR); -HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCWSTR); -LPVOID WINAPI CreateFiber(DWORD,LPFIBER_START_ROUTINE,LPVOID); -HANDLE WINAPI CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE); -HANDLE WINAPI CreateFileW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE); -HANDLE WINAPI CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR); -HANDLE WINAPI CreateFileMappingW(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCWSTR); -HANDLE WINAPI CreateHardLinkA(LPCSTR,LPCSTR,LPSECURITY_ATTRIBUTES); -HANDLE WINAPI CreateHardLinkW(LPCWSTR,LPCWSTR,LPSECURITY_ATTRIBUTES); -HANDLE WINAPI CreateIoCompletionPort(HANDLE,HANDLE,DWORD,DWORD); -HANDLE WINAPI CreateMailslotA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES); -HANDLE WINAPI CreateMailslotW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES); -HANDLE WINAPI CreateMutexA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR); -HANDLE WINAPI CreateMutexW(LPSECURITY_ATTRIBUTES,BOOL,LPCWSTR); -HANDLE WINAPI CreateNamedPipeA(LPCSTR,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,LPSECURITY_ATTRIBUTES); -HANDLE WINAPI CreateNamedPipeW(LPCWSTR,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,LPSECURITY_ATTRIBUTES); -BOOL WINAPI CreatePipe(PHANDLE,PHANDLE,LPSECURITY_ATTRIBUTES,DWORD); -BOOL WINAPI CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR*,BOOL,HANDLE,PGENERIC_MAPPING); -BOOL WINAPI CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION); -BOOL WINAPI CreateProcessW(LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION); -BOOL WINAPI CreateProcessAsUserA(HANDLE,LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION); -BOOL WINAPI CreateProcessAsUserW(HANDLE,LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION); -HANDLE WINAPI CreateRemoteThread(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD); -HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR); -HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR); -DWORD WINAPI CreateTapePartition(HANDLE,DWORD,DWORD,DWORD); -HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,PVOID,DWORD,PDWORD); -HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR); -HANDLE WINAPI CreateWaitableTimerW(LPSECURITY_ATTRIBUTES,BOOL,LPCWSTR); -BOOL WINAPI DebugActiveProcess(DWORD); -void WINAPI DebugBreak(void); -BOOL WINAPI DefineDosDeviceA(DWORD,LPCSTR,LPCSTR); -BOOL WINAPI DefineDosDeviceW(DWORD,LPCWSTR,LPCWSTR); -#define DefineHandleTable(w) ((w),TRUE) -BOOL WINAPI DeleteAce(PACL,DWORD); -ATOM WINAPI DeleteAtom(ATOM); -void WINAPI DeleteCriticalSection(PCRITICAL_SECTION); -void WINAPI DeleteFiber(PVOID); -BOOL WINAPI DeleteFileA(LPCSTR); -BOOL WINAPI DeleteFileW(LPCWSTR); -BOOL WINAPI DeregisterEventSource(HANDLE); -BOOL WINAPI DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR*); -BOOL WINAPI DeviceIoControl(HANDLE,DWORD,PVOID,DWORD,PVOID,DWORD,PDWORD,POVERLAPPED); -BOOL WINAPI DisableThreadLibraryCalls(HMODULE); -BOOL WINAPI DisconnectNamedPipe(HANDLE); -BOOL WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME); -BOOL WINAPI DuplicateHandle(HANDLE,HANDLE,HANDLE,PHANDLE,DWORD,BOOL,DWORD); -BOOL WINAPI DuplicateToken(HANDLE,SECURITY_IMPERSONATION_LEVEL,PHANDLE); -BOOL WINAPI DuplicateTokenEx(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE); -BOOL WINAPI EndUpdateResourceA(HANDLE,BOOL); -BOOL WINAPI EndUpdateResourceW(HANDLE,BOOL); -void WINAPI EnterCriticalSection(LPCRITICAL_SECTION); -BOOL WINAPI EnumResourceLanguagesA(HINSTANCE,LPCSTR,LPCSTR,ENUMRESLANGPROC,LONG); -BOOL WINAPI EnumResourceLanguagesW(HINSTANCE,LPCWSTR,LPCWSTR,ENUMRESLANGPROC,LONG); -BOOL WINAPI EnumResourceNamesA(HINSTANCE,LPCSTR,ENUMRESNAMEPROC,LONG); -BOOL WINAPI EnumResourceNamesW(HINSTANCE,LPCWSTR,ENUMRESNAMEPROC,LONG); -BOOL WINAPI EnumResourceTypesA(HINSTANCE,ENUMRESTYPEPROC,LONG); -BOOL WINAPI EnumResourceTypesW(HINSTANCE,ENUMRESTYPEPROC,LONG); -BOOL WINAPI EqualPrefixSid(PSID,PSID); -BOOL WINAPI EqualSid(PSID,PSID); -DWORD WINAPI EraseTape(HANDLE,DWORD,BOOL); -BOOL WINAPI EscapeCommFunction(HANDLE,DWORD); -DECLSPEC_NORETURN void WINAPI ExitProcess(UINT); -DECLSPEC_NORETURN void WINAPI ExitThread(DWORD); -DWORD WINAPI ExpandEnvironmentStringsA(LPCSTR,LPSTR,DWORD); -DWORD WINAPI ExpandEnvironmentStringsW(LPCWSTR,LPWSTR,DWORD); -void WINAPI FatalAppExitA(UINT,LPCSTR); -void WINAPI FatalAppExitW(UINT,LPCWSTR); -void WINAPI FatalExit(int); -BOOL WINAPI FileTimeToDosDateTime(CONST FILETIME *,LPWORD,LPWORD); -BOOL WINAPI FileTimeToLocalFileTime(FILETIME *,LPFILETIME); -BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *,LPSYSTEMTIME); -ATOM WINAPI FindAtomA(LPCSTR); -ATOM WINAPI FindAtomW(LPCWSTR); -BOOL WINAPI FindClose(HANDLE); -BOOL WINAPI FindCloseChangeNotification(HANDLE); -HANDLE WINAPI FindFirstChangeNotificationA(LPCSTR,BOOL,DWORD); -HANDLE WINAPI FindFirstChangeNotificationW(LPCWSTR,BOOL,DWORD); -HANDLE WINAPI FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA); -HANDLE WINAPI FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW); -HANDLE WINAPI FindFirstFileExA(LPCSTR,FINDEX_INFO_LEVELS,PVOID,FINDEX_SEARCH_OPS,PVOID,DWORD); -HANDLE WINAPI FindFirstFileExW(LPCWSTR,FINDEX_INFO_LEVELS,PVOID,FINDEX_SEARCH_OPS,PVOID,DWORD); -BOOL WINAPI FindFirstFreeAce(PACL,PVOID*); -BOOL WINAPI FindNextChangeNotification(HANDLE); -BOOL WINAPI FindNextFileA(HANDLE,LPWIN32_FIND_DATAA); -BOOL WINAPI FindNextFileW(HANDLE,LPWIN32_FIND_DATAW); -HRSRC WINAPI FindResourceA(HMODULE,LPCSTR,LPCSTR); -HRSRC WINAPI FindResourceW(HINSTANCE,LPCWSTR,LPCWSTR); -HRSRC WINAPI FindResourceExA(HINSTANCE,LPCSTR,LPCSTR,WORD); -HRSRC WINAPI FindResourceExW(HINSTANCE,LPCWSTR,LPCWSTR,WORD); -BOOL WINAPI FlushFileBuffers(HANDLE); -BOOL WINAPI FlushInstructionCache(HANDLE,PCVOID,DWORD); -BOOL WINAPI FlushViewOfFile(PCVOID,DWORD); -DWORD WINAPI FormatMessageA(DWORD,PCVOID,DWORD,DWORD,LPSTR,DWORD,va_list*); -DWORD WINAPI FormatMessageW(DWORD,PCVOID,DWORD,DWORD,LPWSTR,DWORD,va_list*); -BOOL WINAPI FreeEnvironmentStringsA(LPSTR); -BOOL WINAPI FreeEnvironmentStringsW(LPWSTR); -BOOL WINAPI FreeLibrary(HMODULE); -DECLSPEC_NORETURN void WINAPI FreeLibraryAndExitThread(HMODULE,DWORD); -#define FreeModule(m) FreeLibrary(m) -#define FreeProcInstance(p) (void)(p) -#ifndef XFree86Server -BOOL WINAPI FreeResource(HGLOBAL); -#endif /* ndef XFree86Server */ -PVOID WINAPI FreeSid(PSID); -BOOL WINAPI GetAce(PACL,DWORD,PVOID); -BOOL WINAPI GetAclInformation(PACL,PVOID,DWORD,ACL_INFORMATION_CLASS); -UINT WINAPI GetAtomNameA(ATOM,LPSTR,int); -UINT WINAPI GetAtomNameW(ATOM,LPWSTR,int); -BOOL WINAPI GetBinaryTypeA(LPCSTR,PDWORD); -BOOL WINAPI GetBinaryTypeW(LPCWSTR,PDWORD); -LPSTR WINAPI GetCommandLineA(VOID); -LPWSTR WINAPI GetCommandLineW(VOID); -BOOL WINAPI GetCommConfig(HANDLE,LPCOMMCONFIG,PDWORD); -BOOL WINAPI GetCommMask(HANDLE,PDWORD); -BOOL WINAPI GetCommModemStatus(HANDLE,PDWORD); -BOOL WINAPI GetCommProperties(HANDLE,LPCOMMPROP); -BOOL WINAPI GetCommState(HANDLE,LPDCB); -BOOL WINAPI GetCommTimeouts(HANDLE,LPCOMMTIMEOUTS); -DWORD WINAPI GetCompressedFileSizeA(LPCSTR,PDWORD); -DWORD WINAPI GetCompressedFileSizeW(LPCWSTR,PDWORD); -BOOL WINAPI GetComputerNameA(LPSTR,PDWORD); -BOOL WINAPI GetComputerNameW(LPWSTR,PDWORD); -DWORD WINAPI GetCurrentDirectoryA(DWORD,LPSTR); -DWORD WINAPI GetCurrentDirectoryW(DWORD,LPWSTR); -BOOL WINAPI GetCurrentHwProfileA(LPHW_PROFILE_INFOA); -BOOL WINAPI GetCurrentHwProfileW(LPHW_PROFILE_INFOW); -HANDLE WINAPI GetCurrentProcess(void); -DWORD WINAPI GetCurrentProcessId(void); -HANDLE WINAPI GetCurrentThread(void); -DWORD WINAPI GetCurrentThreadId(void); -#define GetCurrentTime GetTickCount -BOOL WINAPI GetDefaultCommConfigA(LPCSTR,LPCOMMCONFIG,PDWORD); -BOOL WINAPI GetDefaultCommConfigW(LPCWSTR,LPCOMMCONFIG,PDWORD); -BOOL WINAPI GetDiskFreeSpaceA(LPCSTR,PDWORD,PDWORD,PDWORD,PDWORD); -BOOL WINAPI GetDiskFreeSpaceW(LPCWSTR,PDWORD,PDWORD,PDWORD,PDWORD); -BOOL WINAPI GetDiskFreeSpaceExA(LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); -BOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); -UINT WINAPI GetDriveTypeA(LPCSTR); -UINT WINAPI GetDriveTypeW(LPCWSTR); -LPSTR WINAPI GetEnvironmentStrings(void); -LPSTR WINAPI GetEnvironmentStringsA(void); -LPWSTR WINAPI GetEnvironmentStringsW(void); -DWORD WINAPI GetEnvironmentVariableA(LPCSTR,LPSTR,DWORD); -DWORD WINAPI GetEnvironmentVariableW(LPCWSTR,LPWSTR,DWORD); -BOOL WINAPI GetExitCodeProcess(HANDLE,PDWORD); -BOOL WINAPI GetExitCodeThread(HANDLE,PDWORD); -DWORD WINAPI GetFileAttributesA(LPCSTR); -DWORD WINAPI GetFileAttributesW(LPCWSTR); -BOOL WINAPI GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,PVOID); -BOOL WINAPI GetFileAttributesExW(LPCWSTR,GET_FILEEX_INFO_LEVELS,PVOID); -BOOL WINAPI GetFileInformationByHandle(HANDLE,LPBY_HANDLE_FILE_INFORMATION); -BOOL WINAPI GetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD); -BOOL WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD); -DWORD WINAPI GetFileSize(HANDLE,PDWORD); -BOOL WINAPI GetFileTime(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME); -DWORD WINAPI GetFileType(HANDLE); -#define GetFreeSpace(w) (0x100000L) -DWORD WINAPI GetFullPathNameA(LPCSTR,DWORD,LPSTR,LPSTR*); -DWORD WINAPI GetFullPathNameW(LPCWSTR,DWORD,LPWSTR,LPWSTR*); -BOOL WINAPI GetHandleInformation(HANDLE,PDWORD); -BOOL WINAPI GetKernelObjectSecurity(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD); -DWORD WINAPI GetLengthSid(PSID); -void WINAPI GetLocalTime(LPSYSTEMTIME); -DWORD WINAPI GetLogicalDrives(void); -DWORD WINAPI GetLogicalDriveStringsA(DWORD,LPSTR); -DWORD WINAPI GetLogicalDriveStringsW(DWORD,LPWSTR); -DWORD WINAPI GetLongPathNameA(LPCSTR,LPSTR,DWORD); -DWORD WINAPI GetLongPathNameW(LPCWSTR,LPWSTR,DWORD); -BOOL WINAPI GetMailslotInfo(HANDLE,PDWORD,PDWORD,PDWORD,PDWORD); -DWORD WINAPI GetModuleFileNameA(HINSTANCE,LPSTR,DWORD); -DWORD WINAPI GetModuleFileNameW(HINSTANCE,LPWSTR,DWORD); -HMODULE WINAPI GetModuleHandleA(LPCSTR); -HMODULE WINAPI GetModuleHandleW(LPCWSTR); -BOOL WINAPI GetNamedPipeHandleStateA(HANDLE,PDWORD,PDWORD,PDWORD,PDWORD,LPSTR,DWORD); -BOOL WINAPI GetNamedPipeHandleStateW(HANDLE,PDWORD,PDWORD,PDWORD,PDWORD,LPWSTR,DWORD); -BOOL WINAPI GetNamedPipeInfo(HANDLE,PDWORD,PDWORD,PDWORD,PDWORD); -BOOL WINAPI GetNumberOfEventLogRecords(HANDLE,PDWORD); -BOOL WINAPI GetOldestEventLogRecord(HANDLE,PDWORD); -BOOL WINAPI GetOverlappedResult(HANDLE,LPOVERLAPPED,PDWORD,BOOL); -DWORD WINAPI GetPriorityClass(HANDLE); -BOOL WINAPI GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD); -UINT WINAPI GetPrivateProfileIntA(LPCSTR,LPCSTR,INT,LPCSTR); -UINT WINAPI GetPrivateProfileIntW(LPCWSTR,LPCWSTR,INT,LPCWSTR); -DWORD WINAPI GetPrivateProfileSectionA(LPCSTR,LPSTR,DWORD,LPCSTR); -DWORD WINAPI GetPrivateProfileSectionW(LPCWSTR,LPWSTR,DWORD,LPCWSTR); -DWORD WINAPI GetPrivateProfileSectionNamesA(LPSTR,DWORD,LPCSTR); -DWORD WINAPI GetPrivateProfileSectionNamesW(LPWSTR,DWORD,LPCWSTR); -DWORD WINAPI GetPrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,DWORD,LPCSTR); -DWORD WINAPI GetPrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,DWORD,LPCWSTR); -BOOL WINAPI GetPrivateProfileStructA(LPCSTR,LPCSTR,PVOID,UINT,LPCSTR); -BOOL WINAPI GetPrivateProfileStructW(LPCWSTR,LPCWSTR,PVOID,UINT,LPCWSTR); -FARPROC WINAPI GetProcAddress(HINSTANCE,LPCSTR); -BOOL WINAPI GetProcessAffinityMask(HANDLE,PDWORD,PDWORD); -HANDLE WINAPI GetProcessHeap(VOID); -DWORD WINAPI GetProcessHeaps(DWORD,PHANDLE); -BOOL WINAPI GetProcessPriorityBoost(HANDLE,PBOOL); -BOOL WINAPI GetProcessShutdownParameters(PDWORD,PDWORD); -BOOL WINAPI GetProcessTimes(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME); -DWORD WINAPI GetProcessVersion(DWORD); -HWINSTA WINAPI GetProcessWindowStation(void); -BOOL WINAPI GetProcessWorkingSetSize(HANDLE,PDWORD,PDWORD); -UINT WINAPI GetProfileIntA(LPCSTR,LPCSTR,INT); -UINT WINAPI GetProfileIntW(LPCWSTR,LPCWSTR,INT); -DWORD WINAPI GetProfileSectionA(LPCSTR,LPSTR,DWORD); -DWORD WINAPI GetProfileSectionW(LPCWSTR,LPWSTR,DWORD); -DWORD WINAPI GetProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,DWORD); -DWORD WINAPI GetProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,DWORD); -BOOL WINAPI GetQueuedCompletionStatus(HANDLE,PDWORD,PDWORD,LPOVERLAPPED*,DWORD); -BOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR_CONTROL,PDWORD); -BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,LPBOOL,PACL*,LPBOOL); -BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID*,LPBOOL); -DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR); -BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID*,LPBOOL); -BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,LPBOOL,PACL*,LPBOOL); -DWORD WINAPI GetShortPathNameA(LPCSTR,LPSTR,DWORD); -DWORD WINAPI GetShortPathNameW(LPCWSTR,LPWSTR,DWORD); -PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(PSID); -DWORD WINAPI GetSidLengthRequired(UCHAR); -PDWORD WINAPI GetSidSubAuthority(PSID,DWORD); -PUCHAR WINAPI GetSidSubAuthorityCount(PSID); -VOID WINAPI GetStartupInfoA(LPSTARTUPINFOA); -VOID WINAPI GetStartupInfoW(LPSTARTUPINFOW); -HANDLE WINAPI GetStdHandle(DWORD); -UINT WINAPI GetSystemDirectoryA(LPSTR,UINT); -UINT WINAPI GetSystemDirectoryW(LPWSTR,UINT); -VOID WINAPI GetSystemInfo(LPSYSTEM_INFO); -BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS); -VOID WINAPI GetSystemTime(LPSYSTEMTIME); -BOOL WINAPI GetSystemTimeAdjustment(PDWORD,PDWORD,PBOOL); -void WINAPI GetSystemTimeAsFileTime(LPFILETIME); -DWORD WINAPI GetTapeParameters(HANDLE,DWORD,PDWORD,PVOID); -DWORD WINAPI GetTapePosition(HANDLE,DWORD,PDWORD,PDWORD,PDWORD); -DWORD WINAPI GetTapeStatus(HANDLE); -UINT WINAPI GetTempFileNameA(LPCSTR,LPCSTR,UINT,LPSTR); -UINT WINAPI GetTempFileNameW(LPCWSTR,LPCWSTR,UINT,LPWSTR); -DWORD WINAPI GetTempPathA(DWORD,LPSTR); -DWORD WINAPI GetTempPathW(DWORD,LPWSTR); -BOOL WINAPI GetThreadContext(HANDLE,LPCONTEXT); -int WINAPI GetThreadPriority(HANDLE); -BOOL WINAPI GetThreadPriorityBoost(HANDLE,PBOOL); -BOOL WINAPI GetThreadSelectorEntry(HANDLE,DWORD,LPLDT_ENTRY); -BOOL WINAPI GetThreadTimes(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME); -DWORD WINAPI GetTickCount(void); -DWORD WINAPI GetTimeZoneInformation(LPTIME_ZONE_INFORMATION); -BOOL WINAPI GetTokenInformation(HANDLE,TOKEN_INFORMATION_CLASS,PVOID,DWORD,PDWORD); -BOOL WINAPI GetUserNameA (LPSTR,PDWORD); -BOOL WINAPI GetUserNameW(LPWSTR,PDWORD); -DWORD WINAPI GetVersion(void); -BOOL WINAPI GetVersionExA(LPOSVERSIONINFOA); -BOOL WINAPI GetVersionExW(LPOSVERSIONINFOW); -BOOL WINAPI GetVolumeInformationA(LPCSTR,LPSTR,DWORD,PDWORD,PDWORD,PDWORD,LPSTR,DWORD); -BOOL WINAPI GetVolumeInformationW(LPCWSTR,LPWSTR,DWORD,PDWORD,PDWORD,PDWORD,LPWSTR,DWORD); -UINT WINAPI GetWindowsDirectoryA(LPSTR,UINT); -UINT WINAPI GetWindowsDirectoryW(LPWSTR,UINT); -DWORD WINAPI GetWindowThreadProcessId(HWND,PDWORD); -ATOM WINAPI GlobalAddAtomA(LPCSTR); -ATOM WINAPI GlobalAddAtomW( LPCWSTR); -HGLOBAL WINAPI GlobalAlloc(UINT,DWORD); -UINT WINAPI GlobalCompact(DWORD); -ATOM WINAPI GlobalDeleteAtom(ATOM); -HGLOBAL GlobalDiscard(HGLOBAL); -ATOM WINAPI GlobalFindAtomA(LPCSTR); -ATOM WINAPI GlobalFindAtomW(LPCWSTR); -VOID WINAPI GlobalFix(HGLOBAL); -UINT WINAPI GlobalFlags(HGLOBAL); -HGLOBAL WINAPI GlobalFree(HGLOBAL); -UINT WINAPI GlobalGetAtomNameA(ATOM,LPSTR,int); -UINT WINAPI GlobalGetAtomNameW(ATOM,LPWSTR,int); -HGLOBAL WINAPI GlobalHandle(PCVOID); -LPVOID WINAPI GlobalLock(HGLOBAL); -VOID WINAPI GlobalMemoryStatus(LPMEMORYSTATUS); -HGLOBAL WINAPI GlobalReAlloc(HGLOBAL,DWORD,UINT); -DWORD WINAPI GlobalSize(HGLOBAL); -VOID WINAPI GlobalUnfix(HGLOBAL); -BOOL WINAPI GlobalUnlock(HGLOBAL); -BOOL WINAPI GlobalUnWire(HGLOBAL); -PVOID WINAPI GlobalWire(HGLOBAL); -#define HasOverlappedIoCompleted(lpOverlapped) ((lpOverlapped)->Internal != STATUS_PENDING) -PVOID WINAPI HeapAlloc(HANDLE,DWORD,DWORD); -UINT WINAPI HeapCompact(HANDLE,DWORD); -HANDLE WINAPI HeapCreate(DWORD,DWORD,DWORD); -BOOL WINAPI HeapDestroy(HANDLE); -BOOL WINAPI HeapFree(HANDLE,DWORD,PVOID); -BOOL WINAPI HeapLock(HANDLE); -PVOID WINAPI HeapReAlloc(HANDLE,DWORD,PVOID,DWORD); -DWORD WINAPI HeapSize(HANDLE,DWORD,PCVOID); -BOOL WINAPI HeapUnlock(HANDLE); -BOOL WINAPI HeapValidate(HANDLE,DWORD,PCVOID); -BOOL WINAPI HeapWalk(HANDLE,LPPROCESS_HEAP_ENTRY); -BOOL WINAPI ImpersonateLoggedOnUser(HANDLE); -BOOL WINAPI ImpersonateNamedPipeClient(HANDLE); -BOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL); -BOOL WINAPI InitAtomTable(DWORD); -BOOL WINAPI InitializeAcl(PACL,DWORD,DWORD); -VOID WINAPI InitializeCriticalSection(LPCRITICAL_SECTION); -#if (_WIN32_WINNT >= 0x0403) /* Needs NT4, SP3 or later. */ -BOOL WINAPI InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION,DWORD); -DWORD WINAPI SetCriticalSectionSpinCount(LPCRITICAL_SECTION,DWORD); +#define FormatMessage FormatMessageA #endif -BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD); -BOOL WINAPI InitializeSid (PSID,PSID_IDENTIFIER_AUTHORITY,BYTE); -LONG WINAPI InterlockedCompareExchange(LPLONG,LONG,LONG); -/* PVOID WINAPI InterlockedCompareExchangePointer(PVOID*,PVOID,PVOID); */ -#define InterlockedCompareExchangePointer(d,e,c) \ - (PVOID)InterlockedCompareExchange((LPLONG)(d),(LONG)(e),(LONG)(c)) -LONG WINAPI InterlockedDecrement(LPLONG); -LONG WINAPI InterlockedExchange(LPLONG,LONG); -/* PVOID WINAPI InterlockedExchangePointer(PVOID*,PVOID); */ -#define InterlockedExchangePointer(t,v) \ - (PVOID)InterlockedExchange((LPLONG)(t),(LONG)(v)) -LONG WINAPI InterlockedExchangeAdd(PLONG,LONG); -LONG WINAPI InterlockedIncrement(LPLONG); -BOOL WINAPI IsBadCodePtr(FARPROC); -BOOL WINAPI IsBadHugeReadPtr(PCVOID,UINT); -BOOL WINAPI IsBadHugeWritePtr(PVOID,UINT); -BOOL WINAPI IsBadReadPtr(PCVOID,UINT); -BOOL WINAPI IsBadStringPtrA(LPCSTR,UINT); -BOOL WINAPI IsBadStringPtrW(LPCWSTR,UINT); -BOOL WINAPI IsBadWritePtr(PVOID,UINT); -BOOL WINAPI IsDebuggerPresent(void); -BOOL WINAPI IsProcessorFeaturePresent(DWORD); -BOOL WINAPI IsTextUnicode(PCVOID,int,LPINT); -BOOL WINAPI IsValidAcl(PACL); -BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR); -BOOL WINAPI IsValidSid(PSID); -void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION); -#define LimitEmsPages(n) -HINSTANCE WINAPI LoadLibraryA(LPCSTR); -HINSTANCE WINAPI LoadLibraryExA(LPCSTR,HANDLE,DWORD); -HINSTANCE WINAPI LoadLibraryExW(LPCWSTR,HANDLE,DWORD); -HINSTANCE WINAPI LoadLibraryW(LPCWSTR); -DWORD WINAPI LoadModule(LPCSTR,PVOID); -HGLOBAL WINAPI LoadResource(HINSTANCE,HRSRC); -HLOCAL WINAPI LocalAlloc(UINT,UINT); -UINT WINAPI LocalCompact(UINT); -HLOCAL LocalDiscard(HLOCAL); -BOOL WINAPI LocalFileTimeToFileTime(CONST FILETIME *,LPFILETIME); -UINT WINAPI LocalFlags(HLOCAL); -HLOCAL WINAPI LocalFree(HLOCAL); -HLOCAL WINAPI LocalHandle(LPCVOID); -PVOID WINAPI LocalLock(HLOCAL); -HLOCAL WINAPI LocalReAlloc(HLOCAL,UINT,UINT); -UINT WINAPI LocalShrink(HLOCAL,UINT); -UINT WINAPI LocalSize(HLOCAL); -BOOL WINAPI LocalUnlock(HLOCAL); -BOOL WINAPI LockFile(HANDLE,DWORD,DWORD,DWORD,DWORD); -BOOL WINAPI LockFileEx(HANDLE,DWORD,DWORD,DWORD,DWORD,LPOVERLAPPED); -PVOID WINAPI LockResource(HGLOBAL); -#define LockSegment(w) GlobalFix((HANDLE)(w)) -BOOL WINAPI LogonUserA(LPSTR,LPSTR,LPSTR,DWORD,DWORD,PHANDLE); -BOOL WINAPI LogonUserW(LPWSTR,LPWSTR,LPWSTR,DWORD,DWORD,PHANDLE); -BOOL WINAPI LookupAccountNameA(LPCSTR,LPCSTR,PSID,PDWORD,LPSTR,PDWORD,PSID_NAME_USE); -BOOL WINAPI LookupAccountNameW(LPCWSTR,LPCWSTR,PSID,PDWORD,LPWSTR,PDWORD,PSID_NAME_USE); -BOOL WINAPI LookupAccountSidA(LPCSTR,PSID,LPSTR,PDWORD,LPSTR,PDWORD,PSID_NAME_USE); -BOOL WINAPI LookupAccountSidW(LPCWSTR,PSID,LPWSTR,PDWORD,LPWSTR,PDWORD,PSID_NAME_USE); -BOOL WINAPI LookupPrivilegeDisplayNameA(LPCSTR,LPCSTR,LPSTR,PDWORD,PDWORD); -BOOL WINAPI LookupPrivilegeDisplayNameW(LPCWSTR,LPCWSTR,LPWSTR,PDWORD,PDWORD); -BOOL WINAPI LookupPrivilegeNameA(LPCSTR,PLUID,LPSTR,PDWORD); -BOOL WINAPI LookupPrivilegeNameW(LPCWSTR,PLUID,LPWSTR,PDWORD); -BOOL WINAPI LookupPrivilegeValueA(LPCSTR,LPCSTR,PLUID); -BOOL WINAPI LookupPrivilegeValueW(LPCWSTR,LPCWSTR,PLUID); -LPSTR WINAPI lstrcatA(LPSTR,LPCSTR); -LPWSTR WINAPI lstrcatW(LPWSTR,LPCWSTR); -int WINAPI lstrcmpA(LPCSTR,LPCSTR); -int WINAPI lstrcmpiA(LPCSTR,LPCSTR); -int WINAPI lstrcmpiW( LPCWSTR,LPCWSTR); -int WINAPI lstrcmpW(LPCWSTR,LPCWSTR); -LPSTR WINAPI lstrcpyA(LPSTR,LPCSTR); -LPSTR WINAPI lstrcpynA(LPSTR,LPCSTR,int); -LPWSTR WINAPI lstrcpynW(LPWSTR,LPCWSTR,int); -LPWSTR WINAPI lstrcpyW(LPWSTR,LPCWSTR); -int WINAPI lstrlenA(LPCSTR); -int WINAPI lstrlenW(LPCWSTR); -BOOL WINAPI MakeAbsoluteSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PDWORD,PACL,PDWORD,PACL,PDWORD,PSID,PDWORD,PSID,PDWORD); -#define MakeProcInstance(p,i) (p) -BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PDWORD); -VOID WINAPI MapGenericMask(PDWORD,PGENERIC_MAPPING); -PVOID WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,DWORD); -PVOID WINAPI MapViewOfFileEx(HANDLE,DWORD,DWORD,DWORD,DWORD,PVOID); -BOOL WINAPI MoveFileA(LPCSTR,LPCSTR); -BOOL WINAPI MoveFileExA(LPCSTR,LPCSTR,DWORD); -BOOL WINAPI MoveFileExW(LPCWSTR,LPCWSTR,DWORD); -BOOL WINAPI MoveFileW(LPCWSTR,LPCWSTR); -int WINAPI MulDiv(int,int,int); -BOOL WINAPI NotifyChangeEventLog(HANDLE,HANDLE); -BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR,PVOID,BOOL); -BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR,PVOID,BOOL); -BOOL WINAPI ObjectDeleteAuditAlarmA(LPCSTR,PVOID,BOOL); -BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR,PVOID,BOOL); -BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR,PVOID,LPSTR,LPSTR,PSECURITY_DESCRIPTOR,HANDLE,DWORD,DWORD,PPRIVILEGE_SET,BOOL,BOOL,PBOOL); -BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR,PVOID,LPWSTR,LPWSTR,PSECURITY_DESCRIPTOR,HANDLE,DWORD,DWORD,PPRIVILEGE_SET,BOOL,BOOL,PBOOL); -BOOL WINAPI ObjectPrivilegeAuditAlarmA(LPCSTR,PVOID,HANDLE,DWORD,PPRIVILEGE_SET,BOOL); -BOOL WINAPI ObjectPrivilegeAuditAlarmW(LPCWSTR,PVOID,HANDLE,DWORD,PPRIVILEGE_SET,BOOL); -HANDLE WINAPI OpenBackupEventLogA(LPCSTR,LPCSTR); -HANDLE WINAPI OpenBackupEventLogW(LPCWSTR,LPCWSTR); -HANDLE WINAPI OpenEventA(DWORD,BOOL,LPCSTR); -HANDLE WINAPI OpenEventLogA (LPCSTR,LPCSTR); -HANDLE WINAPI OpenEventLogW(LPCWSTR,LPCWSTR); -HANDLE WINAPI OpenEventW(DWORD,BOOL,LPCWSTR); -HFILE WINAPI OpenFile(LPCSTR,LPOFSTRUCT,UINT); -HANDLE WINAPI OpenFileMappingA(DWORD,BOOL,LPCSTR); -HANDLE WINAPI OpenFileMappingW(DWORD,BOOL,LPCWSTR); -HANDLE WINAPI OpenMutexA(DWORD,BOOL,LPCSTR); -HANDLE WINAPI OpenMutexW(DWORD,BOOL,LPCWSTR); -HANDLE WINAPI OpenProcess(DWORD,BOOL,DWORD); -BOOL WINAPI OpenProcessToken(HANDLE,DWORD,PHANDLE); -HANDLE WINAPI OpenSemaphoreA(DWORD,BOOL,LPCSTR); -HANDLE WINAPI OpenSemaphoreW(DWORD,BOOL,LPCWSTR); -BOOL WINAPI OpenThreadToken(HANDLE,DWORD,BOOL,PHANDLE); -HANDLE WINAPI OpenWaitableTimerA(DWORD,BOOL,LPCSTR); -HANDLE WINAPI OpenWaitableTimerW(DWORD,BOOL,LPCWSTR); -void WINAPI OutputDebugStringA(LPCSTR); -void WINAPI OutputDebugStringW(LPCWSTR); -BOOL WINAPI PeekNamedPipe(HANDLE,PVOID,DWORD,PDWORD,PDWORD,PDWORD); -BOOL WINAPI PostQueuedCompletionStatus(HANDLE,DWORD,DWORD,LPOVERLAPPED); -DWORD WINAPI PrepareTape(HANDLE,DWORD,BOOL); -BOOL WINAPI PrivilegeCheck (HANDLE,PPRIVILEGE_SET,PBOOL); -BOOL WINAPI PrivilegedServiceAuditAlarmA(LPCSTR,LPCSTR,HANDLE,PPRIVILEGE_SET,BOOL); -BOOL WINAPI PrivilegedServiceAuditAlarmW(LPCWSTR,LPCWSTR,HANDLE,PPRIVILEGE_SET,BOOL); -BOOL WINAPI PulseEvent(HANDLE); -BOOL WINAPI PurgeComm(HANDLE,DWORD); -DWORD WINAPI QueryDosDeviceA(LPCSTR,LPSTR,DWORD); -DWORD WINAPI QueryDosDeviceW(LPCWSTR,LPWSTR,DWORD); -BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER); -BOOL WINAPI QueryPerformanceFrequency(PLARGE_INTEGER); -DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE,DWORD); -void WINAPI RaiseException(DWORD,DWORD,DWORD,const DWORD*); -BOOL WINAPI ReadDirectoryChangesW(HANDLE,PVOID,DWORD,BOOL,DWORD,PDWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE); -BOOL WINAPI ReadEventLogA(HANDLE,DWORD,DWORD,PVOID,DWORD,DWORD *,DWORD *); -BOOL WINAPI ReadEventLogW(HANDLE,DWORD,DWORD,PVOID,DWORD,DWORD *,DWORD *); -BOOL WINAPI ReadFile(HANDLE,PVOID,DWORD,PDWORD,LPOVERLAPPED); -BOOL WINAPI ReadFileEx(HANDLE,PVOID,DWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE); -BOOL WINAPI ReadProcessMemory(HANDLE,PCVOID,PVOID,DWORD,PDWORD); -HANDLE WINAPI RegisterEventSourceA (LPCSTR,LPCSTR); -HANDLE WINAPI RegisterEventSourceW(LPCWSTR,LPCWSTR); -BOOL WINAPI ReleaseMutex(HANDLE); -BOOL WINAPI ReleaseSemaphore(HANDLE,LONG,LPLONG); -BOOL WINAPI RemoveDirectoryA(LPCSTR); -BOOL WINAPI RemoveDirectoryW(LPCWSTR); -BOOL WINAPI ReportEventA(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCSTR*,PVOID); -BOOL WINAPI ReportEventW(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR*,PVOID); -BOOL WINAPI ResetEvent(HANDLE); -DWORD WINAPI ResumeThread(HANDLE); -BOOL WINAPI RevertToSelf(void); -DWORD WINAPI SearchPathA(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*); -DWORD WINAPI SearchPathW(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*); -BOOL WINAPI SetAclInformation(PACL,PVOID,DWORD,ACL_INFORMATION_CLASS); -BOOL WINAPI SetCommBreak(HANDLE); -BOOL WINAPI SetCommConfig(HANDLE,LPCOMMCONFIG,DWORD); -BOOL WINAPI SetCommMask(HANDLE,DWORD); -BOOL WINAPI SetCommState(HANDLE,LPDCB); -BOOL WINAPI SetCommTimeouts(HANDLE,LPCOMMTIMEOUTS); -BOOL WINAPI SetComputerNameA(LPCSTR); -BOOL WINAPI SetComputerNameW(LPCWSTR); -BOOL WINAPI SetCurrentDirectoryA(LPCSTR); -BOOL WINAPI SetCurrentDirectoryW(LPCWSTR); -BOOL WINAPI SetDefaultCommConfigA(LPCSTR,LPCOMMCONFIG,DWORD); -BOOL WINAPI SetDefaultCommConfigW(LPCWSTR,LPCOMMCONFIG,DWORD); -BOOL WINAPI SetEndOfFile(HANDLE); -BOOL WINAPI SetEnvironmentVariableA(LPCSTR,LPCSTR); -BOOL WINAPI SetEnvironmentVariableW(LPCWSTR,LPCWSTR); -UINT WINAPI SetErrorMode(UINT); -BOOL WINAPI SetEvent(HANDLE); -VOID WINAPI SetFileApisToANSI(void); -VOID WINAPI SetFileApisToOEM(void); -BOOL WINAPI SetFileAttributesA(LPCSTR,DWORD); -BOOL WINAPI SetFileAttributesW(LPCWSTR,DWORD); -DWORD WINAPI SetFilePointer(HANDLE,LONG,PLONG,DWORD); -BOOL WINAPI SetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); -BOOL WINAPI SetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); -BOOL WINAPI SetFileTime(HANDLE,const FILETIME*,const FILETIME*,const FILETIME*); -UINT WINAPI SetHandleCount(UINT); -BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD); -BOOL WINAPI SetKernelObjectSecurity(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); -void WINAPI SetLastError(DWORD); -void WINAPI SetLastErrorEx(DWORD,DWORD); -BOOL WINAPI SetLocalTime(const SYSTEMTIME*); -BOOL WINAPI SetMailslotInfo(HANDLE,DWORD); -BOOL WINAPI SetNamedPipeHandleState(HANDLE,PDWORD,PDWORD,PDWORD); -BOOL WINAPI SetPriorityClass(HANDLE,DWORD); -BOOL WINAPI SetPrivateObjectSecurity(SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR *,PGENERIC_MAPPING,HANDLE); -BOOL WINAPI SetProcessAffinityMask(HANDLE,DWORD); -BOOL WINAPI SetProcessPriorityBoost(HANDLE,BOOL); -BOOL WINAPI SetProcessShutdownParameters(DWORD,DWORD); -BOOL WINAPI SetProcessWorkingSetSize(HANDLE,DWORD,DWORD); -BOOL WINAPI SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,SECURITY_DESCRIPTOR_CONTROL,SECURITY_DESCRIPTOR_CONTROL); -BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,BOOL,PACL,BOOL); -BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID,BOOL); -BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID,BOOL); -BOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,BOOL,PACL,BOOL); -BOOL WINAPI SetStdHandle(DWORD,HANDLE); -#define SetSwapAreaSize(w) (w) -BOOL WINAPI SetSystemPowerState(BOOL,BOOL); -BOOL WINAPI SetSystemTime(const SYSTEMTIME*); -BOOL WINAPI SetSystemTimeAdjustment(DWORD,BOOL); -DWORD WINAPI SetTapeParameters(HANDLE,DWORD,PVOID); -DWORD WINAPI SetTapePosition(HANDLE,DWORD,DWORD,DWORD,DWORD,BOOL); -DWORD WINAPI SetThreadAffinityMask(HANDLE,DWORD); -BOOL WINAPI SetThreadContext(HANDLE,const CONTEXT*); -DWORD WINAPI SetThreadIdealProcessor(HANDLE,DWORD); -BOOL WINAPI SetThreadPriority(HANDLE,int); -BOOL WINAPI SetThreadPriorityBoost(HANDLE,BOOL); -BOOL WINAPI SetThreadToken (PHANDLE,HANDLE); -BOOL WINAPI SetTimeZoneInformation(const TIME_ZONE_INFORMATION *); -BOOL WINAPI SetTokenInformation(HANDLE,TOKEN_INFORMATION_CLASS,PVOID,DWORD); -LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER); -BOOL WINAPI SetupComm(HANDLE,DWORD,DWORD); -BOOL WINAPI SetVolumeLabelA(LPCSTR,LPCSTR); -BOOL WINAPI SetVolumeLabelW(LPCWSTR,LPCWSTR); -BOOL WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,PVOID,BOOL); -BOOL WINAPI SignalObjectAndWait(HANDLE,HANDLE,DWORD,BOOL); -DWORD WINAPI SizeofResource(HINSTANCE,HRSRC); -void WINAPI Sleep(DWORD); -DWORD WINAPI SleepEx(DWORD,BOOL); -DWORD WINAPI SuspendThread(HANDLE); -void WINAPI SwitchToFiber(PVOID); -BOOL WINAPI SwitchToThread(void); -BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME); -BOOL WINAPI SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); -BOOL WINAPI TerminateProcess(HANDLE,UINT); -BOOL WINAPI TerminateThread(HANDLE,DWORD); -DWORD WINAPI TlsAlloc(VOID); -BOOL WINAPI TlsFree(DWORD); -PVOID WINAPI TlsGetValue(DWORD); -BOOL WINAPI TlsSetValue(DWORD,PVOID); -BOOL WINAPI TransactNamedPipe(HANDLE,PVOID,DWORD,PVOID,DWORD,PDWORD,LPOVERLAPPED); -BOOL WINAPI TransmitCommChar(HANDLE,char); -BOOL WINAPI TryEnterCriticalSection(LPCRITICAL_SECTION); -LONG WINAPI UnhandledExceptionFilter(LPEXCEPTION_POINTERS); -BOOL WINAPI UnlockFile(HANDLE,DWORD,DWORD,DWORD,DWORD); -BOOL WINAPI UnlockFileEx(HANDLE,DWORD,DWORD,DWORD,LPOVERLAPPED); -#define UnlockResource(h) (h) -#define UnlockSegment(w) GlobalUnfix((HANDLE)(w)) -BOOL WINAPI UnmapViewOfFile(PVOID); -BOOL WINAPI UpdateResourceA(HANDLE,LPCSTR,LPCSTR,WORD,PVOID,DWORD); -BOOL WINAPI UpdateResourceW(HANDLE,LPCWSTR,LPCWSTR,WORD,PVOID,DWORD); -BOOL WINAPI VerifyVersionInfoA(LPOSVERSIONINFOEXA,DWORD,DWORDLONG); -BOOL WINAPI VerifyVersionInfoW(LPOSVERSIONINFOEXW,DWORD,DWORDLONG); -PVOID WINAPI VirtualAlloc(PVOID,DWORD,DWORD,DWORD); -PVOID WINAPI VirtualAllocEx(HANDLE,PVOID,DWORD,DWORD,DWORD); -BOOL WINAPI VirtualFree(PVOID,DWORD,DWORD); -BOOL WINAPI VirtualFreeEx(HANDLE,PVOID,DWORD,DWORD); -BOOL WINAPI VirtualLock(PVOID,DWORD); -BOOL WINAPI VirtualProtect(PVOID,DWORD,DWORD,PDWORD); -BOOL WINAPI VirtualProtectEx(HANDLE,PVOID,DWORD,DWORD,PDWORD); -DWORD WINAPI VirtualQuery(LPCVOID,PMEMORY_BASIC_INFORMATION,DWORD); -DWORD WINAPI VirtualQueryEx(HANDLE,LPCVOID,PMEMORY_BASIC_INFORMATION,DWORD); -BOOL WINAPI VirtualUnlock(PVOID,DWORD); -BOOL WINAPI WaitCommEvent(HANDLE,PDWORD,LPOVERLAPPED); -BOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT,DWORD); -DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,BOOL,DWORD); -DWORD WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE*,BOOL,DWORD,BOOL); -DWORD WINAPI WaitForSingleObject(HANDLE,DWORD); -DWORD WINAPI WaitForSingleObjectEx(HANDLE,DWORD,BOOL); -BOOL WINAPI WaitNamedPipeA(LPCSTR,DWORD); -BOOL WINAPI WaitNamedPipeW(LPCWSTR,DWORD); -BOOL WINAPI WinLoadTrustProvider(GUID*); -BOOL WINAPI WriteFile(HANDLE,PCVOID,DWORD,PDWORD,LPOVERLAPPED); -BOOL WINAPI WriteFileEx(HANDLE,PCVOID,DWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE); -BOOL WINAPI WritePrivateProfileSectionA(LPCSTR,LPCSTR,LPCSTR); -BOOL WINAPI WritePrivateProfileSectionW(LPCWSTR,LPCWSTR,LPCWSTR); -BOOL WINAPI WritePrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPCSTR); -BOOL WINAPI WritePrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR); -BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,PVOID,UINT,LPCSTR); -BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,PVOID,UINT,LPCWSTR); -BOOL WINAPI WriteProcessMemory(HANDLE,PVOID,PVOID,DWORD,PDWORD); -BOOL WINAPI WriteProfileSectionA(LPCSTR,LPCSTR); -BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR); -BOOL WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR); -BOOL WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR); -DWORD WINAPI WriteTapemark(HANDLE,DWORD,DWORD,BOOL); -#define Yield() + + WINBASEAPI WINBOOL WINAPI SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION lpTimeZoneInformation,LPSYSTEMTIME lpUniversalTime,LPSYSTEMTIME lpLocalTime); + WINBASEAPI WINBOOL WINAPI TzSpecificLocalTimeToSystemTime(LPTIME_ZONE_INFORMATION lpTimeZoneInformation,LPSYSTEMTIME lpLocalTime,LPSYSTEMTIME lpUniversalTime); + WINBASEAPI DWORD WINAPI GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation); + WINBASEAPI WINBOOL WINAPI SetTimeZoneInformation(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation); + WINBASEAPI WINBOOL WINAPI SystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime,LPFILETIME lpFileTime); + WINBASEAPI WINBOOL WINAPI FileTimeToLocalFileTime(CONST FILETIME *lpFileTime,LPFILETIME lpLocalFileTime); + WINBASEAPI WINBOOL WINAPI LocalFileTimeToFileTime(CONST FILETIME *lpLocalFileTime,LPFILETIME lpFileTime); + WINBASEAPI WINBOOL WINAPI FileTimeToSystemTime(CONST FILETIME *lpFileTime,LPSYSTEMTIME lpSystemTime); + WINBASEAPI LONG WINAPI CompareFileTime(CONST FILETIME *lpFileTime1,CONST FILETIME *lpFileTime2); + WINBASEAPI WINBOOL WINAPI FileTimeToDosDateTime(CONST FILETIME *lpFileTime,LPWORD lpFatDate,LPWORD lpFatTime); + WINBASEAPI WINBOOL WINAPI DosDateTimeToFileTime(WORD wFatDate,WORD wFatTime,LPFILETIME lpFileTime); + WINBASEAPI DWORD WINAPI GetTickCount(VOID); + WINBASEAPI WINBOOL WINAPI SetSystemTimeAdjustment(DWORD dwTimeAdjustment,WINBOOL bTimeAdjustmentDisabled); + WINBASEAPI WINBOOL WINAPI GetSystemTimeAdjustment(PDWORD lpTimeAdjustment,PDWORD lpTimeIncrement,PBOOL lpTimeAdjustmentDisabled); + WINBASEAPI DWORD WINAPI FormatMessageA(DWORD dwFlags,LPCVOID lpSource,DWORD dwMessageId,DWORD dwLanguageId,LPSTR lpBuffer,DWORD nSize,va_list *Arguments); + WINBASEAPI DWORD WINAPI FormatMessageW(DWORD dwFlags,LPCVOID lpSource,DWORD dwMessageId,DWORD dwLanguageId,LPWSTR lpBuffer,DWORD nSize,va_list *Arguments); + +#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x100 +#define FORMAT_MESSAGE_IGNORE_INSERTS 0x200 +#define FORMAT_MESSAGE_FROM_STRING 0x400 +#define FORMAT_MESSAGE_FROM_HMODULE 0x800 +#define FORMAT_MESSAGE_FROM_SYSTEM 0x1000 +#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x2000 +#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0xff #ifdef UNICODE -typedef STARTUPINFOW STARTUPINFO,*LPSTARTUPINFO; -typedef WIN32_FIND_DATAW WIN32_FIND_DATA,*LPWIN32_FIND_DATA; -typedef HW_PROFILE_INFOW HW_PROFILE_INFO,*LPHW_PROFILE_INFO; -#define AccessCheckAndAuditAlarm AccessCheckAndAuditAlarmW -#define AddAtom AddAtomW -#define BackupEventLog BackupEventLogW -#define BeginUpdateResource BeginUpdateResourceW -#define BuildCommDCB BuildCommDCBW -#define BuildCommDCBAndTimeouts BuildCommDCBAndTimeoutsW -#define CallNamedPipe CallNamedPipeW -#define ClearEventLog ClearEventLogW -#define CommConfigDialog CommConfigDialogW -#define CopyFile CopyFileW -#define CopyFileEx CopyFileExW -#define CreateDirectory CreateDirectoryW -#define CreateDirectoryEx CreateDirectoryExW -#define CreateEvent CreateEventW -#define CreateFile CreateFileW -#define CreateFileMapping CreateFileMappingW -#define CreateHardLink CreateHardLinkW #define CreateMailslot CreateMailslotW +#define EncryptFile EncryptFileW +#define DecryptFile DecryptFileW +#define FileEncryptionStatus FileEncryptionStatusW +#else +#define CreateMailslot CreateMailslotA +#define EncryptFile EncryptFileA +#define DecryptFile DecryptFileA +#define FileEncryptionStatus FileEncryptionStatusA +#endif + + WINBASEAPI WINBOOL WINAPI CreatePipe(PHANDLE hReadPipe,PHANDLE hWritePipe,LPSECURITY_ATTRIBUTES lpPipeAttributes,DWORD nSize); + WINBASEAPI WINBOOL WINAPI ConnectNamedPipe(HANDLE hNamedPipe,LPOVERLAPPED lpOverlapped); + WINBASEAPI WINBOOL WINAPI DisconnectNamedPipe(HANDLE hNamedPipe); + WINBASEAPI WINBOOL WINAPI SetNamedPipeHandleState(HANDLE hNamedPipe,LPDWORD lpMode,LPDWORD lpMaxCollectionCount,LPDWORD lpCollectDataTimeout); + WINBASEAPI WINBOOL WINAPI GetNamedPipeInfo(HANDLE hNamedPipe,LPDWORD lpFlags,LPDWORD lpOutBufferSize,LPDWORD lpInBufferSize,LPDWORD lpMaxInstances); + WINBASEAPI WINBOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe,LPVOID lpBuffer,DWORD nBufferSize,LPDWORD lpBytesRead,LPDWORD lpTotalBytesAvail,LPDWORD lpBytesLeftThisMessage); + WINBASEAPI WINBOOL WINAPI TransactNamedPipe(HANDLE hNamedPipe,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesRead,LPOVERLAPPED lpOverlapped); + WINBASEAPI HANDLE WINAPI CreateMailslotA(LPCSTR lpName,DWORD nMaxMessageSize,DWORD lReadTimeout,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI HANDLE WINAPI CreateMailslotW(LPCWSTR lpName,DWORD nMaxMessageSize,DWORD lReadTimeout,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI WINBOOL WINAPI GetMailslotInfo(HANDLE hMailslot,LPDWORD lpMaxMessageSize,LPDWORD lpNextSize,LPDWORD lpMessageCount,LPDWORD lpReadTimeout); + WINBASEAPI WINBOOL WINAPI SetMailslotInfo(HANDLE hMailslot,DWORD lReadTimeout); + WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,SIZE_T dwNumberOfBytesToMap); + WINBASEAPI WINBOOL WINAPI FlushViewOfFile(LPCVOID lpBaseAddress,SIZE_T dwNumberOfBytesToFlush); + WINBASEAPI WINBOOL WINAPI UnmapViewOfFile(LPCVOID lpBaseAddress); + WINADVAPI WINBOOL WINAPI EncryptFileA(LPCSTR lpFileName); + WINADVAPI WINBOOL WINAPI EncryptFileW(LPCWSTR lpFileName); + WINADVAPI WINBOOL WINAPI DecryptFileA(LPCSTR lpFileName,DWORD dwReserved); + WINADVAPI WINBOOL WINAPI DecryptFileW(LPCWSTR lpFileName,DWORD dwReserved); + +#define FILE_ENCRYPTABLE 0 +#define FILE_IS_ENCRYPTED 1 +#define FILE_SYSTEM_ATTR 2 +#define FILE_ROOT_DIR 3 +#define FILE_SYSTEM_DIR 4 +#define FILE_UNKNOWN 5 +#define FILE_SYSTEM_NOT_SUPPORT 6 +#define FILE_USER_DISALLOWED 7 +#define FILE_READ_ONLY 8 +#define FILE_DIR_DISALLOWED 9 + + WINADVAPI WINBOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName,LPDWORD lpStatus); + WINADVAPI WINBOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName,LPDWORD lpStatus); + +#define EFS_USE_RECOVERY_KEYS (0x1) + + typedef DWORD (WINAPI *PFE_EXPORT_FUNC)(PBYTE pbData,PVOID pvCallbackContext,ULONG ulLength); + typedef DWORD (WINAPI *PFE_IMPORT_FUNC)(PBYTE pbData,PVOID pvCallbackContext,PULONG ulLength); + +#define CREATE_FOR_IMPORT (1) +#define CREATE_FOR_DIR (2) +#define OVERWRITE_HIDDEN (4) + +#ifdef UNICODE +#define OpenEncryptedFileRaw OpenEncryptedFileRawW +#define lstrcmp lstrcmpW +#define lstrcmpi lstrcmpiW +#define lstrcpyn lstrcpynW +#define lstrcpy lstrcpyW +#define lstrcat lstrcatW +#define lstrlen lstrlenW +#else +#define OpenEncryptedFileRaw OpenEncryptedFileRawA +#define lstrcmp lstrcmpA +#define lstrcmpi lstrcmpiA +#define lstrcpyn lstrcpynA +#define lstrcpy lstrcpyA +#define lstrcat lstrcatA +#define lstrlen lstrlenA +#endif + + WINADVAPI DWORD WINAPI OpenEncryptedFileRawA(LPCSTR lpFileName,ULONG ulFlags,PVOID *pvContext); + WINADVAPI DWORD WINAPI OpenEncryptedFileRawW(LPCWSTR lpFileName,ULONG ulFlags,PVOID *pvContext); + WINADVAPI DWORD WINAPI ReadEncryptedFileRaw(PFE_EXPORT_FUNC pfExportCallback,PVOID pvCallbackContext,PVOID pvContext); + WINADVAPI DWORD WINAPI WriteEncryptedFileRaw(PFE_IMPORT_FUNC pfImportCallback,PVOID pvCallbackContext,PVOID pvContext); + WINADVAPI VOID WINAPI CloseEncryptedFileRaw(PVOID pvContext); + WINBASEAPI int WINAPI lstrcmpA(LPCSTR lpString1,LPCSTR lpString2); + WINBASEAPI int WINAPI lstrcmpW(LPCWSTR lpString1,LPCWSTR lpString2); + WINBASEAPI int WINAPI lstrcmpiA(LPCSTR lpString1,LPCSTR lpString2); + WINBASEAPI int WINAPI lstrcmpiW(LPCWSTR lpString1,LPCWSTR lpString2); + WINBASEAPI LPSTR WINAPI lstrcpynA(LPSTR lpString1,LPCSTR lpString2,int iMaxLength); + WINBASEAPI LPWSTR WINAPI lstrcpynW(LPWSTR lpString1,LPCWSTR lpString2,int iMaxLength); + WINBASEAPI LPSTR WINAPI lstrcpyA(LPSTR lpString1,LPCSTR lpString2); + WINBASEAPI LPWSTR WINAPI lstrcpyW(LPWSTR lpString1,LPCWSTR lpString2); + WINBASEAPI LPSTR WINAPI lstrcatA(LPSTR lpString1,LPCSTR lpString2); + WINBASEAPI LPWSTR WINAPI lstrcatW(LPWSTR lpString1,LPCWSTR lpString2); + WINBASEAPI int WINAPI lstrlenA(LPCSTR lpString); + WINBASEAPI int WINAPI lstrlenW(LPCWSTR lpString); + WINBASEAPI HFILE WINAPI OpenFile(LPCSTR lpFileName,LPOFSTRUCT lpReOpenBuff,UINT uStyle); + WINBASEAPI HFILE WINAPI _lopen(LPCSTR lpPathName,int iReadWrite); + WINBASEAPI HFILE WINAPI _lcreat(LPCSTR lpPathName,int iAttribute); + WINBASEAPI UINT WINAPI _lread(HFILE hFile,LPVOID lpBuffer,UINT uBytes); + WINBASEAPI UINT WINAPI _lwrite(HFILE hFile,LPCCH lpBuffer,UINT uBytes); + WINBASEAPI long WINAPI _hread(HFILE hFile,LPVOID lpBuffer,long lBytes); + WINBASEAPI long WINAPI _hwrite(HFILE hFile,LPCCH lpBuffer,long lBytes); + WINBASEAPI HFILE WINAPI _lclose(HFILE hFile); + WINBASEAPI LONG WINAPI _llseek(HFILE hFile,LONG lOffset,int iOrigin); + WINADVAPI WINBOOL WINAPI IsTextUnicode(CONST VOID *lpv,int iSize,LPINT lpiResult); + +#define FLS_OUT_OF_INDEXES ((DWORD)0xffffffff) + + WINBASEAPI DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback); + WINBASEAPI PVOID WINAPI FlsGetValue(DWORD dwFlsIndex); + WINBASEAPI WINBOOL WINAPI FlsSetValue(DWORD dwFlsIndex,PVOID lpFlsData); + WINBASEAPI WINBOOL WINAPI FlsFree(DWORD dwFlsIndex); + +#define TLS_OUT_OF_INDEXES ((DWORD)0xffffffff) + + WINBASEAPI DWORD WINAPI TlsAlloc(VOID); + WINBASEAPI LPVOID WINAPI TlsGetValue(DWORD dwTlsIndex); + WINBASEAPI WINBOOL WINAPI TlsSetValue(DWORD dwTlsIndex,LPVOID lpTlsValue); + WINBASEAPI WINBOOL WINAPI TlsFree(DWORD dwTlsIndex); + + typedef VOID (WINAPI *LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped); + + WINBASEAPI DWORD WINAPI SleepEx(DWORD dwMilliseconds,WINBOOL bAlertable); + WINBASEAPI DWORD WINAPI WaitForSingleObjectEx(HANDLE hHandle,DWORD dwMilliseconds,WINBOOL bAlertable); + WINBASEAPI DWORD WINAPI WaitForMultipleObjectsEx(DWORD nCount,CONST HANDLE *lpHandles,WINBOOL bWaitAll,DWORD dwMilliseconds,WINBOOL bAlertable); + WINBASEAPI DWORD WINAPI SignalObjectAndWait(HANDLE hObjectToSignal,HANDLE hObjectToWaitOn,DWORD dwMilliseconds,WINBOOL bAlertable); + WINBASEAPI WINBOOL WINAPI ReadFileEx(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPOVERLAPPED lpOverlapped,LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + WINBASEAPI WINBOOL WINAPI WriteFileEx(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPOVERLAPPED lpOverlapped,LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + WINBASEAPI WINBOOL WINAPI BackupRead(HANDLE hFile,LPBYTE lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,WINBOOL bAbort,WINBOOL bProcessSecurity,LPVOID *lpContext); + WINBASEAPI WINBOOL WINAPI BackupSeek(HANDLE hFile,DWORD dwLowBytesToSeek,DWORD dwHighBytesToSeek,LPDWORD lpdwLowByteSeeked,LPDWORD lpdwHighByteSeeked,LPVOID *lpContext); + WINBASEAPI WINBOOL WINAPI BackupWrite(HANDLE hFile,LPBYTE lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,WINBOOL bAbort,WINBOOL bProcessSecurity,LPVOID *lpContext); + + typedef struct _WIN32_STREAM_ID { + DWORD dwStreamId; + DWORD dwStreamAttributes; + LARGE_INTEGER Size; + DWORD dwStreamNameSize; + WCHAR cStreamName[ANYSIZE_ARRAY]; + } WIN32_STREAM_ID,*LPWIN32_STREAM_ID; + +#define BACKUP_INVALID 0x0 +#define BACKUP_DATA 0x1 +#define BACKUP_EA_DATA 0x2 +#define BACKUP_SECURITY_DATA 0x3 +#define BACKUP_ALTERNATE_DATA 0x4 +#define BACKUP_LINK 0x5 +#define BACKUP_PROPERTY_DATA 0x6 +#define BACKUP_OBJECT_ID 0x7 +#define BACKUP_REPARSE_DATA 0x8 +#define BACKUP_SPARSE_BLOCK 0x9 + +#define STREAM_NORMAL_ATTRIBUTE 0x0 +#define STREAM_MODIFIED_WHEN_READ 0x1 +#define STREAM_CONTAINS_SECURITY 0x2 +#define STREAM_CONTAINS_PROPERTIES 0x4 +#define STREAM_SPARSE_ATTRIBUTE 0x8 + + WINBASEAPI WINBOOL WINAPI ReadFileScatter(HANDLE hFile,FILE_SEGMENT_ELEMENT aSegmentArray[],DWORD nNumberOfBytesToRead,LPDWORD lpReserved,LPOVERLAPPED lpOverlapped); + WINBASEAPI WINBOOL WINAPI WriteFileGather(HANDLE hFile,FILE_SEGMENT_ELEMENT aSegmentArray[],DWORD nNumberOfBytesToWrite,LPDWORD lpReserved,LPOVERLAPPED lpOverlapped); + +#define STARTF_USESHOWWINDOW 0x1 +#define STARTF_USESIZE 0x2 +#define STARTF_USEPOSITION 0x4 +#define STARTF_USECOUNTCHARS 0x8 +#define STARTF_USEFILLATTRIBUTE 0x10 +#define STARTF_RUNFULLSCREEN 0x20 +#define STARTF_FORCEONFEEDBACK 0x40 +#define STARTF_FORCEOFFFEEDBACK 0x80 +#define STARTF_USESTDHANDLES 0x100 + +#define STARTF_USEHOTKEY 0x200 + + typedef struct _STARTUPINFOA { + DWORD cb; + LPSTR lpReserved; + LPSTR lpDesktop; + LPSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + LPBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + } STARTUPINFOA,*LPSTARTUPINFOA; + + typedef struct _STARTUPINFOW { + DWORD cb; + LPWSTR lpReserved; + LPWSTR lpDesktop; + LPWSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + LPBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + } STARTUPINFOW,*LPSTARTUPINFOW; + +#ifdef UNICODE + typedef STARTUPINFOW STARTUPINFO; + typedef LPSTARTUPINFOW LPSTARTUPINFO; +#else + typedef STARTUPINFOA STARTUPINFO; + typedef LPSTARTUPINFOA LPSTARTUPINFO; +#endif + +#define SHUTDOWN_NORETRY 0x1 + + typedef struct _WIN32_FIND_DATAA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + CHAR cFileName[MAX_PATH]; + CHAR cAlternateFileName[14]; + } WIN32_FIND_DATAA,*PWIN32_FIND_DATAA,*LPWIN32_FIND_DATAA; + + typedef struct _WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + WCHAR cFileName[MAX_PATH]; + WCHAR cAlternateFileName[14]; + } WIN32_FIND_DATAW,*PWIN32_FIND_DATAW,*LPWIN32_FIND_DATAW; + +#ifdef UNICODE + typedef WIN32_FIND_DATAW WIN32_FIND_DATA; + typedef PWIN32_FIND_DATAW PWIN32_FIND_DATA; + typedef LPWIN32_FIND_DATAW LPWIN32_FIND_DATA; +#else + typedef WIN32_FIND_DATAA WIN32_FIND_DATA; + typedef PWIN32_FIND_DATAA PWIN32_FIND_DATA; + typedef LPWIN32_FIND_DATAA LPWIN32_FIND_DATA; +#endif + + typedef struct _WIN32_FILE_ATTRIBUTE_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + } WIN32_FILE_ATTRIBUTE_DATA,*LPWIN32_FILE_ATTRIBUTE_DATA; + +#ifdef UNICODE #define CreateMutex CreateMutexW -#define CreateNamedPipe CreateNamedPipeW -#define CreateProcess CreateProcessW -#define CreateProcessAsUser CreateProcessAsUserW +#define OpenMutex OpenMutexW +#define CreateEvent CreateEventW +#define OpenEvent OpenEventW #define CreateSemaphore CreateSemaphoreW +#define OpenSemaphore OpenSemaphoreW +#else +#define CreateMutex CreateMutexA +#define OpenMutex OpenMutexA +#define CreateEvent CreateEventA +#define OpenEvent OpenEventA +#define CreateSemaphore CreateSemaphoreA +#define OpenSemaphore OpenSemaphoreA +#endif + + WINBASEAPI HANDLE WINAPI CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes,WINBOOL bInitialOwner,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes,WINBOOL bInitialOwner,LPCWSTR lpName); + WINBASEAPI HANDLE WINAPI OpenMutexA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI OpenMutexW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName); + WINBASEAPI HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes,WINBOOL bManualReset,WINBOOL bInitialState,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes,WINBOOL bManualReset,WINBOOL bInitialState,LPCWSTR lpName); + WINBASEAPI HANDLE WINAPI OpenEventA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI OpenEventW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName); + WINBASEAPI HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCWSTR lpName); + WINBASEAPI HANDLE WINAPI OpenSemaphoreA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI OpenSemaphoreW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName); + + typedef VOID (WINAPI *PTIMERAPCROUTINE)(LPVOID lpArgToCompletionRoutine,DWORD dwTimerLowValue,DWORD dwTimerHighValue); + +#ifdef UNICODE #define CreateWaitableTimer CreateWaitableTimerW -#define DefineDosDevice DefineDosDeviceW -#define DeleteFile DeleteFileW -#define EndUpdateResource EndUpdateResourceW -#define EnumResourceLanguages EnumResourceLanguagesW -#define EnumResourceNames EnumResourceNamesW -#define EnumResourceTypes EnumResourceTypesW -#define ExpandEnvironmentStrings ExpandEnvironmentStringsW +#define OpenWaitableTimer OpenWaitableTimerW +#define CreateFileMapping CreateFileMappingW +#define OpenFileMapping OpenFileMappingW +#define GetLogicalDriveStrings GetLogicalDriveStringsW +#define LoadLibrary LoadLibraryW +#define LoadLibraryEx LoadLibraryExW +#define GetModuleFileName GetModuleFileNameW +#define GetModuleHandle GetModuleHandleW +#else +#define CreateWaitableTimer CreateWaitableTimerA +#define OpenWaitableTimer OpenWaitableTimerA +#define CreateFileMapping CreateFileMappingA +#define OpenFileMapping OpenFileMappingA +#define GetLogicalDriveStrings GetLogicalDriveStringsA +#define LoadLibrary LoadLibraryA +#define LoadLibraryEx LoadLibraryExA +#define GetModuleFileName GetModuleFileNameA +#define GetModuleHandle GetModuleHandleA +#endif + + WINBASEAPI HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes,WINBOOL bManualReset,LPCSTR lpTimerName); + WINBASEAPI HANDLE WINAPI CreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes,WINBOOL bManualReset,LPCWSTR lpTimerName); + WINBASEAPI HANDLE WINAPI OpenWaitableTimerA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpTimerName); + WINBASEAPI HANDLE WINAPI OpenWaitableTimerW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpTimerName); + WINBASEAPI WINBOOL WINAPI SetWaitableTimer(HANDLE hTimer,const LARGE_INTEGER *lpDueTime,LONG lPeriod,PTIMERAPCROUTINE pfnCompletionRoutine,LPVOID lpArgToCompletionRoutine,WINBOOL fResume); + WINBASEAPI WINBOOL WINAPI CancelWaitableTimer(HANDLE hTimer); + WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCWSTR lpName); + WINBASEAPI HANDLE WINAPI OpenFileMappingA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI OpenFileMappingW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName); + WINBASEAPI DWORD WINAPI GetLogicalDriveStringsA(DWORD nBufferLength,LPSTR lpBuffer); + WINBASEAPI DWORD WINAPI GetLogicalDriveStringsW(DWORD nBufferLength,LPWSTR lpBuffer); + + typedef enum _MEMORY_RESOURCE_NOTIFICATION_TYPE { + LowMemoryResourceNotification,HighMemoryResourceNotification + } MEMORY_RESOURCE_NOTIFICATION_TYPE; + + WINBASEAPI HANDLE WINAPI CreateMemoryResourceNotification(MEMORY_RESOURCE_NOTIFICATION_TYPE NotificationType); + WINBASEAPI WINBOOL WINAPI QueryMemoryResourceNotification(HANDLE ResourceNotificationHandle,PBOOL ResourceState); + WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName); + WINBASEAPI HMODULE WINAPI LoadLibraryW(LPCWSTR lpLibFileName); + WINBASEAPI HMODULE WINAPI LoadLibraryExA(LPCSTR lpLibFileName,HANDLE hFile,DWORD dwFlags); + WINBASEAPI HMODULE WINAPI LoadLibraryExW(LPCWSTR lpLibFileName,HANDLE hFile,DWORD dwFlags); + +#define DONT_RESOLVE_DLL_REFERENCES 0x1 +#define LOAD_LIBRARY_AS_DATAFILE 0x2 +#define LOAD_WITH_ALTERED_SEARCH_PATH 0x8 +#define LOAD_IGNORE_CODE_AUTHZ_LEVEL 0x10 +#define LOAD_LINRARY_AS_IMAGE_RESOURCE 0x20 +#define LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE 0x40 + + WINBASEAPI DWORD WINAPI GetModuleFileNameA(HMODULE hModule,LPCH lpFilename,DWORD nSize); + WINBASEAPI DWORD WINAPI GetModuleFileNameW(HMODULE hModule,LPWCH lpFilename,DWORD nSize); + WINBASEAPI HMODULE WINAPI GetModuleHandleA(LPCSTR lpModuleName); + WINBASEAPI HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName); + +#ifndef RC_INVOKED +#define GET_MODULE_HANDLE_EX_FLAG_PIN (0x1) +#define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT (0x2) +#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS (0x4) + + typedef WINBOOL (WINAPI *PGET_MODULE_HANDLE_EXA)(DWORD dwFlags,LPCSTR lpModuleName,HMODULE *phModule); + typedef WINBOOL (WINAPI *PGET_MODULE_HANDLE_EXW)(DWORD dwFlags,LPCWSTR lpModuleName,HMODULE *phModule); + +#ifdef UNICODE +#define PGET_MODULE_HANDLE_EX PGET_MODULE_HANDLE_EXW +#define GetModuleHandleEx GetModuleHandleExW +#else +#define PGET_MODULE_HANDLE_EX PGET_MODULE_HANDLE_EXA +#define GetModuleHandleEx GetModuleHandleExA +#endif + + WINBASEAPI WINBOOL WINAPI GetModuleHandleExA(DWORD dwFlags,LPCSTR lpModuleName,HMODULE *phModule); + WINBASEAPI WINBOOL WINAPI GetModuleHandleExW(DWORD dwFlags,LPCWSTR lpModuleName,HMODULE *phModule); +#endif + +#ifdef UNICODE +#define NeedCurrentDirectoryForExePath NeedCurrentDirectoryForExePathW +#define CreateProcess CreateProcessW #define FatalAppExit FatalAppExitW -#define FindAtom FindAtomW -#define FindFirstChangeNotification FindFirstChangeNotificationW -#define FindFirstFile FindFirstFileW -#define FindFirstFileEx FindFirstFileExW -#define FindNextFile FindNextFileW +#define GetStartupInfo GetStartupInfoW +#define GetCommandLine GetCommandLineW +#define GetEnvironmentVariable GetEnvironmentVariableW +#define SetEnvironmentVariable SetEnvironmentVariableW +#define ExpandEnvironmentStrings ExpandEnvironmentStringsW +#define GetFirmwareEnvironmentVariable GetFirmwareEnvironmentVariableW +#define SetFirmwareEnvironmentVariable SetFirmwareEnvironmentVariableW +#define OutputDebugString OutputDebugStringW #define FindResource FindResourceW #define FindResourceEx FindResourceExW -#define FormatMessage FormatMessageW -#define FreeEnvironmentStrings FreeEnvironmentStringsW +#else +#define NeedCurrentDirectoryForExePath NeedCurrentDirectoryForExePathA +#define CreateProcess CreateProcessA +#define FatalAppExit FatalAppExitA +#define GetStartupInfo GetStartupInfoA +#define GetCommandLine GetCommandLineA +#define GetEnvironmentVariable GetEnvironmentVariableA +#define SetEnvironmentVariable SetEnvironmentVariableA +#define ExpandEnvironmentStrings ExpandEnvironmentStringsA +#define GetFirmwareEnvironmentVariable GetFirmwareEnvironmentVariableA +#define SetFirmwareEnvironmentVariable SetFirmwareEnvironmentVariableA +#define OutputDebugString OutputDebugStringA +#define FindResource FindResourceA +#define FindResourceEx FindResourceExA +#endif + + WINBASEAPI WINBOOL WINAPI NeedCurrentDirectoryForExePathA(LPCSTR ExeName); + WINBASEAPI WINBOOL WINAPI NeedCurrentDirectoryForExePathW(LPCWSTR ExeName); + WINBASEAPI WINBOOL WINAPI CreateProcessA(LPCSTR lpApplicationName,LPSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,WINBOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); + WINBASEAPI WINBOOL WINAPI CreateProcessW(LPCWSTR lpApplicationName,LPWSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,WINBOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); + WINBASEAPI DWORD WINAPI AddLocalAlternateComputerNameA(LPCSTR lpDnsFQHostname,ULONG ulFlags); + WINBASEAPI DWORD WINAPI AddLocalAlternateComputerNameW(LPCWSTR lpDnsFQHostname,ULONG ulFlags); + WINBASEAPI WINBOOL WINAPI SetProcessShutdownParameters(DWORD dwLevel,DWORD dwFlags); + WINBASEAPI WINBOOL WINAPI GetProcessShutdownParameters(LPDWORD lpdwLevel,LPDWORD lpdwFlags); + WINBASEAPI DWORD WINAPI GetProcessVersion(DWORD ProcessId); + WINBASEAPI VOID WINAPI FatalAppExitA(UINT uAction,LPCSTR lpMessageText); + WINBASEAPI VOID WINAPI FatalAppExitW(UINT uAction,LPCWSTR lpMessageText); + WINBASEAPI VOID WINAPI GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo); + WINBASEAPI VOID WINAPI GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo); + WINBASEAPI LPSTR WINAPI GetCommandLineA(VOID); + WINBASEAPI LPWSTR WINAPI GetCommandLineW(VOID); + WINBASEAPI DWORD WINAPI GetEnvironmentVariableA(LPCSTR lpName,LPSTR lpBuffer,DWORD nSize); + WINBASEAPI DWORD WINAPI GetEnvironmentVariableW(LPCWSTR lpName,LPWSTR lpBuffer,DWORD nSize); + WINBASEAPI WINBOOL WINAPI SetEnvironmentVariableA(LPCSTR lpName,LPCSTR lpValue); + WINBASEAPI WINBOOL WINAPI SetEnvironmentVariableW(LPCWSTR lpName,LPCWSTR lpValue); + WINBASEAPI DWORD WINAPI ExpandEnvironmentStringsA(LPCSTR lpSrc,LPSTR lpDst,DWORD nSize); + WINBASEAPI DWORD WINAPI ExpandEnvironmentStringsW(LPCWSTR lpSrc,LPWSTR lpDst,DWORD nSize); + WINBASEAPI DWORD WINAPI GetFirmwareEnvironmentVariableA(LPCSTR lpName,LPCSTR lpGuid,PVOID pBuffer,DWORD nSize); + WINBASEAPI DWORD WINAPI GetFirmwareEnvironmentVariableW(LPCWSTR lpName,LPCWSTR lpGuid,PVOID pBuffer,DWORD nSize); + WINBASEAPI WINBOOL WINAPI SetFirmwareEnvironmentVariableA(LPCSTR lpName,LPCSTR lpGuid,PVOID pValue,DWORD nSize); + WINBASEAPI WINBOOL WINAPI SetFirmwareEnvironmentVariableW(LPCWSTR lpName,LPCWSTR lpGuid,PVOID pValue,DWORD nSize); + WINBASEAPI VOID WINAPI OutputDebugStringA(LPCSTR lpOutputString); + WINBASEAPI VOID WINAPI OutputDebugStringW(LPCWSTR lpOutputString); + WINBASEAPI HRSRC WINAPI FindResourceA(HMODULE hModule,LPCSTR lpName,LPCSTR lpType); + WINBASEAPI HRSRC WINAPI FindResourceW(HMODULE hModule,LPCWSTR lpName,LPCWSTR lpType); + WINBASEAPI HRSRC WINAPI FindResourceExA(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,WORD wLanguage); + WINBASEAPI HRSRC WINAPI FindResourceExW(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,WORD wLanguage); + +#ifdef UNICODE +#define ENUMRESTYPEPROC ENUMRESTYPEPROCW +#define ENUMRESNAMEPROC ENUMRESNAMEPROCW +#define ENUMRESLANGPROC ENUMRESLANGPROCW +#define EnumResourceTypes EnumResourceTypesW +#define EnumResourceNames EnumResourceNamesW +#define EnumResourceLanguages EnumResourceLanguagesW +#define BeginUpdateResource BeginUpdateResourceW +#define UpdateResource UpdateResourceW +#define EndUpdateResource EndUpdateResourceW +#define GlobalAddAtom GlobalAddAtomW +#define GlobalFindAtom GlobalFindAtomW +#define GlobalGetAtomName GlobalGetAtomNameW +#define AddAtom AddAtomW +#define FindAtom FindAtomW #define GetAtomName GetAtomNameW -#define GetBinaryType GetBinaryTypeW -#define GetCommandLine GetCommandLineW -#define GetCompressedFileSize GetCompressedFileSizeW -#define GetComputerName GetComputerNameW -#define GetCurrentDirectory GetCurrentDirectoryW -#define GetDefaultCommConfig GetDefaultCommConfigW -#define GetDiskFreeSpace GetDiskFreeSpaceW -#define GetDiskFreeSpaceEx GetDiskFreeSpaceExW -#define GetDriveType GetDriveTypeW -#define GetEnvironmentStrings GetEnvironmentStringsW -#define GetEnvironmentVariable GetEnvironmentVariableW -#define GetFileAttributes GetFileAttributesW -#define GetFileSecurity GetFileSecurityW -#define GetFileAttributesEx GetFileAttributesExW -#define GetFullPathName GetFullPathNameW -#define GetLogicalDriveStrings GetLogicalDriveStringsW -#define GetLongPathName GetLongPathNameW -#define GetModuleFileName GetModuleFileNameW -#define GetModuleHandle GetModuleHandleW -#define GetNamedPipeHandleState GetNamedPipeHandleStateW +#define GetProfileInt GetProfileIntW +#define GetProfileString GetProfileStringW +#define WriteProfileString WriteProfileStringW +#define GetProfileSection GetProfileSectionW +#define WriteProfileSection WriteProfileSectionW #define GetPrivateProfileInt GetPrivateProfileIntW +#define GetPrivateProfileString GetPrivateProfileStringW +#define WritePrivateProfileString WritePrivateProfileStringW #define GetPrivateProfileSection GetPrivateProfileSectionW +#define WritePrivateProfileSection WritePrivateProfileSectionW #define GetPrivateProfileSectionNames GetPrivateProfileSectionNamesW -#define GetPrivateProfileString GetPrivateProfileStringW #define GetPrivateProfileStruct GetPrivateProfileStructW -#define GetProfileInt GetProfileIntW -#define GetProfileSection GetProfileSectionW -#define GetProfileString GetProfileStringW -#define GetShortPathName GetShortPathNameW -#define GetStartupInfo GetStartupInfoW +#define WritePrivateProfileStruct WritePrivateProfileStructW +#define GetDriveType GetDriveTypeW #define GetSystemDirectory GetSystemDirectoryW -#define GetTempFileName GetTempFileNameW #define GetTempPath GetTempPathW -#define GetUserName GetUserNameW -#define GetVersionEx GetVersionExW -#define GetVolumeInformation GetVolumeInformationW +#define GetTempFileName GetTempFileNameW #define GetWindowsDirectory GetWindowsDirectoryW -#define GlobalAddAtom GlobalAddAtomW -#define GlobalFindAtom GlobalFindAtomW -#define GlobalGetAtomName GlobalGetAtomNameW -#define IsBadStringPtr IsBadStringPtrW -#define LoadLibrary LoadLibraryW -#define LoadLibraryEx LoadLibraryExW -#define LogonUser LogonUserW -#define LookupAccountName LookupAccountNameW -#define LookupAccountSid LookupAccountSidW -#define LookupPrivilegeDisplayName LookupPrivilegeDisplayNameW -#define LookupPrivilegeName LookupPrivilegeNameW -#define LookupPrivilegeValue LookupPrivilegeValueW -#define lstrcat lstrcatW -#define lstrcmp lstrcmpW -#define lstrcmpi lstrcmpiW -#define lstrcpy lstrcpyW -#define lstrcpyn lstrcpynW -#define lstrlen lstrlenW -#define MoveFile MoveFileW -#define MoveFileEx MoveFileExW -#define ObjectCloseAuditAlarm ObjectCloseAuditAlarmW -#define ObjectDeleteAuditAlarm ObjectDeleteAuditAlarmW -#define ObjectOpenAuditAlarm ObjectOpenAuditAlarmW -#define ObjectPrivilegeAuditAlarm ObjectPrivilegeAuditAlarmW -#define OpenBackupEventLog OpenBackupEventLogW -#define OpenEvent OpenEventW -#define OpenEventLog OpenEventLogW -#define OpenFileMapping OpenFileMappingW -#define OpenMutex OpenMutexW -#define OpenSemaphore OpenSemaphoreW -#define OutputDebugString OutputDebugStringW -#define PrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmW -#define QueryDosDevice QueryDosDeviceW -#define ReadEventLog ReadEventLogW -#define RegisterEventSource RegisterEventSourceW -#define RemoveDirectory RemoveDirectoryW -#define ReportEvent ReportEventW -#define SearchPath SearchPathW -#define SetComputerName SetComputerNameW -#define SetCurrentDirectory SetCurrentDirectoryW -#define SetDefaultCommConfig SetDefaultCommConfigW -#define SetEnvironmentVariable SetEnvironmentVariableW -#define SetFileAttributes SetFileAttributesW -#define SetFileSecurity SetFileSecurityW -#define SetVolumeLabel SetVolumeLabelW -#define UpdateResource UpdateResourceW -#define VerifyVersionInfo VerifyVersionInfoW -#define WaitNamedPipe WaitNamedPipeW -#define WritePrivateProfileSection WritePrivateProfileSectionW -#define WritePrivateProfileString WritePrivateProfileStringW -#define WritePrivateProfileStruct WritePrivateProfileStructW -#define WriteProfileSection WriteProfileSectionW -#define WriteProfileString WriteProfileStringW +#define GetSystemWindowsDirectory GetSystemWindowsDirectoryW +#define AddLocalAlternateComputerName AddLocalAlternateComputerNameW #else -typedef STARTUPINFOA STARTUPINFO,*LPSTARTUPINFO; -typedef WIN32_FIND_DATAA WIN32_FIND_DATA,*LPWIN32_FIND_DATA; -typedef HW_PROFILE_INFOA HW_PROFILE_INFO,*LPHW_PROFILE_INFO; -#define AccessCheckAndAuditAlarm AccessCheckAndAuditAlarmA -#define AddAtom AddAtomA -#define BackupEventLog BackupEventLogA +#define ENUMRESTYPEPROC ENUMRESTYPEPROCA +#define ENUMRESNAMEPROC ENUMRESNAMEPROCA +#define ENUMRESLANGPROC ENUMRESLANGPROCA +#define EnumResourceTypes EnumResourceTypesA +#define EnumResourceNames EnumResourceNamesA +#define EnumResourceLanguages EnumResourceLanguagesA #define BeginUpdateResource BeginUpdateResourceA -#define BuildCommDCB BuildCommDCBA -#define BuildCommDCBAndTimeouts BuildCommDCBAndTimeoutsA -#define CallNamedPipe CallNamedPipeA -#define ClearEventLog ClearEventLogA -#define CommConfigDialog CommConfigDialogA -#define CopyFile CopyFileA -#define CopyFileEx CopyFileExA -#define CreateDirectory CreateDirectoryA -#define CreateDirectoryEx CreateDirectoryExA -#define CreateEvent CreateEventA -#define CreateFile CreateFileA -#define CreateFileMapping CreateFileMappingA -#define CreateHardLink CreateHardLinkA -#define CreateMailslot CreateMailslotA -#define CreateMutex CreateMutexA -#define CreateNamedPipe CreateNamedPipeA -#define CreateProcess CreateProcessA -#define CreateProcessAsUser CreateProcessAsUserA -#define CreateSemaphore CreateSemaphoreA -#define CreateWaitableTimer CreateWaitableTimerA -#define DefineDosDevice DefineDosDeviceA -#define DeleteFile DeleteFileA +#define UpdateResource UpdateResourceA #define EndUpdateResource EndUpdateResourceA -#define EnumResourceLanguages EnumResourceLanguagesA -#define EnumResourceNames EnumResourceNamesA -#define EnumResourceTypes EnumResourceTypesA -#define ExpandEnvironmentStrings ExpandEnvironmentStringsA -#define FatalAppExit FatalAppExitA +#define GlobalAddAtom GlobalAddAtomA +#define GlobalFindAtom GlobalFindAtomA +#define GlobalGetAtomName GlobalGetAtomNameA +#define AddAtom AddAtomA #define FindAtom FindAtomA -#define FindFirstChangeNotification FindFirstChangeNotificationA -#define FindFirstFile FindFirstFileA -#define FindFirstFileEx FindFirstFileExW -#define FindNextFile FindNextFileA -#define FindResource FindResourceA -#define FindResourceEx FindResourceExA -#define FormatMessage FormatMessageA -#define FreeEnvironmentStrings FreeEnvironmentStringsA #define GetAtomName GetAtomNameA -#define GetBinaryType GetBinaryTypeA -#define GetCommandLine GetCommandLineA -#define GetComputerName GetComputerNameA -#define GetCompressedFileSize GetCompressedFileSizeA -#define GetCurrentDirectory GetCurrentDirectoryA -#define GetDefaultCommConfig GetDefaultCommConfigA -#define GetDiskFreeSpace GetDiskFreeSpaceA -#define GetDiskFreeSpaceEx GetDiskFreeSpaceExA -#define GetDriveType GetDriveTypeA -#define GetEnvironmentStringsA GetEnvironmentStrings -#define GetEnvironmentVariable GetEnvironmentVariableA -#define GetFileAttributes GetFileAttributesA -#define GetFileSecurity GetFileSecurityA -#define GetFileAttributesEx GetFileAttributesExA -#define GetFullPathName GetFullPathNameA -#define GetLogicalDriveStrings GetLogicalDriveStringsA -#define GetLongPathName GetLongPathNameA -#define GetNamedPipeHandleState GetNamedPipeHandleStateA -#define GetModuleHandle GetModuleHandleA -#define GetModuleFileName GetModuleFileNameA +#define GetProfileInt GetProfileIntA +#define GetProfileString GetProfileStringA +#define WriteProfileString WriteProfileStringA +#define GetProfileSection GetProfileSectionA +#define WriteProfileSection WriteProfileSectionA #define GetPrivateProfileInt GetPrivateProfileIntA +#define GetPrivateProfileString GetPrivateProfileStringA +#define WritePrivateProfileString WritePrivateProfileStringA #define GetPrivateProfileSection GetPrivateProfileSectionA +#define WritePrivateProfileSection WritePrivateProfileSectionA #define GetPrivateProfileSectionNames GetPrivateProfileSectionNamesA -#define GetPrivateProfileString GetPrivateProfileStringA #define GetPrivateProfileStruct GetPrivateProfileStructA -#define GetProfileInt GetProfileIntA -#define GetProfileSection GetProfileSectionA -#define GetProfileString GetProfileStringA -#define GetShortPathName GetShortPathNameA -#define GetStartupInfo GetStartupInfoA +#define WritePrivateProfileStruct WritePrivateProfileStructA +#define GetDriveType GetDriveTypeA #define GetSystemDirectory GetSystemDirectoryA -#define GetTempFileName GetTempFileNameA #define GetTempPath GetTempPathA -#define GetUserName GetUserNameA -#define GetVersionEx GetVersionExA -#define GetVolumeInformation GetVolumeInformationA +#define GetTempFileName GetTempFileNameA #define GetWindowsDirectory GetWindowsDirectoryA -#define GlobalAddAtom GlobalAddAtomA -#define GlobalFindAtom GlobalFindAtomA -#define GlobalGetAtomName GlobalGetAtomNameA -#define IsBadStringPtr IsBadStringPtrA -#define LoadLibrary LoadLibraryA -#define LoadLibraryEx LoadLibraryExA -#define LogonUser LogonUserA -#define LookupAccountName LookupAccountNameA -#define LookupAccountSid LookupAccountSidA -#define LookupPrivilegeDisplayName LookupPrivilegeDisplayNameA -#define LookupPrivilegeName LookupPrivilegeNameA -#define LookupPrivilegeValue LookupPrivilegeValueA -#define lstrcat lstrcatA -#define lstrcmp lstrcmpA -#define lstrcmpi lstrcmpiA -#define lstrcpy lstrcpyA -#define lstrcpyn lstrcpynA -#define lstrlen lstrlenA +#define GetSystemWindowsDirectory GetSystemWindowsDirectoryA +#define AddLocalAlternateComputerName AddLocalAlternateComputerNameA +#endif + + typedef WINBOOL (CALLBACK *ENUMRESTYPEPROCA)(HMODULE hModule,LPSTR lpType,LONG_PTR lParam); + typedef WINBOOL (CALLBACK *ENUMRESTYPEPROCW)(HMODULE hModule,LPWSTR lpType,LONG_PTR lParam); + typedef WINBOOL (CALLBACK *ENUMRESNAMEPROCA)(HMODULE hModule,LPCSTR lpType,LPSTR lpName,LONG_PTR lParam); + typedef WINBOOL (CALLBACK *ENUMRESNAMEPROCW)(HMODULE hModule,LPCWSTR lpType,LPWSTR lpName,LONG_PTR lParam); + typedef WINBOOL (CALLBACK *ENUMRESLANGPROCA)(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,WORD wLanguage,LONG_PTR lParam); + typedef WINBOOL (CALLBACK *ENUMRESLANGPROCW)(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,WORD wLanguage,LONG_PTR lParam); + + WINBASEAPI WINBOOL WINAPI EnumResourceTypesA(HMODULE hModule,ENUMRESTYPEPROCA lpEnumFunc,LONG_PTR lParam); + WINBASEAPI WINBOOL WINAPI EnumResourceTypesW(HMODULE hModule,ENUMRESTYPEPROCW lpEnumFunc,LONG_PTR lParam); + WINBASEAPI WINBOOL WINAPI EnumResourceNamesA(HMODULE hModule,LPCSTR lpType,ENUMRESNAMEPROCA lpEnumFunc,LONG_PTR lParam); + WINBASEAPI WINBOOL WINAPI EnumResourceNamesW(HMODULE hModule,LPCWSTR lpType,ENUMRESNAMEPROCW lpEnumFunc,LONG_PTR lParam); + WINBASEAPI WINBOOL WINAPI EnumResourceLanguagesA(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,ENUMRESLANGPROCA lpEnumFunc,LONG_PTR lParam); + WINBASEAPI WINBOOL WINAPI EnumResourceLanguagesW(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,ENUMRESLANGPROCW lpEnumFunc,LONG_PTR lParam); + WINBASEAPI HANDLE WINAPI BeginUpdateResourceA(LPCSTR pFileName,WINBOOL bDeleteExistingResources); + WINBASEAPI HANDLE WINAPI BeginUpdateResourceW(LPCWSTR pFileName,WINBOOL bDeleteExistingResources); + WINBASEAPI WINBOOL WINAPI UpdateResourceA(HANDLE hUpdate,LPCSTR lpType,LPCSTR lpName,WORD wLanguage,LPVOID lpData,DWORD cb); + WINBASEAPI WINBOOL WINAPI UpdateResourceW(HANDLE hUpdate,LPCWSTR lpType,LPCWSTR lpName,WORD wLanguage,LPVOID lpData,DWORD cb); + WINBASEAPI WINBOOL WINAPI EndUpdateResourceA(HANDLE hUpdate,WINBOOL fDiscard); + WINBASEAPI WINBOOL WINAPI EndUpdateResourceW(HANDLE hUpdate,WINBOOL fDiscard); + WINBASEAPI ATOM WINAPI GlobalAddAtomA(LPCSTR lpString); + WINBASEAPI ATOM WINAPI GlobalAddAtomW(LPCWSTR lpString); + WINBASEAPI ATOM WINAPI GlobalFindAtomA(LPCSTR lpString); + WINBASEAPI ATOM WINAPI GlobalFindAtomW(LPCWSTR lpString); + WINBASEAPI UINT WINAPI GlobalGetAtomNameA(ATOM nAtom,LPSTR lpBuffer,int nSize); + WINBASEAPI UINT WINAPI GlobalGetAtomNameW(ATOM nAtom,LPWSTR lpBuffer,int nSize); + WINBASEAPI ATOM WINAPI AddAtomA(LPCSTR lpString); + WINBASEAPI ATOM WINAPI AddAtomW(LPCWSTR lpString); + WINBASEAPI ATOM WINAPI FindAtomA(LPCSTR lpString); + WINBASEAPI ATOM WINAPI FindAtomW(LPCWSTR lpString); + WINBASEAPI UINT WINAPI GetAtomNameA(ATOM nAtom,LPSTR lpBuffer,int nSize); + WINBASEAPI UINT WINAPI GetAtomNameW(ATOM nAtom,LPWSTR lpBuffer,int nSize); + WINBASEAPI UINT WINAPI GetProfileIntA(LPCSTR lpAppName,LPCSTR lpKeyName,INT nDefault); + WINBASEAPI UINT WINAPI GetProfileIntW(LPCWSTR lpAppName,LPCWSTR lpKeyName,INT nDefault); + WINBASEAPI DWORD WINAPI GetProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize); + WINBASEAPI DWORD WINAPI GetProfileStringW(LPCWSTR lpAppName,LPCWSTR lpKeyName,LPCWSTR lpDefault,LPWSTR lpReturnedString,DWORD nSize); + WINBASEAPI WINBOOL WINAPI WriteProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpString); + WINBASEAPI WINBOOL WINAPI WriteProfileStringW(LPCWSTR lpAppName,LPCWSTR lpKeyName,LPCWSTR lpString); + WINBASEAPI DWORD WINAPI GetProfileSectionA(LPCSTR lpAppName,LPSTR lpReturnedString,DWORD nSize); + WINBASEAPI DWORD WINAPI GetProfileSectionW(LPCWSTR lpAppName,LPWSTR lpReturnedString,DWORD nSize); + WINBASEAPI WINBOOL WINAPI WriteProfileSectionA(LPCSTR lpAppName,LPCSTR lpString); + WINBASEAPI WINBOOL WINAPI WriteProfileSectionW(LPCWSTR lpAppName,LPCWSTR lpString); + WINBASEAPI UINT WINAPI GetPrivateProfileIntA(LPCSTR lpAppName,LPCSTR lpKeyName,INT nDefault,LPCSTR lpFileName); + WINBASEAPI UINT WINAPI GetPrivateProfileIntW(LPCWSTR lpAppName,LPCWSTR lpKeyName,INT nDefault,LPCWSTR lpFileName); + WINBASEAPI DWORD WINAPI GetPrivateProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize,LPCSTR lpFileName); + WINBASEAPI DWORD WINAPI GetPrivateProfileStringW(LPCWSTR lpAppName,LPCWSTR lpKeyName,LPCWSTR lpDefault,LPWSTR lpReturnedString,DWORD nSize,LPCWSTR lpFileName); + WINBASEAPI WINBOOL WINAPI WritePrivateProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpString,LPCSTR lpFileName); + WINBASEAPI WINBOOL WINAPI WritePrivateProfileStringW(LPCWSTR lpAppName,LPCWSTR lpKeyName,LPCWSTR lpString,LPCWSTR lpFileName); + WINBASEAPI DWORD WINAPI GetPrivateProfileSectionA(LPCSTR lpAppName,LPSTR lpReturnedString,DWORD nSize,LPCSTR lpFileName); + WINBASEAPI DWORD WINAPI GetPrivateProfileSectionW(LPCWSTR lpAppName,LPWSTR lpReturnedString,DWORD nSize,LPCWSTR lpFileName); + WINBASEAPI WINBOOL WINAPI WritePrivateProfileSectionA(LPCSTR lpAppName,LPCSTR lpString,LPCSTR lpFileName); + WINBASEAPI WINBOOL WINAPI WritePrivateProfileSectionW(LPCWSTR lpAppName,LPCWSTR lpString,LPCWSTR lpFileName); + WINBASEAPI DWORD WINAPI GetPrivateProfileSectionNamesA(LPSTR lpszReturnBuffer,DWORD nSize,LPCSTR lpFileName); + WINBASEAPI DWORD WINAPI GetPrivateProfileSectionNamesW(LPWSTR lpszReturnBuffer,DWORD nSize,LPCWSTR lpFileName); + WINBASEAPI WINBOOL WINAPI GetPrivateProfileStructA(LPCSTR lpszSection,LPCSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCSTR szFile); + WINBASEAPI WINBOOL WINAPI GetPrivateProfileStructW(LPCWSTR lpszSection,LPCWSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCWSTR szFile); + WINBASEAPI WINBOOL WINAPI WritePrivateProfileStructA(LPCSTR lpszSection,LPCSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCSTR szFile); + WINBASEAPI WINBOOL WINAPI WritePrivateProfileStructW(LPCWSTR lpszSection,LPCWSTR lpszKey,LPVOID lpStruct,UINT uSizeStruct,LPCWSTR szFile); + WINBASEAPI UINT WINAPI GetDriveTypeA(LPCSTR lpRootPathName); + WINBASEAPI UINT WINAPI GetDriveTypeW(LPCWSTR lpRootPathName); + WINBASEAPI UINT WINAPI GetSystemDirectoryA(LPSTR lpBuffer,UINT uSize); + WINBASEAPI UINT WINAPI GetSystemDirectoryW(LPWSTR lpBuffer,UINT uSize); + WINBASEAPI DWORD WINAPI GetTempPathA(DWORD nBufferLength,LPSTR lpBuffer); + WINBASEAPI DWORD WINAPI GetTempPathW(DWORD nBufferLength,LPWSTR lpBuffer); + WINBASEAPI UINT WINAPI GetTempFileNameA(LPCSTR lpPathName,LPCSTR lpPrefixString,UINT uUnique,LPSTR lpTempFileName); + WINBASEAPI UINT WINAPI GetTempFileNameW(LPCWSTR lpPathName,LPCWSTR lpPrefixString,UINT uUnique,LPWSTR lpTempFileName); + WINBASEAPI UINT WINAPI GetWindowsDirectoryA(LPSTR lpBuffer,UINT uSize); + WINBASEAPI UINT WINAPI GetWindowsDirectoryW(LPWSTR lpBuffer,UINT uSize); + WINBASEAPI UINT WINAPI GetSystemWindowsDirectoryA(LPSTR lpBuffer,UINT uSize); + WINBASEAPI UINT WINAPI GetSystemWindowsDirectoryW(LPWSTR lpBuffer,UINT uSize); + +#ifndef RC_INVOKED +#ifdef UNICODE +#define GetSystemWow64Directory GetSystemWow64DirectoryW +#else +#define GetSystemWow64Directory GetSystemWow64DirectoryA +#endif + + WINBASEAPI UINT WINAPI GetSystemWow64DirectoryA(LPSTR lpBuffer,UINT uSize); + WINBASEAPI UINT WINAPI GetSystemWow64DirectoryW(LPWSTR lpBuffer,UINT uSize); + WINBASEAPI BOOLEAN WINAPI Wow64EnableWow64FsRedirection(BOOLEAN Wow64FsEnableRedirection); + WINBASEAPI WINBOOL WINAPI Wow64DisableWow64FsRedirection(PVOID *OldValue); + WINBASEAPI WINBOOL WINAPI Wow64RevertWow64FsRedirection(PVOID OlValue); + + typedef UINT (WINAPI *PGET_SYSTEM_WOW64_DIRECTORY_A)(LPSTR lpBuffer,UINT uSize); + typedef UINT (WINAPI *PGET_SYSTEM_WOW64_DIRECTORY_W)(LPWSTR lpBuffer,UINT uSize); + +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_A_A "GetSystemWow64DirectoryA" +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_A_W L"GetSystemWow64DirectoryA" +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_A_T TEXT("GetSystemWow64DirectoryA") +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_W_A "GetSystemWow64DirectoryW" +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_W_W L"GetSystemWow64DirectoryW" +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_W_T TEXT("GetSystemWow64DirectoryW") + +#ifdef UNICODE +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_A GET_SYSTEM_WOW64_DIRECTORY_NAME_W_A +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_W GET_SYSTEM_WOW64_DIRECTORY_NAME_W_W +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_T GET_SYSTEM_WOW64_DIRECTORY_NAME_W_T +#else +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_A GET_SYSTEM_WOW64_DIRECTORY_NAME_A_A +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_W GET_SYSTEM_WOW64_DIRECTORY_NAME_A_W +#define GET_SYSTEM_WOW64_DIRECTORY_NAME_T_T GET_SYSTEM_WOW64_DIRECTORY_NAME_A_T +#endif +#endif + +#ifdef UNICODE +#define SetCurrentDirectory SetCurrentDirectoryW +#define GetCurrentDirectory GetCurrentDirectoryW +#define SetDllDirectory SetDllDirectoryW +#define GetDllDirectory GetDllDirectoryW +#define GetDiskFreeSpace GetDiskFreeSpaceW +#define GetDiskFreeSpaceEx GetDiskFreeSpaceExW +#define CreateDirectory CreateDirectoryW +#define CreateDirectoryEx CreateDirectoryExW +#define RemoveDirectory RemoveDirectoryW +#define GetFullPathName GetFullPathNameW +#define DefineDosDevice DefineDosDeviceW +#define QueryDosDevice QueryDosDeviceW +#define CreateFile CreateFileW +#define SetFileAttributes SetFileAttributesW +#define GetFileAttributes GetFileAttributesW +#else +#define SetCurrentDirectory SetCurrentDirectoryA +#define GetCurrentDirectory GetCurrentDirectoryA +#define SetDllDirectory SetDllDirectoryA +#define GetDllDirectory GetDllDirectoryA +#define GetDiskFreeSpace GetDiskFreeSpaceA +#define GetDiskFreeSpaceEx GetDiskFreeSpaceExA +#define CreateDirectory CreateDirectoryA +#define CreateDirectoryEx CreateDirectoryExA +#define RemoveDirectory RemoveDirectoryA +#define GetFullPathName GetFullPathNameA +#define DefineDosDevice DefineDosDeviceA +#define QueryDosDevice QueryDosDeviceA +#define CreateFile CreateFileA +#define SetFileAttributes SetFileAttributesA +#define GetFileAttributes GetFileAttributesA +#endif + + WINBASEAPI WINBOOL WINAPI SetCurrentDirectoryA(LPCSTR lpPathName); + WINBASEAPI WINBOOL WINAPI SetCurrentDirectoryW(LPCWSTR lpPathName); + WINBASEAPI DWORD WINAPI GetCurrentDirectoryA(DWORD nBufferLength,LPSTR lpBuffer); + WINBASEAPI DWORD WINAPI GetCurrentDirectoryW(DWORD nBufferLength,LPWSTR lpBuffer); + WINBASEAPI WINBOOL WINAPI SetDllDirectoryA(LPCSTR lpPathName); + WINBASEAPI WINBOOL WINAPI SetDllDirectoryW(LPCWSTR lpPathName); + WINBASEAPI DWORD WINAPI GetDllDirectoryA(DWORD nBufferLength,LPSTR lpBuffer); + WINBASEAPI DWORD WINAPI GetDllDirectoryW(DWORD nBufferLength,LPWSTR lpBuffer); + WINBASEAPI WINBOOL WINAPI GetDiskFreeSpaceA(LPCSTR lpRootPathName,LPDWORD lpSectorsPerCluster,LPDWORD lpBytesPerSector,LPDWORD lpNumberOfFreeClusters,LPDWORD lpTotalNumberOfClusters); + WINBASEAPI WINBOOL WINAPI GetDiskFreeSpaceW(LPCWSTR lpRootPathName,LPDWORD lpSectorsPerCluster,LPDWORD lpBytesPerSector,LPDWORD lpNumberOfFreeClusters,LPDWORD lpTotalNumberOfClusters); + WINBASEAPI WINBOOL WINAPI GetDiskFreeSpaceExA(LPCSTR lpDirectoryName,PULARGE_INTEGER lpFreeBytesAvailableToCaller,PULARGE_INTEGER lpTotalNumberOfBytes,PULARGE_INTEGER lpTotalNumberOfFreeBytes); + WINBASEAPI WINBOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR lpDirectoryName,PULARGE_INTEGER lpFreeBytesAvailableToCaller,PULARGE_INTEGER lpTotalNumberOfBytes,PULARGE_INTEGER lpTotalNumberOfFreeBytes); + WINBASEAPI WINBOOL WINAPI CreateDirectoryA(LPCSTR lpPathName,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI WINBOOL WINAPI CreateDirectoryW(LPCWSTR lpPathName,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI WINBOOL WINAPI CreateDirectoryExA(LPCSTR lpTemplateDirectory,LPCSTR lpNewDirectory,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI WINBOOL WINAPI CreateDirectoryExW(LPCWSTR lpTemplateDirectory,LPCWSTR lpNewDirectory,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI WINBOOL WINAPI RemoveDirectoryA(LPCSTR lpPathName); + WINBASEAPI WINBOOL WINAPI RemoveDirectoryW(LPCWSTR lpPathName); + WINBASEAPI DWORD WINAPI GetFullPathNameA(LPCSTR lpFileName,DWORD nBufferLength,LPSTR lpBuffer,LPSTR *lpFilePart); + WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR lpFileName,DWORD nBufferLength,LPWSTR lpBuffer,LPWSTR *lpFilePart); + +#define DDD_RAW_TARGET_PATH 0x1 +#define DDD_REMOVE_DEFINITION 0x2 +#define DDD_EXACT_MATCH_ON_REMOVE 0x4 +#define DDD_NO_BROADCAST_SYSTEM 0x8 +#define DDD_LUID_BROADCAST_DRIVE 0x10 + + WINBASEAPI WINBOOL WINAPI DefineDosDeviceA(DWORD dwFlags,LPCSTR lpDeviceName,LPCSTR lpTargetPath); + WINBASEAPI WINBOOL WINAPI DefineDosDeviceW(DWORD dwFlags,LPCWSTR lpDeviceName,LPCWSTR lpTargetPath); + WINBASEAPI DWORD WINAPI QueryDosDeviceA(LPCSTR lpDeviceName,LPSTR lpTargetPath,DWORD ucchMax); + WINBASEAPI DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName,LPWSTR lpTargetPath,DWORD ucchMax); + +#define EXPAND_LOCAL_DRIVES + + WINBASEAPI HANDLE WINAPI CreateFileA(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile); + WINBASEAPI HANDLE WINAPI CreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile); + WINBASEAPI HANDLE WINAPI ReOpenFile(HANDLE hOriginalFile,DWORD dwDesiredAccess,DWORD dwShareMode,DWORD dwFlagsAndAttributes); + WINBASEAPI WINBOOL WINAPI SetFileAttributesA(LPCSTR lpFileName,DWORD dwFileAttributes); + WINBASEAPI WINBOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName,DWORD dwFileAttributes); + WINBASEAPI DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName); + WINBASEAPI DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName); + + typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard,GetFileExMaxInfoLevel + } GET_FILEEX_INFO_LEVELS; + +#ifdef UNICODE +#define GetFileAttributesEx GetFileAttributesExW +#define GetCompressedFileSize GetCompressedFileSizeW +#define DeleteFile DeleteFileW +#define CheckNameLegalDOS8Dot3 CheckNameLegalDOS8Dot3W +#else +#define GetFileAttributesEx GetFileAttributesExA +#define GetCompressedFileSize GetCompressedFileSizeA +#define DeleteFile DeleteFileA +#define CheckNameLegalDOS8Dot3 CheckNameLegalDOS8Dot3A +#endif + + WINBASEAPI WINBOOL WINAPI GetFileAttributesExA(LPCSTR lpFileName,GET_FILEEX_INFO_LEVELS fInfoLevelId,LPVOID lpFileInformation); + WINBASEAPI WINBOOL WINAPI GetFileAttributesExW(LPCWSTR lpFileName,GET_FILEEX_INFO_LEVELS fInfoLevelId,LPVOID lpFileInformation); + WINBASEAPI DWORD WINAPI GetCompressedFileSizeA(LPCSTR lpFileName,LPDWORD lpFileSizeHigh); + WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName,LPDWORD lpFileSizeHigh); + WINBASEAPI WINBOOL WINAPI DeleteFileA(LPCSTR lpFileName); + WINBASEAPI WINBOOL WINAPI DeleteFileW(LPCWSTR lpFileName); + WINBASEAPI WINBOOL WINAPI CheckNameLegalDOS8Dot3A(LPCSTR lpName,LPSTR lpOemName,DWORD OemNameSize,PBOOL pbNameContainsSpaces,PBOOL pbNameLegal); + WINBASEAPI WINBOOL WINAPI CheckNameLegalDOS8Dot3W(LPCWSTR lpName,LPSTR lpOemName,DWORD OemNameSize,PBOOL pbNameContainsSpaces,PBOOL pbNameLegal); + + typedef enum _FINDEX_INFO_LEVELS { + FindExInfoStandard,FindExInfoMaxInfoLevel + } FINDEX_INFO_LEVELS; + + typedef enum _FINDEX_SEARCH_OPS { + FindExSearchNameMatch,FindExSearchLimitToDirectories,FindExSearchLimitToDevices,FindExSearchMaxSearchOp + } FINDEX_SEARCH_OPS; + +#define FIND_FIRST_EX_CASE_SENSITIVE 0x1 + +#ifdef UNICODE +#define FindFirstFileEx FindFirstFileExW +#define FindFirstFile FindFirstFileW +#define FindNextFile FindNextFileW +#define SearchPath SearchPathW +#define CopyFile CopyFileW +#define CopyFileEx CopyFileExW +#define MoveFile MoveFileW +#define MoveFileEx MoveFileExW +#define MoveFileWithProgress MoveFileWithProgressW +#define ReplaceFile ReplaceFileW +#define CreateHardLink CreateHardLinkW +#define CreateNamedPipe CreateNamedPipeW +#define GetNamedPipeHandleState GetNamedPipeHandleStateW +#define CallNamedPipe CallNamedPipeW +#define WaitNamedPipe WaitNamedPipeW +#define SetVolumeLabel SetVolumeLabelW +#define GetVolumeInformation GetVolumeInformationW +#define ClearEventLog ClearEventLogW +#define BackupEventLog BackupEventLogW +#define OpenEventLog OpenEventLogW +#define RegisterEventSource RegisterEventSourceW +#define OpenBackupEventLog OpenBackupEventLogW +#define ReadEventLog ReadEventLogW +#define ReportEvent ReportEventW +#define AccessCheckAndAuditAlarm AccessCheckAndAuditAlarmW +#define AccessCheckByTypeAndAuditAlarm AccessCheckByTypeAndAuditAlarmW +#define AccessCheckByTypeResultListAndAuditAlarm AccessCheckByTypeResultListAndAuditAlarmW +#define AccessCheckByTypeResultListAndAuditAlarmByHandle AccessCheckByTypeResultListAndAuditAlarmByHandleW +#define ObjectOpenAuditAlarm ObjectOpenAuditAlarmW +#define ObjectPrivilegeAuditAlarm ObjectPrivilegeAuditAlarmW +#define ObjectCloseAuditAlarm ObjectCloseAuditAlarmW +#define ObjectDeleteAuditAlarm ObjectDeleteAuditAlarmW +#define PrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmW +#define SetFileSecurity SetFileSecurityW +#define GetFileSecurity GetFileSecurityW +#define FindFirstChangeNotification FindFirstChangeNotificationW +#define IsBadStringPtr IsBadStringPtrW +#define LookupAccountSid LookupAccountSidW +#define LookupAccountName LookupAccountNameW +#define LookupPrivilegeValue LookupPrivilegeValueW +#define LookupPrivilegeName LookupPrivilegeNameW +#define LookupPrivilegeDisplayName LookupPrivilegeDisplayNameW +#define BuildCommDCB BuildCommDCBW +#define BuildCommDCBAndTimeouts BuildCommDCBAndTimeoutsW +#define CommConfigDialog CommConfigDialogW +#define GetDefaultCommConfig GetDefaultCommConfigW +#define SetDefaultCommConfig SetDefaultCommConfigW +#define GetComputerName GetComputerNameW +#define SetComputerName SetComputerNameW +#define GetComputerNameEx GetComputerNameExW +#define SetComputerNameEx SetComputerNameExW +#define DnsHostnameToComputerName DnsHostnameToComputerNameW +#define GetUserName GetUserNameW +#else +#define FindFirstFileEx FindFirstFileExA +#define FindFirstFile FindFirstFileA +#define FindNextFile FindNextFileA +#define SearchPath SearchPathA +#define CopyFile CopyFileA +#define CopyFileEx CopyFileExA #define MoveFile MoveFileA #define MoveFileEx MoveFileExA -#define ObjectCloseAuditAlarm ObjectCloseAuditAlarmA -#define ObjectDeleteAuditAlarm ObjectDeleteAuditAlarmA -#define ObjectOpenAuditAlarm ObjectOpenAuditAlarmA -#define ObjectPrivilegeAuditAlarm ObjectPrivilegeAuditAlarmA -#define OpenBackupEventLog OpenBackupEventLogA -#define OpenEvent OpenEventA +#define MoveFileWithProgress MoveFileWithProgressA +#define ReplaceFile ReplaceFileA +#define CreateHardLink CreateHardLinkA +#define CreateNamedPipe CreateNamedPipeA +#define GetNamedPipeHandleState GetNamedPipeHandleStateA +#define CallNamedPipe CallNamedPipeA +#define WaitNamedPipe WaitNamedPipeA +#define SetVolumeLabel SetVolumeLabelA +#define GetVolumeInformation GetVolumeInformationA +#define ClearEventLog ClearEventLogA +#define BackupEventLog BackupEventLogA #define OpenEventLog OpenEventLogA -#define OpenFileMapping OpenFileMappingA -#define OpenMutex OpenMutexA -#define OpenSemaphore OpenSemaphoreA -#define OutputDebugString OutputDebugStringA -#define PrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmA -#define QueryDosDevice QueryDosDeviceA -#define ReadEventLog ReadEventLogA #define RegisterEventSource RegisterEventSourceA -#define RemoveDirectory RemoveDirectoryA +#define OpenBackupEventLog OpenBackupEventLogA +#define ReadEventLog ReadEventLogA #define ReportEvent ReportEventA -#define SearchPath SearchPathA -#define SetComputerName SetComputerNameA -#define SetCurrentDirectory SetCurrentDirectoryA -#define SetDefaultCommConfig SetDefaultCommConfigA -#define SetEnvironmentVariable SetEnvironmentVariableA -#define SetFileAttributes SetFileAttributesA +#define AccessCheckAndAuditAlarm AccessCheckAndAuditAlarmA +#define AccessCheckByTypeAndAuditAlarm AccessCheckByTypeAndAuditAlarmA +#define AccessCheckByTypeResultListAndAuditAlarm AccessCheckByTypeResultListAndAuditAlarmA +#define AccessCheckByTypeResultListAndAuditAlarmByHandle AccessCheckByTypeResultListAndAuditAlarmByHandleA +#define ObjectOpenAuditAlarm ObjectOpenAuditAlarmA +#define ObjectPrivilegeAuditAlarm ObjectPrivilegeAuditAlarmA +#define ObjectCloseAuditAlarm ObjectCloseAuditAlarmA +#define ObjectDeleteAuditAlarm ObjectDeleteAuditAlarmA +#define PrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmA #define SetFileSecurity SetFileSecurityA -#define SetVolumeLabel SetVolumeLabelA -#define UpdateResource UpdateResourceA +#define GetFileSecurity GetFileSecurityA +#define FindFirstChangeNotification FindFirstChangeNotificationA +#define IsBadStringPtr IsBadStringPtrA +#define LookupAccountSid LookupAccountSidA +#define LookupAccountName LookupAccountNameA +#define LookupPrivilegeValue LookupPrivilegeValueA +#define LookupPrivilegeName LookupPrivilegeNameA +#define LookupPrivilegeDisplayName LookupPrivilegeDisplayNameA +#define BuildCommDCB BuildCommDCBA +#define BuildCommDCBAndTimeouts BuildCommDCBAndTimeoutsA +#define CommConfigDialog CommConfigDialogA +#define GetDefaultCommConfig GetDefaultCommConfigA +#define SetDefaultCommConfig SetDefaultCommConfigA +#define GetComputerName GetComputerNameA +#define SetComputerName SetComputerNameA +#define GetComputerNameEx GetComputerNameExA +#define SetComputerNameEx SetComputerNameExA +#define DnsHostnameToComputerName DnsHostnameToComputerNameA +#define GetUserName GetUserNameA +#endif + + WINBASEAPI HANDLE WINAPI FindFirstFileExA(LPCSTR lpFileName,FINDEX_INFO_LEVELS fInfoLevelId,LPVOID lpFindFileData,FINDEX_SEARCH_OPS fSearchOp,LPVOID lpSearchFilter,DWORD dwAdditionalFlags); + WINBASEAPI HANDLE WINAPI FindFirstFileExW(LPCWSTR lpFileName,FINDEX_INFO_LEVELS fInfoLevelId,LPVOID lpFindFileData,FINDEX_SEARCH_OPS fSearchOp,LPVOID lpSearchFilter,DWORD dwAdditionalFlags); + WINBASEAPI HANDLE WINAPI FindFirstFileA(LPCSTR lpFileName,LPWIN32_FIND_DATAA lpFindFileData); + WINBASEAPI HANDLE WINAPI FindFirstFileW(LPCWSTR lpFileName,LPWIN32_FIND_DATAW lpFindFileData); + WINBASEAPI WINBOOL WINAPI FindNextFileA(HANDLE hFindFile,LPWIN32_FIND_DATAA lpFindFileData); + WINBASEAPI WINBOOL WINAPI FindNextFileW(HANDLE hFindFile,LPWIN32_FIND_DATAW lpFindFileData); + WINBASEAPI DWORD WINAPI SearchPathA(LPCSTR lpPath,LPCSTR lpFileName,LPCSTR lpExtension,DWORD nBufferLength,LPSTR lpBuffer,LPSTR *lpFilePart); + WINBASEAPI DWORD WINAPI SearchPathW(LPCWSTR lpPath,LPCWSTR lpFileName,LPCWSTR lpExtension,DWORD nBufferLength,LPWSTR lpBuffer,LPWSTR *lpFilePart); + WINBASEAPI WINBOOL WINAPI CopyFileA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,WINBOOL bFailIfExists); + WINBASEAPI WINBOOL WINAPI CopyFileW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,WINBOOL bFailIfExists); + + typedef DWORD (WINAPI *LPPROGRESS_ROUTINE)(LARGE_INTEGER TotalFileSize,LARGE_INTEGER TotalBytesTransferred,LARGE_INTEGER StreamSize,LARGE_INTEGER StreamBytesTransferred,DWORD dwStreamNumber,DWORD dwCallbackReason,HANDLE hSourceFile,HANDLE hDestinationFile,LPVOID lpData); + + WINBASEAPI WINBOOL WINAPI CopyFileExA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine,LPVOID lpData,LPBOOL pbCancel,DWORD dwCopyFlags); + WINBASEAPI WINBOOL WINAPI CopyFileExW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine,LPVOID lpData,LPBOOL pbCancel,DWORD dwCopyFlags); + WINBASEAPI WINBOOL WINAPI MoveFileA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName); + WINBASEAPI WINBOOL WINAPI MoveFileW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName); + WINBASEAPI WINBOOL WINAPI MoveFileExA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,DWORD dwFlags); + WINBASEAPI WINBOOL WINAPI MoveFileExW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,DWORD dwFlags); + WINBASEAPI WINBOOL WINAPI MoveFileWithProgressA(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine,LPVOID lpData,DWORD dwFlags); + WINBASEAPI WINBOOL WINAPI MoveFileWithProgressW(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine,LPVOID lpData,DWORD dwFlags); + +#define MOVEFILE_REPLACE_EXISTING 0x1 +#define MOVEFILE_COPY_ALLOWED 0x2 +#define MOVEFILE_DELAY_UNTIL_REBOOT 0x4 +#define MOVEFILE_WRITE_THROUGH 0x8 +#define MOVEFILE_CREATE_HARDLINK 0x10 +#define MOVEFILE_FAIL_IF_NOT_TRACKABLE 0x20 + + WINBASEAPI WINBOOL WINAPI ReplaceFileA(LPCSTR lpReplacedFileName,LPCSTR lpReplacementFileName,LPCSTR lpBackupFileName,DWORD dwReplaceFlags,LPVOID lpExclude,LPVOID lpReserved); + WINBASEAPI WINBOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName,LPCWSTR lpReplacementFileName,LPCWSTR lpBackupFileName,DWORD dwReplaceFlags,LPVOID lpExclude,LPVOID lpReserved); + WINBASEAPI WINBOOL WINAPI CreateHardLinkA(LPCSTR lpFileName,LPCSTR lpExistingFileName,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI WINBOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName,LPCWSTR lpExistingFileName,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + + typedef enum _STREAM_INFO_LEVELS { + FindStreamInfoStandard,FindStreamInfoMaxInfoLevel + } STREAM_INFO_LEVELS; + + typedef struct _WIN32_FIND_STREAM_DATA { + LARGE_INTEGER StreamSize; + WCHAR cStreamName[MAX_PATH + 36]; + } WIN32_FIND_STREAM_DATA,*PWIN32_FIND_STREAM_DATA; + + HANDLE WINAPI FindFirstStreamW(LPCWSTR lpFileName,STREAM_INFO_LEVELS InfoLevel,LPVOID lpFindStreamData,DWORD dwFlags); + WINBOOL WINAPI FindNextStreamW(HANDLE hFindStream,LPVOID lpFindStreamData); + WINBASEAPI HANDLE WINAPI CreateNamedPipeA(LPCSTR lpName,DWORD dwOpenMode,DWORD dwPipeMode,DWORD nMaxInstances,DWORD nOutBufferSize,DWORD nInBufferSize,DWORD nDefaultTimeOut,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName,DWORD dwOpenMode,DWORD dwPipeMode,DWORD nMaxInstances,DWORD nOutBufferSize,DWORD nInBufferSize,DWORD nDefaultTimeOut,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINBASEAPI WINBOOL WINAPI GetNamedPipeHandleStateA(HANDLE hNamedPipe,LPDWORD lpState,LPDWORD lpCurInstances,LPDWORD lpMaxCollectionCount,LPDWORD lpCollectDataTimeout,LPSTR lpUserName,DWORD nMaxUserNameSize); + WINBASEAPI WINBOOL WINAPI GetNamedPipeHandleStateW(HANDLE hNamedPipe,LPDWORD lpState,LPDWORD lpCurInstances,LPDWORD lpMaxCollectionCount,LPDWORD lpCollectDataTimeout,LPWSTR lpUserName,DWORD nMaxUserNameSize); + WINBASEAPI WINBOOL WINAPI CallNamedPipeA(LPCSTR lpNamedPipeName,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesRead,DWORD nTimeOut); + WINBASEAPI WINBOOL WINAPI CallNamedPipeW(LPCWSTR lpNamedPipeName,LPVOID lpInBuffer,DWORD nInBufferSize,LPVOID lpOutBuffer,DWORD nOutBufferSize,LPDWORD lpBytesRead,DWORD nTimeOut); + WINBASEAPI WINBOOL WINAPI WaitNamedPipeA(LPCSTR lpNamedPipeName,DWORD nTimeOut); + WINBASEAPI WINBOOL WINAPI WaitNamedPipeW(LPCWSTR lpNamedPipeName,DWORD nTimeOut); + WINBASEAPI WINBOOL WINAPI SetVolumeLabelA(LPCSTR lpRootPathName,LPCSTR lpVolumeName); + WINBASEAPI WINBOOL WINAPI SetVolumeLabelW(LPCWSTR lpRootPathName,LPCWSTR lpVolumeName); + WINBASEAPI VOID WINAPI SetFileApisToOEM(VOID); + WINBASEAPI VOID WINAPI SetFileApisToANSI(VOID); + WINBASEAPI WINBOOL WINAPI AreFileApisANSI(VOID); + WINBASEAPI WINBOOL WINAPI GetVolumeInformationA(LPCSTR lpRootPathName,LPSTR lpVolumeNameBuffer,DWORD nVolumeNameSize,LPDWORD lpVolumeSerialNumber,LPDWORD lpMaximumComponentLength,LPDWORD lpFileSystemFlags,LPSTR lpFileSystemNameBuffer,DWORD nFileSystemNameSize); + WINBASEAPI WINBOOL WINAPI GetVolumeInformationW(LPCWSTR lpRootPathName,LPWSTR lpVolumeNameBuffer,DWORD nVolumeNameSize,LPDWORD lpVolumeSerialNumber,LPDWORD lpMaximumComponentLength,LPDWORD lpFileSystemFlags,LPWSTR lpFileSystemNameBuffer,DWORD nFileSystemNameSize); + WINBASEAPI WINBOOL WINAPI CancelIo(HANDLE hFile); + WINADVAPI WINBOOL WINAPI ClearEventLogA(HANDLE hEventLog,LPCSTR lpBackupFileName); + WINADVAPI WINBOOL WINAPI ClearEventLogW(HANDLE hEventLog,LPCWSTR lpBackupFileName); + WINADVAPI WINBOOL WINAPI BackupEventLogA(HANDLE hEventLog,LPCSTR lpBackupFileName); + WINADVAPI WINBOOL WINAPI BackupEventLogW(HANDLE hEventLog,LPCWSTR lpBackupFileName); + WINADVAPI WINBOOL WINAPI CloseEventLog(HANDLE hEventLog); + WINADVAPI WINBOOL WINAPI DeregisterEventSource(HANDLE hEventLog); + WINADVAPI WINBOOL WINAPI NotifyChangeEventLog(HANDLE hEventLog,HANDLE hEvent); + WINADVAPI WINBOOL WINAPI GetNumberOfEventLogRecords(HANDLE hEventLog,PDWORD NumberOfRecords); + WINADVAPI WINBOOL WINAPI GetOldestEventLogRecord(HANDLE hEventLog,PDWORD OldestRecord); + WINADVAPI HANDLE WINAPI OpenEventLogA(LPCSTR lpUNCServerName,LPCSTR lpSourceName); + WINADVAPI HANDLE WINAPI OpenEventLogW(LPCWSTR lpUNCServerName,LPCWSTR lpSourceName); + WINADVAPI HANDLE WINAPI RegisterEventSourceA(LPCSTR lpUNCServerName,LPCSTR lpSourceName); + WINADVAPI HANDLE WINAPI RegisterEventSourceW(LPCWSTR lpUNCServerName,LPCWSTR lpSourceName); + WINADVAPI HANDLE WINAPI OpenBackupEventLogA(LPCSTR lpUNCServerName,LPCSTR lpFileName); + WINADVAPI HANDLE WINAPI OpenBackupEventLogW(LPCWSTR lpUNCServerName,LPCWSTR lpFileName); + WINADVAPI WINBOOL WINAPI ReadEventLogA(HANDLE hEventLog,DWORD dwReadFlags,DWORD dwRecordOffset,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,DWORD *pnBytesRead,DWORD *pnMinNumberOfBytesNeeded); + WINADVAPI WINBOOL WINAPI ReadEventLogW(HANDLE hEventLog,DWORD dwReadFlags,DWORD dwRecordOffset,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,DWORD *pnBytesRead,DWORD *pnMinNumberOfBytesNeeded); + WINADVAPI WINBOOL WINAPI ReportEventA(HANDLE hEventLog,WORD wType,WORD wCategory,DWORD dwEventID,PSID lpUserSid,WORD wNumStrings,DWORD dwDataSize,LPCSTR *lpStrings,LPVOID lpRawData); + WINADVAPI WINBOOL WINAPI ReportEventW(HANDLE hEventLog,WORD wType,WORD wCategory,DWORD dwEventID,PSID lpUserSid,WORD wNumStrings,DWORD dwDataSize,LPCWSTR *lpStrings,LPVOID lpRawData); + +#define EVENTLOG_FULL_INFO 0 + + typedef struct _EVENTLOG_FULL_INFORMATION { + DWORD dwFull; + } EVENTLOG_FULL_INFORMATION,*LPEVENTLOG_FULL_INFORMATION; + + WINADVAPI WINBOOL WINAPI GetEventLogInformation(HANDLE hEventLog,DWORD dwInfoLevel,LPVOID lpBuffer,DWORD cbBufSize,LPDWORD pcbBytesNeeded); + WINADVAPI WINBOOL WINAPI DuplicateToken(HANDLE ExistingTokenHandle,SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,PHANDLE DuplicateTokenHandle); + WINADVAPI WINBOOL WINAPI GetKernelObjectSecurity(HANDLE Handle,SECURITY_INFORMATION RequestedInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,DWORD nLength,LPDWORD lpnLengthNeeded); + WINADVAPI WINBOOL WINAPI ImpersonateNamedPipeClient(HANDLE hNamedPipe); + WINADVAPI WINBOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel); + WINADVAPI WINBOOL WINAPI RevertToSelf(VOID); + WINADVAPI WINBOOL WINAPI SetThreadToken (PHANDLE Thread,HANDLE Token); + WINADVAPI WINBOOL WINAPI AccessCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,HANDLE ClientToken,DWORD DesiredAccess,PGENERIC_MAPPING GenericMapping,PPRIVILEGE_SET PrivilegeSet,LPDWORD PrivilegeSetLength,LPDWORD GrantedAccess,LPBOOL AccessStatus); + WINADVAPI WINBOOL WINAPI AccessCheckByType(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID PrincipalSelfSid,HANDLE ClientToken,DWORD DesiredAccess,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,PPRIVILEGE_SET PrivilegeSet,LPDWORD PrivilegeSetLength,LPDWORD GrantedAccess,LPBOOL AccessStatus); + WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultList(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID PrincipalSelfSid,HANDLE ClientToken,DWORD DesiredAccess,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,PPRIVILEGE_SET PrivilegeSet,LPDWORD PrivilegeSetLength,LPDWORD GrantedAccessList,LPDWORD AccessStatusList); + WINADVAPI WINBOOL WINAPI OpenProcessToken(HANDLE ProcessHandle,DWORD DesiredAccess,PHANDLE TokenHandle); + WINADVAPI WINBOOL WINAPI OpenThreadToken(HANDLE ThreadHandle,DWORD DesiredAccess,WINBOOL OpenAsSelf,PHANDLE TokenHandle); + WINADVAPI WINBOOL WINAPI GetTokenInformation(HANDLE TokenHandle,TOKEN_INFORMATION_CLASS TokenInformationClass,LPVOID TokenInformation,DWORD TokenInformationLength,PDWORD ReturnLength); + WINADVAPI WINBOOL WINAPI SetTokenInformation(HANDLE TokenHandle,TOKEN_INFORMATION_CLASS TokenInformationClass,LPVOID TokenInformation,DWORD TokenInformationLength); + WINADVAPI WINBOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle,WINBOOL DisableAllPrivileges,PTOKEN_PRIVILEGES NewState,DWORD BufferLength,PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength); + WINADVAPI WINBOOL WINAPI AdjustTokenGroups(HANDLE TokenHandle,WINBOOL ResetToDefault,PTOKEN_GROUPS NewState,DWORD BufferLength,PTOKEN_GROUPS PreviousState,PDWORD ReturnLength); + WINADVAPI WINBOOL WINAPI PrivilegeCheck(HANDLE ClientToken,PPRIVILEGE_SET RequiredPrivileges,LPBOOL pfResult); + WINADVAPI WINBOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,LPSTR ObjectTypeName,LPSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,DWORD DesiredAccess,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPBOOL AccessStatus,LPBOOL pfGenerateOnClose); + WINADVAPI WINBOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,LPWSTR ObjectTypeName,LPWSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,DWORD DesiredAccess,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPBOOL AccessStatus,LPBOOL pfGenerateOnClose); + WINADVAPI WINBOOL WINAPI AccessCheckByTypeAndAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,LPCSTR ObjectTypeName,LPCSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPBOOL AccessStatus,LPBOOL pfGenerateOnClose); + WINADVAPI WINBOOL WINAPI AccessCheckByTypeAndAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,LPCWSTR ObjectTypeName,LPCWSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPBOOL AccessStatus,LPBOOL pfGenerateOnClose); + WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,LPCSTR ObjectTypeName,LPCSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPDWORD AccessStatusList,LPBOOL pfGenerateOnClose); + WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,LPCWSTR ObjectTypeName,LPCWSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPDWORD AccessStatusList,LPBOOL pfGenerateOnClose); + WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmByHandleA(LPCSTR SubsystemName,LPVOID HandleId,HANDLE ClientToken,LPCSTR ObjectTypeName,LPCSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPDWORD AccessStatusList,LPBOOL pfGenerateOnClose); + WINADVAPI WINBOOL WINAPI AccessCheckByTypeResultListAndAuditAlarmByHandleW(LPCWSTR SubsystemName,LPVOID HandleId,HANDLE ClientToken,LPCWSTR ObjectTypeName,LPCWSTR ObjectName,PSECURITY_DESCRIPTOR SecurityDescriptor,PSID PrincipalSelfSid,DWORD DesiredAccess,AUDIT_EVENT_TYPE AuditType,DWORD Flags,POBJECT_TYPE_LIST ObjectTypeList,DWORD ObjectTypeListLength,PGENERIC_MAPPING GenericMapping,WINBOOL ObjectCreation,LPDWORD GrantedAccess,LPDWORD AccessStatusList,LPBOOL pfGenerateOnClose); + WINADVAPI WINBOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,LPSTR ObjectTypeName,LPSTR ObjectName,PSECURITY_DESCRIPTOR pSecurityDescriptor,HANDLE ClientToken,DWORD DesiredAccess,DWORD GrantedAccess,PPRIVILEGE_SET Privileges,WINBOOL ObjectCreation,WINBOOL AccessGranted,LPBOOL GenerateOnClose); + WINADVAPI WINBOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,LPWSTR ObjectTypeName,LPWSTR ObjectName,PSECURITY_DESCRIPTOR pSecurityDescriptor,HANDLE ClientToken,DWORD DesiredAccess,DWORD GrantedAccess,PPRIVILEGE_SET Privileges,WINBOOL ObjectCreation,WINBOOL AccessGranted,LPBOOL GenerateOnClose); + WINADVAPI WINBOOL WINAPI ObjectPrivilegeAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,HANDLE ClientToken,DWORD DesiredAccess,PPRIVILEGE_SET Privileges,WINBOOL AccessGranted); + WINADVAPI WINBOOL WINAPI ObjectPrivilegeAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,HANDLE ClientToken,DWORD DesiredAccess,PPRIVILEGE_SET Privileges,WINBOOL AccessGranted); + WINADVAPI WINBOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,WINBOOL GenerateOnClose); + WINADVAPI WINBOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,WINBOOL GenerateOnClose); + WINADVAPI WINBOOL WINAPI ObjectDeleteAuditAlarmA(LPCSTR SubsystemName,LPVOID HandleId,WINBOOL GenerateOnClose); + WINADVAPI WINBOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName,LPVOID HandleId,WINBOOL GenerateOnClose); + WINADVAPI WINBOOL WINAPI PrivilegedServiceAuditAlarmA(LPCSTR SubsystemName,LPCSTR ServiceName,HANDLE ClientToken,PPRIVILEGE_SET Privileges,WINBOOL AccessGranted); + WINADVAPI WINBOOL WINAPI PrivilegedServiceAuditAlarmW(LPCWSTR SubsystemName,LPCWSTR ServiceName,HANDLE ClientToken,PPRIVILEGE_SET Privileges,WINBOOL AccessGranted); + WINADVAPI WINBOOL WINAPI IsWellKnownSid(PSID pSid,WELL_KNOWN_SID_TYPE WellKnownSidType); + WINADVAPI WINBOOL WINAPI CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType,PSID DomainSid,PSID pSid,DWORD *cbSid); + WINADVAPI WINBOOL WINAPI EqualDomainSid(PSID pSid1,PSID pSid2,WINBOOL *pfEqual); + WINADVAPI WINBOOL WINAPI GetWindowsAccountDomainSid(PSID pSid,PSID pDomainSid,DWORD *cbDomainSid); + WINADVAPI WINBOOL WINAPI IsValidSid(PSID pSid); + WINADVAPI WINBOOL WINAPI EqualSid(PSID pSid1,PSID pSid2); + WINADVAPI WINBOOL WINAPI EqualPrefixSid(PSID pSid1,PSID pSid2); + WINADVAPI DWORD WINAPI GetSidLengthRequired (UCHAR nSubAuthorityCount); + WINADVAPI WINBOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,BYTE nSubAuthorityCount,DWORD nSubAuthority0,DWORD nSubAuthority1,DWORD nSubAuthority2,DWORD nSubAuthority3,DWORD nSubAuthority4,DWORD nSubAuthority5,DWORD nSubAuthority6,DWORD nSubAuthority7,PSID *pSid); + WINADVAPI PVOID WINAPI FreeSid(PSID pSid); + WINADVAPI WINBOOL WINAPI InitializeSid(PSID Sid,PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,BYTE nSubAuthorityCount); + WINADVAPI PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(PSID pSid); + WINADVAPI PDWORD WINAPI GetSidSubAuthority(PSID pSid,DWORD nSubAuthority); + WINADVAPI PUCHAR WINAPI GetSidSubAuthorityCount(PSID pSid); + WINADVAPI DWORD WINAPI GetLengthSid(PSID pSid); + WINADVAPI WINBOOL WINAPI CopySid(DWORD nDestinationSidLength,PSID pDestinationSid,PSID pSourceSid); + WINADVAPI WINBOOL WINAPI AreAllAccessesGranted(DWORD GrantedAccess,DWORD DesiredAccess); + WINADVAPI WINBOOL WINAPI AreAnyAccessesGranted(DWORD GrantedAccess,DWORD DesiredAccess); + WINADVAPI VOID WINAPI MapGenericMask(PDWORD AccessMask,PGENERIC_MAPPING GenericMapping); + WINADVAPI WINBOOL WINAPI IsValidAcl(PACL pAcl); + WINADVAPI WINBOOL WINAPI InitializeAcl(PACL pAcl,DWORD nAclLength,DWORD dwAclRevision); + WINADVAPI WINBOOL WINAPI GetAclInformation(PACL pAcl,LPVOID pAclInformation,DWORD nAclInformationLength,ACL_INFORMATION_CLASS dwAclInformationClass); + WINADVAPI WINBOOL WINAPI SetAclInformation(PACL pAcl,LPVOID pAclInformation,DWORD nAclInformationLength,ACL_INFORMATION_CLASS dwAclInformationClass); + WINADVAPI WINBOOL WINAPI AddAce(PACL pAcl,DWORD dwAceRevision,DWORD dwStartingAceIndex,LPVOID pAceList,DWORD nAceListLength); + WINADVAPI WINBOOL WINAPI DeleteAce(PACL pAcl,DWORD dwAceIndex); + WINADVAPI WINBOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce); + WINADVAPI WINBOOL WINAPI AddAccessAllowedAce(PACL pAcl,DWORD dwAceRevision,DWORD AccessMask,PSID pSid); + WINADVAPI WINBOOL WINAPI AddAccessAllowedAceEx(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,PSID pSid); + WINADVAPI WINBOOL WINAPI AddAccessDeniedAce(PACL pAcl,DWORD dwAceRevision,DWORD AccessMask,PSID pSid); + WINADVAPI WINBOOL WINAPI AddAccessDeniedAceEx(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,PSID pSid); + WINADVAPI WINBOOL WINAPI AddAuditAccessAce(PACL pAcl,DWORD dwAceRevision,DWORD dwAccessMask,PSID pSid,WINBOOL bAuditSuccess,WINBOOL bAuditFailure); + WINADVAPI WINBOOL WINAPI AddAuditAccessAceEx(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD dwAccessMask,PSID pSid,WINBOOL bAuditSuccess,WINBOOL bAuditFailure); + WINADVAPI WINBOOL WINAPI AddAccessAllowedObjectAce(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,GUID *ObjectTypeGuid,GUID *InheritedObjectTypeGuid,PSID pSid); + WINADVAPI WINBOOL WINAPI AddAccessDeniedObjectAce(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,GUID *ObjectTypeGuid,GUID *InheritedObjectTypeGuid,PSID pSid); + WINADVAPI WINBOOL WINAPI AddAuditAccessObjectAce(PACL pAcl,DWORD dwAceRevision,DWORD AceFlags,DWORD AccessMask,GUID *ObjectTypeGuid,GUID *InheritedObjectTypeGuid,PSID pSid,WINBOOL bAuditSuccess,WINBOOL bAuditFailure); + WINADVAPI WINBOOL WINAPI FindFirstFreeAce(PACL pAcl,LPVOID *pAce); + WINADVAPI WINBOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor,DWORD dwRevision); + WINADVAPI WINBOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor); + WINADVAPI DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR pSecurityDescriptor); + WINADVAPI WINBOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSECURITY_DESCRIPTOR_CONTROL pControl,LPDWORD lpdwRevision); + WINADVAPI WINBOOL WINAPI SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR pSecurityDescriptor,SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet); + WINADVAPI WINBOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor,WINBOOL bDaclPresent,PACL pDacl,WINBOOL bDaclDefaulted); + WINADVAPI WINBOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor,LPBOOL lpbDaclPresent,PACL *pDacl,LPBOOL lpbDaclDefaulted); + WINADVAPI WINBOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor,WINBOOL bSaclPresent,PACL pSacl,WINBOOL bSaclDefaulted); + WINADVAPI WINBOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor,LPBOOL lpbSaclPresent,PACL *pSacl,LPBOOL lpbSaclDefaulted); + WINADVAPI WINBOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID pOwner,WINBOOL bOwnerDefaulted); + WINADVAPI WINBOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID *pOwner,LPBOOL lpbOwnerDefaulted); + WINADVAPI WINBOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID pGroup,WINBOOL bGroupDefaulted); + WINADVAPI WINBOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor,PSID *pGroup,LPBOOL lpbGroupDefaulted); + WINADVAPI DWORD WINAPI SetSecurityDescriptorRMControl(PSECURITY_DESCRIPTOR SecurityDescriptor,PUCHAR RMControl); + WINADVAPI DWORD WINAPI GetSecurityDescriptorRMControl(PSECURITY_DESCRIPTOR SecurityDescriptor,PUCHAR RMControl); + WINADVAPI WINBOOL WINAPI CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR *NewDescriptor,WINBOOL IsDirectoryObject,HANDLE Token,PGENERIC_MAPPING GenericMapping); + WINADVAPI WINBOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CurrentSecurityDescriptor,PSECURITY_DESCRIPTOR *NewSecurityDescriptor,GUID *ObjectType,BOOLEAN IsDirectoryObject,PGENERIC_MAPPING GenericMapping); + WINADVAPI WINBOOL WINAPI CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR *NewDescriptor,GUID *ObjectType,WINBOOL IsContainerObject,ULONG AutoInheritFlags,HANDLE Token,PGENERIC_MAPPING GenericMapping); + WINADVAPI WINBOOL WINAPI CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,PSECURITY_DESCRIPTOR CreatorDescriptor,PSECURITY_DESCRIPTOR *NewDescriptor,GUID **ObjectTypes,ULONG GuidCount,WINBOOL IsContainerObject,ULONG AutoInheritFlags,HANDLE Token,PGENERIC_MAPPING GenericMapping); + WINADVAPI WINBOOL WINAPI SetPrivateObjectSecurity (SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR ModificationDescriptor,PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,PGENERIC_MAPPING GenericMapping,HANDLE Token); + WINADVAPI WINBOOL WINAPI SetPrivateObjectSecurityEx (SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR ModificationDescriptor,PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,ULONG AutoInheritFlags,PGENERIC_MAPPING GenericMapping,HANDLE Token); + WINADVAPI WINBOOL WINAPI GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR ResultantDescriptor,DWORD DescriptorLength,PDWORD ReturnLength); + WINADVAPI WINBOOL WINAPI DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor); + WINADVAPI WINBOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,LPDWORD lpdwBufferLength); + WINADVAPI WINBOOL WINAPI MakeAbsoluteSD(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,LPDWORD lpdwAbsoluteSecurityDescriptorSize,PACL pDacl,LPDWORD lpdwDaclSize,PACL pSacl,LPDWORD lpdwSaclSize,PSID pOwner,LPDWORD lpdwOwnerSize,PSID pPrimaryGroup,LPDWORD lpdwPrimaryGroupSize); + WINADVAPI WINBOOL WINAPI MakeAbsoluteSD2(PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,LPDWORD lpdwBufferSize); + WINADVAPI WINBOOL WINAPI SetFileSecurityA(LPCSTR lpFileName,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor); + WINADVAPI WINBOOL WINAPI SetFileSecurityW(LPCWSTR lpFileName,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor); + WINADVAPI WINBOOL WINAPI GetFileSecurityA(LPCSTR lpFileName,SECURITY_INFORMATION RequestedInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,DWORD nLength,LPDWORD lpnLengthNeeded); + WINADVAPI WINBOOL WINAPI GetFileSecurityW(LPCWSTR lpFileName,SECURITY_INFORMATION RequestedInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,DWORD nLength,LPDWORD lpnLengthNeeded); + WINADVAPI WINBOOL WINAPI SetKernelObjectSecurity(HANDLE Handle,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR SecurityDescriptor); + WINBASEAPI HANDLE WINAPI FindFirstChangeNotificationA(LPCSTR lpPathName,WINBOOL bWatchSubtree,DWORD dwNotifyFilter); + WINBASEAPI HANDLE WINAPI FindFirstChangeNotificationW(LPCWSTR lpPathName,WINBOOL bWatchSubtree,DWORD dwNotifyFilter); + WINBASEAPI WINBOOL WINAPI FindNextChangeNotification(HANDLE hChangeHandle); + WINBASEAPI WINBOOL WINAPI FindCloseChangeNotification(HANDLE hChangeHandle); + WINBASEAPI WINBOOL WINAPI ReadDirectoryChangesW(HANDLE hDirectory,LPVOID lpBuffer,DWORD nBufferLength,WINBOOL bWatchSubtree,DWORD dwNotifyFilter,LPDWORD lpBytesReturned,LPOVERLAPPED lpOverlapped,LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + WINBASEAPI WINBOOL WINAPI VirtualLock(LPVOID lpAddress,SIZE_T dwSize); + WINBASEAPI WINBOOL WINAPI VirtualUnlock(LPVOID lpAddress,SIZE_T dwSize); + WINBASEAPI LPVOID WINAPI MapViewOfFileEx(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,SIZE_T dwNumberOfBytesToMap,LPVOID lpBaseAddress); + WINBASEAPI WINBOOL WINAPI SetPriorityClass(HANDLE hProcess,DWORD dwPriorityClass); + WINBASEAPI DWORD WINAPI GetPriorityClass(HANDLE hProcess); + WINBASEAPI WINBOOL WINAPI IsBadReadPtr(CONST VOID *lp,UINT_PTR ucb); + WINBASEAPI WINBOOL WINAPI IsBadWritePtr(LPVOID lp,UINT_PTR ucb); + WINBASEAPI WINBOOL WINAPI IsBadHugeReadPtr(CONST VOID *lp,UINT_PTR ucb); + WINBASEAPI WINBOOL WINAPI IsBadHugeWritePtr(LPVOID lp,UINT_PTR ucb); + WINBASEAPI WINBOOL WINAPI IsBadCodePtr(FARPROC lpfn); + WINBASEAPI WINBOOL WINAPI IsBadStringPtrA(LPCSTR lpsz,UINT_PTR ucchMax); + WINBASEAPI WINBOOL WINAPI IsBadStringPtrW(LPCWSTR lpsz,UINT_PTR ucchMax); + WINADVAPI WINBOOL WINAPI LookupAccountSidA(LPCSTR lpSystemName,PSID Sid,LPSTR Name,LPDWORD cchName,LPSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse); + WINADVAPI WINBOOL WINAPI LookupAccountSidW(LPCWSTR lpSystemName,PSID Sid,LPWSTR Name,LPDWORD cchName,LPWSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse); + WINADVAPI WINBOOL WINAPI LookupAccountNameA(LPCSTR lpSystemName,LPCSTR lpAccountName,PSID Sid,LPDWORD cbSid,LPSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse); + WINADVAPI WINBOOL WINAPI LookupAccountNameW(LPCWSTR lpSystemName,LPCWSTR lpAccountName,PSID Sid,LPDWORD cbSid,LPWSTR ReferencedDomainName,LPDWORD cchReferencedDomainName,PSID_NAME_USE peUse); + WINADVAPI WINBOOL WINAPI LookupPrivilegeValueA(LPCSTR lpSystemName,LPCSTR lpName,PLUID lpLuid); + WINADVAPI WINBOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName,LPCWSTR lpName,PLUID lpLuid); + WINADVAPI WINBOOL WINAPI LookupPrivilegeNameA(LPCSTR lpSystemName,PLUID lpLuid,LPSTR lpName,LPDWORD cchName); + WINADVAPI WINBOOL WINAPI LookupPrivilegeNameW(LPCWSTR lpSystemName,PLUID lpLuid,LPWSTR lpName,LPDWORD cchName); + WINADVAPI WINBOOL WINAPI LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,LPCSTR lpName,LPSTR lpDisplayName,LPDWORD cchDisplayName,LPDWORD lpLanguageId); + WINADVAPI WINBOOL WINAPI LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,LPCWSTR lpName,LPWSTR lpDisplayName,LPDWORD cchDisplayName,LPDWORD lpLanguageId); + WINADVAPI WINBOOL WINAPI AllocateLocallyUniqueId(PLUID Luid); + WINBASEAPI WINBOOL WINAPI BuildCommDCBA(LPCSTR lpDef,LPDCB lpDCB); + WINBASEAPI WINBOOL WINAPI BuildCommDCBW(LPCWSTR lpDef,LPDCB lpDCB); + WINBASEAPI WINBOOL WINAPI BuildCommDCBAndTimeoutsA(LPCSTR lpDef,LPDCB lpDCB,LPCOMMTIMEOUTS lpCommTimeouts); + WINBASEAPI WINBOOL WINAPI BuildCommDCBAndTimeoutsW(LPCWSTR lpDef,LPDCB lpDCB,LPCOMMTIMEOUTS lpCommTimeouts); + WINBASEAPI WINBOOL WINAPI CommConfigDialogA(LPCSTR lpszName,HWND hWnd,LPCOMMCONFIG lpCC); + WINBASEAPI WINBOOL WINAPI CommConfigDialogW(LPCWSTR lpszName,HWND hWnd,LPCOMMCONFIG lpCC); + WINBASEAPI WINBOOL WINAPI GetDefaultCommConfigA(LPCSTR lpszName,LPCOMMCONFIG lpCC,LPDWORD lpdwSize); + WINBASEAPI WINBOOL WINAPI GetDefaultCommConfigW(LPCWSTR lpszName,LPCOMMCONFIG lpCC,LPDWORD lpdwSize); + WINBASEAPI WINBOOL WINAPI SetDefaultCommConfigA(LPCSTR lpszName,LPCOMMCONFIG lpCC,DWORD dwSize); + WINBASEAPI WINBOOL WINAPI SetDefaultCommConfigW(LPCWSTR lpszName,LPCOMMCONFIG lpCC,DWORD dwSize); + +#define MAX_COMPUTERNAME_LENGTH 15 + + WINBASEAPI WINBOOL WINAPI GetComputerNameA(LPSTR lpBuffer,LPDWORD nSize); + WINBASEAPI WINBOOL WINAPI GetComputerNameW(LPWSTR lpBuffer,LPDWORD nSize); + WINBASEAPI WINBOOL WINAPI SetComputerNameA(LPCSTR lpComputerName); + WINBASEAPI WINBOOL WINAPI SetComputerNameW(LPCWSTR lpComputerName); + + typedef enum _COMPUTER_NAME_FORMAT { + ComputerNameNetBIOS,ComputerNameDnsHostname,ComputerNameDnsDomain,ComputerNameDnsFullyQualified,ComputerNamePhysicalNetBIOS,ComputerNamePhysicalDnsHostname,ComputerNamePhysicalDnsDomain,ComputerNamePhysicalDnsFullyQualified,ComputerNameMax + } COMPUTER_NAME_FORMAT; + + WINBASEAPI WINBOOL WINAPI GetComputerNameExA(COMPUTER_NAME_FORMAT NameType,LPSTR lpBuffer,LPDWORD nSize); + WINBASEAPI WINBOOL WINAPI GetComputerNameExW(COMPUTER_NAME_FORMAT NameType,LPWSTR lpBuffer,LPDWORD nSize); + WINBASEAPI WINBOOL WINAPI SetComputerNameExA(COMPUTER_NAME_FORMAT NameType,LPCSTR lpBuffer); + WINBASEAPI WINBOOL WINAPI SetComputerNameExW(COMPUTER_NAME_FORMAT NameType,LPCWSTR lpBuffer); + WINBASEAPI WINBOOL WINAPI DnsHostnameToComputerNameA(LPCSTR Hostname,LPSTR ComputerName,LPDWORD nSize); + WINBASEAPI WINBOOL WINAPI DnsHostnameToComputerNameW(LPCWSTR Hostname,LPWSTR ComputerName,LPDWORD nSize); + WINADVAPI WINBOOL WINAPI GetUserNameA(LPSTR lpBuffer,LPDWORD pcbBuffer); + WINADVAPI WINBOOL WINAPI GetUserNameW(LPWSTR lpBuffer,LPDWORD pcbBuffer); + +#define LOGON32_LOGON_INTERACTIVE 2 +#define LOGON32_LOGON_NETWORK 3 +#define LOGON32_LOGON_BATCH 4 +#define LOGON32_LOGON_SERVICE 5 +#define LOGON32_LOGON_UNLOCK 7 +#define LOGON32_LOGON_NETWORK_CLEARTEXT 8 +#define LOGON32_LOGON_NEW_CREDENTIALS 9 + +#define LOGON32_PROVIDER_DEFAULT 0 +#define LOGON32_PROVIDER_WINNT35 1 +#define LOGON32_PROVIDER_WINNT40 2 +#define LOGON32_PROVIDER_WINNT50 3 + +#ifdef UNICODE +#define LogonUser LogonUserW +#define LogonUserEx LogonUserExW +#define CreateProcessAsUser CreateProcessAsUserW +#else +#define LogonUser LogonUserA +#define LogonUserEx LogonUserExA +#define CreateProcessAsUser CreateProcessAsUserA +#endif + + WINADVAPI WINBOOL WINAPI LogonUserA(LPCSTR lpszUsername,LPCSTR lpszDomain,LPCSTR lpszPassword,DWORD dwLogonType,DWORD dwLogonProvider,PHANDLE phToken); + WINADVAPI WINBOOL WINAPI LogonUserW(LPCWSTR lpszUsername,LPCWSTR lpszDomain,LPCWSTR lpszPassword,DWORD dwLogonType,DWORD dwLogonProvider,PHANDLE phToken); + WINADVAPI WINBOOL WINAPI LogonUserExA(LPCSTR lpszUsername,LPCSTR lpszDomain,LPCSTR lpszPassword,DWORD dwLogonType,DWORD dwLogonProvider,PHANDLE phToken,PSID *ppLogonSid,PVOID *ppProfileBuffer,LPDWORD pdwProfileLength,PQUOTA_LIMITS pQuotaLimits); + WINADVAPI WINBOOL WINAPI LogonUserExW(LPCWSTR lpszUsername,LPCWSTR lpszDomain,LPCWSTR lpszPassword,DWORD dwLogonType,DWORD dwLogonProvider,PHANDLE phToken,PSID *ppLogonSid,PVOID *ppProfileBuffer,LPDWORD pdwProfileLength,PQUOTA_LIMITS pQuotaLimits); + WINADVAPI WINBOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken); + WINADVAPI WINBOOL WINAPI CreateProcessAsUserA(HANDLE hToken,LPCSTR lpApplicationName,LPSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,WINBOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); + WINADVAPI WINBOOL WINAPI CreateProcessAsUserW(HANDLE hToken,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,WINBOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); + +#define LOGON_WITH_PROFILE 0x1 +#define LOGON_NETCREDENTIALS_ONLY 0x2 +#define LOGON_ZERO_PASSWORD_BUFFER 0x80000000 + + WINADVAPI WINBOOL WINAPI CreateProcessWithLogonW(LPCWSTR lpUsername,LPCWSTR lpDomain,LPCWSTR lpPassword,DWORD dwLogonFlags,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); + WINADVAPI WINBOOL WINAPI CreateProcessWithTokenW(HANDLE hToken,DWORD dwLogonFlags,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCWSTR lpCurrentDirectory,LPSTARTUPINFOW lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation); + WINADVAPI WINBOOL WINAPI ImpersonateAnonymousToken(HANDLE ThreadHandle); + WINADVAPI WINBOOL WINAPI DuplicateTokenEx(HANDLE hExistingToken,DWORD dwDesiredAccess,LPSECURITY_ATTRIBUTES lpTokenAttributes,SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,TOKEN_TYPE TokenType,PHANDLE phNewToken); + WINADVAPI WINBOOL WINAPI CreateRestrictedToken(HANDLE ExistingTokenHandle,DWORD Flags,DWORD DisableSidCount,PSID_AND_ATTRIBUTES SidsToDisable,DWORD DeletePrivilegeCount,PLUID_AND_ATTRIBUTES PrivilegesToDelete,DWORD RestrictedSidCount,PSID_AND_ATTRIBUTES SidsToRestrict,PHANDLE NewTokenHandle); + WINADVAPI WINBOOL WINAPI IsTokenRestricted(HANDLE TokenHandle); + WINADVAPI WINBOOL WINAPI IsTokenUntrusted(HANDLE TokenHandle); + WINADVAPI WINBOOL WINAPI CheckTokenMembership(HANDLE TokenHandle,PSID SidToCheck,PBOOL IsMember); + + typedef WAITORTIMERCALLBACKFUNC WAITORTIMERCALLBACK; + + WINBASEAPI WINBOOL WINAPI RegisterWaitForSingleObject(PHANDLE phNewWaitObject,HANDLE hObject,WAITORTIMERCALLBACK Callback,PVOID Context,ULONG dwMilliseconds,ULONG dwFlags); + WINBASEAPI HANDLE WINAPI RegisterWaitForSingleObjectEx(HANDLE hObject,WAITORTIMERCALLBACK Callback,PVOID Context,ULONG dwMilliseconds,ULONG dwFlags); + WINBASEAPI WINBOOL WINAPI UnregisterWait(HANDLE WaitHandle); + WINBASEAPI WINBOOL WINAPI UnregisterWaitEx(HANDLE WaitHandle,HANDLE CompletionEvent); + WINBASEAPI WINBOOL WINAPI QueueUserWorkItem(LPTHREAD_START_ROUTINE Function,PVOID Context,ULONG Flags); + WINBASEAPI WINBOOL WINAPI BindIoCompletionCallback(HANDLE FileHandle,LPOVERLAPPED_COMPLETION_ROUTINE Function,ULONG Flags); + WINBASEAPI HANDLE WINAPI CreateTimerQueue(VOID); + WINBASEAPI WINBOOL WINAPI CreateTimerQueueTimer(PHANDLE phNewTimer,HANDLE TimerQueue,WAITORTIMERCALLBACK Callback,PVOID Parameter,DWORD DueTime,DWORD Period,ULONG Flags); + WINBASEAPI WINBOOL WINAPI ChangeTimerQueueTimer(HANDLE TimerQueue,HANDLE Timer,ULONG DueTime,ULONG Period); + WINBASEAPI WINBOOL WINAPI DeleteTimerQueueTimer(HANDLE TimerQueue,HANDLE Timer,HANDLE CompletionEvent); + WINBASEAPI WINBOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue,HANDLE CompletionEvent); + WINBASEAPI HANDLE WINAPI SetTimerQueueTimer(HANDLE TimerQueue,WAITORTIMERCALLBACK Callback,PVOID Parameter,DWORD DueTime,DWORD Period,WINBOOL PreferIo); + WINBASEAPI WINBOOL WINAPI CancelTimerQueueTimer(HANDLE TimerQueue,HANDLE Timer); + WINBASEAPI WINBOOL WINAPI DeleteTimerQueue(HANDLE TimerQueue); + +#define HW_PROFILE_GUIDLEN 39 +#define MAX_PROFILE_LEN 80 + +#define DOCKINFO_UNDOCKED (0x1) +#define DOCKINFO_DOCKED (0x2) +#define DOCKINFO_USER_SUPPLIED (0x4) +#define DOCKINFO_USER_UNDOCKED (DOCKINFO_USER_SUPPLIED | DOCKINFO_UNDOCKED) +#define DOCKINFO_USER_DOCKED (DOCKINFO_USER_SUPPLIED | DOCKINFO_DOCKED) + + typedef struct tagHW_PROFILE_INFOA { + DWORD dwDockInfo; + CHAR szHwProfileGuid[HW_PROFILE_GUIDLEN]; + CHAR szHwProfileName[MAX_PROFILE_LEN]; + } HW_PROFILE_INFOA,*LPHW_PROFILE_INFOA; + + typedef struct tagHW_PROFILE_INFOW { + DWORD dwDockInfo; + WCHAR szHwProfileGuid[HW_PROFILE_GUIDLEN]; + WCHAR szHwProfileName[MAX_PROFILE_LEN]; + } HW_PROFILE_INFOW,*LPHW_PROFILE_INFOW; + +#ifdef UNICODE + typedef HW_PROFILE_INFOW HW_PROFILE_INFO; + typedef LPHW_PROFILE_INFOW LPHW_PROFILE_INFO; +#else + typedef HW_PROFILE_INFOA HW_PROFILE_INFO; + typedef LPHW_PROFILE_INFOA LPHW_PROFILE_INFO; +#endif + +#ifdef UNICODE +#define GetCurrentHwProfile GetCurrentHwProfileW +#define GetVersionEx GetVersionExW +#define VerifyVersionInfo VerifyVersionInfoW +#else +#define GetCurrentHwProfile GetCurrentHwProfileA +#define GetVersionEx GetVersionExA #define VerifyVersionInfo VerifyVersionInfoA -#define WaitNamedPipe WaitNamedPipeA -#define WritePrivateProfileSection WritePrivateProfileSectionA -#define WritePrivateProfileString WritePrivateProfileStringA -#define WritePrivateProfileStruct WritePrivateProfileStructA -#define WriteProfileSection WriteProfileSectionA -#define WriteProfileString WriteProfileStringA #endif + + WINADVAPI WINBOOL WINAPI GetCurrentHwProfileA (LPHW_PROFILE_INFOA lpHwProfileInfo); + WINADVAPI WINBOOL WINAPI GetCurrentHwProfileW (LPHW_PROFILE_INFOW lpHwProfileInfo); + WINBASEAPI WINBOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount); + WINBASEAPI WINBOOL WINAPI QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency); + WINBASEAPI WINBOOL WINAPI GetVersionExA(LPOSVERSIONINFOA lpVersionInformation); + WINBASEAPI WINBOOL WINAPI GetVersionExW(LPOSVERSIONINFOW lpVersionInformation); + WINBASEAPI WINBOOL WINAPI VerifyVersionInfoA(LPOSVERSIONINFOEXA lpVersionInformation,DWORD dwTypeMask,DWORDLONG dwlConditionMask); + WINBASEAPI WINBOOL WINAPI VerifyVersionInfoW(LPOSVERSIONINFOEXW lpVersionInformation,DWORD dwTypeMask,DWORDLONG dwlConditionMask); + +#include <winerror.h> + +#define TC_NORMAL 0 +#define TC_HARDERR 1 +#define TC_GP_TRAP 2 +#define TC_SIGNAL 3 + +#define AC_LINE_OFFLINE 0x0 +#define AC_LINE_ONLINE 0x1 +#define AC_LINE_BACKUP_POWER 0x2 +#define AC_LINE_UNKNOWN 0xff + +#define BATTERY_FLAG_HIGH 0x1 +#define BATTERY_FLAG_LOW 0x2 +#define BATTERY_FLAG_CRITICAL 0x4 +#define BATTERY_FLAG_CHARGING 0x8 +#define BATTERY_FLAG_NO_BATTERY 0x80 +#define BATTERY_FLAG_UNKNOWN 0xff + +#define BATTERY_PERCENTAGE_UNKNOWN 0xff + +#define BATTERY_LIFE_UNKNOWN 0xffffffff + + typedef struct _SYSTEM_POWER_STATUS { + BYTE ACLineStatus; + BYTE BatteryFlag; + BYTE BatteryLifePercent; + BYTE Reserved1; + DWORD BatteryLifeTime; + DWORD BatteryFullLifeTime; + } SYSTEM_POWER_STATUS,*LPSYSTEM_POWER_STATUS; + +#ifdef UNICODE +#define CreateJobObject CreateJobObjectW +#define OpenJobObject OpenJobObjectW +#define FindFirstVolume FindFirstVolumeW +#define FindNextVolume FindNextVolumeW +#define FindFirstVolumeMountPoint FindFirstVolumeMountPointW +#define FindNextVolumeMountPoint FindNextVolumeMountPointW +#define SetVolumeMountPoint SetVolumeMountPointW +#define DeleteVolumeMountPoint DeleteVolumeMountPointW +#define GetVolumeNameForVolumeMountPoint GetVolumeNameForVolumeMountPointW +#define GetVolumePathName GetVolumePathNameW +#define GetVolumePathNamesForVolumeName GetVolumePathNamesForVolumeNameW +#else +#define CreateJobObject CreateJobObjectA +#define OpenJobObject OpenJobObjectA +#define FindFirstVolume FindFirstVolumeA +#define FindNextVolume FindNextVolumeA +#define FindFirstVolumeMountPoint FindFirstVolumeMountPointA +#define FindNextVolumeMountPoint FindNextVolumeMountPointA +#define SetVolumeMountPoint SetVolumeMountPointA +#define DeleteVolumeMountPoint DeleteVolumeMountPointA +#define GetVolumeNameForVolumeMountPoint GetVolumeNameForVolumeMountPointA +#define GetVolumePathName GetVolumePathNameA +#define GetVolumePathNamesForVolumeName GetVolumePathNamesForVolumeNameA +#endif + + WINBOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS lpSystemPowerStatus); + WINBOOL WINAPI SetSystemPowerState(WINBOOL fSuspend,WINBOOL fForce); + WINBASEAPI WINBOOL WINAPI AllocateUserPhysicalPages(HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR PageArray); + WINBASEAPI WINBOOL WINAPI FreeUserPhysicalPages(HANDLE hProcess,PULONG_PTR NumberOfPages,PULONG_PTR PageArray); + WINBASEAPI WINBOOL WINAPI MapUserPhysicalPages(PVOID VirtualAddress,ULONG_PTR NumberOfPages,PULONG_PTR PageArray); + WINBASEAPI WINBOOL WINAPI MapUserPhysicalPagesScatter(PVOID *VirtualAddresses,ULONG_PTR NumberOfPages,PULONG_PTR PageArray); + WINBASEAPI HANDLE WINAPI CreateJobObjectA(LPSECURITY_ATTRIBUTES lpJobAttributes,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI CreateJobObjectW(LPSECURITY_ATTRIBUTES lpJobAttributes,LPCWSTR lpName); + WINBASEAPI HANDLE WINAPI OpenJobObjectA(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCSTR lpName); + WINBASEAPI HANDLE WINAPI OpenJobObjectW(DWORD dwDesiredAccess,WINBOOL bInheritHandle,LPCWSTR lpName); + WINBASEAPI WINBOOL WINAPI AssignProcessToJobObject(HANDLE hJob,HANDLE hProcess); + WINBASEAPI WINBOOL WINAPI TerminateJobObject(HANDLE hJob,UINT uExitCode); + WINBASEAPI WINBOOL WINAPI QueryInformationJobObject(HANDLE hJob,JOBOBJECTINFOCLASS JobObjectInformationClass,LPVOID lpJobObjectInformation,DWORD cbJobObjectInformationLength,LPDWORD lpReturnLength); + WINBASEAPI WINBOOL WINAPI SetInformationJobObject(HANDLE hJob,JOBOBJECTINFOCLASS JobObjectInformationClass,LPVOID lpJobObjectInformation,DWORD cbJobObjectInformationLength); + WINBASEAPI WINBOOL WINAPI IsProcessInJob(HANDLE ProcessHandle,HANDLE JobHandle,PBOOL Result); + WINBASEAPI WINBOOL WINAPI CreateJobSet(ULONG NumJob,PJOB_SET_ARRAY UserJobSet,ULONG Flags); + WINBASEAPI PVOID WINAPI AddVectoredExceptionHandler (ULONG First,PVECTORED_EXCEPTION_HANDLER Handler); + WINBASEAPI ULONG WINAPI RemoveVectoredExceptionHandler(PVOID Handle); + WINBASEAPI PVOID WINAPI AddVectoredContinueHandler (ULONG First,PVECTORED_EXCEPTION_HANDLER Handler); + WINBASEAPI ULONG WINAPI RemoveVectoredContinueHandler(PVOID Handle); + WINBASEAPI HANDLE WINAPI FindFirstVolumeA(LPSTR lpszVolumeName,DWORD cchBufferLength); + WINBASEAPI HANDLE WINAPI FindFirstVolumeW(LPWSTR lpszVolumeName,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI FindNextVolumeA(HANDLE hFindVolume,LPSTR lpszVolumeName,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI FindNextVolumeW(HANDLE hFindVolume,LPWSTR lpszVolumeName,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI FindVolumeClose(HANDLE hFindVolume); + WINBASEAPI HANDLE WINAPI FindFirstVolumeMountPointA(LPCSTR lpszRootPathName,LPSTR lpszVolumeMountPoint,DWORD cchBufferLength); + WINBASEAPI HANDLE WINAPI FindFirstVolumeMountPointW(LPCWSTR lpszRootPathName,LPWSTR lpszVolumeMountPoint,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI FindNextVolumeMountPointA(HANDLE hFindVolumeMountPoint,LPSTR lpszVolumeMountPoint,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI FindNextVolumeMountPointW(HANDLE hFindVolumeMountPoint,LPWSTR lpszVolumeMountPoint,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI FindVolumeMountPointClose(HANDLE hFindVolumeMountPoint); + WINBASEAPI WINBOOL WINAPI SetVolumeMountPointA(LPCSTR lpszVolumeMountPoint,LPCSTR lpszVolumeName); + WINBASEAPI WINBOOL WINAPI SetVolumeMountPointW(LPCWSTR lpszVolumeMountPoint,LPCWSTR lpszVolumeName); + WINBASEAPI WINBOOL WINAPI DeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint); + WINBASEAPI WINBOOL WINAPI DeleteVolumeMountPointW(LPCWSTR lpszVolumeMountPoint); + WINBASEAPI WINBOOL WINAPI GetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint,LPSTR lpszVolumeName,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI GetVolumeNameForVolumeMountPointW(LPCWSTR lpszVolumeMountPoint,LPWSTR lpszVolumeName,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI GetVolumePathNameA(LPCSTR lpszFileName,LPSTR lpszVolumePathName,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI GetVolumePathNameW(LPCWSTR lpszFileName,LPWSTR lpszVolumePathName,DWORD cchBufferLength); + WINBASEAPI WINBOOL WINAPI GetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName,LPCH lpszVolumePathNames,DWORD cchBufferLength,PDWORD lpcchReturnLength); + WINBASEAPI WINBOOL WINAPI GetVolumePathNamesForVolumeNameW(LPCWSTR lpszVolumeName,LPWCH lpszVolumePathNames,DWORD cchBufferLength,PDWORD lpcchReturnLength); + +#define ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID 0x1 +#define ACTCTX_FLAG_LANGID_VALID 0x2 +#define ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID 0x4 +#define ACTCTX_FLAG_RESOURCE_NAME_VALID 0x8 +#define ACTCTX_FLAG_SET_PROCESS_DEFAULT 0x10 +#define ACTCTX_FLAG_APPLICATION_NAME_VALID 0x20 +#define ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF 0x40 +#define ACTCTX_FLAG_HMODULE_VALID 0x80 + + typedef struct tagACTCTXA { + ULONG cbSize; + DWORD dwFlags; + LPCSTR lpSource; + USHORT wProcessorArchitecture; + LANGID wLangId; + LPCSTR lpAssemblyDirectory; + LPCSTR lpResourceName; + LPCSTR lpApplicationName; + HMODULE hModule; + } ACTCTXA,*PACTCTXA; + + typedef struct tagACTCTXW { + ULONG cbSize; + DWORD dwFlags; + LPCWSTR lpSource; + USHORT wProcessorArchitecture; + LANGID wLangId; + LPCWSTR lpAssemblyDirectory; + LPCWSTR lpResourceName; + LPCWSTR lpApplicationName; + HMODULE hModule; + } ACTCTXW,*PACTCTXW; + + typedef const ACTCTXA *PCACTCTXA; + typedef const ACTCTXW *PCACTCTXW; + +#ifdef UNICODE + typedef ACTCTXW ACTCTX; + typedef PACTCTXW PACTCTX; + typedef PCACTCTXW PCACTCTX; +#else + typedef ACTCTXA ACTCTX; + typedef PACTCTXA PACTCTX; + typedef PCACTCTXA PCACTCTX; +#endif + +#ifdef UNICODE +#define CreateActCtx CreateActCtxW +#else +#define CreateActCtx CreateActCtxA #endif + + WINBASEAPI HANDLE WINAPI CreateActCtxA(PCACTCTXA pActCtx); + WINBASEAPI HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx); + WINBASEAPI VOID WINAPI AddRefActCtx(HANDLE hActCtx); + WINBASEAPI VOID WINAPI ReleaseActCtx(HANDLE hActCtx); + WINBASEAPI WINBOOL WINAPI ZombifyActCtx(HANDLE hActCtx); + WINBASEAPI WINBOOL WINAPI ActivateActCtx(HANDLE hActCtx,ULONG_PTR *lpCookie); + +#define DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION (0x1) + + WINBASEAPI WINBOOL WINAPI DeactivateActCtx(DWORD dwFlags,ULONG_PTR ulCookie); + WINBASEAPI WINBOOL WINAPI GetCurrentActCtx(HANDLE *lphActCtx); + + typedef struct tagACTCTX_SECTION_KEYED_DATA_2600 { + ULONG cbSize; + ULONG ulDataFormatVersion; + PVOID lpData; + ULONG ulLength; + PVOID lpSectionGlobalData; + ULONG ulSectionGlobalDataLength; + PVOID lpSectionBase; + ULONG ulSectionTotalLength; + HANDLE hActCtx; + ULONG ulAssemblyRosterIndex; + } ACTCTX_SECTION_KEYED_DATA_2600,*PACTCTX_SECTION_KEYED_DATA_2600; + + typedef const ACTCTX_SECTION_KEYED_DATA_2600 *PCACTCTX_SECTION_KEYED_DATA_2600; + + typedef struct tagACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA { + PVOID lpInformation; + PVOID lpSectionBase; + ULONG ulSectionLength; + PVOID lpSectionGlobalDataBase; + ULONG ulSectionGlobalDataLength; + } ACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA,*PACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA; + + typedef const ACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA *PCACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA; + + typedef struct tagACTCTX_SECTION_KEYED_DATA { + ULONG cbSize; + ULONG ulDataFormatVersion; + PVOID lpData; + ULONG ulLength; + PVOID lpSectionGlobalData; + ULONG ulSectionGlobalDataLength; + PVOID lpSectionBase; + ULONG ulSectionTotalLength; + HANDLE hActCtx; + ULONG ulAssemblyRosterIndex; + + ULONG ulFlags; + ACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA AssemblyMetadata; + } ACTCTX_SECTION_KEYED_DATA,*PACTCTX_SECTION_KEYED_DATA; + + typedef const ACTCTX_SECTION_KEYED_DATA *PCACTCTX_SECTION_KEYED_DATA; + +#define FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX 0x1 +#define FIND_ACTCTX_SECTION_KEY_RETURN_FLAGS 0x2 +#define FIND_ACTCTX_SECTION_KEY_RETURN_ASSEMBLY_METADATA 0x4 + +#ifdef UNICODE +#define FindActCtxSectionString FindActCtxSectionStringW +#else +#define FindActCtxSectionString FindActCtxSectionStringA +#endif + + WINBASEAPI WINBOOL WINAPI FindActCtxSectionStringA(DWORD dwFlags,const GUID *lpExtensionGuid,ULONG ulSectionId,LPCSTR lpStringToFind,PACTCTX_SECTION_KEYED_DATA ReturnedData); + WINBASEAPI WINBOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags,const GUID *lpExtensionGuid,ULONG ulSectionId,LPCWSTR lpStringToFind,PACTCTX_SECTION_KEYED_DATA ReturnedData); + WINBASEAPI WINBOOL WINAPI FindActCtxSectionGuid(DWORD dwFlags,const GUID *lpExtensionGuid,ULONG ulSectionId,const GUID *lpGuidToFind,PACTCTX_SECTION_KEYED_DATA ReturnedData); + +#ifndef RC_INVOKED +#ifndef ACTIVATION_CONTEXT_BASIC_INFORMATION_DEFINED + + typedef struct _ACTIVATION_CONTEXT_BASIC_INFORMATION { + HANDLE hActCtx; + DWORD dwFlags; + } ACTIVATION_CONTEXT_BASIC_INFORMATION,*PACTIVATION_CONTEXT_BASIC_INFORMATION; + + typedef const struct _ACTIVATION_CONTEXT_BASIC_INFORMATION *PCACTIVATION_CONTEXT_BASIC_INFORMATION; + +#define ACTIVATION_CONTEXT_BASIC_INFORMATION_DEFINED 1 +#endif +#endif + +#define QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX 0x4 +#define QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE 0x8 +#define QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS 0x10 +#define QUERY_ACTCTX_FLAG_NO_ADDREF 0x80000000 + + WINBASEAPI WINBOOL WINAPI QueryActCtxW(DWORD dwFlags,HANDLE hActCtx,PVOID pvSubInstance,ULONG ulInfoClass,PVOID pvBuffer,SIZE_T cbBuffer,SIZE_T *pcbWrittenOrRequired); + + typedef WINBOOL (WINAPI *PQUERYACTCTXW_FUNC)(DWORD dwFlags,HANDLE hActCtx,PVOID pvSubInstance,ULONG ulInfoClass,PVOID pvBuffer,SIZE_T cbBuffer,SIZE_T *pcbWrittenOrRequired); + + WINBASEAPI WINBOOL WINAPI ProcessIdToSessionId(DWORD dwProcessId,DWORD *pSessionId); + WINBASEAPI DWORD WINAPI WTSGetActiveConsoleSessionId(); + WINBASEAPI WINBOOL WINAPI IsWow64Process(HANDLE hProcess,PBOOL Wow64Process); + WINBASEAPI WINBOOL WINAPI GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,PDWORD ReturnedLength); + WINBASEAPI WINBOOL WINAPI GetNumaHighestNodeNumber(PULONG HighestNodeNumber); + WINBASEAPI WINBOOL WINAPI GetNumaProcessorNode(UCHAR Processor,PUCHAR NodeNumber); + WINBASEAPI WINBOOL WINAPI GetNumaNodeProcessorMask(UCHAR Node,PULONGLONG ProcessorMask); + WINBASEAPI WINBOOL WINAPI GetNumaAvailableMemoryNode(UCHAR Node,PULONGLONG AvailableBytes); + #ifdef __cplusplus } #endif -#endif /* _WINBASE_H */ +#endif diff --git a/tinyc/win32/include/winapi/wincon.h b/tinyc/win32/include/winapi/wincon.h index 8539fe5c6..a3501ee70 100644 --- a/tinyc/win32/include/winapi/wincon.h +++ b/tinyc/win32/include/winapi/wincon.h @@ -1,206 +1,300 @@ -#ifndef _WINCON_H -#define _WINCON_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINCON_ +#define _WINCON_ #ifdef __cplusplus extern "C" { #endif -#define FOREGROUND_BLUE 1 -#define FOREGROUND_GREEN 2 -#define FOREGROUND_RED 4 -#define FOREGROUND_INTENSITY 8 -#define BACKGROUND_BLUE 16 -#define BACKGROUND_GREEN 32 -#define BACKGROUND_RED 64 -#define BACKGROUND_INTENSITY 128 + typedef struct _COORD { + SHORT X; + SHORT Y; + } COORD,*PCOORD; + + typedef struct _SMALL_RECT { + SHORT Left; + SHORT Top; + SHORT Right; + SHORT Bottom; + } SMALL_RECT,*PSMALL_RECT; + + typedef struct _KEY_EVENT_RECORD { + WINBOOL bKeyDown; + WORD wRepeatCount; + WORD wVirtualKeyCode; + WORD wVirtualScanCode; + union { + WCHAR UnicodeChar; + CHAR AsciiChar; + } uChar; + DWORD dwControlKeyState; + } KEY_EVENT_RECORD,*PKEY_EVENT_RECORD; + +#define RIGHT_ALT_PRESSED 0x1 +#define LEFT_ALT_PRESSED 0x2 +#define RIGHT_CTRL_PRESSED 0x4 +#define LEFT_CTRL_PRESSED 0x8 +#define SHIFT_PRESSED 0x10 +#define NUMLOCK_ON 0x20 +#define SCROLLLOCK_ON 0x40 +#define CAPSLOCK_ON 0x80 +#define ENHANCED_KEY 0x100 +#define NLS_DBCSCHAR 0x10000 +#define NLS_ALPHANUMERIC 0x0 +#define NLS_KATAKANA 0x20000 +#define NLS_HIRAGANA 0x40000 +#define NLS_ROMAN 0x400000 +#define NLS_IME_CONVERSION 0x800000 +#define NLS_IME_DISABLE 0x20000000 + + typedef struct _MOUSE_EVENT_RECORD { + COORD dwMousePosition; + DWORD dwButtonState; + DWORD dwControlKeyState; + DWORD dwEventFlags; + } MOUSE_EVENT_RECORD,*PMOUSE_EVENT_RECORD; + +#define FROM_LEFT_1ST_BUTTON_PRESSED 0x1 +#define RIGHTMOST_BUTTON_PRESSED 0x2 +#define FROM_LEFT_2ND_BUTTON_PRESSED 0x4 +#define FROM_LEFT_3RD_BUTTON_PRESSED 0x8 +#define FROM_LEFT_4TH_BUTTON_PRESSED 0x10 + +#define MOUSE_MOVED 0x1 +#define DOUBLE_CLICK 0x2 +#define MOUSE_WHEELED 0x4 + + typedef struct _WINDOW_BUFFER_SIZE_RECORD { + COORD dwSize; + } WINDOW_BUFFER_SIZE_RECORD,*PWINDOW_BUFFER_SIZE_RECORD; + + typedef struct _MENU_EVENT_RECORD { + UINT dwCommandId; + } MENU_EVENT_RECORD,*PMENU_EVENT_RECORD; + + typedef struct _FOCUS_EVENT_RECORD { + WINBOOL bSetFocus; + } FOCUS_EVENT_RECORD,*PFOCUS_EVENT_RECORD; + + typedef struct _INPUT_RECORD { + WORD EventType; + union { + KEY_EVENT_RECORD KeyEvent; + MOUSE_EVENT_RECORD MouseEvent; + WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; + MENU_EVENT_RECORD MenuEvent; + FOCUS_EVENT_RECORD FocusEvent; + } Event; + } INPUT_RECORD,*PINPUT_RECORD; + +#define KEY_EVENT 0x1 +#define MOUSE_EVENT 0x2 +#define WINDOW_BUFFER_SIZE_EVENT 0x4 +#define MENU_EVENT 0x8 +#define FOCUS_EVENT 0x10 + + typedef struct _CHAR_INFO { + union { + WCHAR UnicodeChar; + CHAR AsciiChar; + } Char; + WORD Attributes; + } CHAR_INFO,*PCHAR_INFO; + +#define FOREGROUND_BLUE 0x1 +#define FOREGROUND_GREEN 0x2 +#define FOREGROUND_RED 0x4 +#define FOREGROUND_INTENSITY 0x8 +#define BACKGROUND_BLUE 0x10 +#define BACKGROUND_GREEN 0x20 +#define BACKGROUND_RED 0x40 +#define BACKGROUND_INTENSITY 0x80 +#define COMMON_LVB_LEADING_BYTE 0x100 +#define COMMON_LVB_TRAILING_BYTE 0x200 +#define COMMON_LVB_GRID_HORIZONTAL 0x400 +#define COMMON_LVB_GRID_LVERTICAL 0x800 +#define COMMON_LVB_GRID_RVERTICAL 0x1000 +#define COMMON_LVB_REVERSE_VIDEO 0x4000 +#define COMMON_LVB_UNDERSCORE 0x8000 + +#define COMMON_LVB_SBCSDBCS 0x300 + + typedef struct _CONSOLE_SCREEN_BUFFER_INFO { + COORD dwSize; + COORD dwCursorPosition; + WORD wAttributes; + SMALL_RECT srWindow; + COORD dwMaximumWindowSize; + } CONSOLE_SCREEN_BUFFER_INFO,*PCONSOLE_SCREEN_BUFFER_INFO; + + typedef struct _CONSOLE_CURSOR_INFO { + DWORD dwSize; + WINBOOL bVisible; + } CONSOLE_CURSOR_INFO,*PCONSOLE_CURSOR_INFO; + + typedef struct _CONSOLE_FONT_INFO { + DWORD nFont; + COORD dwFontSize; + } CONSOLE_FONT_INFO,*PCONSOLE_FONT_INFO; + + typedef struct _CONSOLE_SELECTION_INFO { + DWORD dwFlags; + COORD dwSelectionAnchor; + SMALL_RECT srSelection; + } CONSOLE_SELECTION_INFO,*PCONSOLE_SELECTION_INFO; + +#define CONSOLE_NO_SELECTION 0x0 +#define CONSOLE_SELECTION_IN_PROGRESS 0x1 +#define CONSOLE_SELECTION_NOT_EMPTY 0x2 +#define CONSOLE_MOUSE_SELECTION 0x4 +#define CONSOLE_MOUSE_DOWN 0x8 + + typedef WINBOOL (WINAPI *PHANDLER_ROUTINE)(DWORD CtrlType); + #define CTRL_C_EVENT 0 #define CTRL_BREAK_EVENT 1 #define CTRL_CLOSE_EVENT 2 + #define CTRL_LOGOFF_EVENT 5 #define CTRL_SHUTDOWN_EVENT 6 -#define ENABLE_LINE_INPUT 2 -#define ENABLE_ECHO_INPUT 4 -#define ENABLE_PROCESSED_INPUT 1 -#define ENABLE_WINDOW_INPUT 8 -#define ENABLE_MOUSE_INPUT 16 -#define ENABLE_PROCESSED_OUTPUT 1 -#define ENABLE_WRAP_AT_EOL_OUTPUT 2 -#define KEY_EVENT 1 -#define MOUSE_EVENT 2 -#define WINDOW_BUFFER_SIZE_EVENT 4 -#define MENU_EVENT 8 -#define FOCUS_EVENT 16 -#define CAPSLOCK_ON 128 -#define ENHANCED_KEY 256 -#define RIGHT_ALT_PRESSED 1 -#define LEFT_ALT_PRESSED 2 -#define RIGHT_CTRL_PRESSED 4 -#define LEFT_CTRL_PRESSED 8 -#define SHIFT_PRESSED 16 -#define NUMLOCK_ON 32 -#define SCROLLLOCK_ON 64 -#define FROM_LEFT_1ST_BUTTON_PRESSED 1 -#define RIGHTMOST_BUTTON_PRESSED 2 -#define FROM_LEFT_2ND_BUTTON_PRESSED 4 -#define FROM_LEFT_3RD_BUTTON_PRESSED 8 -#define FROM_LEFT_4TH_BUTTON_PRESSED 16 -#define MOUSE_MOVED 1 -#define DOUBLE_CLICK 2 -#define MOUSE_WHEELED 4 - -typedef struct _CHAR_INFO { - union { - WCHAR UnicodeChar; - CHAR AsciiChar; - } Char; - WORD Attributes; -} CHAR_INFO,*PCHAR_INFO; -typedef struct _SMALL_RECT { - SHORT Left; - SHORT Top; - SHORT Right; - SHORT Bottom; -} SMALL_RECT,*PSMALL_RECT; -typedef struct _CONSOLE_CURSOR_INFO { - DWORD dwSize; - BOOL bVisible; -} CONSOLE_CURSOR_INFO,*PCONSOLE_CURSOR_INFO; -typedef struct _COORD { - SHORT X; - SHORT Y; -} COORD; -typedef struct _CONSOLE_SCREEN_BUFFER_INFO { - COORD dwSize; - COORD dwCursorPosition; - WORD wAttributes; - SMALL_RECT srWindow; - COORD dwMaximumWindowSize; -} CONSOLE_SCREEN_BUFFER_INFO,*PCONSOLE_SCREEN_BUFFER_INFO; -typedef BOOL(CALLBACK *PHANDLER_ROUTINE)(DWORD); -typedef struct _KEY_EVENT_RECORD { - BOOL bKeyDown; - WORD wRepeatCount; - WORD wVirtualKeyCode; - WORD wVirtualScanCode; - union { - WCHAR UnicodeChar; - CHAR AsciiChar; - } uChar; - DWORD dwControlKeyState; -} -#ifdef __GNUC__ -/* gcc's alignment is not what win32 expects */ - PACKED -#endif -KEY_EVENT_RECORD; - -typedef struct _MOUSE_EVENT_RECORD { - COORD dwMousePosition; - DWORD dwButtonState; - DWORD dwControlKeyState; - DWORD dwEventFlags; -} MOUSE_EVENT_RECORD; -typedef struct _WINDOW_BUFFER_SIZE_RECORD { COORD dwSize; } WINDOW_BUFFER_SIZE_RECORD; -typedef struct _MENU_EVENT_RECORD { UINT dwCommandId; } MENU_EVENT_RECORD,*PMENU_EVENT_RECORD; -typedef struct _FOCUS_EVENT_RECORD { BOOL bSetFocus; } FOCUS_EVENT_RECORD; -typedef struct _INPUT_RECORD { - WORD EventType; - union { - KEY_EVENT_RECORD KeyEvent; - MOUSE_EVENT_RECORD MouseEvent; - WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; - MENU_EVENT_RECORD MenuEvent; - FOCUS_EVENT_RECORD FocusEvent; - } Event; -} INPUT_RECORD,*PINPUT_RECORD; - -BOOL WINAPI AllocConsole(void); -HANDLE WINAPI CreateConsoleScreenBuffer(DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,PVOID); -BOOL WINAPI FillConsoleOutputAttribute(HANDLE,WORD,DWORD,COORD,PDWORD); -BOOL WINAPI FillConsoleOutputCharacterA(HANDLE,CHAR,DWORD,COORD,PDWORD); -BOOL WINAPI FillConsoleOutputCharacterW(HANDLE,WCHAR,DWORD,COORD,PDWORD); -BOOL WINAPI FlushConsoleInputBuffer(HANDLE); -BOOL WINAPI FreeConsole(void); -BOOL WINAPI GenerateConsoleCtrlEvent(DWORD,DWORD); -UINT WINAPI GetConsoleCP(void); -BOOL WINAPI GetConsoleCursorInfo(HANDLE,PCONSOLE_CURSOR_INFO); -BOOL WINAPI GetConsoleMode(HANDLE,PDWORD); -UINT WINAPI GetConsoleOutputCP(void); -BOOL WINAPI GetConsoleScreenBufferInfo(HANDLE,PCONSOLE_SCREEN_BUFFER_INFO); -DWORD WINAPI GetConsoleTitleA(LPSTR,DWORD); -DWORD WINAPI GetConsoleTitleW(LPWSTR,DWORD); -COORD WINAPI GetLargestConsoleWindowSize(HANDLE); -BOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE,PDWORD); -BOOL WINAPI GetNumberOfConsoleMouseButtons(PDWORD); -BOOL WINAPI PeekConsoleInputA(HANDLE,PINPUT_RECORD,DWORD,PDWORD); -BOOL WINAPI PeekConsoleInputW(HANDLE,PINPUT_RECORD,DWORD,PDWORD); -BOOL WINAPI ReadConsoleA(HANDLE,PVOID,DWORD,PDWORD,PVOID); -BOOL WINAPI ReadConsoleW(HANDLE,PVOID,DWORD,PDWORD,PVOID); -BOOL WINAPI ReadConsoleInputA(HANDLE,PINPUT_RECORD,DWORD,PDWORD); -BOOL WINAPI ReadConsoleInputW(HANDLE,PINPUT_RECORD,DWORD,PDWORD); -BOOL WINAPI ReadConsoleOutputAttribute(HANDLE,LPWORD,DWORD,COORD,LPDWORD); -BOOL WINAPI ReadConsoleOutputCharacterA(HANDLE,LPSTR,DWORD,COORD,PDWORD); -BOOL WINAPI ReadConsoleOutputCharacterW(HANDLE,LPWSTR,DWORD,COORD,PDWORD); -BOOL WINAPI ReadConsoleOutputA(HANDLE,PCHAR_INFO,COORD,COORD,PSMALL_RECT); -BOOL WINAPI ReadConsoleOutputW(HANDLE,PCHAR_INFO,COORD,COORD,PSMALL_RECT); -BOOL WINAPI ScrollConsoleScreenBufferA(HANDLE,const SMALL_RECT*,const SMALL_RECT*,COORD,const CHAR_INFO*); -BOOL WINAPI ScrollConsoleScreenBufferW(HANDLE,const SMALL_RECT*,const SMALL_RECT*,COORD,const CHAR_INFO*); -BOOL WINAPI SetConsoleActiveScreenBuffer(HANDLE); -BOOL WINAPI SetConsoleCP(UINT); -BOOL WINAPI SetConsoleCtrlHandler(PHANDLER_ROUTINE,BOOL); -BOOL WINAPI SetConsoleCursorInfo(HANDLE,const CONSOLE_CURSOR_INFO*); -BOOL WINAPI SetConsoleCursorPosition(HANDLE,COORD); -BOOL WINAPI SetConsoleMode(HANDLE,DWORD); -BOOL WINAPI SetConsoleOutputCP(UINT); -BOOL WINAPI SetConsoleScreenBufferSize(HANDLE,COORD); -BOOL WINAPI SetConsoleTextAttribute(HANDLE,WORD); -BOOL WINAPI SetConsoleTitleA(LPCSTR); -BOOL WINAPI SetConsoleTitleW(LPCWSTR); -BOOL WINAPI SetConsoleWindowInfo(HANDLE,BOOL,const SMALL_RECT*); -BOOL WINAPI WriteConsoleA(HANDLE,PCVOID,DWORD,PDWORD,PVOID); -BOOL WINAPI WriteConsoleW(HANDLE,PCVOID,DWORD,PDWORD,PVOID); -BOOL WINAPI WriteConsoleInputA(HANDLE,const INPUT_RECORD*,DWORD,PDWORD); -BOOL WINAPI WriteConsoleInputW(HANDLE,const INPUT_RECORD*,DWORD,PDWORD); -BOOL WINAPI WriteConsoleOutputA(HANDLE,const CHAR_INFO*,COORD,COORD,PSMALL_RECT); -BOOL WINAPI WriteConsoleOutputW(HANDLE,const CHAR_INFO*,COORD,COORD,PSMALL_RECT); -BOOL WINAPI WriteConsoleOutputAttribute(HANDLE,const WORD*,DWORD,COORD,PDWORD); -BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE,LPCSTR,DWORD,COORD,PDWORD); -BOOL WINAPI WriteConsoleOutputCharacterW(HANDLE,LPCWSTR,DWORD,COORD,PDWORD); + +#define ENABLE_PROCESSED_INPUT 0x1 +#define ENABLE_LINE_INPUT 0x2 +#define ENABLE_ECHO_INPUT 0x4 +#define ENABLE_WINDOW_INPUT 0x8 +#define ENABLE_MOUSE_INPUT 0x10 + +#define ENABLE_PROCESSED_OUTPUT 0x1 +#define ENABLE_WRAP_AT_EOL_OUTPUT 0x2 #ifdef UNICODE -#define FillConsoleOutputCharacter FillConsoleOutputCharacterW -#define GetConsoleTitle GetConsoleTitleW #define PeekConsoleInput PeekConsoleInputW -#define ReadConsole ReadConsoleW #define ReadConsoleInput ReadConsoleInputW +#define WriteConsoleInput WriteConsoleInputW #define ReadConsoleOutput ReadConsoleOutputW +#define WriteConsoleOutput WriteConsoleOutputW #define ReadConsoleOutputCharacter ReadConsoleOutputCharacterW +#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterW +#define FillConsoleOutputCharacter FillConsoleOutputCharacterW #define ScrollConsoleScreenBuffer ScrollConsoleScreenBufferW +#define GetConsoleTitle GetConsoleTitleW #define SetConsoleTitle SetConsoleTitleW +#define ReadConsole ReadConsoleW #define WriteConsole WriteConsoleW -#define WriteConsoleInput WriteConsoleInputW -#define WriteConsoleOutput WriteConsoleOutputW -#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterW +#define AddConsoleAlias AddConsoleAliasW +#define GetConsoleAlias GetConsoleAliasW +#define GetConsoleAliasesLength GetConsoleAliasesLengthW +#define GetConsoleAliasExesLength GetConsoleAliasExesLengthW +#define GetConsoleAliases GetConsoleAliasesW +#define GetConsoleAliasExes GetConsoleAliasExesW #else -#define FillConsoleOutputCharacter FillConsoleOutputCharacterA -#define GetConsoleTitle GetConsoleTitleA #define PeekConsoleInput PeekConsoleInputA -#define ReadConsole ReadConsoleA #define ReadConsoleInput ReadConsoleInputA +#define WriteConsoleInput WriteConsoleInputA #define ReadConsoleOutput ReadConsoleOutputA +#define WriteConsoleOutput WriteConsoleOutputA #define ReadConsoleOutputCharacter ReadConsoleOutputCharacterA +#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterA +#define FillConsoleOutputCharacter FillConsoleOutputCharacterA #define ScrollConsoleScreenBuffer ScrollConsoleScreenBufferA +#define GetConsoleTitle GetConsoleTitleA #define SetConsoleTitle SetConsoleTitleA +#define ReadConsole ReadConsoleA #define WriteConsole WriteConsoleA -#define WriteConsoleInput WriteConsoleInputA -#define WriteConsoleOutput WriteConsoleOutputA -#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterA +#define AddConsoleAlias AddConsoleAliasA +#define GetConsoleAlias GetConsoleAliasA +#define GetConsoleAliasesLength GetConsoleAliasesLengthA +#define GetConsoleAliasExesLength GetConsoleAliasExesLengthA +#define GetConsoleAliases GetConsoleAliasesA +#define GetConsoleAliasExes GetConsoleAliasExesA #endif + WINBASEAPI WINBOOL WINAPI PeekConsoleInputA(HANDLE hConsoleInput,PINPUT_RECORD lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsRead); + WINBASEAPI WINBOOL WINAPI PeekConsoleInputW(HANDLE hConsoleInput,PINPUT_RECORD lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsRead); + WINBASEAPI WINBOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput,PINPUT_RECORD lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsRead); + WINBASEAPI WINBOOL WINAPI ReadConsoleInputW(HANDLE hConsoleInput,PINPUT_RECORD lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsRead); + WINBASEAPI WINBOOL WINAPI WriteConsoleInputA(HANDLE hConsoleInput,CONST INPUT_RECORD *lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsWritten); + WINBASEAPI WINBOOL WINAPI WriteConsoleInputW(HANDLE hConsoleInput,CONST INPUT_RECORD *lpBuffer,DWORD nLength,LPDWORD lpNumberOfEventsWritten); + WINBASEAPI WINBOOL WINAPI ReadConsoleOutputA(HANDLE hConsoleOutput,PCHAR_INFO lpBuffer,COORD dwBufferSize,COORD dwBufferCoord,PSMALL_RECT lpReadRegion); + WINBASEAPI WINBOOL WINAPI ReadConsoleOutputW(HANDLE hConsoleOutput,PCHAR_INFO lpBuffer,COORD dwBufferSize,COORD dwBufferCoord,PSMALL_RECT lpReadRegion); + WINBASEAPI WINBOOL WINAPI WriteConsoleOutputA(HANDLE hConsoleOutput,CONST CHAR_INFO *lpBuffer,COORD dwBufferSize,COORD dwBufferCoord,PSMALL_RECT lpWriteRegion); + WINBASEAPI WINBOOL WINAPI WriteConsoleOutputW(HANDLE hConsoleOutput,CONST CHAR_INFO *lpBuffer,COORD dwBufferSize,COORD dwBufferCoord,PSMALL_RECT lpWriteRegion); + WINBASEAPI WINBOOL WINAPI ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,LPSTR lpCharacter,DWORD nLength,COORD dwReadCoord,LPDWORD lpNumberOfCharsRead); + WINBASEAPI WINBOOL WINAPI ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,LPWSTR lpCharacter,DWORD nLength,COORD dwReadCoord,LPDWORD lpNumberOfCharsRead); + WINBASEAPI WINBOOL WINAPI ReadConsoleOutputAttribute(HANDLE hConsoleOutput,LPWORD lpAttribute,DWORD nLength,COORD dwReadCoord,LPDWORD lpNumberOfAttrsRead); + WINBASEAPI WINBOOL WINAPI WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,LPCSTR lpCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten); + WINBASEAPI WINBOOL WINAPI WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,LPCWSTR lpCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten); + WINBASEAPI WINBOOL WINAPI WriteConsoleOutputAttribute(HANDLE hConsoleOutput,CONST WORD *lpAttribute,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfAttrsWritten); + WINBASEAPI WINBOOL WINAPI FillConsoleOutputCharacterA(HANDLE hConsoleOutput,CHAR cCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten); + WINBASEAPI WINBOOL WINAPI FillConsoleOutputCharacterW(HANDLE hConsoleOutput,WCHAR cCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten); + WINBASEAPI WINBOOL WINAPI FillConsoleOutputAttribute(HANDLE hConsoleOutput,WORD wAttribute,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfAttrsWritten); + WINBASEAPI WINBOOL WINAPI GetConsoleMode(HANDLE hConsoleHandle,LPDWORD lpMode); + WINBASEAPI WINBOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,LPDWORD lpNumberOfEvents); + WINBASEAPI WINBOOL WINAPI GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo); + WINBASEAPI COORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput); + WINBASEAPI WINBOOL WINAPI GetConsoleCursorInfo(HANDLE hConsoleOutput,PCONSOLE_CURSOR_INFO lpConsoleCursorInfo); + WINBASEAPI WINBOOL WINAPI GetCurrentConsoleFont(HANDLE hConsoleOutput,WINBOOL bMaximumWindow,PCONSOLE_FONT_INFO lpConsoleCurrentFont); + WINBASEAPI COORD WINAPI GetConsoleFontSize(HANDLE hConsoleOutput,DWORD nFont); + WINBASEAPI WINBOOL WINAPI GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo); + WINBASEAPI WINBOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons); + WINBASEAPI WINBOOL WINAPI SetConsoleMode(HANDLE hConsoleHandle,DWORD dwMode); + WINBASEAPI WINBOOL WINAPI SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput); + WINBASEAPI WINBOOL WINAPI FlushConsoleInputBuffer(HANDLE hConsoleInput); + WINBASEAPI WINBOOL WINAPI SetConsoleScreenBufferSize(HANDLE hConsoleOutput,COORD dwSize); + WINBASEAPI WINBOOL WINAPI SetConsoleCursorPosition(HANDLE hConsoleOutput,COORD dwCursorPosition); + WINBASEAPI WINBOOL WINAPI SetConsoleCursorInfo(HANDLE hConsoleOutput,CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo); + WINBASEAPI WINBOOL WINAPI ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,CONST SMALL_RECT *lpScrollRectangle,CONST SMALL_RECT *lpClipRectangle,COORD dwDestinationOrigin,CONST CHAR_INFO *lpFill); + WINBASEAPI WINBOOL WINAPI ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,CONST SMALL_RECT *lpScrollRectangle,CONST SMALL_RECT *lpClipRectangle,COORD dwDestinationOrigin,CONST CHAR_INFO *lpFill); + WINBASEAPI WINBOOL WINAPI SetConsoleWindowInfo(HANDLE hConsoleOutput,WINBOOL bAbsolute,CONST SMALL_RECT *lpConsoleWindow); + WINBASEAPI WINBOOL WINAPI SetConsoleTextAttribute(HANDLE hConsoleOutput,WORD wAttributes); + WINBASEAPI WINBOOL WINAPI SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,WINBOOL Add); + WINBASEAPI WINBOOL WINAPI GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,DWORD dwProcessGroupId); + WINBASEAPI WINBOOL WINAPI AllocConsole(VOID); + WINBASEAPI WINBOOL WINAPI FreeConsole(VOID); + WINBASEAPI WINBOOL WINAPI AttachConsole(DWORD dwProcessId); + +#define ATTACH_PARENT_PROCESS ((DWORD)-1) + + WINBASEAPI DWORD WINAPI GetConsoleTitleA(LPSTR lpConsoleTitle,DWORD nSize); + WINBASEAPI DWORD WINAPI GetConsoleTitleW(LPWSTR lpConsoleTitle,DWORD nSize); + WINBASEAPI WINBOOL WINAPI SetConsoleTitleA(LPCSTR lpConsoleTitle); + WINBASEAPI WINBOOL WINAPI SetConsoleTitleW(LPCWSTR lpConsoleTitle); + WINBASEAPI WINBOOL WINAPI ReadConsoleA(HANDLE hConsoleInput,LPVOID lpBuffer,DWORD nNumberOfCharsToRead,LPDWORD lpNumberOfCharsRead,LPVOID lpReserved); + WINBASEAPI WINBOOL WINAPI ReadConsoleW(HANDLE hConsoleInput,LPVOID lpBuffer,DWORD nNumberOfCharsToRead,LPDWORD lpNumberOfCharsRead,LPVOID lpReserved); + WINBASEAPI WINBOOL WINAPI WriteConsoleA(HANDLE hConsoleOutput,CONST VOID *lpBuffer,DWORD nNumberOfCharsToWrite,LPDWORD lpNumberOfCharsWritten,LPVOID lpReserved); + WINBASEAPI WINBOOL WINAPI WriteConsoleW(HANDLE hConsoleOutput,CONST VOID *lpBuffer,DWORD nNumberOfCharsToWrite,LPDWORD lpNumberOfCharsWritten,LPVOID lpReserved); + +#define CONSOLE_TEXTMODE_BUFFER 1 + + WINBASEAPI HANDLE WINAPI CreateConsoleScreenBuffer(DWORD dwDesiredAccess,DWORD dwShareMode,CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,DWORD dwFlags,LPVOID lpScreenBufferData); + WINBASEAPI UINT WINAPI GetConsoleCP(VOID); + WINBASEAPI WINBOOL WINAPI SetConsoleCP(UINT wCodePageID); + WINBASEAPI UINT WINAPI GetConsoleOutputCP(VOID); + WINBASEAPI WINBOOL WINAPI SetConsoleOutputCP(UINT wCodePageID); + +#define CONSOLE_FULLSCREEN 1 +#define CONSOLE_FULLSCREEN_HARDWARE 2 + + WINBASEAPI WINBOOL WINAPI GetConsoleDisplayMode(LPDWORD lpModeFlags); + WINBASEAPI HWND WINAPI GetConsoleWindow(VOID); + WINBASEAPI DWORD WINAPI GetConsoleProcessList(LPDWORD lpdwProcessList,DWORD dwProcessCount); + WINBASEAPI WINBOOL WINAPI AddConsoleAliasA(LPSTR Source,LPSTR Target,LPSTR ExeName); + WINBASEAPI WINBOOL WINAPI AddConsoleAliasW(LPWSTR Source,LPWSTR Target,LPWSTR ExeName); + WINBASEAPI DWORD WINAPI GetConsoleAliasA(LPSTR Source,LPSTR TargetBuffer,DWORD TargetBufferLength,LPSTR ExeName); + WINBASEAPI DWORD WINAPI GetConsoleAliasW(LPWSTR Source,LPWSTR TargetBuffer,DWORD TargetBufferLength,LPWSTR ExeName); + WINBASEAPI DWORD WINAPI GetConsoleAliasesLengthA(LPSTR ExeName); + WINBASEAPI DWORD WINAPI GetConsoleAliasesLengthW(LPWSTR ExeName); + WINBASEAPI DWORD WINAPI GetConsoleAliasExesLengthA(VOID); + WINBASEAPI DWORD WINAPI GetConsoleAliasExesLengthW(VOID); + WINBASEAPI DWORD WINAPI GetConsoleAliasesA(LPSTR AliasBuffer,DWORD AliasBufferLength,LPSTR ExeName); + WINBASEAPI DWORD WINAPI GetConsoleAliasesW(LPWSTR AliasBuffer,DWORD AliasBufferLength,LPWSTR ExeName); + WINBASEAPI DWORD WINAPI GetConsoleAliasExesA(LPSTR ExeNameBuffer,DWORD ExeNameBufferLength); + WINBASEAPI DWORD WINAPI GetConsoleAliasExesW(LPWSTR ExeNameBuffer,DWORD ExeNameBufferLength); + #ifdef __cplusplus } #endif diff --git a/tinyc/win32/include/winapi/windef.h b/tinyc/win32/include/winapi/windef.h index 1ee3f39f6..d63bdef13 100644 --- a/tinyc/win32/include/winapi/windef.h +++ b/tinyc/win32/include/winapi/windef.h @@ -1,7 +1,13 @@ -#ifndef _WINDEF_H -#define _WINDEF_H -#if __GNUC__ >=3 -#pragma GCC system_header +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINDEF_ +#define _WINDEF_ + +#ifndef STRICT +#define STRICT 1 #endif #ifdef __cplusplus @@ -9,230 +15,277 @@ extern "C" { #endif #ifndef WINVER -#define WINVER 0x0400 -#endif -#ifndef _WIN32_WINNT -#define _WIN32_WINNT WINVER -#endif -#ifndef WIN32 -#define WIN32 +#define WINVER 0x0502 #endif -#ifndef _WIN32 -#define _WIN32 -#endif -#define FAR -#define far -#define NEAR -#define near -#ifndef CONST -#define CONST const + +#ifndef BASETYPES +#define BASETYPES + typedef unsigned long ULONG; + typedef ULONG *PULONG; + typedef unsigned short USHORT; + typedef USHORT *PUSHORT; + typedef unsigned char UCHAR; + typedef UCHAR *PUCHAR; + typedef char *PSZ; #endif -#undef MAX_PATH + #define MAX_PATH 260 #ifndef NULL #ifdef __cplusplus #define NULL 0 #else -#define NULL ((void*)0) +#define NULL ((void *)0) #endif #endif + #ifndef FALSE #define FALSE 0 #endif + #ifndef TRUE #define TRUE 1 #endif + +#ifndef IN #define IN +#endif + +#ifndef OUT #define OUT +#endif + #ifndef OPTIONAL #define OPTIONAL #endif -#ifdef __GNUC__ -#define PACKED __attribute__((packed)) -#ifndef _stdcall -#define _stdcall __attribute__((stdcall)) -#endif -#ifndef __stdcall -#define __stdcall __attribute__((stdcall)) -#endif -#ifndef _cdecl -#define _cdecl __attribute__((cdecl)) +#undef far +#undef near +#undef pascal + +#define far +#define near +#define pascal __stdcall + +#define cdecl +#ifndef CDECL +#define CDECL #endif -#ifndef __cdecl -#define __cdecl __attribute__((cdecl)) +#ifndef CALLBACK +#define CALLBACK __stdcall #endif -#ifndef __declspec -#define __declspec(e) __attribute__((e)) +#ifndef WINAPI +#define WINAPI __stdcall #endif -#ifndef _declspec -#define _declspec(e) __attribute__((e)) +#define WINAPIV __cdecl +#define APIENTRY WINAPI +#define APIPRIVATE WINAPI +#define PASCAL WINAPI +#define WINAPI_INLINE WINAPI + +#undef FAR +#undef NEAR +#define FAR +#define NEAR +#ifndef CONST +#define CONST const #endif -#else -#define PACKED -#define _cdecl -#define __cdecl + + typedef unsigned long DWORD; + typedef int WINBOOL; +#define BOOL WINBOOL + typedef unsigned char BYTE; + typedef unsigned short WORD; + typedef float FLOAT; + typedef FLOAT *PFLOAT; + typedef WINBOOL *PBOOL; + typedef WINBOOL *LPBOOL; + typedef BYTE *PBYTE; + typedef BYTE *LPBYTE; + typedef int *PINT; + typedef int *LPINT; + typedef WORD *PWORD; + typedef WORD *LPWORD; + typedef long *LPLONG; + typedef DWORD *PDWORD; + typedef DWORD *LPDWORD; + typedef void *LPVOID; +# ifndef _LPCVOID_DEFINED +#define _LPCVOID_DEFINED +typedef CONST void *LPCVOID; #endif + typedef int INT; + typedef unsigned int UINT; + typedef unsigned int *PUINT; -#undef pascal -#undef _pascal -#undef __pascal -#define pascal __stdcall -#define _pascal __stdcall -#define __pascal __stdcall -#define PASCAL _pascal -#define CDECL _cdecl -#define STDCALL __stdcall -#define WINAPI __stdcall -#define WINAPIV __cdecl -#define APIENTRY __stdcall -#define CALLBACK __stdcall -#define APIPRIVATE __stdcall - -#define DECLSPEC_IMPORT __declspec(dllimport) -#define DECLSPEC_EXPORT __declspec(dllexport) -#ifdef __GNUC__ -#define DECLSPEC_NORETURN __declspec(noreturn) -#define DECLARE_STDCALL_P( type ) __stdcall type -#elif defined(__WATCOMC__) -#define DECLSPEC_NORETURN -#define DECLARE_STDCALL_P( type ) type __stdcall -#endif /* __GNUC__/__WATCOMC__ */ -#define MAKEWORD(a,b) ((WORD)(((BYTE)(a))|(((WORD)((BYTE)(b)))<<8))) -#define MAKELONG(a,b) ((LONG)(((WORD)(a))|(((DWORD)((WORD)(b)))<<16))) -#define LOWORD(l) ((WORD)((DWORD)(l))) -#define HIWORD(l) ((WORD)(((DWORD)(l)>>16)&0xFFFF)) -#define LOBYTE(w) ((BYTE)(w)) -#define HIBYTE(w) ((BYTE)(((WORD)(w)>>8)&0xFF)) - -#ifndef _export -#define _export -#endif -#ifndef __export -#define __export +#ifndef NT_INCLUDED +#include <winnt.h> #endif +//gr #include <specstrings.h> + + typedef UINT_PTR WPARAM; + typedef LONG_PTR LPARAM; + typedef LONG_PTR LRESULT; + +#ifndef __cplusplus #ifndef NOMINMAX #ifndef max -#define max(a,b) ((a)>(b)?(a):(b)) +#define max(a,b) (((a) > (b)) ? (a) : (b)) #endif + #ifndef min -#define min(a,b) ((a)<(b)?(a):(b)) +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif #endif #endif -#define UNREFERENCED_PARAMETER(P) {(P)=(P);} -#define UNREFERENCED_LOCAL_VARIABLE(L) {(L)=(L);} -#define DBG_UNREFERENCED_PARAMETER(P) -#define DBG_UNREFERENCED_LOCAL_VARIABLE(L) +#define MAKEWORD(a,b) ((WORD)(((BYTE)((DWORD_PTR)(a) & 0xff)) | ((WORD)((BYTE)((DWORD_PTR)(b) & 0xff))) << 8)) +#define MAKELONG(a,b) ((LONG)(((WORD)((DWORD_PTR)(a) & 0xffff)) | ((DWORD)((WORD)((DWORD_PTR)(b) & 0xffff))) << 16)) +#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffff)) +#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) +#define LOBYTE(w) ((BYTE)((DWORD_PTR)(w) & 0xff)) +#define HIBYTE(w) ((BYTE)((DWORD_PTR)(w) >> 8)) -typedef unsigned long DWORD; -typedef int WINBOOL,*PWINBOOL,*LPWINBOOL; -/* FIXME: Is there a good solution to this? */ -#ifndef XFree86Server -#ifndef __OBJC__ -typedef WINBOOL BOOL; +#ifndef WIN_INTERNAL + DECLARE_HANDLE (HWND); + DECLARE_HANDLE (HHOOK); +#ifdef WINABLE + DECLARE_HANDLE (HEVENT); +#endif +#endif + + typedef WORD ATOM; + + typedef HANDLE *SPHANDLE; + typedef HANDLE *LPHANDLE; + typedef HANDLE HGLOBAL; + typedef HANDLE HLOCAL; + typedef HANDLE GLOBALHANDLE; + typedef HANDLE LOCALHANDLE; +#ifdef _WIN64 + typedef INT_PTR (WINAPI *FARPROC)(); + typedef INT_PTR (WINAPI *NEARPROC)(); + typedef INT_PTR (WINAPI *PROC)(); #else -#define BOOL WINBOOL + typedef int (WINAPI *FARPROC)(); + typedef int (WINAPI *NEARPROC)(); + typedef int (WINAPI *PROC)(); #endif -typedef unsigned char BYTE; -#endif /* ndef XFree86Server */ -typedef BOOL *PBOOL,*LPBOOL; -typedef unsigned short WORD; -typedef float FLOAT; -typedef FLOAT *PFLOAT; -typedef BYTE *PBYTE,*LPBYTE; -typedef int *PINT,*LPINT; -typedef WORD *PWORD,*LPWORD; -typedef long *LPLONG; -typedef DWORD *PDWORD,*LPDWORD; -typedef void *PVOID,*LPVOID; -typedef CONST void *PCVOID,*LPCVOID; -typedef int INT; -typedef unsigned int UINT,*PUINT,*LPUINT; -#include <winnt.h> + typedef void *HGDIOBJ; + + DECLARE_HANDLE(HKEY); + typedef HKEY *PHKEY; + + DECLARE_HANDLE(HACCEL); + DECLARE_HANDLE(HBITMAP); + DECLARE_HANDLE(HBRUSH); + DECLARE_HANDLE(HCOLORSPACE); + DECLARE_HANDLE(HDC); + DECLARE_HANDLE(HGLRC); + DECLARE_HANDLE(HDESK); + DECLARE_HANDLE(HENHMETAFILE); + DECLARE_HANDLE(HFONT); + DECLARE_HANDLE(HICON); + DECLARE_HANDLE(HMENU); + DECLARE_HANDLE(HMETAFILE); + DECLARE_HANDLE(HINSTANCE); + typedef HINSTANCE HMODULE; + DECLARE_HANDLE(HPALETTE); + DECLARE_HANDLE(HPEN); + DECLARE_HANDLE(HRGN); + DECLARE_HANDLE(HRSRC); + DECLARE_HANDLE(HSTR); + DECLARE_HANDLE(HTASK); + DECLARE_HANDLE(HWINSTA); + DECLARE_HANDLE(HKL); + DECLARE_HANDLE(HMONITOR); + DECLARE_HANDLE(HWINEVENTHOOK); + DECLARE_HANDLE(HUMPD); + + typedef int HFILE; + typedef HICON HCURSOR; + typedef DWORD COLORREF; + typedef DWORD *LPCOLORREF; + +#define HFILE_ERROR ((HFILE)-1) + + typedef struct tagRECT { + LONG left; + LONG top; + LONG right; + LONG bottom; + } RECT,*PRECT,*NPRECT,*LPRECT; + + typedef const RECT *LPCRECT; + + typedef struct _RECTL { + LONG left; + LONG top; + LONG right; + LONG bottom; + } RECTL,*PRECTL,*LPRECTL; + + typedef const RECTL *LPCRECTL; + + typedef struct tagPOINT { + LONG x; + LONG y; + } POINT,*PPOINT,*NPPOINT,*LPPOINT; + + typedef struct _POINTL { + LONG x; + LONG y; + } POINTL,*PPOINTL; + + typedef struct tagSIZE { + LONG cx; + LONG cy; + } SIZE,*PSIZE,*LPSIZE; + + typedef SIZE SIZEL; + typedef SIZE *PSIZEL,*LPSIZEL; + + typedef struct tagPOINTS { + SHORT x; + SHORT y; + } POINTS,*PPOINTS,*LPPOINTS; + + typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } FILETIME,*PFILETIME,*LPFILETIME; +#define _FILETIME_ + +#define DM_UPDATE 1 +#define DM_COPY 2 +#define DM_PROMPT 4 +#define DM_MODIFY 8 + +#define DM_IN_BUFFER DM_MODIFY +#define DM_IN_PROMPT DM_PROMPT +#define DM_OUT_BUFFER DM_COPY +#define DM_OUT_DEFAULT DM_UPDATE -typedef UINT WPARAM; -typedef LONG LPARAM; -typedef LONG LRESULT; -#ifndef _HRESULT_DEFINED -typedef LONG HRESULT; -#define _HRESULT_DEFINED -#endif -#ifndef XFree86Server -typedef WORD ATOM; -#endif /* XFree86Server */ -typedef HANDLE HGLOBAL; -typedef HANDLE HLOCAL; -typedef HANDLE GLOBALHANDLE; -typedef HANDLE LOCALHANDLE; -typedef void *HGDIOBJ; -DECLARE_HANDLE(HACCEL); -DECLARE_HANDLE(HBITMAP); -DECLARE_HANDLE(HBRUSH); -DECLARE_HANDLE(HCOLORSPACE); -DECLARE_HANDLE(HDC); -DECLARE_HANDLE(HGLRC); -DECLARE_HANDLE(HDESK); -DECLARE_HANDLE(HENHMETAFILE); -DECLARE_HANDLE(HFONT); -DECLARE_HANDLE(HICON); -DECLARE_HANDLE(HKEY); -/* FIXME: How to handle these. SM_CMONITORS etc in winuser.h also. */ -/* #if (WINVER >= 0x0500) */ -DECLARE_HANDLE(HMONITOR); -#define HMONITOR_DECLARED 1 -DECLARE_HANDLE(HTERMINAL); -DECLARE_HANDLE(HWINEVENTHOOK); -/* #endif */ -typedef HKEY *PHKEY; -DECLARE_HANDLE(HMENU); -DECLARE_HANDLE(HMETAFILE); -DECLARE_HANDLE(HINSTANCE); -typedef HINSTANCE HMODULE; -DECLARE_HANDLE(HPALETTE); -DECLARE_HANDLE(HPEN); -DECLARE_HANDLE(HRGN); -DECLARE_HANDLE(HRSRC); -DECLARE_HANDLE(HSTR); -DECLARE_HANDLE(HTASK); -DECLARE_HANDLE(HWND); -DECLARE_HANDLE(HWINSTA); -DECLARE_HANDLE(HKL); -typedef int HFILE; -typedef HICON HCURSOR; -typedef DWORD COLORREF; -typedef int (WINAPI *FARPROC)(); -typedef int (WINAPI *NEARPROC)(); -typedef int (WINAPI *PROC)(); -typedef struct tagRECT { - LONG left; - LONG top; - LONG right; - LONG bottom; -} RECT,*PRECT,*LPRECT; -typedef const RECT *LPCRECT; -typedef struct tagRECTL { - LONG left; - LONG top; - LONG right; - LONG bottom; -} RECTL,*PRECTL,*LPRECTL; -typedef const RECTL *LPCRECTL; -typedef struct tagPOINT { - LONG x; - LONG y; -} POINT,POINTL,*PPOINT,*LPPOINT,*PPOINTL,*LPPOINTL; -typedef struct tagSIZE { - LONG cx; - LONG cy; -} SIZE,SIZEL,*PSIZE,*LPSIZE,*PSIZEL,*LPSIZEL; -typedef struct tagPOINTS { - SHORT x; - SHORT y; -} POINTS,*PPOINTS,*LPPOINTS; +#define DC_FIELDS 1 +#define DC_PAPERS 2 +#define DC_PAPERSIZE 3 +#define DC_MINEXTENT 4 +#define DC_MAXEXTENT 5 +#define DC_BINS 6 +#define DC_DUPLEX 7 +#define DC_SIZE 8 +#define DC_EXTRA 9 +#define DC_VERSION 10 +#define DC_DRIVER 11 +#define DC_BINNAMES 12 +#define DC_ENUMRESOLUTIONS 13 +#define DC_FILEDEPENDENCIES 14 +#define DC_TRUETYPE 15 +#define DC_PAPERNAMES 16 +#define DC_ORIENTATION 17 +#define DC_COPIES 18 #ifdef __cplusplus } diff --git a/tinyc/win32/include/winapi/windows.h b/tinyc/win32/include/winapi/windows.h index de2cf9b85..2660d7f08 100644 --- a/tinyc/win32/include/winapi/windows.h +++ b/tinyc/win32/include/winapi/windows.h @@ -1,136 +1,79 @@ -/* - windows.h - main header file for the Win32 API - - Written by Anders Norlander <anorland@hem2.passagen.se> - - This file is part of a free library for the Win32 API. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -*/ -#ifndef _WINDOWS_H -#define _WINDOWS_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -/* translate GCC target defines to MS equivalents. Keep this synchronized - with winnt.h. */ -#if defined(__i686__) && !defined(_M_IX86) -#define _M_IX86 600 -#elif defined(__i586__) && !defined(_M_IX86) -#define _M_IX86 500 -#elif defined(__i486__) && !defined(_M_IX86) -#define _M_IX86 400 -#elif defined(__i386__) && !defined(_M_IX86) -#define _M_IX86 300 -#endif -#if defined(_M_IX86) && !defined(_X86_) -#define _X86_ -#elif defined(_M_ALPHA) && !defined(_ALPHA_) -#define _ALPHA_ -#elif defined(_M_PPC) && !defined(_PPC_) -#define _PPC_ -#elif defined(_M_MRX000) && !defined(_MIPS_) -#define _MIPS_ -#elif defined(_M_M68K) && !defined(_68K_) -#define _68K_ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINDOWS_ +#define _WINDOWS_ + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 #endif -#ifdef RC_INVOKED -/* winresrc.h includes the necessary headers */ +#ifndef WINVER +#define WINVER 0x0502 +#endif + +#include <_mingw.h> + +#ifndef _INC_WINDOWS +#define _INC_WINDOWS + +#if defined(RC_INVOKED) && !defined(NOWINRES) + #include <winresrc.h> #else -#ifdef __GNUC__ -#ifndef NONAMELESSUNION -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) -#define _ANONYMOUS_UNION __extension__ -#define _ANONYMOUS_STRUCT __extension__ -#else -#if defined(__cplusplus) -#define _ANONYMOUS_UNION __extension__ -#endif /* __cplusplus */ -#endif /* __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) */ -#endif /* NONAMELESSUNION */ -#elif defined(__WATCOMC__) -#define _ANONYMOUS_UNION -#define _ANONYMOUS_STRUCT -#endif /* __GNUC__/__WATCOMC__ */ - -#ifndef _ANONYMOUS_UNION -#define _ANONYMOUS_UNION -#define _UNION_NAME(x) x -#define DUMMYUNIONNAME u -#define DUMMYUNIONNAME2 u2 -#define DUMMYUNIONNAME3 u3 -#define DUMMYUNIONNAME4 u4 -#define DUMMYUNIONNAME5 u5 -#define DUMMYUNIONNAME6 u6 -#define DUMMYUNIONNAME7 u7 -#define DUMMYUNIONNAME8 u8 -#else -#define _UNION_NAME(x) -#define DUMMYUNIONNAME -#define DUMMYUNIONNAME2 -#define DUMMYUNIONNAME3 -#define DUMMYUNIONNAME4 -#define DUMMYUNIONNAME5 -#define DUMMYUNIONNAME6 -#define DUMMYUNIONNAME7 -#define DUMMYUNIONNAME8 -#endif -#ifndef _ANONYMOUS_STRUCT -#define _ANONYMOUS_STRUCT -#define _STRUCT_NAME(x) x -#define DUMMYSTRUCTNAME s -#define DUMMYSTRUCTNAME2 s2 -#define DUMMYSTRUCTNAME3 s3 -#else -#define _STRUCT_NAME(x) -#define DUMMYSTRUCTNAME -#define DUMMYSTRUCTNAME2 -#define DUMMYSTRUCTNAME3 +#ifdef RC_INVOKED +#define NOATOM +#define NOGDI +#define NOGDICAPMASKS +#define NOMETAFILE +#define NOMINMAX +#define NOMSG +#define NOOPENFILE +#define NORASTEROPS +#define NOSCROLL +#define NOSOUND +#define NOSYSMETRICS +#define NOTEXTMETRIC +#define NOWH +#define NOCOMM +#define NOKANJI +#define NOCRYPT +#define NOMCX #endif -#ifndef NO_STRICT -#ifndef STRICT -#define STRICT 1 +#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && (defined(_X86_) && !defined(__x86_64)) +#define I_X86_ +#endif + +#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(__x86_64) +#define _AMD64_ +#endif + +#if !defined(I_X86_) && !(defined(_X86_) && !defined(__x86_64)) && !defined(_AMD64_) && defined(__ia64__) +#if !defined(_IA64_) +#define _IA64_ #endif #endif +#ifndef RC_INVOKED +#include <excpt.h> #include <stdarg.h> +#endif + #include <windef.h> -#include <wincon.h> -#include <basetyps.h> -#include <excpt.h> #include <winbase.h> -#ifndef _WINGDI_H #include <wingdi.h> -#endif -#ifndef _WINUSER_H #include <winuser.h> -#endif -#ifndef _WINNLS_H -#include <winnls.h> -#endif -#ifndef _WINVER_H +//gr #include <winnls.h> +#include <wincon.h> #include <winver.h> -#endif -#ifndef _WINNETWK_H -#include <winnetwk.h> -#endif -#ifndef _WINREG_H #include <winreg.h> -#endif -#ifndef _WINSVC_H -#include <winsvc.h> -#endif +//gr #include <winnetwk.h> #ifndef WIN32_LEAN_AND_MEAN -#include <commdlg.h> #include <cderr.h> #include <dde.h> #include <ddeml.h> @@ -141,36 +84,44 @@ #include <rpc.h> #include <shellapi.h> #include <winperf.h> +#include <winsock.h> +#ifndef NOCRYPT +#include <wincrypt.h> +#include <winefs.h> +#include <winscard.h> +#endif + +#ifndef NOUSER +#ifndef NOGDI #include <winspool.h> -#if defined(Win32_Winsock) -#warning "The Win32_Winsock macro name is deprecated.\ - Please use __USE_W32_SOCKETS instead" -#ifndef __USE_W32_SOCKETS -#define __USE_W32_SOCKETS -#endif -#endif -#if defined(__USE_W32_SOCKETS) || !(defined(__CYGWIN__) || defined(__MSYS__) || defined(_UWIN)) -#if (_WIN32_WINNT >= 0x0400) -#include <winsock2.h> -/* - * MS likes to include mswsock.h here as well, - * but that can cause undefined symbols if - * winsock2.h is included before windows.h - */ +#ifdef INC_OLE1 +#include <ole.h> #else -#include <winsock.h> -#endif /* (_WIN32_WINNT >= 0x0400) */ +#include <ole2.h> +#endif +#include <commdlg.h> +#endif +#endif +#endif + +//gr #include <stralign.h> + +#ifdef INC_OLE2 +#include <ole2.h> #endif -#endif /* WIN32_LEAN_AND_MEAN */ -#endif /* RC_INVOKED */ +#ifndef NOSERVICE +#include <winsvc.h> +#endif + +#ifndef NOMCX +#include <mcx.h> +#endif -#ifdef __OBJC__ -/* FIXME: Not undefining BOOL here causes all BOOLs to be WINBOOL (int), - but undefining it causes trouble as well if a file is included after - windows.h -*/ -#undef BOOL +#ifndef NOIME +#include <imm.h> #endif #endif +#endif +#endif diff --git a/tinyc/win32/include/winapi/winerror.h b/tinyc/win32/include/winapi/winerror.h index 8865d9782..77d85edc8 100644 --- a/tinyc/win32/include/winapi/winerror.h +++ b/tinyc/win32/include/winapi/winerror.h @@ -1,11 +1,45 @@ -#ifndef _WINERROR_H -#define _WINERROR_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINERROR_ +#define _WINERROR_ +#define FACILITY_WINDOWSUPDATE 36 +#define FACILITY_WINDOWS_CE 24 +#define FACILITY_WINDOWS 8 +#define FACILITY_URT 19 +#define FACILITY_UMI 22 +#define FACILITY_SXS 23 +#define FACILITY_STORAGE 3 +#define FACILITY_STATE_MANAGEMENT 34 +#define FACILITY_SSPI 9 +#define FACILITY_SCARD 16 +#define FACILITY_SETUPAPI 15 +#define FACILITY_SECURITY 9 +#define FACILITY_RPC 1 +#define FACILITY_WIN32 7 +#define FACILITY_CONTROL 10 +#define FACILITY_NULL 0 +#define FACILITY_METADIRECTORY 35 +#define FACILITY_MSMQ 14 +#define FACILITY_MEDIASERVER 13 +#define FACILITY_INTERNET 12 +#define FACILITY_ITF 4 +#define FACILITY_HTTP 25 +#define FACILITY_DPLAY 21 +#define FACILITY_DISPATCH 2 +#define FACILITY_DIRECTORYSERVICE 37 +#define FACILITY_CONFIGURATION 33 +#define FACILITY_COMPLUS 17 +#define FACILITY_CERT 11 +#define FACILITY_BACKGROUNDCOPY 32 +#define FACILITY_ACS 20 +#define FACILITY_AAF 18 #define ERROR_SUCCESS 0L #define NO_ERROR 0L +#define SEC_E_OK ((HRESULT)0x00000000L) #define ERROR_INVALID_FUNCTION 1L #define ERROR_FILE_NOT_FOUND 2L #define ERROR_PATH_NOT_FOUND 3L @@ -171,6 +205,9 @@ #define ERROR_LOCKED 212L #define ERROR_TOO_MANY_MODULES 214L #define ERROR_NESTING_NOT_ALLOWED 215L +#define ERROR_EXE_MACHINE_TYPE_MISMATCH 216L +#define ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY 217L +#define ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY 218L #define ERROR_BAD_PIPE 230L #define ERROR_PIPE_BUSY 231L #define ERROR_NO_DATA 232L @@ -179,6 +216,7 @@ #define ERROR_VC_DISCONNECTED 240L #define ERROR_INVALID_EA_NAME 254L #define ERROR_EA_LIST_INCONSISTENT 255L +#define WAIT_TIMEOUT 258L #define ERROR_NO_MORE_ITEMS 259L #define ERROR_CANNOT_COPY 266L #define ERROR_DIRECTORY 267L @@ -190,7 +228,12 @@ #define ERROR_NOT_OWNER 288L #define ERROR_TOO_MANY_POSTS 298L #define ERROR_PARTIAL_COPY 299L +#define ERROR_OPLOCK_NOT_GRANTED 300L +#define ERROR_INVALID_OPLOCK_PROTOCOL 301L +#define ERROR_DISK_TOO_FRAGMENTED 302L +#define ERROR_DELETE_PENDING 303L #define ERROR_MR_MID_NOT_FOUND 317L +#define ERROR_SCOPE_NOT_FOUND 318L #define ERROR_INVALID_ADDRESS 487L #define ERROR_ARITHMETIC_OVERFLOW 534L #define ERROR_PIPE_CONNECTED 535L @@ -251,6 +294,12 @@ #define ERROR_BOOT_ALREADY_ACCEPTED 1076L #define ERROR_SERVICE_NEVER_STARTED 1077L #define ERROR_DUPLICATE_SERVICE_NAME 1078L +#define ERROR_DIFFERENT_SERVICE_ACCOUNT 1079L +#define ERROR_CANNOT_DETECT_DRIVER_FAILURE 1080L +#define ERROR_CANNOT_DETECT_PROCESS_ABORT 1081L +#define ERROR_NO_RECOVERY_PROGRAM 1082L +#define ERROR_SERVICE_NOT_IN_EXE 1083L +#define ERROR_NOT_SAFEBOOT_SERVICE 1084L #define ERROR_END_OF_MEDIA 1100L #define ERROR_FILEMARK_DETECTED 1101L #define ERROR_BEGINNING_OF_MEDIA 1102L @@ -295,11 +344,29 @@ #define ERROR_NO_ASSOCIATION 1155L #define ERROR_DDE_FAIL 1156L #define ERROR_DLL_NOT_FOUND 1157L -#define ERROR_BAD_USERNAME 2202L -#define ERROR_NOT_CONNECTED 2250L -#define ERROR_OPEN_FILES 2401L -#define ERROR_ACTIVE_CONNECTIONS 2402L -#define ERROR_DEVICE_IN_USE 2404L +#define ERROR_NO_MORE_USER_HANDLES 1158L +#define ERROR_MESSAGE_SYNC_ONLY 1159L +#define ERROR_SOURCE_ELEMENT_EMPTY 1160L +#define ERROR_DESTINATION_ELEMENT_FULL 1161L +#define ERROR_ILLEGAL_ELEMENT_ADDRESS 1162L +#define ERROR_MAGAZINE_NOT_PRESENT 1163L +#define ERROR_DEVICE_REINITIALIZATION_NEEDED 1164L +#define ERROR_DEVICE_REQUIRES_CLEANING 1165L +#define ERROR_DEVICE_DOOR_OPEN 1166L +#define ERROR_DEVICE_NOT_CONNECTED 1167L +#define ERROR_NOT_FOUND 1168L +#define ERROR_NO_MATCH 1169L +#define ERROR_SET_NOT_FOUND 1170L +#define ERROR_POINT_NOT_FOUND 1171L +#define ERROR_NO_TRACKING_SERVICE 1172L +#define ERROR_NO_VOLUME_ID 1173L +#define ERROR_UNABLE_TO_REMOVE_REPLACED 1175L +#define ERROR_UNABLE_TO_MOVE_REPLACEMENT 1176L +#define ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 1177L +#define ERROR_JOURNAL_DELETE_IN_PROGRESS 1178L +#define ERROR_JOURNAL_NOT_ACTIVE 1179L +#define ERROR_POTENTIAL_FILE_FOUND 1180L +#define ERROR_JOURNAL_ENTRY_DELETED 1181L #define ERROR_BAD_DEVICE 1200L #define ERROR_CONNECTION_UNAVAIL 1201L #define ERROR_DEVICE_ALREADY_REMEMBERED 1202L @@ -349,6 +416,39 @@ #define ERROR_CONTINUE 1246L #define ERROR_ALREADY_INITIALIZED 1247L #define ERROR_NO_MORE_DEVICES 1248L +#define ERROR_NO_SUCH_SITE 1249L +#define ERROR_DOMAIN_CONTROLLER_EXISTS 1250L +#define ERROR_ONLY_IF_CONNECTED 1251L +#define ERROR_OVERRIDE_NOCHANGES 1252L +#define ERROR_BAD_USER_PROFILE 1253L +#define ERROR_NOT_SUPPORTED_ON_SBS 1254L +#define ERROR_SERVER_SHUTDOWN_IN_PROGRESS 1255L +#define ERROR_HOST_DOWN 1256L +#define ERROR_NON_ACCOUNT_SID 1257L +#define ERROR_NON_DOMAIN_SID 1258L +#define ERROR_APPHELP_BLOCK 1259L +#define ERROR_ACCESS_DISABLED_BY_POLICY 1260L +#define ERROR_REG_NAT_CONSUMPTION 1261L +#define ERROR_CSCSHARE_OFFLINE 1262L +#define ERROR_PKINIT_FAILURE 1263L +#define ERROR_SMARTCARD_SUBSYSTEM_FAILURE 1264L +#define ERROR_DOWNGRADE_DETECTED 1265L +#define ERROR_MACHINE_LOCKED 1271L +#define ERROR_CALLBACK_SUPPLIED_INVALID_DATA 1273L +#define ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED 1274L +#define ERROR_DRIVER_BLOCKED 1275L +#define ERROR_INVALID_IMPORT_OF_NON_DLL 1276L +#define ERROR_ACCESS_DISABLED_WEBBLADE 1277L +#define ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER 1278L +#define ERROR_RECOVERY_FAILURE 1279L +#define ERROR_ALREADY_FIBER 1280L +#define ERROR_ALREADY_THREAD 1281L +#define ERROR_STACK_BUFFER_OVERRUN 1282L +#define ERROR_PARAMETER_QUOTA_EXCEEDED 1283L +#define ERROR_DEBUGGER_INACTIVE 1284L +#define ERROR_DELAY_LOAD_FAILED 1285L +#define ERROR_VDM_DISALLOWED 1286L +#define ERROR_UNIDENTIFIED_ERROR 1287L #define ERROR_NOT_ALL_ASSIGNED 1300L #define ERROR_SOME_NOT_MAPPED 1301L #define ERROR_NO_QUOTAS_FOR_ACCOUNT 1302L @@ -444,6 +544,10 @@ #define ERROR_DISK_CORRUPT 1393L #define ERROR_NO_USER_SESSION_KEY 1394L #define ERROR_LICENSE_QUOTA_EXCEEDED 1395L +#define ERROR_WRONG_TARGET_NAME 1396L +#define ERROR_MUTUAL_AUTH_FAILED 1397L +#define ERROR_TIME_SKEW 1398L +#define ERROR_CURRENT_DOMAIN_NOT_ALLOWED 1399L #define ERROR_INVALID_WINDOW_HANDLE 1400L #define ERROR_INVALID_MENU_HANDLE 1401L #define ERROR_INVALID_CURSOR_HANDLE 1402L @@ -501,10 +605,61 @@ #define ERROR_PAGEFILE_QUOTA 1454L #define ERROR_COMMITMENT_LIMIT 1455L #define ERROR_MENU_ITEM_NOT_FOUND 1456L +#define ERROR_INVALID_KEYBOARD_HANDLE 1457L +#define ERROR_HOOK_TYPE_NOT_ALLOWED 1458L +#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION 1459L +#define ERROR_TIMEOUT 1460L +#define ERROR_INVALID_MONITOR_HANDLE 1461L +#define ERROR_INCORRECT_SIZE 1462L #define ERROR_EVENTLOG_FILE_CORRUPT 1500L #define ERROR_EVENTLOG_CANT_START 1501L #define ERROR_LOG_FILE_FULL 1502L #define ERROR_EVENTLOG_FILE_CHANGED 1503L +#define ERROR_INSTALL_SERVICE_FAILURE 1601L +#define ERROR_INSTALL_USEREXIT 1602L +#define ERROR_INSTALL_FAILURE 1603L +#define ERROR_INSTALL_SUSPEND 1604L +#define ERROR_UNKNOWN_PRODUCT 1605L +#define ERROR_UNKNOWN_FEATURE 1606L +#define ERROR_UNKNOWN_COMPONENT 1607L +#define ERROR_UNKNOWN_PROPERTY 1608L +#define ERROR_INVALID_HANDLE_STATE 1609L +#define ERROR_BAD_CONFIGURATION 1610L +#define ERROR_INDEX_ABSENT 1611L +#define ERROR_INSTALL_SOURCE_ABSENT 1612L +#define ERROR_INSTALL_PACKAGE_VERSION 1613L +#define ERROR_PRODUCT_UNINSTALLED 1614L +#define ERROR_BAD_QUERY_SYNTAX 1615L +#define ERROR_INVALID_FIELD 1616L +#define ERROR_DEVICE_REMOVED 1617L +#define ERROR_INSTALL_ALREADY_RUNNING 1618L +#define ERROR_INSTALL_PACKAGE_OPEN_FAILED 1619L +#define ERROR_INSTALL_PACKAGE_INVALID 1620L +#define ERROR_INSTALL_UI_FAILURE 1621L +#define ERROR_INSTALL_LOG_FAILURE 1622L +#define ERROR_INSTALL_LANGUAGE_UNSUPPORTED 1623L +#define ERROR_INSTALL_TRANSFORM_FAILURE 1624L +#define ERROR_INSTALL_PACKAGE_REJECTED 1625L +#define ERROR_FUNCTION_NOT_CALLED 1626L +#define ERROR_FUNCTION_FAILED 1627L +#define ERROR_INVALID_TABLE 1628L +#define ERROR_DATATYPE_MISMATCH 1629L +#define ERROR_UNSUPPORTED_TYPE 1630L +#define ERROR_CREATE_FAILED 1631L +#define ERROR_INSTALL_TEMP_UNWRITABLE 1632L +#define ERROR_INSTALL_PLATFORM_UNSUPPORTED 1633L +#define ERROR_INSTALL_NOTUSED 1634L +#define ERROR_PATCH_PACKAGE_OPEN_FAILED 1635L +#define ERROR_PATCH_PACKAGE_INVALID 1636L +#define ERROR_PATCH_PACKAGE_UNSUPPORTED 1637L +#define ERROR_PRODUCT_VERSION 1638L +#define ERROR_INVALID_COMMAND_LINE 1639L +#define ERROR_INSTALL_REMOTE_DISALLOWED 1640L +#define ERROR_SUCCESS_REBOOT_INITIATED 1641L +#define ERROR_PATCH_TARGET_NOT_FOUND 1642L +#define ERROR_PATCH_PACKAGE_REJECTED 1643L +#define ERROR_INSTALL_TRANSFORM_REJECTED 1644L +#define ERROR_INSTALL_REMOTE_PROHIBITED 1645L #define RPC_S_INVALID_STRING_BINDING 1700L #define RPC_S_WRONG_KIND_OF_BINDING 1701L #define RPC_S_INVALID_BINDING 1702L @@ -631,6 +786,9 @@ #define RPC_X_INVALID_ES_ACTION 1827L #define RPC_X_WRONG_ES_VERSION 1828L #define RPC_X_WRONG_STUB_VERSION 1829L +#define RPC_X_INVALID_PIPE_OBJECT 1830L +#define RPC_X_WRONG_PIPE_ORDER 1831L +#define RPC_X_WRONG_PIPE_VERSION 1832L #define RPC_S_GROUP_MEMBER_NOT_FOUND 1898L #define EPT_S_CANT_CREATE 1899L #define RPC_S_INVALID_OBJECT 1900L @@ -643,13 +801,59 @@ #define ERROR_PASSWORD_MUST_CHANGE 1907L #define ERROR_DOMAIN_CONTROLLER_NOT_FOUND 1908L #define ERROR_ACCOUNT_LOCKED_OUT 1909L -#define ERROR_NO_BROWSER_SERVERS_FOUND 6118L +#define OR_INVALID_OXID 1910L +#define OR_INVALID_OID 1911L +#define OR_INVALID_SET 1912L +#define RPC_S_SEND_INCOMPLETE 1913L +#define RPC_S_INVALID_ASYNC_HANDLE 1914L +#define RPC_S_INVALID_ASYNC_CALL 1915L +#define RPC_X_PIPE_CLOSED 1916L +#define RPC_X_PIPE_DISCIPLINE_ERROR 1917L +#define RPC_X_PIPE_EMPTY 1918L +#define ERROR_NO_SITENAME 1919L +#define ERROR_CANT_ACCESS_FILE 1920L +#define ERROR_CANT_RESOLVE_FILENAME 1921L +#define RPC_S_ENTRY_TYPE_MISMATCH 1922L +#define RPC_S_NOT_ALL_OBJS_EXPORTED 1923L +#define RPC_S_INTERFACE_NOT_EXPORTED 1924L +#define RPC_S_PROFILE_NOT_ADDED 1925L +#define RPC_S_PRF_ELT_NOT_ADDED 1926L +#define RPC_S_PRF_ELT_NOT_REMOVED 1927L +#define RPC_S_GRP_ELT_NOT_ADDED 1928L +#define RPC_S_GRP_ELT_NOT_REMOVED 1929L +#define ERROR_KM_DRIVER_BLOCKED 1930L +#define ERROR_CONTEXT_EXPIRED 1931L +#define ERROR_PER_USER_TRUST_QUOTA_EXCEEDED 1932L +#define ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED 1933L +#define ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED 1934L +#define ERROR_AUTHENTICATION_FIREWALL_FAILED 1935L +#define ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED 1936L #define ERROR_INVALID_PIXEL_FORMAT 2000L #define ERROR_BAD_DRIVER 2001L #define ERROR_INVALID_WINDOW_STYLE 2002L #define ERROR_METAFILE_NOT_SUPPORTED 2003L #define ERROR_TRANSFORM_NOT_SUPPORTED 2004L #define ERROR_CLIPPING_NOT_SUPPORTED 2005L +#define ERROR_INVALID_CMM 2010L +#define ERROR_INVALID_PROFILE 2011L +#define ERROR_TAG_NOT_FOUND 2012L +#define ERROR_TAG_NOT_PRESENT 2013L +#define ERROR_DUPLICATE_TAG 2014L +#define ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE 2015L +#define ERROR_PROFILE_NOT_FOUND 2016L +#define ERROR_INVALID_COLORSPACE 2017L +#define ERROR_ICM_NOT_ENABLED 2018L +#define ERROR_DELETING_ICM_XFORM 2019L +#define ERROR_INVALID_TRANSFORM 2020L +#define ERROR_COLORSPACE_MISMATCH 2021L +#define ERROR_INVALID_COLORINDEX 2022L +#define ERROR_CONNECTED_OTHER_PASSWORD 2108L +#define ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT 2109L +#define ERROR_BAD_USERNAME 2202L +#define ERROR_NOT_CONNECTED 2250L +#define ERROR_OPEN_FILES 2401L +#define ERROR_ACTIVE_CONNECTIONS 2402L +#define ERROR_DEVICE_IN_USE 2404L #define ERROR_UNKNOWN_PRINT_MONITOR 3000L #define ERROR_PRINTER_DRIVER_IN_USE 3001L #define ERROR_SPOOL_FILE_NOT_FOUND 3002L @@ -657,6 +861,14 @@ #define ERROR_SPL_NO_ADDJOB 3004L #define ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED 3005L #define ERROR_PRINT_MONITOR_ALREADY_INSTALLED 3006L +#define ERROR_INVALID_PRINT_MONITOR 3007L +#define ERROR_PRINT_MONITOR_IN_USE 3008L +#define ERROR_PRINTER_HAS_JOBS_QUEUED 3009L +#define ERROR_SUCCESS_REBOOT_REQUIRED 3010L +#define ERROR_SUCCESS_RESTART_REQUIRED 3011L +#define ERROR_PRINTER_NOT_FOUND 3012L +#define ERROR_PRINTER_DRIVER_WARNED 3013L +#define ERROR_PRINTER_DRIVER_BLOCKED 3014L #define ERROR_WINS_INTERNAL 4000L #define ERROR_CAN_NOT_DEL_LOCAL_WINS 4001L #define ERROR_STATIC_INIT 4002L @@ -664,107 +876,1220 @@ #define ERROR_FULL_BACKUP 4004L #define ERROR_REC_NON_EXISTENT 4005L #define ERROR_RPL_NOT_ALLOWED 4006L +#define ERROR_DHCP_ADDRESS_CONFLICT 4100L +#define ERROR_WMI_GUID_NOT_FOUND 4200L +#define ERROR_WMI_INSTANCE_NOT_FOUND 4201L +#define ERROR_WMI_ITEMID_NOT_FOUND 4202L +#define ERROR_WMI_TRY_AGAIN 4203L +#define ERROR_WMI_DP_NOT_FOUND 4204L +#define ERROR_WMI_UNRESOLVED_INSTANCE_REF 4205L +#define ERROR_WMI_ALREADY_ENABLED 4206L +#define ERROR_WMI_GUID_DISCONNECTED 4207L +#define ERROR_WMI_SERVER_UNAVAILABLE 4208L +#define ERROR_WMI_DP_FAILED 4209L +#define ERROR_WMI_INVALID_MOF 4210L +#define ERROR_WMI_INVALID_REGINFO 4211L +#define ERROR_WMI_ALREADY_DISABLED 4212L +#define ERROR_WMI_READ_ONLY 4213L +#define ERROR_WMI_SET_FAILURE 4214L +#define ERROR_INVALID_MEDIA 4300L +#define ERROR_INVALID_LIBRARY 4301L +#define ERROR_INVALID_MEDIA_POOL 4302L +#define ERROR_DRIVE_MEDIA_MISMATCH 4303L +#define ERROR_MEDIA_OFFLINE 4304L +#define ERROR_LIBRARY_OFFLINE 4305L +#define ERROR_EMPTY 4306L +#define ERROR_NOT_EMPTY 4307L +#define ERROR_MEDIA_UNAVAILABLE 4308L +#define ERROR_RESOURCE_DISABLED 4309L +#define ERROR_INVALID_CLEANER 4310L +#define ERROR_UNABLE_TO_CLEAN 4311L +#define ERROR_OBJECT_NOT_FOUND 4312L +#define ERROR_DATABASE_FAILURE 4313L +#define ERROR_DATABASE_FULL 4314L +#define ERROR_MEDIA_INCOMPATIBLE 4315L +#define ERROR_RESOURCE_NOT_PRESENT 4316L +#define ERROR_INVALID_OPERATION 4317L +#define ERROR_MEDIA_NOT_AVAILABLE 4318L +#define ERROR_DEVICE_NOT_AVAILABLE 4319L +#define ERROR_REQUEST_REFUSED 4320L +#define ERROR_INVALID_DRIVE_OBJECT 4321L +#define ERROR_LIBRARY_FULL 4322L +#define ERROR_MEDIUM_NOT_ACCESSIBLE 4323L +#define ERROR_UNABLE_TO_LOAD_MEDIUM 4324L +#define ERROR_UNABLE_TO_INVENTORY_DRIVE 4325L +#define ERROR_UNABLE_TO_INVENTORY_SLOT 4326L +#define ERROR_UNABLE_TO_INVENTORY_TRANSPORT 4327L +#define ERROR_TRANSPORT_FULL 4328L +#define ERROR_CONTROLLING_IEPORT 4329L +#define ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA 4330L +#define ERROR_CLEANER_SLOT_SET 4331L +#define ERROR_CLEANER_SLOT_NOT_SET 4332L +#define ERROR_CLEANER_CARTRIDGE_SPENT 4333L +#define ERROR_UNEXPECTED_OMID 4334L +#define ERROR_CANT_DELETE_LAST_ITEM 4335L +#define ERROR_MESSAGE_EXCEEDS_MAX_SIZE 4336L +#define ERROR_VOLUME_CONTAINS_SYS_FILES 4337L +#define ERROR_INDIGENOUS_TYPE 4338L +#define ERROR_NO_SUPPORTING_DRIVES 4339L +#define ERROR_CLEANER_CARTRIDGE_INSTALLED 4340L +#define ERROR_IEPORT_FULL 4341L +#define ERROR_FILE_OFFLINE 4350L +#define ERROR_REMOTE_STORAGE_NOT_ACTIVE 4351L +#define ERROR_REMOTE_STORAGE_MEDIA_ERROR 4352L +#define ERROR_NOT_A_REPARSE_POINT 4390L +#define ERROR_REPARSE_ATTRIBUTE_CONFLICT 4391L +#define ERROR_INVALID_REPARSE_DATA 4392L +#define ERROR_REPARSE_TAG_INVALID 4393L +#define ERROR_REPARSE_TAG_MISMATCH 4394L +#define ERROR_VOLUME_NOT_SIS_ENABLED 4500L +#define ERROR_DEPENDENT_RESOURCE_EXISTS 5001L +#define ERROR_DEPENDENCY_NOT_FOUND 5002L +#define ERROR_DEPENDENCY_ALREADY_EXISTS 5003L +#define ERROR_RESOURCE_NOT_ONLINE 5004L +#define ERROR_HOST_NODE_NOT_AVAILABLE 5005L +#define ERROR_RESOURCE_NOT_AVAILABLE 5006L +#define ERROR_RESOURCE_NOT_FOUND 5007L +#define ERROR_SHUTDOWN_CLUSTER 5008L +#define ERROR_CANT_EVICT_ACTIVE_NODE 5009L +#define ERROR_OBJECT_ALREADY_EXISTS 5010L +#define ERROR_OBJECT_IN_LIST 5011L +#define ERROR_GROUP_NOT_AVAILABLE 5012L +#define ERROR_GROUP_NOT_FOUND 5013L +#define ERROR_GROUP_NOT_ONLINE 5014L +#define ERROR_HOST_NODE_NOT_RESOURCE_OWNER 5015L +#define ERROR_HOST_NODE_NOT_GROUP_OWNER 5016L +#define ERROR_RESMON_CREATE_FAILED 5017L +#define ERROR_RESMON_ONLINE_FAILED 5018L +#define ERROR_RESOURCE_ONLINE 5019L +#define ERROR_QUORUM_RESOURCE 5020L +#define ERROR_NOT_QUORUM_CAPABLE 5021L +#define ERROR_CLUSTER_SHUTTING_DOWN 5022L +#define ERROR_INVALID_STATE 5023L +#define ERROR_RESOURCE_PROPERTIES_STORED 5024L +#define ERROR_NOT_QUORUM_CLASS 5025L +#define ERROR_CORE_RESOURCE 5026L +#define ERROR_QUORUM_RESOURCE_ONLINE_FAILED 5027L +#define ERROR_QUORUMLOG_OPEN_FAILED 5028L +#define ERROR_CLUSTERLOG_CORRUPT 5029L +#define ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE 5030L +#define ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE 5031L +#define ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND 5032L +#define ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE 5033L +#define ERROR_QUORUM_OWNER_ALIVE 5034L +#define ERROR_NETWORK_NOT_AVAILABLE 5035L +#define ERROR_NODE_NOT_AVAILABLE 5036L +#define ERROR_ALL_NODES_NOT_AVAILABLE 5037L +#define ERROR_RESOURCE_FAILED 5038L +#define ERROR_CLUSTER_INVALID_NODE 5039L +#define ERROR_CLUSTER_NODE_EXISTS 5040L +#define ERROR_CLUSTER_JOIN_IN_PROGRESS 5041L +#define ERROR_CLUSTER_NODE_NOT_FOUND 5042L +#define ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND 5043L +#define ERROR_CLUSTER_NETWORK_EXISTS 5044L +#define ERROR_CLUSTER_NETWORK_NOT_FOUND 5045L +#define ERROR_CLUSTER_NETINTERFACE_EXISTS 5046L +#define ERROR_CLUSTER_NETINTERFACE_NOT_FOUND 5047L +#define ERROR_CLUSTER_INVALID_REQUEST 5048L +#define ERROR_CLUSTER_INVALID_NETWORK_PROVIDER 5049L +#define ERROR_CLUSTER_NODE_DOWN 5050L +#define ERROR_CLUSTER_NODE_UNREACHABLE 5051L +#define ERROR_CLUSTER_NODE_NOT_MEMBER 5052L +#define ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS 5053L +#define ERROR_CLUSTER_INVALID_NETWORK 5054L +#define ERROR_CLUSTER_NODE_UP 5056L +#define ERROR_CLUSTER_IPADDR_IN_USE 5057L +#define ERROR_CLUSTER_NODE_NOT_PAUSED 5058L +#define ERROR_CLUSTER_NO_SECURITY_CONTEXT 5059L +#define ERROR_CLUSTER_NETWORK_NOT_INTERNAL 5060L +#define ERROR_CLUSTER_NODE_ALREADY_UP 5061L +#define ERROR_CLUSTER_NODE_ALREADY_DOWN 5062L +#define ERROR_CLUSTER_NETWORK_ALREADY_ONLINE 5063L +#define ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE 5064L +#define ERROR_CLUSTER_NODE_ALREADY_MEMBER 5065L +#define ERROR_CLUSTER_LAST_INTERNAL_NETWORK 5066L +#define ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS 5067L +#define ERROR_INVALID_OPERATION_ON_QUORUM 5068L +#define ERROR_DEPENDENCY_NOT_ALLOWED 5069L +#define ERROR_CLUSTER_NODE_PAUSED 5070L +#define ERROR_NODE_CANT_HOST_RESOURCE 5071L +#define ERROR_CLUSTER_NODE_NOT_READY 5072L +#define ERROR_CLUSTER_NODE_SHUTTING_DOWN 5073L +#define ERROR_CLUSTER_JOIN_ABORTED 5074L +#define ERROR_CLUSTER_INCOMPATIBLE_VERSIONS 5075L +#define ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED 5076L +#define ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED 5077L +#define ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND 5078L +#define ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED 5079L +#define ERROR_CLUSTER_RESNAME_NOT_FOUND 5080L +#define ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED 5081L +#define ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST 5082L +#define ERROR_CLUSTER_DATABASE_SEQMISMATCH 5083L +#define ERROR_RESMON_INVALID_STATE 5084L +#define ERROR_CLUSTER_GUM_NOT_LOCKER 5085L +#define ERROR_QUORUM_DISK_NOT_FOUND 5086L +#define ERROR_DATABASE_BACKUP_CORRUPT 5087L +#define ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT 5088L +#define ERROR_RESOURCE_PROPERTY_UNCHANGEABLE 5089L +#define ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE 5890L +#define ERROR_CLUSTER_QUORUMLOG_NOT_FOUND 5891L +#define ERROR_CLUSTER_MEMBERSHIP_HALT 5892L +#define ERROR_CLUSTER_INSTANCE_ID_MISMATCH 5893L +#define ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP 5894L +#define ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH 5895L +#define ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP 5896L +#define ERROR_CLUSTER_PARAMETER_MISMATCH 5897L +#define ERROR_NODE_CANNOT_BE_CLUSTERED 5898L +#define ERROR_CLUSTER_WRONG_OS_VERSION 5899L +#define ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME 5900L +#define ERROR_CLUSCFG_ALREADY_COMMITTED 5901L +#define ERROR_CLUSCFG_ROLLBACK_FAILED 5902L +#define ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT 5903L +#define ERROR_CLUSTER_OLD_VERSION 5904L +#define ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME 5905L +#define ERROR_ENCRYPTION_FAILED 6000L +#define ERROR_DECRYPTION_FAILED 6001L +#define ERROR_FILE_ENCRYPTED 6002L +#define ERROR_NO_RECOVERY_POLICY 6003L +#define ERROR_NO_EFS 6004L +#define ERROR_WRONG_EFS 6005L +#define ERROR_NO_USER_KEYS 6006L +#define ERROR_FILE_NOT_ENCRYPTED 6007L +#define ERROR_NOT_EXPORT_FORMAT 6008L +#define ERROR_FILE_READ_ONLY 6009L +#define ERROR_DIR_EFS_DISALLOWED 6010L +#define ERROR_EFS_SERVER_NOT_TRUSTED 6011L +#define ERROR_BAD_RECOVERY_POLICY 6012L +#define ERROR_EFS_ALG_BLOB_TOO_BIG 6013L +#define ERROR_VOLUME_NOT_SUPPORT_EFS 6014L +#define ERROR_EFS_DISABLED 6015L +#define ERROR_EFS_VERSION_NOT_SUPPORT 6016L +#define ERROR_NO_BROWSER_SERVERS_FOUND 6118L +#define SCHED_E_SERVICE_NOT_LOCALSYSTEM 6200L +#define ERROR_CTX_WINSTATION_NAME_INVALID 7001L +#define ERROR_CTX_INVALID_PD 7002L +#define ERROR_CTX_PD_NOT_FOUND 7003L +#define ERROR_CTX_WD_NOT_FOUND 7004L +#define ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY 7005L +#define ERROR_CTX_SERVICE_NAME_COLLISION 7006L +#define ERROR_CTX_CLOSE_PENDING 7007L +#define ERROR_CTX_NO_OUTBUF 7008L +#define ERROR_CTX_MODEM_INF_NOT_FOUND 7009L +#define ERROR_CTX_INVALID_MODEMNAME 7010L +#define ERROR_CTX_MODEM_RESPONSE_ERROR 7011L +#define ERROR_CTX_MODEM_RESPONSE_TIMEOUT 7012L +#define ERROR_CTX_MODEM_RESPONSE_NO_CARRIER 7013L +#define ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE 7014L +#define ERROR_CTX_MODEM_RESPONSE_BUSY 7015L +#define ERROR_CTX_MODEM_RESPONSE_VOICE 7016L +#define ERROR_CTX_TD_ERROR 7017L +#define ERROR_CTX_WINSTATION_NOT_FOUND 7022L +#define ERROR_CTX_WINSTATION_ALREADY_EXISTS 7023L +#define ERROR_CTX_WINSTATION_BUSY 7024L +#define ERROR_CTX_BAD_VIDEO_MODE 7025L +#define ERROR_CTX_GRAPHICS_INVALID 7035L +#define ERROR_CTX_LOGON_DISABLED 7037L +#define ERROR_CTX_NOT_CONSOLE 7038L +#define ERROR_CTX_CLIENT_QUERY_TIMEOUT 7040L +#define ERROR_CTX_CONSOLE_DISCONNECT 7041L +#define ERROR_CTX_CONSOLE_CONNECT 7042L +#define ERROR_CTX_SHADOW_DENIED 7044L +#define ERROR_CTX_WINSTATION_ACCESS_DENIED 7045L +#define ERROR_CTX_INVALID_WD 7049L +#define ERROR_CTX_SHADOW_INVALID 7050L +#define ERROR_CTX_SHADOW_DISABLED 7051L +#define ERROR_CTX_CLIENT_LICENSE_IN_USE 7052L +#define ERROR_CTX_CLIENT_LICENSE_NOT_SET 7053L +#define ERROR_CTX_LICENSE_NOT_AVAILABLE 7054L +#define ERROR_CTX_LICENSE_CLIENT_INVALID 7055L +#define ERROR_CTX_LICENSE_EXPIRED 7056L +#define ERROR_CTX_SHADOW_NOT_RUNNING 7057L +#define ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE 7058L +#define ERROR_ACTIVATION_COUNT_EXCEEDED 7059L +#define FRS_ERR_INVALID_API_SEQUENCE 8001L +#define FRS_ERR_STARTING_SERVICE 8002L +#define FRS_ERR_STOPPING_SERVICE 8003L +#define FRS_ERR_INTERNAL_API 8004L +#define FRS_ERR_INTERNAL 8005L +#define FRS_ERR_SERVICE_COMM 8006L +#define FRS_ERR_INSUFFICIENT_PRIV 8007L +#define FRS_ERR_AUTHENTICATION 8008L +#define FRS_ERR_PARENT_INSUFFICIENT_PRIV 8009L +#define FRS_ERR_PARENT_AUTHENTICATION 8010L +#define FRS_ERR_CHILD_TO_PARENT_COMM 8011L +#define FRS_ERR_PARENT_TO_CHILD_COMM 8012L +#define FRS_ERR_SYSVOL_POPULATE 8013L +#define FRS_ERR_SYSVOL_POPULATE_TIMEOUT 8014L +#define FRS_ERR_SYSVOL_IS_BUSY 8015L +#define FRS_ERR_SYSVOL_DEMOTE 8016L +#define FRS_ERR_INVALID_SERVICE_PARAMETER 8017L +#define DS_S_SUCCESS NO_ERROR +#define ERROR_DS_NOT_INSTALLED 8200L +#define ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY 8201L +#define ERROR_DS_NO_ATTRIBUTE_OR_VALUE 8202L +#define ERROR_DS_INVALID_ATTRIBUTE_SYNTAX 8203L +#define ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED 8204L +#define ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS 8205L +#define ERROR_DS_BUSY 8206L +#define ERROR_DS_UNAVAILABLE 8207L +#define ERROR_DS_NO_RIDS_ALLOCATED 8208L +#define ERROR_DS_NO_MORE_RIDS 8209L +#define ERROR_DS_INCORRECT_ROLE_OWNER 8210L +#define ERROR_DS_RIDMGR_INIT_ERROR 8211L +#define ERROR_DS_OBJ_CLASS_VIOLATION 8212L +#define ERROR_DS_CANT_ON_NON_LEAF 8213L +#define ERROR_DS_CANT_ON_RDN 8214L +#define ERROR_DS_CANT_MOD_OBJ_CLASS 8215L +#define ERROR_DS_CROSS_DOM_MOVE_ERROR 8216L +#define ERROR_DS_GC_NOT_AVAILABLE 8217L +#define ERROR_SHARED_POLICY 8218L +#define ERROR_POLICY_OBJECT_NOT_FOUND 8219L +#define ERROR_POLICY_ONLY_IN_DS 8220L +#define ERROR_PROMOTION_ACTIVE 8221L +#define ERROR_NO_PROMOTION_ACTIVE 8222L +#define ERROR_DS_OPERATIONS_ERROR 8224L +#define ERROR_DS_PROTOCOL_ERROR 8225L +#define ERROR_DS_TIMELIMIT_EXCEEDED 8226L +#define ERROR_DS_SIZELIMIT_EXCEEDED 8227L +#define ERROR_DS_ADMIN_LIMIT_EXCEEDED 8228L +#define ERROR_DS_COMPARE_FALSE 8229L +#define ERROR_DS_COMPARE_TRUE 8230L +#define ERROR_DS_AUTH_METHOD_NOT_SUPPORTED 8231L +#define ERROR_DS_STRONG_AUTH_REQUIRED 8232L +#define ERROR_DS_INAPPROPRIATE_AUTH 8233L +#define ERROR_DS_AUTH_UNKNOWN 8234L +#define ERROR_DS_REFERRAL 8235L +#define ERROR_DS_UNAVAILABLE_CRIT_EXTENSION 8236L +#define ERROR_DS_CONFIDENTIALITY_REQUIRED 8237L +#define ERROR_DS_INAPPROPRIATE_MATCHING 8238L +#define ERROR_DS_CONSTRAINT_VIOLATION 8239L +#define ERROR_DS_NO_SUCH_OBJECT 8240L +#define ERROR_DS_ALIAS_PROBLEM 8241L +#define ERROR_DS_INVALID_DN_SYNTAX 8242L +#define ERROR_DS_IS_LEAF 8243L +#define ERROR_DS_ALIAS_DEREF_PROBLEM 8244L +#define ERROR_DS_UNWILLING_TO_PERFORM 8245L +#define ERROR_DS_LOOP_DETECT 8246L +#define ERROR_DS_NAMING_VIOLATION 8247L +#define ERROR_DS_OBJECT_RESULTS_TOO_LARGE 8248L +#define ERROR_DS_AFFECTS_MULTIPLE_DSAS 8249L +#define ERROR_DS_SERVER_DOWN 8250L +#define ERROR_DS_LOCAL_ERROR 8251L +#define ERROR_DS_ENCODING_ERROR 8252L +#define ERROR_DS_DECODING_ERROR 8253L +#define ERROR_DS_FILTER_UNKNOWN 8254L +#define ERROR_DS_PARAM_ERROR 8255L +#define ERROR_DS_NOT_SUPPORTED 8256L +#define ERROR_DS_NO_RESULTS_RETURNED 8257L +#define ERROR_DS_CONTROL_NOT_FOUND 8258L +#define ERROR_DS_CLIENT_LOOP 8259L +#define ERROR_DS_REFERRAL_LIMIT_EXCEEDED 8260L +#define ERROR_DS_SORT_CONTROL_MISSING 8261L +#define ERROR_DS_OFFSET_RANGE_ERROR 8262L +#define ERROR_DS_ROOT_MUST_BE_NC 8301L +#define ERROR_DS_ADD_REPLICA_INHIBITED 8302L +#define ERROR_DS_ATT_NOT_DEF_IN_SCHEMA 8303L +#define ERROR_DS_MAX_OBJ_SIZE_EXCEEDED 8304L +#define ERROR_DS_OBJ_STRING_NAME_EXISTS 8305L +#define ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA 8306L +#define ERROR_DS_RDN_DOESNT_MATCH_SCHEMA 8307L +#define ERROR_DS_NO_REQUESTED_ATTS_FOUND 8308L +#define ERROR_DS_USER_BUFFER_TO_SMALL 8309L +#define ERROR_DS_ATT_IS_NOT_ON_OBJ 8310L +#define ERROR_DS_ILLEGAL_MOD_OPERATION 8311L +#define ERROR_DS_OBJ_TOO_LARGE 8312L +#define ERROR_DS_BAD_INSTANCE_TYPE 8313L +#define ERROR_DS_MASTERDSA_REQUIRED 8314L +#define ERROR_DS_OBJECT_CLASS_REQUIRED 8315L +#define ERROR_DS_MISSING_REQUIRED_ATT 8316L +#define ERROR_DS_ATT_NOT_DEF_FOR_CLASS 8317L +#define ERROR_DS_ATT_ALREADY_EXISTS 8318L +#define ERROR_DS_CANT_ADD_ATT_VALUES 8320L +#define ERROR_DS_SINGLE_VALUE_CONSTRAINT 8321L +#define ERROR_DS_RANGE_CONSTRAINT 8322L +#define ERROR_DS_ATT_VAL_ALREADY_EXISTS 8323L +#define ERROR_DS_CANT_REM_MISSING_ATT 8324L +#define ERROR_DS_CANT_REM_MISSING_ATT_VAL 8325L +#define ERROR_DS_ROOT_CANT_BE_SUBREF 8326L +#define ERROR_DS_NO_CHAINING 8327L +#define ERROR_DS_NO_CHAINED_EVAL 8328L +#define ERROR_DS_NO_PARENT_OBJECT 8329L +#define ERROR_DS_PARENT_IS_AN_ALIAS 8330L +#define ERROR_DS_CANT_MIX_MASTER_AND_REPS 8331L +#define ERROR_DS_CHILDREN_EXIST 8332L +#define ERROR_DS_OBJ_NOT_FOUND 8333L +#define ERROR_DS_ALIASED_OBJ_MISSING 8334L +#define ERROR_DS_BAD_NAME_SYNTAX 8335L +#define ERROR_DS_ALIAS_POINTS_TO_ALIAS 8336L +#define ERROR_DS_CANT_DEREF_ALIAS 8337L +#define ERROR_DS_OUT_OF_SCOPE 8338L +#define ERROR_DS_OBJECT_BEING_REMOVED 8339L +#define ERROR_DS_CANT_DELETE_DSA_OBJ 8340L +#define ERROR_DS_GENERIC_ERROR 8341L +#define ERROR_DS_DSA_MUST_BE_INT_MASTER 8342L +#define ERROR_DS_CLASS_NOT_DSA 8343L +#define ERROR_DS_INSUFF_ACCESS_RIGHTS 8344L +#define ERROR_DS_ILLEGAL_SUPERIOR 8345L +#define ERROR_DS_ATTRIBUTE_OWNED_BY_SAM 8346L +#define ERROR_DS_NAME_TOO_MANY_PARTS 8347L +#define ERROR_DS_NAME_TOO_LONG 8348L +#define ERROR_DS_NAME_VALUE_TOO_LONG 8349L +#define ERROR_DS_NAME_UNPARSEABLE 8350L +#define ERROR_DS_NAME_TYPE_UNKNOWN 8351L +#define ERROR_DS_NOT_AN_OBJECT 8352L +#define ERROR_DS_SEC_DESC_TOO_SHORT 8353L +#define ERROR_DS_SEC_DESC_INVALID 8354L +#define ERROR_DS_NO_DELETED_NAME 8355L +#define ERROR_DS_SUBREF_MUST_HAVE_PARENT 8356L +#define ERROR_DS_NCNAME_MUST_BE_NC 8357L +#define ERROR_DS_CANT_ADD_SYSTEM_ONLY 8358L +#define ERROR_DS_CLASS_MUST_BE_CONCRETE 8359L +#define ERROR_DS_INVALID_DMD 8360L +#define ERROR_DS_OBJ_GUID_EXISTS 8361L +#define ERROR_DS_NOT_ON_BACKLINK 8362L +#define ERROR_DS_NO_CROSSREF_FOR_NC 8363L +#define ERROR_DS_SHUTTING_DOWN 8364L +#define ERROR_DS_UNKNOWN_OPERATION 8365L +#define ERROR_DS_INVALID_ROLE_OWNER 8366L +#define ERROR_DS_COULDNT_CONTACT_FSMO 8367L +#define ERROR_DS_CROSS_NC_DN_RENAME 8368L +#define ERROR_DS_CANT_MOD_SYSTEM_ONLY 8369L +#define ERROR_DS_REPLICATOR_ONLY 8370L +#define ERROR_DS_OBJ_CLASS_NOT_DEFINED 8371L +#define ERROR_DS_OBJ_CLASS_NOT_SUBCLASS 8372L +#define ERROR_DS_NAME_REFERENCE_INVALID 8373L +#define ERROR_DS_CROSS_REF_EXISTS 8374L +#define ERROR_DS_CANT_DEL_MASTER_CROSSREF 8375L +#define ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD 8376L +#define ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX 8377L +#define ERROR_DS_DUP_RDN 8378L +#define ERROR_DS_DUP_OID 8379L +#define ERROR_DS_DUP_MAPI_ID 8380L +#define ERROR_DS_DUP_SCHEMA_ID_GUID 8381L +#define ERROR_DS_DUP_LDAP_DISPLAY_NAME 8382L +#define ERROR_DS_SEMANTIC_ATT_TEST 8383L +#define ERROR_DS_SYNTAX_MISMATCH 8384L +#define ERROR_DS_EXISTS_IN_MUST_HAVE 8385L +#define ERROR_DS_EXISTS_IN_MAY_HAVE 8386L +#define ERROR_DS_NONEXISTENT_MAY_HAVE 8387L +#define ERROR_DS_NONEXISTENT_MUST_HAVE 8388L +#define ERROR_DS_AUX_CLS_TEST_FAIL 8389L +#define ERROR_DS_NONEXISTENT_POSS_SUP 8390L +#define ERROR_DS_SUB_CLS_TEST_FAIL 8391L +#define ERROR_DS_BAD_RDN_ATT_ID_SYNTAX 8392L +#define ERROR_DS_EXISTS_IN_AUX_CLS 8393L +#define ERROR_DS_EXISTS_IN_SUB_CLS 8394L +#define ERROR_DS_EXISTS_IN_POSS_SUP 8395L +#define ERROR_DS_RECALCSCHEMA_FAILED 8396L +#define ERROR_DS_TREE_DELETE_NOT_FINISHED 8397L +#define ERROR_DS_CANT_DELETE 8398L +#define ERROR_DS_ATT_SCHEMA_REQ_ID 8399L +#define ERROR_DS_BAD_ATT_SCHEMA_SYNTAX 8400L +#define ERROR_DS_CANT_CACHE_ATT 8401L +#define ERROR_DS_CANT_CACHE_CLASS 8402L +#define ERROR_DS_CANT_REMOVE_ATT_CACHE 8403L +#define ERROR_DS_CANT_REMOVE_CLASS_CACHE 8404L +#define ERROR_DS_CANT_RETRIEVE_DN 8405L +#define ERROR_DS_MISSING_SUPREF 8406L +#define ERROR_DS_CANT_RETRIEVE_INSTANCE 8407L +#define ERROR_DS_CODE_INCONSISTENCY 8408L +#define ERROR_DS_DATABASE_ERROR 8409L +#define ERROR_DS_GOVERNSID_MISSING 8410L +#define ERROR_DS_MISSING_EXPECTED_ATT 8411L +#define ERROR_DS_NCNAME_MISSING_CR_REF 8412L +#define ERROR_DS_SECURITY_CHECKING_ERROR 8413L +#define ERROR_DS_SCHEMA_NOT_LOADED 8414L +#define ERROR_DS_SCHEMA_ALLOC_FAILED 8415L +#define ERROR_DS_ATT_SCHEMA_REQ_SYNTAX 8416L +#define ERROR_DS_GCVERIFY_ERROR 8417L +#define ERROR_DS_DRA_SCHEMA_MISMATCH 8418L +#define ERROR_DS_CANT_FIND_DSA_OBJ 8419L +#define ERROR_DS_CANT_FIND_EXPECTED_NC 8420L +#define ERROR_DS_CANT_FIND_NC_IN_CACHE 8421L +#define ERROR_DS_CANT_RETRIEVE_CHILD 8422L +#define ERROR_DS_SECURITY_ILLEGAL_MODIFY 8423L +#define ERROR_DS_CANT_REPLACE_HIDDEN_REC 8424L +#define ERROR_DS_BAD_HIERARCHY_FILE 8425L +#define ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED 8426L +#define ERROR_DS_CONFIG_PARAM_MISSING 8427L +#define ERROR_DS_COUNTING_AB_INDICES_FAILED 8428L +#define ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED 8429L +#define ERROR_DS_INTERNAL_FAILURE 8430L +#define ERROR_DS_UNKNOWN_ERROR 8431L +#define ERROR_DS_ROOT_REQUIRES_CLASS_TOP 8432L +#define ERROR_DS_REFUSING_FSMO_ROLES 8433L +#define ERROR_DS_MISSING_FSMO_SETTINGS 8434L +#define ERROR_DS_UNABLE_TO_SURRENDER_ROLES 8435L +#define ERROR_DS_DRA_GENERIC 8436L +#define ERROR_DS_DRA_INVALID_PARAMETER 8437L +#define ERROR_DS_DRA_BUSY 8438L +#define ERROR_DS_DRA_BAD_DN 8439L +#define ERROR_DS_DRA_BAD_NC 8440L +#define ERROR_DS_DRA_DN_EXISTS 8441L +#define ERROR_DS_DRA_INTERNAL_ERROR 8442L +#define ERROR_DS_DRA_INCONSISTENT_DIT 8443L +#define ERROR_DS_DRA_CONNECTION_FAILED 8444L +#define ERROR_DS_DRA_BAD_INSTANCE_TYPE 8445L +#define ERROR_DS_DRA_OUT_OF_MEM 8446L +#define ERROR_DS_DRA_MAIL_PROBLEM 8447L +#define ERROR_DS_DRA_REF_ALREADY_EXISTS 8448L +#define ERROR_DS_DRA_REF_NOT_FOUND 8449L +#define ERROR_DS_DRA_OBJ_IS_REP_SOURCE 8450L +#define ERROR_DS_DRA_DB_ERROR 8451L +#define ERROR_DS_DRA_NO_REPLICA 8452L +#define ERROR_DS_DRA_ACCESS_DENIED 8453L +#define ERROR_DS_DRA_NOT_SUPPORTED 8454L +#define ERROR_DS_DRA_RPC_CANCELLED 8455L +#define ERROR_DS_DRA_SOURCE_DISABLED 8456L +#define ERROR_DS_DRA_SINK_DISABLED 8457L +#define ERROR_DS_DRA_NAME_COLLISION 8458L +#define ERROR_DS_DRA_SOURCE_REINSTALLED 8459L +#define ERROR_DS_DRA_MISSING_PARENT 8460L +#define ERROR_DS_DRA_PREEMPTED 8461L +#define ERROR_DS_DRA_ABANDON_SYNC 8462L +#define ERROR_DS_DRA_SHUTDOWN 8463L +#define ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET 8464L +#define ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA 8465L +#define ERROR_DS_DRA_EXTN_CONNECTION_FAILED 8466L +#define ERROR_DS_INSTALL_SCHEMA_MISMATCH 8467L +#define ERROR_DS_DUP_LINK_ID 8468L +#define ERROR_DS_NAME_ERROR_RESOLVING 8469L +#define ERROR_DS_NAME_ERROR_NOT_FOUND 8470L +#define ERROR_DS_NAME_ERROR_NOT_UNIQUE 8471L +#define ERROR_DS_NAME_ERROR_NO_MAPPING 8472L +#define ERROR_DS_NAME_ERROR_DOMAIN_ONLY 8473L +#define ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING 8474L +#define ERROR_DS_CONSTRUCTED_ATT_MOD 8475L +#define ERROR_DS_WRONG_OM_OBJ_CLASS 8476L +#define ERROR_DS_DRA_REPL_PENDING 8477L +#define ERROR_DS_DS_REQUIRED 8478L +#define ERROR_DS_INVALID_LDAP_DISPLAY_NAME 8479L +#define ERROR_DS_NON_BASE_SEARCH 8480L +#define ERROR_DS_CANT_RETRIEVE_ATTS 8481L +#define ERROR_DS_BACKLINK_WITHOUT_LINK 8482L +#define ERROR_DS_EPOCH_MISMATCH 8483L +#define ERROR_DS_SRC_NAME_MISMATCH 8484L +#define ERROR_DS_SRC_AND_DST_NC_IDENTICAL 8485L +#define ERROR_DS_DST_NC_MISMATCH 8486L +#define ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC 8487L +#define ERROR_DS_SRC_GUID_MISMATCH 8488L +#define ERROR_DS_CANT_MOVE_DELETED_OBJECT 8489L +#define ERROR_DS_PDC_OPERATION_IN_PROGRESS 8490L +#define ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD 8491L +#define ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION 8492L +#define ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS 8493L +#define ERROR_DS_NC_MUST_HAVE_NC_PARENT 8494L +#define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE 8495L +#define ERROR_DS_DST_DOMAIN_NOT_NATIVE 8496L +#define ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER 8497L +#define ERROR_DS_CANT_MOVE_ACCOUNT_GROUP 8498L +#define ERROR_DS_CANT_MOVE_RESOURCE_GROUP 8499L +#define ERROR_DS_INVALID_SEARCH_FLAG 8500L +#define ERROR_DS_NO_TREE_DELETE_ABOVE_NC 8501L +#define ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE 8502L +#define ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE 8503L +#define ERROR_DS_SAM_INIT_FAILURE 8504L +#define ERROR_DS_SENSITIVE_GROUP_VIOLATION 8505L +#define ERROR_DS_CANT_MOD_PRIMARYGROUPID 8506L +#define ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD 8507L +#define ERROR_DS_NONSAFE_SCHEMA_CHANGE 8508L +#define ERROR_DS_SCHEMA_UPDATE_DISALLOWED 8509L +#define ERROR_DS_CANT_CREATE_UNDER_SCHEMA 8510L +#define ERROR_DS_INSTALL_NO_SRC_SCH_VERSION 8511L +#define ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE 8512L +#define ERROR_DS_INVALID_GROUP_TYPE 8513L +#define ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN 8514L +#define ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN 8515L +#define ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER 8516L +#define ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER 8517L +#define ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER 8518L +#define ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER 8519L +#define ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER 8520L +#define ERROR_DS_HAVE_PRIMARY_MEMBERS 8521L +#define ERROR_DS_STRING_SD_CONVERSION_FAILED 8522L +#define ERROR_DS_NAMING_MASTER_GC 8523L +#define ERROR_DS_DNS_LOOKUP_FAILURE 8524L +#define ERROR_DS_COULDNT_UPDATE_SPNS 8525L +#define ERROR_DS_CANT_RETRIEVE_SD 8526L +#define ERROR_DS_KEY_NOT_UNIQUE 8527L +#define ERROR_DS_WRONG_LINKED_ATT_SYNTAX 8528L +#define ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD 8529L +#define ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY 8530L +#define ERROR_DS_CANT_START 8531L +#define ERROR_DS_INIT_FAILURE 8532L +#define ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION 8533L +#define ERROR_DS_SOURCE_DOMAIN_IN_FOREST 8534L +#define ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST 8535L +#define ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED 8536L +#define ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN 8537L +#define ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER 8538L +#define ERROR_DS_SRC_SID_EXISTS_IN_FOREST 8539L +#define ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH 8540L +#define ERROR_SAM_INIT_FAILURE 8541L +#define ERROR_DS_DRA_SCHEMA_INFO_SHIP 8542L +#define ERROR_DS_DRA_SCHEMA_CONFLICT 8543L +#define ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT 8544L +#define ERROR_DS_DRA_OBJ_NC_MISMATCH 8545L +#define ERROR_DS_NC_STILL_HAS_DSAS 8546L +#define ERROR_DS_GC_REQUIRED 8547L +#define ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY 8548L +#define ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS 8549L +#define ERROR_DS_CANT_ADD_TO_GC 8550L +#define ERROR_DS_NO_CHECKPOINT_WITH_PDC 8551L +#define ERROR_DS_SOURCE_AUDITING_NOT_ENABLED 8552L +#define ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC 8553L +#define ERROR_DS_INVALID_NAME_FOR_SPN 8554L +#define ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS 8555L +#define ERROR_DS_UNICODEPWD_NOT_IN_QUOTES 8556L +#define ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED 8557L +#define ERROR_DS_MUST_BE_RUN_ON_DST_DC 8558L +#define ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER 8559L +#define ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ 8560L +#define ERROR_DS_INIT_FAILURE_CONSOLE 8561L +#define ERROR_DS_SAM_INIT_FAILURE_CONSOLE 8562L +#define ERROR_DS_FOREST_VERSION_TOO_HIGH 8563L +#define ERROR_DS_DOMAIN_VERSION_TOO_HIGH 8564L +#define ERROR_DS_FOREST_VERSION_TOO_LOW 8565L +#define ERROR_DS_DOMAIN_VERSION_TOO_LOW 8566L +#define ERROR_DS_INCOMPATIBLE_VERSION 8567L +#define ERROR_DS_LOW_DSA_VERSION 8568L +#define ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN 8569L +#define ERROR_DS_NOT_SUPPORTED_SORT_ORDER 8570L +#define ERROR_DS_NAME_NOT_UNIQUE 8571L +#define ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4 8572L +#define ERROR_DS_OUT_OF_VERSION_STORE 8573L +#define ERROR_DS_INCOMPATIBLE_CONTROLS_USED 8574L +#define ERROR_DS_NO_REF_DOMAIN 8575L +#define ERROR_DS_RESERVED_LINK_ID 8576L +#define ERROR_DS_LINK_ID_NOT_AVAILABLE 8577L +#define ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER 8578L +#define ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE 8579L +#define ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC 8580L +#define ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG 8581L +#define ERROR_DS_MODIFYDN_WRONG_GRANDPARENT 8582L +#define ERROR_DS_NAME_ERROR_TRUST_REFERRAL 8583L +#define ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER 8584L +#define ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD 8585L +#define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2 8586L +#define ERROR_DS_THREAD_LIMIT_EXCEEDED 8587L +#define ERROR_DS_NOT_CLOSEST 8588L +#define ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF 8589L +#define ERROR_DS_SINGLE_USER_MODE_FAILED 8590L +#define ERROR_DS_NTDSCRIPT_SYNTAX_ERROR 8591L +#define ERROR_DS_NTDSCRIPT_PROCESS_ERROR 8592L +#define ERROR_DS_DIFFERENT_REPL_EPOCHS 8593L +#define ERROR_DS_DRS_EXTENSIONS_CHANGED 8594L +#define ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR 8595L +#define ERROR_DS_NO_MSDS_INTID 8596L +#define ERROR_DS_DUP_MSDS_INTID 8597L +#define ERROR_DS_EXISTS_IN_RDNATTID 8598L +#define ERROR_DS_AUTHORIZATION_FAILED 8599L +#define ERROR_DS_INVALID_SCRIPT 8600L +#define ERROR_DS_REMOTE_CROSSREF_OP_FAILED 8601L +#define ERROR_DS_CROSS_REF_BUSY 8602L +#define ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN 8603L +#define ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC 8604L +#define ERROR_DS_DUPLICATE_ID_FOUND 8605L +#define ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT 8606L +#define ERROR_DS_GROUP_CONVERSION_ERROR 8607L +#define ERROR_DS_CANT_MOVE_APP_BASIC_GROUP 8608L +#define ERROR_DS_CANT_MOVE_APP_QUERY_GROUP 8609L +#define ERROR_DS_ROLE_NOT_VERIFIED 8610L +#define ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL 8611L +#define ERROR_DS_DOMAIN_RENAME_IN_PROGRESS 8612L +#define ERROR_DS_EXISTING_AD_CHILD_NC 8613L +#define ERROR_DS_REPL_LIFETIME_EXCEEDED 8614L +#define ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER 8615L +#define ERROR_DS_LDAP_SEND_QUEUE_FULL 8616L +#define ERROR_DS_DRA_OUT_SCHEDULE_WINDOW 8617L +#define DNS_ERROR_RESPONSE_CODES_BASE 9000 +#define DNS_ERROR_RCODE_NO_ERROR NO_ERROR +#define DNS_ERROR_MASK 0x00002328 +#define DNS_ERROR_RCODE_FORMAT_ERROR 9001L +#define DNS_ERROR_RCODE_SERVER_FAILURE 9002L +#define DNS_ERROR_RCODE_NAME_ERROR 9003L +#define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004L +#define DNS_ERROR_RCODE_REFUSED 9005L +#define DNS_ERROR_RCODE_YXDOMAIN 9006L +#define DNS_ERROR_RCODE_YXRRSET 9007L +#define DNS_ERROR_RCODE_NXRRSET 9008L +#define DNS_ERROR_RCODE_NOTAUTH 9009L +#define DNS_ERROR_RCODE_NOTZONE 9010L +#define DNS_ERROR_RCODE_BADSIG 9016L +#define DNS_ERROR_RCODE_BADKEY 9017L +#define DNS_ERROR_RCODE_BADTIME 9018L +#define DNS_ERROR_RCODE_LAST DNS_ERROR_RCODE_BADTIME +#define DNS_ERROR_PACKET_FMT_BASE 9500 +#define DNS_INFO_NO_RECORDS 9501L +#define DNS_ERROR_BAD_PACKET 9502L +#define DNS_ERROR_NO_PACKET 9503L +#define DNS_ERROR_RCODE 9504L +#define DNS_ERROR_UNSECURE_PACKET 9505L +#define DNS_STATUS_PACKET_UNSECURE DNS_ERROR_UNSECURE_PACKET +#define DNS_ERROR_NO_MEMORY ERROR_OUTOFMEMORY +#define DNS_ERROR_INVALID_NAME ERROR_INVALID_NAME +#define DNS_ERROR_INVALID_DATA ERROR_INVALID_DATA +#define DNS_ERROR_GENERAL_API_BASE 9550 +#define DNS_ERROR_INVALID_TYPE 9551L +#define DNS_ERROR_INVALID_IP_ADDRESS 9552L +#define DNS_ERROR_INVALID_PROPERTY 9553L +#define DNS_ERROR_TRY_AGAIN_LATER 9554L +#define DNS_ERROR_NOT_UNIQUE 9555L +#define DNS_ERROR_NON_RFC_NAME 9556L +#define DNS_STATUS_FQDN 9557L +#define DNS_STATUS_DOTTED_NAME 9558L +#define DNS_STATUS_SINGLE_PART_NAME 9559L +#define DNS_ERROR_INVALID_NAME_CHAR 9560L +#define DNS_ERROR_NUMERIC_NAME 9561L +#define DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER 9562L +#define DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION 9563L +#define DNS_ERROR_CANNOT_FIND_ROOT_HINTS 9564L +#define DNS_ERROR_INCONSISTENT_ROOT_HINTS 9565L +#define DNS_ERROR_ZONE_BASE 9600 +#define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601L +#define DNS_ERROR_NO_ZONE_INFO 9602L +#define DNS_ERROR_INVALID_ZONE_OPERATION 9603L +#define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604L +#define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605L +#define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606L +#define DNS_ERROR_ZONE_LOCKED 9607L +#define DNS_ERROR_ZONE_CREATION_FAILED 9608L +#define DNS_ERROR_ZONE_ALREADY_EXISTS 9609L +#define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610L +#define DNS_ERROR_INVALID_ZONE_TYPE 9611L +#define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612L +#define DNS_ERROR_ZONE_NOT_SECONDARY 9613L +#define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614L +#define DNS_ERROR_WINS_INIT_FAILED 9615L +#define DNS_ERROR_NEED_WINS_SERVERS 9616L +#define DNS_ERROR_NBSTAT_INIT_FAILED 9617L +#define DNS_ERROR_SOA_DELETE_INVALID 9618L +#define DNS_ERROR_FORWARDER_ALREADY_EXISTS 9619L +#define DNS_ERROR_ZONE_REQUIRES_MASTER_IP 9620L +#define DNS_ERROR_ZONE_IS_SHUTDOWN 9621L +#define DNS_ERROR_DATAFILE_BASE 9650 +#define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651L +#define DNS_ERROR_INVALID_DATAFILE_NAME 9652L +#define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653L +#define DNS_ERROR_FILE_WRITEBACK_FAILED 9654L +#define DNS_ERROR_DATAFILE_PARSING 9655L +#define DNS_ERROR_DATABASE_BASE 9700 +#define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701L +#define DNS_ERROR_RECORD_FORMAT 9702L +#define DNS_ERROR_NODE_CREATION_FAILED 9703L +#define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704L +#define DNS_ERROR_RECORD_TIMED_OUT 9705L +#define DNS_ERROR_NAME_NOT_IN_ZONE 9706L +#define DNS_ERROR_CNAME_LOOP 9707L +#define DNS_ERROR_NODE_IS_CNAME 9708L +#define DNS_ERROR_CNAME_COLLISION 9709L +#define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710L +#define DNS_ERROR_RECORD_ALREADY_EXISTS 9711L +#define DNS_ERROR_SECONDARY_DATA 9712L +#define DNS_ERROR_NO_CREATE_CACHE_DATA 9713L +#define DNS_ERROR_NAME_DOES_NOT_EXIST 9714L +#define DNS_WARNING_PTR_CREATE_FAILED 9715L +#define DNS_WARNING_DOMAIN_UNDELETED 9716L +#define DNS_ERROR_DS_UNAVAILABLE 9717L +#define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718L +#define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719L +#define DNS_ERROR_OPERATION_BASE 9750 +#define DNS_INFO_AXFR_COMPLETE 9751L +#define DNS_ERROR_AXFR 9752L +#define DNS_INFO_ADDED_LOCAL_WINS 9753L +#define DNS_ERROR_SECURE_BASE 9800 +#define DNS_STATUS_CONTINUE_NEEDED 9801L +#define DNS_ERROR_SETUP_BASE 9850 +#define DNS_ERROR_NO_TCPIP 9851L +#define DNS_ERROR_NO_DNS_SERVERS 9852L +#define DNS_ERROR_DP_BASE 9900 +#define DNS_ERROR_DP_DOES_NOT_EXIST 9901L +#define DNS_ERROR_DP_ALREADY_EXISTS 9902L +#define DNS_ERROR_DP_NOT_ENLISTED 9903L +#define DNS_ERROR_DP_ALREADY_ENLISTED 9904L +#define DNS_ERROR_DP_NOT_AVAILABLE 9905L +#define DNS_ERROR_DP_FSMO_ERROR 9906L + +#ifndef WSABASEERR +#define WSABASEERR 10000 +#define WSAEINTR 10004L +#define WSAEBADF 10009L +#define WSAEACCES 10013L +#define WSAEFAULT 10014L +#define WSAEINVAL 10022L +#define WSAEMFILE 10024L +#define WSAEWOULDBLOCK 10035L +#define WSAEINPROGRESS 10036L +#define WSAEALREADY 10037L +#define WSAENOTSOCK 10038L +#define WSAEDESTADDRREQ 10039L +#define WSAEMSGSIZE 10040L +#define WSAEPROTOTYPE 10041L +#define WSAENOPROTOOPT 10042L +#define WSAEPROTONOSUPPORT 10043L +#define WSAESOCKTNOSUPPORT 10044L +#define WSAEOPNOTSUPP 10045L +#define WSAEPFNOSUPPORT 10046L +#define WSAEAFNOSUPPORT 10047L +#define WSAEADDRINUSE 10048L +#define WSAEADDRNOTAVAIL 10049L +#define WSAENETDOWN 10050L +#define WSAENETUNREACH 10051L +#define WSAENETRESET 10052L +#define WSAECONNABORTED 10053L +#define WSAECONNRESET 10054L +#define WSAENOBUFS 10055L +#define WSAEISCONN 10056L +#define WSAENOTCONN 10057L +#define WSAESHUTDOWN 10058L +#define WSAETOOMANYREFS 10059L +#define WSAETIMEDOUT 10060L +#define WSAECONNREFUSED 10061L +#define WSAELOOP 10062L +#define WSAENAMETOOLONG 10063L +#define WSAEHOSTDOWN 10064L +#define WSAEHOSTUNREACH 10065L +#define WSAENOTEMPTY 10066L +#define WSAEPROCLIM 10067L +#define WSAEUSERS 10068L +#define WSAEDQUOT 10069L +#define WSAESTALE 10070L +#define WSAEREMOTE 10071L +#define WSASYSNOTREADY 10091L +#define WSAVERNOTSUPPORTED 10092L +#define WSANOTINITIALISED 10093L +#define WSAEDISCON 10101L +#define WSAENOMORE 10102L +#define WSAECANCELLED 10103L +#define WSAEINVALIDPROCTABLE 10104L +#define WSAEINVALIDPROVIDER 10105L +#define WSAEPROVIDERFAILEDINIT 10106L +#define WSASYSCALLFAILURE 10107L +#define WSASERVICE_NOT_FOUND 10108L +#define WSATYPE_NOT_FOUND 10109L +#define WSA_E_NO_MORE 10110L +#define WSA_E_CANCELLED 10111L +#define WSAEREFUSED 10112L +#ifndef WSAHOST_NOT_FOUND +#define WSAHOST_NOT_FOUND 11001L +#endif +#ifndef WSATRY_AGAIN +#define WSATRY_AGAIN 11002L +#endif +#ifndef WSANO_RECOVERY +#define WSANO_RECOVERY 11003L +#endif +#ifndef WSANO_DATA +#define WSANO_DATA 11004L +#endif +#ifndef WSA_QOS_RECEIVERS +#define WSA_QOS_RECEIVERS 11005L +#endif +#ifndef WSA_QOS_SENDERS +#define WSA_QOS_SENDERS 11006L +#endif +#ifndef WSA_QOS_NO_SENDERS +#define WSA_QOS_NO_SENDERS 11007L +#endif +#ifndef WSA_QOS_NO_RECEIVERS +#define WSA_QOS_NO_RECEIVERS 11008L +#endif +#ifndef WSA_QOS_REQUEST_CONFIRMED +#define WSA_QOS_REQUEST_CONFIRMED 11009L +#endif +#ifndef WSA_QOS_ADMISSION_FAILURE +#define WSA_QOS_ADMISSION_FAILURE 11010L +#endif +#ifndef WSA_QOS_POLICY_FAILURE +#define WSA_QOS_POLICY_FAILURE 11011L +#endif +#ifndef WSA_QOS_BAD_STYLE +#define WSA_QOS_BAD_STYLE 11012L +#endif +#ifndef WSA_QOS_BAD_OBJECT +#define WSA_QOS_BAD_OBJECT 11013L +#endif +#ifndef WSA_QOS_TRAFFIC_CTRL_ERROR +#define WSA_QOS_TRAFFIC_CTRL_ERROR 11014L +#endif +#ifndef WSA_QOS_GENERIC_ERROR +#define WSA_QOS_GENERIC_ERROR 11015L +#endif +#ifndef WSA_QOS_ESERVICETYPE +#define WSA_QOS_ESERVICETYPE 11016L +#endif +#ifndef WSA_QOS_EFLOWSPEC +#define WSA_QOS_EFLOWSPEC 11017L +#endif +#ifndef WSA_QOS_EPROVSPECBUF +#define WSA_QOS_EPROVSPECBUF 11018L +#endif +#ifndef WSA_QOS_EFILTERSTYLE +#define WSA_QOS_EFILTERSTYLE 11019L +#endif +#ifndef WSA_QOS_EFILTERTYPE +#define WSA_QOS_EFILTERTYPE 11020L +#endif +#ifndef WSA_QOS_EFILTERCOUNT +#define WSA_QOS_EFILTERCOUNT 11021L +#endif +#ifndef WSA_QOS_EOBJLENGTH +#define WSA_QOS_EOBJLENGTH 11022L +#endif +#ifndef WSA_QOS_EFLOWCOUNT +#define WSA_QOS_EFLOWCOUNT 11023L +#endif +#ifndef WSA_QOS_EUNKNOWNPSOBJ +#define WSA_QOS_EUNKNOWNPSOBJ 11024L +#endif +#ifndef WSA_QOS_EPOLICYOBJ +#define WSA_QOS_EPOLICYOBJ 11025L +#endif +#ifndef WSA_QOS_EFLOWDESC +#define WSA_QOS_EFLOWDESC 11026L +#endif +#ifndef WSA_QOS_EPSFLOWSPEC +#define WSA_QOS_EPSFLOWSPEC 11027L +#endif +#ifndef WSA_QOS_EPSFILTERSPEC +#define WSA_QOS_EPSFILTERSPEC 11028L +#endif +#ifndef WSA_QOS_ESDMODEOBJ +#define WSA_QOS_ESDMODEOBJ 11029L +#endif +#ifndef WSA_QOS_ESHAPERATEOBJ +#define WSA_QOS_ESHAPERATEOBJ 11030L +#endif +#ifndef WSA_QOS_RESERVED_PETYPE +#define WSA_QOS_RESERVED_PETYPE 11031L +#endif +#endif /* WSABASEERR */ + +#define ERROR_SXS_SECTION_NOT_FOUND 14000L +#define ERROR_SXS_CANT_GEN_ACTCTX 14001L +#define ERROR_SXS_INVALID_ACTCTXDATA_FORMAT 14002L +#define ERROR_SXS_ASSEMBLY_NOT_FOUND 14003L +#define ERROR_SXS_MANIFEST_FORMAT_ERROR 14004L +#define ERROR_SXS_MANIFEST_PARSE_ERROR 14005L +#define ERROR_SXS_ACTIVATION_CONTEXT_DISABLED 14006L +#define ERROR_SXS_KEY_NOT_FOUND 14007L +#define ERROR_SXS_VERSION_CONFLICT 14008L +#define ERROR_SXS_WRONG_SECTION_TYPE 14009L +#define ERROR_SXS_THREAD_QUERIES_DISABLED 14010L +#define ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET 14011L +#define ERROR_SXS_UNKNOWN_ENCODING_GROUP 14012L +#define ERROR_SXS_UNKNOWN_ENCODING 14013L +#define ERROR_SXS_INVALID_XML_NAMESPACE_URI 14014L +#define ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED 14015L +#define ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED 14016L +#define ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE 14017L +#define ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE 14018L +#define ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE 14019L +#define ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT 14020L +#define ERROR_SXS_DUPLICATE_DLL_NAME 14021L +#define ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME 14022L +#define ERROR_SXS_DUPLICATE_CLSID 14023L +#define ERROR_SXS_DUPLICATE_IID 14024L +#define ERROR_SXS_DUPLICATE_TLBID 14025L +#define ERROR_SXS_DUPLICATE_PROGID 14026L +#define ERROR_SXS_DUPLICATE_ASSEMBLY_NAME 14027L +#define ERROR_SXS_FILE_HASH_MISMATCH 14028L +#define ERROR_SXS_POLICY_PARSE_ERROR 14029L +#define ERROR_SXS_XML_E_MISSINGQUOTE 14030L +#define ERROR_SXS_XML_E_COMMENTSYNTAX 14031L +#define ERROR_SXS_XML_E_BADSTARTNAMECHAR 14032L +#define ERROR_SXS_XML_E_BADNAMECHAR 14033L +#define ERROR_SXS_XML_E_BADCHARINSTRING 14034L +#define ERROR_SXS_XML_E_XMLDECLSYNTAX 14035L +#define ERROR_SXS_XML_E_BADCHARDATA 14036L +#define ERROR_SXS_XML_E_MISSINGWHITESPACE 14037L +#define ERROR_SXS_XML_E_EXPECTINGTAGEND 14038L +#define ERROR_SXS_XML_E_MISSINGSEMICOLON 14039L +#define ERROR_SXS_XML_E_UNBALANCEDPAREN 14040L +#define ERROR_SXS_XML_E_INTERNALERROR 14041L +#define ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE 14042L +#define ERROR_SXS_XML_E_INCOMPLETE_ENCODING 14043L +#define ERROR_SXS_XML_E_MISSING_PAREN 14044L +#define ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE 14045L +#define ERROR_SXS_XML_E_MULTIPLE_COLONS 14046L +#define ERROR_SXS_XML_E_INVALID_DECIMAL 14047L +#define ERROR_SXS_XML_E_INVALID_HEXIDECIMAL 14048L +#define ERROR_SXS_XML_E_INVALID_UNICODE 14049L +#define ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK 14050L +#define ERROR_SXS_XML_E_UNEXPECTEDENDTAG 14051L +#define ERROR_SXS_XML_E_UNCLOSEDTAG 14052L +#define ERROR_SXS_XML_E_DUPLICATEATTRIBUTE 14053L +#define ERROR_SXS_XML_E_MULTIPLEROOTS 14054L +#define ERROR_SXS_XML_E_INVALIDATROOTLEVEL 14055L +#define ERROR_SXS_XML_E_BADXMLDECL 14056L +#define ERROR_SXS_XML_E_MISSINGROOT 14057L +#define ERROR_SXS_XML_E_UNEXPECTEDEOF 14058L +#define ERROR_SXS_XML_E_BADPEREFINSUBSET 14059L +#define ERROR_SXS_XML_E_UNCLOSEDSTARTTAG 14060L +#define ERROR_SXS_XML_E_UNCLOSEDENDTAG 14061L +#define ERROR_SXS_XML_E_UNCLOSEDSTRING 14062L +#define ERROR_SXS_XML_E_UNCLOSEDCOMMENT 14063L +#define ERROR_SXS_XML_E_UNCLOSEDDECL 14064L +#define ERROR_SXS_XML_E_UNCLOSEDCDATA 14065L +#define ERROR_SXS_XML_E_RESERVEDNAMESPACE 14066L +#define ERROR_SXS_XML_E_INVALIDENCODING 14067L +#define ERROR_SXS_XML_E_INVALIDSWITCH 14068L +#define ERROR_SXS_XML_E_BADXMLCASE 14069L +#define ERROR_SXS_XML_E_INVALID_STANDALONE 14070L +#define ERROR_SXS_XML_E_UNEXPECTED_STANDALONE 14071L +#define ERROR_SXS_XML_E_INVALID_VERSION 14072L +#define ERROR_SXS_XML_E_MISSINGEQUALS 14073L +#define ERROR_SXS_PROTECTION_RECOVERY_FAILED 14074L +#define ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT 14075L +#define ERROR_SXS_PROTECTION_CATALOG_NOT_VALID 14076L +#define ERROR_SXS_UNTRANSLATABLE_HRESULT 14077L +#define ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING 14078L +#define ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE 14079L +#define ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME 14080L +#define ERROR_IPSEC_QM_POLICY_EXISTS 13000L +#define ERROR_IPSEC_QM_POLICY_NOT_FOUND 13001L +#define ERROR_IPSEC_QM_POLICY_IN_USE 13002L +#define ERROR_IPSEC_MM_POLICY_EXISTS 13003L +#define ERROR_IPSEC_MM_POLICY_NOT_FOUND 13004L +#define ERROR_IPSEC_MM_POLICY_IN_USE 13005L +#define ERROR_IPSEC_MM_FILTER_EXISTS 13006L +#define ERROR_IPSEC_MM_FILTER_NOT_FOUND 13007L +#define ERROR_IPSEC_TRANSPORT_FILTER_EXISTS 13008L +#define ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND 13009L +#define ERROR_IPSEC_MM_AUTH_EXISTS 13010L +#define ERROR_IPSEC_MM_AUTH_NOT_FOUND 13011L +#define ERROR_IPSEC_MM_AUTH_IN_USE 13012L +#define ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND 13013L +#define ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND 13014L +#define ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND 13015L +#define ERROR_IPSEC_TUNNEL_FILTER_EXISTS 13016L +#define ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND 13017L +#define ERROR_IPSEC_MM_FILTER_PENDING_DELETION 13018L +#define ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION 13019L +#define ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION 13020L +#define ERROR_IPSEC_MM_POLICY_PENDING_DELETION 13021L +#define ERROR_IPSEC_MM_AUTH_PENDING_DELETION 13022L +#define ERROR_IPSEC_QM_POLICY_PENDING_DELETION 13023L +#define WARNING_IPSEC_MM_POLICY_PRUNED 13024L +#define WARNING_IPSEC_QM_POLICY_PRUNED 13025L +#define ERROR_IPSEC_IKE_NEG_STATUS_BEGIN 13800L +#define ERROR_IPSEC_IKE_AUTH_FAIL 13801L +#define ERROR_IPSEC_IKE_ATTRIB_FAIL 13802L +#define ERROR_IPSEC_IKE_NEGOTIATION_PENDING 13803L +#define ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR 13804L +#define ERROR_IPSEC_IKE_TIMED_OUT 13805L +#define ERROR_IPSEC_IKE_NO_CERT 13806L +#define ERROR_IPSEC_IKE_SA_DELETED 13807L +#define ERROR_IPSEC_IKE_SA_REAPED 13808L +#define ERROR_IPSEC_IKE_MM_ACQUIRE_DROP 13809L +#define ERROR_IPSEC_IKE_QM_ACQUIRE_DROP 13810L +#define ERROR_IPSEC_IKE_QUEUE_DROP_MM 13811L +#define ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM 13812L +#define ERROR_IPSEC_IKE_DROP_NO_RESPONSE 13813L +#define ERROR_IPSEC_IKE_MM_DELAY_DROP 13814L +#define ERROR_IPSEC_IKE_QM_DELAY_DROP 13815L +#define ERROR_IPSEC_IKE_ERROR 13816L +#define ERROR_IPSEC_IKE_CRL_FAILED 13817L +#define ERROR_IPSEC_IKE_INVALID_KEY_USAGE 13818L +#define ERROR_IPSEC_IKE_INVALID_CERT_TYPE 13819L +#define ERROR_IPSEC_IKE_NO_PRIVATE_KEY 13820L +#define ERROR_IPSEC_IKE_DH_FAIL 13822L +#define ERROR_IPSEC_IKE_INVALID_HEADER 13824L +#define ERROR_IPSEC_IKE_NO_POLICY 13825L +#define ERROR_IPSEC_IKE_INVALID_SIGNATURE 13826L +#define ERROR_IPSEC_IKE_KERBEROS_ERROR 13827L +#define ERROR_IPSEC_IKE_NO_PUBLIC_KEY 13828L +#define ERROR_IPSEC_IKE_PROCESS_ERR 13829L +#define ERROR_IPSEC_IKE_PROCESS_ERR_SA 13830L +#define ERROR_IPSEC_IKE_PROCESS_ERR_PROP 13831L +#define ERROR_IPSEC_IKE_PROCESS_ERR_TRANS 13832L +#define ERROR_IPSEC_IKE_PROCESS_ERR_KE 13833L +#define ERROR_IPSEC_IKE_PROCESS_ERR_ID 13834L +#define ERROR_IPSEC_IKE_PROCESS_ERR_CERT 13835L +#define ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ 13836L +#define ERROR_IPSEC_IKE_PROCESS_ERR_HASH 13837L +#define ERROR_IPSEC_IKE_PROCESS_ERR_SIG 13838L +#define ERROR_IPSEC_IKE_PROCESS_ERR_NONCE 13839L +#define ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY 13840L +#define ERROR_IPSEC_IKE_PROCESS_ERR_DELETE 13841L +#define ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR 13842L +#define ERROR_IPSEC_IKE_INVALID_PAYLOAD 13843L +#define ERROR_IPSEC_IKE_LOAD_SOFT_SA 13844L +#define ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN 13845L +#define ERROR_IPSEC_IKE_INVALID_COOKIE 13846L +#define ERROR_IPSEC_IKE_NO_PEER_CERT 13847L +#define ERROR_IPSEC_IKE_PEER_CRL_FAILED 13848L +#define ERROR_IPSEC_IKE_POLICY_CHANGE 13849L +#define ERROR_IPSEC_IKE_NO_MM_POLICY 13850L +#define ERROR_IPSEC_IKE_NOTCBPRIV 13851L +#define ERROR_IPSEC_IKE_SECLOADFAIL 13852L +#define ERROR_IPSEC_IKE_FAILSSPINIT 13853L +#define ERROR_IPSEC_IKE_FAILQUERYSSP 13854L +#define ERROR_IPSEC_IKE_SRVACQFAIL 13855L +#define ERROR_IPSEC_IKE_SRVQUERYCRED 13856L +#define ERROR_IPSEC_IKE_GETSPIFAIL 13857L +#define ERROR_IPSEC_IKE_INVALID_FILTER 13858L +#define ERROR_IPSEC_IKE_OUT_OF_MEMORY 13859L +#define ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED 13860L +#define ERROR_IPSEC_IKE_INVALID_POLICY 13861L +#define ERROR_IPSEC_IKE_UNKNOWN_DOI 13862L +#define ERROR_IPSEC_IKE_INVALID_SITUATION 13863L +#define ERROR_IPSEC_IKE_DH_FAILURE 13864L +#define ERROR_IPSEC_IKE_INVALID_GROUP 13865L +#define ERROR_IPSEC_IKE_ENCRYPT 13866L +#define ERROR_IPSEC_IKE_DECRYPT 13867L +#define ERROR_IPSEC_IKE_POLICY_MATCH 13868L +#define ERROR_IPSEC_IKE_UNSUPPORTED_ID 13869L +#define ERROR_IPSEC_IKE_INVALID_HASH 13870L +#define ERROR_IPSEC_IKE_INVALID_HASH_ALG 13871L +#define ERROR_IPSEC_IKE_INVALID_HASH_SIZE 13872L +#define ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG 13873L +#define ERROR_IPSEC_IKE_INVALID_AUTH_ALG 13874L +#define ERROR_IPSEC_IKE_INVALID_SIG 13875L +#define ERROR_IPSEC_IKE_LOAD_FAILED 13876L +#define ERROR_IPSEC_IKE_RPC_DELETE 13877L +#define ERROR_IPSEC_IKE_BENIGN_REINIT 13878L +#define ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY 13879L +#define ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN 13881L +#define ERROR_IPSEC_IKE_MM_LIMIT 13882L +#define ERROR_IPSEC_IKE_NEGOTIATION_DISABLED 13883L +#define ERROR_IPSEC_IKE_NEG_STATUS_END 13884L #define SEVERITY_SUCCESS 0 #define SEVERITY_ERROR 1 -#define FACILITY_WINDOWS 8 -#define FACILITY_STORAGE 3 -#define FACILITY_RPC 1 -#define FACILITY_WIN32 7 -#define FACILITY_CONTROL 10 -#define FACILITY_NULL 0 -#define FACILITY_ITF 4 -#define FACILITY_DISPATCH 2 -#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0) -#define FAILED(Status) ((HRESULT)(Status)<0) -#define IS_ERROR(Status) ((unsigned long)(Status) >> 31 == SEVERITY_ERROR) -#define HRESULT_CODE(r) ((r)&0xFFFF) -#define SCODE_CODE(c) ((c)&0xFFFF) -#define HRESULT_FACILITY(r) (((r)>>16)&0x1fff) -#define SCODE_FACILITY(c) (((c)>>16)&0x1fff) -#define HRESULT_SEVERITY(r) (((r)>>31)&0x1) -#define SCODE_SEVERITY(c) (((c)>>31)&0x1) -#define MAKE_HRESULT(s,f,c) ((HRESULT)(((unsigned long)(s)<<31)|((unsigned long)(f)<<16)|((unsigned long)(c)))) -#define MAKE_SCODE(s,f,c) ((SCODE)(((unsigned long)(s)<<31)|((unsigned long)(f)<<16)|((unsigned long)(c))) ) +#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) +#define FAILED(hr) ((HRESULT)(hr) < 0) +#define IS_ERROR(Status) ((unsigned long)(Status) >> 31==SEVERITY_ERROR) +#define HRESULT_CODE(hr) ((hr) & 0xFFFF) +#define SCODE_CODE(sc) ((sc) & 0xFFFF) +#define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff) +#define SCODE_FACILITY(sc) (((sc) >> 16) & 0x1fff) +#define HRESULT_SEVERITY(hr) (((hr) >> 31) & 0x1) +#define SCODE_SEVERITY(sc) (((sc) >> 31) & 0x1) +#define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code)))) +#define MAKE_SCODE(sev,fac,code) ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code)))) #define FACILITY_NT_BIT 0x10000000 -#define HRESULT_FROM_WIN32(x) (x?((HRESULT)(((x)&0x0000FFFF)|(FACILITY_WIN32<<16)|0x80000000)):0) -#define HRESULT_FROM_NT(x) ((HRESULT)((x)|FACILITY_NT_BIT)) +#define __HRESULT_FROM_WIN32(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000))) +#ifdef INLINE_HRESULT_FROM_WIN32 +#ifndef _HRESULT_DEFINED +#define _HRESULT_DEFINED +typedef long HRESULT; +#endif +__CRT_INLINE HRESULT HRESULT_FROM_WIN32(long x) { return x <= 0 ? (HRESULT)x : (HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);} +#else +#define HRESULT_FROM_WIN32(x) __HRESULT_FROM_WIN32(x) +#endif +#define HRESULT_FROM_NT(x) ((HRESULT) ((x) | FACILITY_NT_BIT)) #define GetScode(hr) ((SCODE) (hr)) #define ResultFromScode(sc) ((HRESULT) (sc)) -#define PropagateResult(hrPrevious, scBase) ((HRESULT) scBase) - -#define NOERROR S_OK -#define E_UNEXPECTED 0x8000FFFFL -#define E_NOTIMPL 0x80004001L -#define E_OUTOFMEMORY 0x8007000EL -#define E_INVALIDARG 0x80070057L -#define E_NOINTERFACE 0x80004002L -#define E_POINTER 0x80004003L -#define E_HANDLE 0x80070006L -#define E_ABORT 0x80004004L -#define E_FAIL 0x80004005L -#define E_ACCESSDENIED 0x80070005L -#define E_PENDING 0x8000000AL -#define CO_E_INIT_TLS 0x80004006L -#define CO_E_INIT_SHARED_ALLOCATOR 0x80004007L -#define CO_E_INIT_MEMORY_ALLOCATOR 0x80004008L -#define CO_E_INIT_CLASS_CACHE 0x80004009L -#define CO_E_INIT_RPC_CHANNEL 0x8000400AL -#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL 0x8000400BL -#define CO_E_INIT_TLS_CHANNEL_CONTROL 0x8000400CL -#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR 0x8000400DL -#define CO_E_INIT_SCM_MUTEX_EXISTS 0x8000400EL -#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS 0x8000400FL -#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE 0x80004010L -#define CO_E_INIT_SCM_EXEC_FAILURE 0x80004011L -#define CO_E_INIT_ONLY_SINGLE_THREADED 0x80004012L -#define S_OK (0x00000000L) -#define S_FALSE (0x00000001L) -#define OLE_E_FIRST 0x80040000L -#define OLE_E_LAST 0x800400FFL -#define OLE_S_FIRST 0x00040000L -#define OLE_S_LAST 0x000400FFL -#define OLE_E_OLEVERB 0x80040000L -#define OLE_E_ADVF 0x80040001L -#define OLE_E_ENUM_NOMORE 0x80040002L -#define OLE_E_ADVISENOTSUPPORTED 0x80040003L -#define OLE_E_NOCONNECTION 0x80040004L -#define OLE_E_NOTRUNNING 0x80040005L -#define OLE_E_NOCACHE 0x80040006L -#define OLE_E_BLANK 0x80040007L -#define OLE_E_CLASSDIFF 0x80040008L -#define OLE_E_CANT_GETMONIKER 0x80040009L -#define OLE_E_CANT_BINDTOSOURCE 0x8004000AL -#define OLE_E_STATIC 0x8004000BL -#define OLE_E_PROMPTSAVECANCELLED 0x8004000CL -#define OLE_E_INVALIDRECT 0x8004000DL -#define OLE_E_WRONGCOMPOBJ 0x8004000EL -#define OLE_E_INVALIDHWND 0x8004000FL -#define OLE_E_NOT_INPLACEACTIVE 0x80040010L -#define OLE_E_CANTCONVERT 0x80040011L -#define OLE_E_NOSTORAGE 0x80040012L -#define DV_E_FORMATETC 0x80040064L -#define DV_E_DVTARGETDEVICE 0x80040065L -#define DV_E_STGMEDIUM 0x80040066L -#define DV_E_STATDATA 0x80040067L -#define DV_E_LINDEX 0x80040068L -#define DV_E_TYMED 0x80040069L -#define DV_E_CLIPFORMAT 0x8004006AL -#define DV_E_DVASPECT 0x8004006BL -#define DV_E_DVTARGETDEVICE_SIZE 0x8004006CL -#define DV_E_NOIVIEWOBJECT 0x8004006DL +#define PropagateResult(hrPrevious,scBase) ((HRESULT) scBase) +#ifdef RC_INVOKED +#define _HRESULT_TYPEDEF_(_sc) _sc +#else +#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc) +#endif +#define NOERROR 0 +#define E_UNEXPECTED _HRESULT_TYPEDEF_(0x8000FFFFL) +#define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001L) +#define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000EL) +#define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057L) +#define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002L) +#define E_POINTER _HRESULT_TYPEDEF_(0x80004003L) +#define E_HANDLE _HRESULT_TYPEDEF_(0x80070006L) +#define E_ABORT _HRESULT_TYPEDEF_(0x80004004L) +#define E_FAIL _HRESULT_TYPEDEF_(0x80004005L) +#define E_ACCESSDENIED _HRESULT_TYPEDEF_(0x80070005L) +#define E_PENDING _HRESULT_TYPEDEF_(0x8000000AL) +#define CO_E_INIT_TLS _HRESULT_TYPEDEF_(0x80004006L) +#define CO_E_INIT_SHARED_ALLOCATOR _HRESULT_TYPEDEF_(0x80004007L) +#define CO_E_INIT_MEMORY_ALLOCATOR _HRESULT_TYPEDEF_(0x80004008L) +#define CO_E_INIT_CLASS_CACHE _HRESULT_TYPEDEF_(0x80004009L) +#define CO_E_INIT_RPC_CHANNEL _HRESULT_TYPEDEF_(0x8000400AL) +#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL _HRESULT_TYPEDEF_(0x8000400BL) +#define CO_E_INIT_TLS_CHANNEL_CONTROL _HRESULT_TYPEDEF_(0x8000400CL) +#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR _HRESULT_TYPEDEF_(0x8000400DL) +#define CO_E_INIT_SCM_MUTEX_EXISTS _HRESULT_TYPEDEF_(0x8000400EL) +#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS _HRESULT_TYPEDEF_(0x8000400FL) +#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE _HRESULT_TYPEDEF_(0x80004010L) +#define CO_E_INIT_SCM_EXEC_FAILURE _HRESULT_TYPEDEF_(0x80004011L) +#define CO_E_INIT_ONLY_SINGLE_THREADED _HRESULT_TYPEDEF_(0x80004012L) +#define CO_E_CANT_REMOTE _HRESULT_TYPEDEF_(0x80004013L) +#define CO_E_BAD_SERVER_NAME _HRESULT_TYPEDEF_(0x80004014L) +#define CO_E_WRONG_SERVER_IDENTITY _HRESULT_TYPEDEF_(0x80004015L) +#define CO_E_OLE1DDE_DISABLED _HRESULT_TYPEDEF_(0x80004016L) +#define CO_E_RUNAS_SYNTAX _HRESULT_TYPEDEF_(0x80004017L) +#define CO_E_CREATEPROCESS_FAILURE _HRESULT_TYPEDEF_(0x80004018L) +#define CO_E_RUNAS_CREATEPROCESS_FAILURE _HRESULT_TYPEDEF_(0x80004019L) +#define CO_E_RUNAS_LOGON_FAILURE _HRESULT_TYPEDEF_(0x8000401AL) +#define CO_E_LAUNCH_PERMSSION_DENIED _HRESULT_TYPEDEF_(0x8000401BL) +#define CO_E_START_SERVICE_FAILURE _HRESULT_TYPEDEF_(0x8000401CL) +#define CO_E_REMOTE_COMMUNICATION_FAILURE _HRESULT_TYPEDEF_(0x8000401DL) +#define CO_E_SERVER_START_TIMEOUT _HRESULT_TYPEDEF_(0x8000401EL) +#define CO_E_CLSREG_INCONSISTENT _HRESULT_TYPEDEF_(0x8000401FL) +#define CO_E_IIDREG_INCONSISTENT _HRESULT_TYPEDEF_(0x80004020L) +#define CO_E_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80004021L) +#define CO_E_RELOAD_DLL _HRESULT_TYPEDEF_(0x80004022L) +#define CO_E_MSI_ERROR _HRESULT_TYPEDEF_(0x80004023L) +#define CO_E_ATTEMPT_TO_CREATE_OUTSIDE_CLIENT_CONTEXT _HRESULT_TYPEDEF_(0x80004024L) +#define CO_E_SERVER_PAUSED _HRESULT_TYPEDEF_(0x80004025L) +#define CO_E_SERVER_NOT_PAUSED _HRESULT_TYPEDEF_(0x80004026L) +#define CO_E_CLASS_DISABLED _HRESULT_TYPEDEF_(0x80004027L) +#define CO_E_CLRNOTAVAILABLE _HRESULT_TYPEDEF_(0x80004028L) +#define CO_E_ASYNC_WORK_REJECTED _HRESULT_TYPEDEF_(0x80004029L) +#define CO_E_SERVER_INIT_TIMEOUT _HRESULT_TYPEDEF_(0x8000402AL) +#define CO_E_NO_SECCTX_IN_ACTIVATE _HRESULT_TYPEDEF_(0x8000402BL) +#define CO_E_TRACKER_CONFIG _HRESULT_TYPEDEF_(0x80004030L) +#define CO_E_THREADPOOL_CONFIG _HRESULT_TYPEDEF_(0x80004031L) +#define CO_E_SXS_CONFIG _HRESULT_TYPEDEF_(0x80004032L) +#define CO_E_MALFORMED_SPN _HRESULT_TYPEDEF_(0x80004033L) +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) +#define OLE_E_FIRST ((HRESULT)0x80040000L) +#define OLE_E_LAST ((HRESULT)0x800400FFL) +#define OLE_S_FIRST ((HRESULT)0x00040000L) +#define OLE_S_LAST ((HRESULT)0x000400FFL) +#define OLE_E_OLEVERB _HRESULT_TYPEDEF_(0x80040000L) +#define OLE_E_ADVF _HRESULT_TYPEDEF_(0x80040001L) +#define OLE_E_ENUM_NOMORE _HRESULT_TYPEDEF_(0x80040002L) +#define OLE_E_ADVISENOTSUPPORTED _HRESULT_TYPEDEF_(0x80040003L) +#define OLE_E_NOCONNECTION _HRESULT_TYPEDEF_(0x80040004L) +#define OLE_E_NOTRUNNING _HRESULT_TYPEDEF_(0x80040005L) +#define OLE_E_NOCACHE _HRESULT_TYPEDEF_(0x80040006L) +#define OLE_E_BLANK _HRESULT_TYPEDEF_(0x80040007L) +#define OLE_E_CLASSDIFF _HRESULT_TYPEDEF_(0x80040008L) +#define OLE_E_CANT_GETMONIKER _HRESULT_TYPEDEF_(0x80040009L) +#define OLE_E_CANT_BINDTOSOURCE _HRESULT_TYPEDEF_(0x8004000AL) +#define OLE_E_STATIC _HRESULT_TYPEDEF_(0x8004000BL) +#define OLE_E_PROMPTSAVECANCELLED _HRESULT_TYPEDEF_(0x8004000CL) +#define OLE_E_INVALIDRECT _HRESULT_TYPEDEF_(0x8004000DL) +#define OLE_E_WRONGCOMPOBJ _HRESULT_TYPEDEF_(0x8004000EL) +#define OLE_E_INVALIDHWND _HRESULT_TYPEDEF_(0x8004000FL) +#define OLE_E_NOT_INPLACEACTIVE _HRESULT_TYPEDEF_(0x80040010L) +#define OLE_E_CANTCONVERT _HRESULT_TYPEDEF_(0x80040011L) +#define OLE_E_NOSTORAGE _HRESULT_TYPEDEF_(0x80040012L) +#define DV_E_FORMATETC _HRESULT_TYPEDEF_(0x80040064L) +#define DV_E_DVTARGETDEVICE _HRESULT_TYPEDEF_(0x80040065L) +#define DV_E_STGMEDIUM _HRESULT_TYPEDEF_(0x80040066L) +#define DV_E_STATDATA _HRESULT_TYPEDEF_(0x80040067L) +#define DV_E_LINDEX _HRESULT_TYPEDEF_(0x80040068L) +#define DV_E_TYMED _HRESULT_TYPEDEF_(0x80040069L) +#define DV_E_CLIPFORMAT _HRESULT_TYPEDEF_(0x8004006AL) +#define DV_E_DVASPECT _HRESULT_TYPEDEF_(0x8004006BL) +#define DV_E_DVTARGETDEVICE_SIZE _HRESULT_TYPEDEF_(0x8004006CL) +#define DV_E_NOIVIEWOBJECT _HRESULT_TYPEDEF_(0x8004006DL) #define DRAGDROP_E_FIRST 0x80040100L #define DRAGDROP_E_LAST 0x8004010FL #define DRAGDROP_S_FIRST 0x00040100L #define DRAGDROP_S_LAST 0x0004010FL -#define DRAGDROP_E_NOTREGISTERED 0x80040100L -#define DRAGDROP_E_ALREADYREGISTERED 0x80040101L -#define DRAGDROP_E_INVALIDHWND 0x80040102L +#define DRAGDROP_E_NOTREGISTERED _HRESULT_TYPEDEF_(0x80040100L) +#define DRAGDROP_E_ALREADYREGISTERED _HRESULT_TYPEDEF_(0x80040101L) +#define DRAGDROP_E_INVALIDHWND _HRESULT_TYPEDEF_(0x80040102L) #define CLASSFACTORY_E_FIRST 0x80040110L #define CLASSFACTORY_E_LAST 0x8004011FL #define CLASSFACTORY_S_FIRST 0x00040110L #define CLASSFACTORY_S_LAST 0x0004011FL -#define CLASS_E_NOAGGREGATION 0x80040110L -#define CLASS_E_CLASSNOTAVAILABLE 0x80040111L +#define CLASS_E_NOAGGREGATION _HRESULT_TYPEDEF_(0x80040110L) +#define CLASS_E_CLASSNOTAVAILABLE _HRESULT_TYPEDEF_(0x80040111L) +#define CLASS_E_NOTLICENSED _HRESULT_TYPEDEF_(0x80040112L) #define MARSHAL_E_FIRST 0x80040120L #define MARSHAL_E_LAST 0x8004012FL #define MARSHAL_S_FIRST 0x00040120L @@ -777,34 +2102,53 @@ #define VIEW_E_LAST 0x8004014FL #define VIEW_S_FIRST 0x00040140L #define VIEW_S_LAST 0x0004014FL -#define VIEW_E_DRAW 0x80040140L +#define VIEW_E_DRAW _HRESULT_TYPEDEF_(0x80040140L) #define REGDB_E_FIRST 0x80040150L #define REGDB_E_LAST 0x8004015FL #define REGDB_S_FIRST 0x00040150L #define REGDB_S_LAST 0x0004015FL -#define REGDB_E_READREGDB 0x80040150L -#define REGDB_E_WRITEREGDB 0x80040151L -#define REGDB_E_KEYMISSING 0x80040152L -#define REGDB_E_INVALIDVALUE 0x80040153L -#define REGDB_E_CLASSNOTREG 0x80040154L -#define REGDB_E_IIDNOTREG 0x80040155L +#define REGDB_E_READREGDB _HRESULT_TYPEDEF_(0x80040150L) +#define REGDB_E_WRITEREGDB _HRESULT_TYPEDEF_(0x80040151L) +#define REGDB_E_KEYMISSING _HRESULT_TYPEDEF_(0x80040152L) +#define REGDB_E_INVALIDVALUE _HRESULT_TYPEDEF_(0x80040153L) +#define REGDB_E_CLASSNOTREG _HRESULT_TYPEDEF_(0x80040154L) +#define REGDB_E_IIDNOTREG _HRESULT_TYPEDEF_(0x80040155L) +#define REGDB_E_BADTHREADINGMODEL _HRESULT_TYPEDEF_(0x80040156L) +#define CAT_E_FIRST 0x80040160L +#define CAT_E_LAST 0x80040161L +#define CAT_E_CATIDNOEXIST _HRESULT_TYPEDEF_(0x80040160L) +#define CAT_E_NODESCRIPTION _HRESULT_TYPEDEF_(0x80040161L) +#define CS_E_FIRST 0x80040164L +#define CS_E_LAST 0x8004016FL +#define CS_E_PACKAGE_NOTFOUND _HRESULT_TYPEDEF_(0x80040164L) +#define CS_E_NOT_DELETABLE _HRESULT_TYPEDEF_(0x80040165L) +#define CS_E_CLASS_NOTFOUND _HRESULT_TYPEDEF_(0x80040166L) +#define CS_E_INVALID_VERSION _HRESULT_TYPEDEF_(0x80040167L) +#define CS_E_NO_CLASSSTORE _HRESULT_TYPEDEF_(0x80040168L) +#define CS_E_OBJECT_NOTFOUND _HRESULT_TYPEDEF_(0x80040169L) +#define CS_E_OBJECT_ALREADY_EXISTS _HRESULT_TYPEDEF_(0x8004016AL) +#define CS_E_INVALID_PATH _HRESULT_TYPEDEF_(0x8004016BL) +#define CS_E_NETWORK_ERROR _HRESULT_TYPEDEF_(0x8004016CL) +#define CS_E_ADMIN_LIMIT_EXCEEDED _HRESULT_TYPEDEF_(0x8004016DL) +#define CS_E_SCHEMA_MISMATCH _HRESULT_TYPEDEF_(0x8004016EL) +#define CS_E_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x8004016FL) #define CACHE_E_FIRST 0x80040170L #define CACHE_E_LAST 0x8004017FL #define CACHE_S_FIRST 0x00040170L #define CACHE_S_LAST 0x0004017FL -#define CACHE_E_NOCACHE_UPDATED 0x80040170L +#define CACHE_E_NOCACHE_UPDATED _HRESULT_TYPEDEF_(0x80040170L) #define OLEOBJ_E_FIRST 0x80040180L #define OLEOBJ_E_LAST 0x8004018FL #define OLEOBJ_S_FIRST 0x00040180L #define OLEOBJ_S_LAST 0x0004018FL -#define OLEOBJ_E_NOVERBS 0x80040180L -#define OLEOBJ_E_INVALIDVERB 0x80040181L +#define OLEOBJ_E_NOVERBS _HRESULT_TYPEDEF_(0x80040180L) +#define OLEOBJ_E_INVALIDVERB _HRESULT_TYPEDEF_(0x80040181L) #define CLIENTSITE_E_FIRST 0x80040190L #define CLIENTSITE_E_LAST 0x8004019FL #define CLIENTSITE_S_FIRST 0x00040190L #define CLIENTSITE_S_LAST 0x0004019FL -#define INPLACE_E_NOTUNDOABLE 0x800401A0L -#define INPLACE_E_NOTOOLSPACE 0x800401A1L +#define INPLACE_E_NOTUNDOABLE _HRESULT_TYPEDEF_(0x800401A0L) +#define INPLACE_E_NOTOOLSPACE _HRESULT_TYPEDEF_(0x800401A1L) #define INPLACE_E_FIRST 0x800401A0L #define INPLACE_E_LAST 0x800401AFL #define INPLACE_S_FIRST 0x000401A0L @@ -817,238 +2161,1006 @@ #define CONVERT10_E_LAST 0x800401CFL #define CONVERT10_S_FIRST 0x000401C0L #define CONVERT10_S_LAST 0x000401CFL -#define CONVERT10_E_OLESTREAM_GET 0x800401C0L -#define CONVERT10_E_OLESTREAM_PUT 0x800401C1L -#define CONVERT10_E_OLESTREAM_FMT 0x800401C2L -#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB 0x800401C3L -#define CONVERT10_E_STG_FMT 0x800401C4L -#define CONVERT10_E_STG_NO_STD_STREAM 0x800401C5L -#define CONVERT10_E_STG_DIB_TO_BITMAP 0x800401C6L +#define CONVERT10_E_OLESTREAM_GET _HRESULT_TYPEDEF_(0x800401C0L) +#define CONVERT10_E_OLESTREAM_PUT _HRESULT_TYPEDEF_(0x800401C1L) +#define CONVERT10_E_OLESTREAM_FMT _HRESULT_TYPEDEF_(0x800401C2L) +#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB _HRESULT_TYPEDEF_(0x800401C3L) +#define CONVERT10_E_STG_FMT _HRESULT_TYPEDEF_(0x800401C4L) +#define CONVERT10_E_STG_NO_STD_STREAM _HRESULT_TYPEDEF_(0x800401C5L) +#define CONVERT10_E_STG_DIB_TO_BITMAP _HRESULT_TYPEDEF_(0x800401C6L) #define CLIPBRD_E_FIRST 0x800401D0L #define CLIPBRD_E_LAST 0x800401DFL #define CLIPBRD_S_FIRST 0x000401D0L #define CLIPBRD_S_LAST 0x000401DFL -#define CLIPBRD_E_CANT_OPEN 0x800401D0L -#define CLIPBRD_E_CANT_EMPTY 0x800401D1L -#define CLIPBRD_E_CANT_SET 0x800401D2L -#define CLIPBRD_E_BAD_DATA 0x800401D3L -#define CLIPBRD_E_CANT_CLOSE 0x800401D4L +#define CLIPBRD_E_CANT_OPEN _HRESULT_TYPEDEF_(0x800401D0L) +#define CLIPBRD_E_CANT_EMPTY _HRESULT_TYPEDEF_(0x800401D1L) +#define CLIPBRD_E_CANT_SET _HRESULT_TYPEDEF_(0x800401D2L) +#define CLIPBRD_E_BAD_DATA _HRESULT_TYPEDEF_(0x800401D3L) +#define CLIPBRD_E_CANT_CLOSE _HRESULT_TYPEDEF_(0x800401D4L) #define MK_E_FIRST 0x800401E0L #define MK_E_LAST 0x800401EFL #define MK_S_FIRST 0x000401E0L #define MK_S_LAST 0x000401EFL -#define MK_E_CONNECTMANUALLY 0x800401E0L -#define MK_E_EXCEEDEDDEADLINE 0x800401E1L -#define MK_E_NEEDGENERIC 0x800401E2L -#define MK_E_UNAVAILABLE 0x800401E3L -#define MK_E_SYNTAX 0x800401E4L -#define MK_E_NOOBJECT 0x800401E5L -#define MK_E_INVALIDEXTENSION 0x800401E6L -#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED 0x800401E7L -#define MK_E_NOTBINDABLE 0x800401E8L -#define MK_E_NOTBOUND 0x800401E9L -#define MK_E_CANTOPENFILE 0x800401EAL -#define MK_E_MUSTBOTHERUSER 0x800401EBL -#define MK_E_NOINVERSE 0x800401ECL -#define MK_E_NOSTORAGE 0x800401EDL -#define MK_E_NOPREFIX 0x800401EEL -#define MK_E_ENUMERATION_FAILED 0x800401EFL +#define MK_E_CONNECTMANUALLY _HRESULT_TYPEDEF_(0x800401E0L) +#define MK_E_EXCEEDEDDEADLINE _HRESULT_TYPEDEF_(0x800401E1L) +#define MK_E_NEEDGENERIC _HRESULT_TYPEDEF_(0x800401E2L) +#define MK_E_UNAVAILABLE _HRESULT_TYPEDEF_(0x800401E3L) +#define MK_E_SYNTAX _HRESULT_TYPEDEF_(0x800401E4L) +#define MK_E_NOOBJECT _HRESULT_TYPEDEF_(0x800401E5L) +#define MK_E_INVALIDEXTENSION _HRESULT_TYPEDEF_(0x800401E6L) +#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED _HRESULT_TYPEDEF_(0x800401E7L) +#define MK_E_NOTBINDABLE _HRESULT_TYPEDEF_(0x800401E8L) +#define MK_E_NOTBOUND _HRESULT_TYPEDEF_(0x800401E9L) +#define MK_E_CANTOPENFILE _HRESULT_TYPEDEF_(0x800401EAL) +#define MK_E_MUSTBOTHERUSER _HRESULT_TYPEDEF_(0x800401EBL) +#define MK_E_NOINVERSE _HRESULT_TYPEDEF_(0x800401ECL) +#define MK_E_NOSTORAGE _HRESULT_TYPEDEF_(0x800401EDL) +#define MK_E_NOPREFIX _HRESULT_TYPEDEF_(0x800401EEL) +#define MK_E_ENUMERATION_FAILED _HRESULT_TYPEDEF_(0x800401EFL) #define CO_E_FIRST 0x800401F0L #define CO_E_LAST 0x800401FFL #define CO_S_FIRST 0x000401F0L #define CO_S_LAST 0x000401FFL -#define CO_E_NOTINITIALIZED 0x800401F0L -#define CO_E_ALREADYINITIALIZED 0x800401F1L -#define CO_E_CANTDETERMINECLASS 0x800401F2L -#define CO_E_CLASSSTRING 0x800401F3L -#define CO_E_IIDSTRING 0x800401F4L -#define CO_E_APPNOTFOUND 0x800401F5L -#define CO_E_APPSINGLEUSE 0x800401F6L -#define CO_E_ERRORINAPP 0x800401F7L -#define CO_E_DLLNOTFOUND 0x800401F8L -#define CO_E_ERRORINDLL 0x800401F9L -#define CO_E_WRONGOSFORAPP 0x800401FAL -#define CO_E_OBJNOTREG 0x800401FBL -#define CO_E_OBJISREG 0x800401FCL -#define CO_E_OBJNOTCONNECTED 0x800401FDL -#define CO_E_APPDIDNTREG 0x800401FEL -#define CO_E_RELEASED 0x800401FFL -#define OLE_S_USEREG 0x00040000L -#define OLE_S_STATIC 0x00040001L -#define OLE_S_MAC_CLIPFORMAT 0x00040002L -#define DRAGDROP_S_DROP 0x00040100L -#define DRAGDROP_S_CANCEL 0x00040101L -#define DRAGDROP_S_USEDEFAULTCURSORS 0x00040102L -#define DATA_S_SAMEFORMATETC 0x00040130L -#define VIEW_S_ALREADY_FROZEN 0x00040140L -#define CACHE_S_FORMATETC_NOTSUPPORTED 0x00040170L -#define CACHE_S_SAMECACHE 0x00040171L -#define CACHE_S_SOMECACHES_NOTUPDATED 0x00040172L -#define OLEOBJ_S_INVALIDVERB 0x00040180L -#define OLEOBJ_S_CANNOT_DOVERB_NOW 0x00040181L -#define OLEOBJ_S_INVALIDHWND 0x00040182L -#define INPLACE_S_TRUNCATED 0x000401A0L -#define CONVERT10_S_NO_PRESENTATION 0x000401C0L -#define MK_S_REDUCED_TO_SELF 0x000401E2L -#define MK_S_ME 0x000401E4L -#define MK_S_HIM 0x000401E5L -#define MK_S_US 0x000401E6L -#define MK_S_MONIKERALREADYREGISTERED 0x000401E7L -#define CO_E_CLASS_CREATE_FAILED 0x80080001L -#define CO_E_SCM_ERROR 0x80080002L -#define CO_E_SCM_RPC_FAILURE 0x80080003L -#define CO_E_BAD_PATH 0x80080004L -#define CO_E_SERVER_EXEC_FAILURE 0x80080005L -#define CO_E_OBJSRV_RPC_FAILURE 0x80080006L -#define MK_E_NO_NORMALIZED 0x80080007L -#define CO_E_SERVER_STOPPING 0x80080008L -#define MEM_E_INVALID_ROOT 0x80080009L -#define MEM_E_INVALID_LINK 0x80080010L -#define MEM_E_INVALID_SIZE 0x80080011L -#define DISP_E_UNKNOWNINTERFACE 0x80020001L -#define DISP_E_MEMBERNOTFOUND 0x80020003L -#define DISP_E_PARAMNOTFOUND 0x80020004L -#define DISP_E_TYPEMISMATCH 0x80020005L -#define DISP_E_UNKNOWNNAME 0x80020006L -#define DISP_E_NONAMEDARGS 0x80020007L -#define DISP_E_BADVARTYPE 0x80020008L -#define DISP_E_EXCEPTION 0x80020009L -#define DISP_E_OVERFLOW 0x8002000AL -#define DISP_E_BADINDEX 0x8002000BL -#define DISP_E_UNKNOWNLCID 0x8002000CL -#define DISP_E_ARRAYISLOCKED 0x8002000DL -#define DISP_E_BADPARAMCOUNT 0x8002000EL -#define DISP_E_PARAMNOTOPTIONAL 0x8002000FL -#define DISP_E_BADCALLEE 0x80020010L -#define DISP_E_NOTACOLLECTION 0x80020011L -#define TYPE_E_BUFFERTOOSMALL 0x80028016L -#define TYPE_E_INVDATAREAD 0x80028018L -#define TYPE_E_UNSUPFORMAT 0x80028019L -#define TYPE_E_REGISTRYACCESS 0x8002801CL -#define TYPE_E_LIBNOTREGISTERED 0x8002801DL -#define TYPE_E_UNDEFINEDTYPE 0x80028027L -#define TYPE_E_QUALIFIEDNAMEDISALLOWED 0x80028028L -#define TYPE_E_INVALIDSTATE 0x80028029L -#define TYPE_E_WRONGTYPEKIND 0x8002802AL -#define TYPE_E_ELEMENTNOTFOUND 0x8002802BL -#define TYPE_E_AMBIGUOUSNAME 0x8002802CL -#define TYPE_E_NAMECONFLICT 0x8002802DL -#define TYPE_E_UNKNOWNLCID 0x8002802EL -#define TYPE_E_DLLFUNCTIONNOTFOUND 0x8002802FL -#define TYPE_E_BADMODULEKIND 0x800288BDL -#define TYPE_E_SIZETOOBIG 0x800288C5L -#define TYPE_E_DUPLICATEID 0x800288C6L -#define TYPE_E_INVALIDID 0x800288CFL -#define TYPE_E_TYPEMISMATCH 0x80028CA0L -#define TYPE_E_OUTOFBOUNDS 0x80028CA1L -#define TYPE_E_IOERROR 0x80028CA2L -#define TYPE_E_CANTCREATETMPFILE 0x80028CA3L -#define TYPE_E_CANTLOADLIBRARY 0x80029C4AL -#define TYPE_E_INCONSISTENTPROPFUNCS 0x80029C83L -#define TYPE_E_CIRCULARTYPE 0x80029C84L -#define STG_E_INVALIDFUNCTION 0x80030001L -#define STG_E_FILENOTFOUND 0x80030002L -#define STG_E_PATHNOTFOUND 0x80030003L -#define STG_E_TOOMANYOPENFILES 0x80030004L -#define STG_E_ACCESSDENIED 0x80030005L -#define STG_E_INVALIDHANDLE 0x80030006L -#define STG_E_INSUFFICIENTMEMORY 0x80030008L -#define STG_E_INVALIDPOINTER 0x80030009L -#define STG_E_NOMOREFILES 0x80030012L -#define STG_E_DISKISWRITEPROTECTED 0x80030013L -#define STG_E_SEEKERROR 0x80030019L -#define STG_E_WRITEFAULT 0x8003001DL -#define STG_E_READFAULT 0x8003001EL -#define STG_E_SHAREVIOLATION 0x80030020L -#define STG_E_LOCKVIOLATION 0x80030021L -#define STG_E_FILEALREADYEXISTS 0x80030050L -#define STG_E_INVALIDPARAMETER 0x80030057L -#define STG_E_MEDIUMFULL 0x80030070L -#define STG_E_ABNORMALAPIEXIT 0x800300FAL -#define STG_E_INVALIDHEADER 0x800300FBL -#define STG_E_INVALIDNAME 0x800300FCL -#define STG_E_UNKNOWN 0x800300FDL -#define STG_E_UNIMPLEMENTEDFUNCTION 0x800300FEL -#define STG_E_INVALIDFLAG 0x800300FFL -#define STG_E_INUSE 0x80030100L -#define STG_E_NOTCURRENT 0x80030101L -#define STG_E_REVERTED 0x80030102L -#define STG_E_CANTSAVE 0x80030103L -#define STG_E_OLDFORMAT 0x80030104L -#define STG_E_OLDDLL 0x80030105L -#define STG_E_SHAREREQUIRED 0x80030106L -#define STG_E_NOTFILEBASEDSTORAGE 0x80030107L -#define STG_E_EXTANTMARSHALLINGS 0x80030108L -#define STG_S_CONVERTED 0x00030200L -#define RPC_E_CALL_REJECTED 0x80010001L -#define RPC_E_CALL_CANCELED 0x80010002L -#define RPC_E_CANTPOST_INSENDCALL 0x80010003L -#define RPC_E_CANTCALLOUT_INASYNCCALL 0x80010004L -#define RPC_E_CANTCALLOUT_INEXTERNALCALL 0x80010005L -#define RPC_E_CONNECTION_TERMINATED 0x80010006L -#define RPC_E_SERVER_DIED 0x80010007L -#define RPC_E_CLIENT_DIED 0x80010008L -#define RPC_E_INVALID_DATAPACKET 0x80010009L -#define RPC_E_CANTTRANSMIT_CALL 0x8001000AL -#define RPC_E_CLIENT_CANTMARSHAL_DATA 0x8001000BL -#define RPC_E_CLIENT_CANTUNMARSHAL_DATA 0x8001000CL -#define RPC_E_SERVER_CANTMARSHAL_DATA 0x8001000DL -#define RPC_E_SERVER_CANTUNMARSHAL_DATA 0x8001000EL -#define RPC_E_INVALID_DATA 0x8001000FL -#define RPC_E_INVALID_PARAMETER 0x80010010L -#define RPC_E_CANTCALLOUT_AGAIN 0x80010011L -#define RPC_E_SERVER_DIED_DNE 0x80010012L -#define RPC_E_SYS_CALL_FAILED 0x80010100L -#define RPC_E_OUT_OF_RESOURCES 0x80010101L -#define RPC_E_ATTEMPTED_MULTITHREAD 0x80010102L -#define RPC_E_NOT_REGISTERED 0x80010103L -#define RPC_E_FAULT 0x80010104L -#define RPC_E_SERVERFAULT 0x80010105L -#define RPC_E_CHANGED_MODE 0x80010106L -#define RPC_E_INVALIDMETHOD 0x80010107L -#define RPC_E_DISCONNECTED 0x80010108L -#define RPC_E_RETRY 0x80010109L -#define RPC_E_SERVERCALL_RETRYLATER 0x8001010AL -#define RPC_E_SERVERCALL_REJECTED 0x8001010BL -#define RPC_E_INVALID_CALLDATA 0x8001010CL -#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL 0x8001010DL -#define RPC_E_WRONG_THREAD 0x8001010EL -#define RPC_E_THREAD_NOT_INIT 0x8001010FL -#define RPC_E_UNEXPECTED 0x8001FFFFL - -#define NTE_BAD_UID 0x80090001L -#define NTE_BAD_HASH 0x80090002L -#define NTE_BAD_KEY 0x80090003L -#define NTE_BAD_LEN 0x80090004L -#define NTE_BAD_DATA 0x80090005L -#define NTE_BAD_SIGNATURE 0x80090006L -#define NTE_BAD_VER 0x80090007L -#define NTE_BAD_ALGID 0x80090008L -#define NTE_BAD_FLAGS 0x80090009L -#define NTE_BAD_TYPE 0x8009000AL -#define NTE_BAD_KEY_STATE 0x8009000BL -#define NTE_BAD_HASH_STATE 0x8009000CL -#define NTE_NO_KEY 0x8009000DL -#define NTE_NO_MEMORY 0x8009000EL -#define NTE_EXISTS 0x8009000FL -#define NTE_PERM 0x80090010L -#define NTE_NOT_FOUND 0x80090011L -#define NTE_DOUBLE_ENCRYPT 0x80090012L -#define NTE_BAD_PROVIDER 0x80090013L -#define NTE_BAD_PROV_TYPE 0x80090014L -#define NTE_BAD_PUBLIC_KEY 0x80090015L -#define NTE_BAD_KEYSET 0x80090016L -#define NTE_PROV_TYPE_NOT_DEF 0x80090017L -#define NTE_PROV_TYPE_ENTRY_BAD 0x80090018L -#define NTE_KEYSET_NOT_DEF 0x80090019L -#define NTE_KEYSET_ENTRY_BAD 0x8009001AL -#define NTE_PROV_TYPE_NO_MATCH 0x8009001BL -#define NTE_SIGNATURE_FILE_BAD 0x8009001CL -#define NTE_PROVIDER_DLL_FAIL 0x8009001DL -#define NTE_PROV_DLL_NOT_FOUND 0x8009001EL -#define NTE_BAD_KEYSET_PARAM 0x8009001FL -#define NTE_FAIL 0x80090020L -#define NTE_SYS_ERR 0x80090021L -/* #define NTE_TOKEN_KEYSET_STORAGE ??? */ - -#endif +#define CO_E_NOTINITIALIZED _HRESULT_TYPEDEF_(0x800401F0L) +#define CO_E_ALREADYINITIALIZED _HRESULT_TYPEDEF_(0x800401F1L) +#define CO_E_CANTDETERMINECLASS _HRESULT_TYPEDEF_(0x800401F2L) +#define CO_E_CLASSSTRING _HRESULT_TYPEDEF_(0x800401F3L) +#define CO_E_IIDSTRING _HRESULT_TYPEDEF_(0x800401F4L) +#define CO_E_APPNOTFOUND _HRESULT_TYPEDEF_(0x800401F5L) +#define CO_E_APPSINGLEUSE _HRESULT_TYPEDEF_(0x800401F6L) +#define CO_E_ERRORINAPP _HRESULT_TYPEDEF_(0x800401F7L) +#define CO_E_DLLNOTFOUND _HRESULT_TYPEDEF_(0x800401F8L) +#define CO_E_ERRORINDLL _HRESULT_TYPEDEF_(0x800401F9L) +#define CO_E_WRONGOSFORAPP _HRESULT_TYPEDEF_(0x800401FAL) +#define CO_E_OBJNOTREG _HRESULT_TYPEDEF_(0x800401FBL) +#define CO_E_OBJISREG _HRESULT_TYPEDEF_(0x800401FCL) +#define CO_E_OBJNOTCONNECTED _HRESULT_TYPEDEF_(0x800401FDL) +#define CO_E_APPDIDNTREG _HRESULT_TYPEDEF_(0x800401FEL) +#define CO_E_RELEASED _HRESULT_TYPEDEF_(0x800401FFL) +#define EVENT_E_FIRST 0x80040200L +#define EVENT_E_LAST 0x8004021FL +#define EVENT_S_FIRST 0x00040200L +#define EVENT_S_LAST 0x0004021FL +#define EVENT_S_SOME_SUBSCRIBERS_FAILED _HRESULT_TYPEDEF_(0x00040200L) +#define EVENT_E_ALL_SUBSCRIBERS_FAILED _HRESULT_TYPEDEF_(0x80040201L) +#define EVENT_S_NOSUBSCRIBERS _HRESULT_TYPEDEF_(0x00040202L) +#define EVENT_E_QUERYSYNTAX _HRESULT_TYPEDEF_(0x80040203L) +#define EVENT_E_QUERYFIELD _HRESULT_TYPEDEF_(0x80040204L) +#define EVENT_E_INTERNALEXCEPTION _HRESULT_TYPEDEF_(0x80040205L) +#define EVENT_E_INTERNALERROR _HRESULT_TYPEDEF_(0x80040206L) +#define EVENT_E_INVALID_PER_USER_SID _HRESULT_TYPEDEF_(0x80040207L) +#define EVENT_E_USER_EXCEPTION _HRESULT_TYPEDEF_(0x80040208L) +#define EVENT_E_TOO_MANY_METHODS _HRESULT_TYPEDEF_(0x80040209L) +#define EVENT_E_MISSING_EVENTCLASS _HRESULT_TYPEDEF_(0x8004020AL) +#define EVENT_E_NOT_ALL_REMOVED _HRESULT_TYPEDEF_(0x8004020BL) +#define EVENT_E_COMPLUS_NOT_INSTALLED _HRESULT_TYPEDEF_(0x8004020CL) +#define EVENT_E_CANT_MODIFY_OR_DELETE_UNCONFIGURED_OBJECT _HRESULT_TYPEDEF_(0x8004020DL) +#define EVENT_E_CANT_MODIFY_OR_DELETE_CONFIGURED_OBJECT _HRESULT_TYPEDEF_(0x8004020EL) +#define EVENT_E_INVALID_EVENT_CLASS_PARTITION _HRESULT_TYPEDEF_(0x8004020FL) +#define EVENT_E_PER_USER_SID_NOT_LOGGED_ON _HRESULT_TYPEDEF_(0x80040210L) +#define XACT_E_FIRST 0x8004D000 +#define XACT_E_LAST 0x8004D029 +#define XACT_S_FIRST 0x0004D000 +#define XACT_S_LAST 0x0004D010 +#define XACT_E_ALREADYOTHERSINGLEPHASE _HRESULT_TYPEDEF_(0x8004D000L) +#define XACT_E_CANTRETAIN _HRESULT_TYPEDEF_(0x8004D001L) +#define XACT_E_COMMITFAILED _HRESULT_TYPEDEF_(0x8004D002L) +#define XACT_E_COMMITPREVENTED _HRESULT_TYPEDEF_(0x8004D003L) +#define XACT_E_HEURISTICABORT _HRESULT_TYPEDEF_(0x8004D004L) +#define XACT_E_HEURISTICCOMMIT _HRESULT_TYPEDEF_(0x8004D005L) +#define XACT_E_HEURISTICDAMAGE _HRESULT_TYPEDEF_(0x8004D006L) +#define XACT_E_HEURISTICDANGER _HRESULT_TYPEDEF_(0x8004D007L) +#define XACT_E_ISOLATIONLEVEL _HRESULT_TYPEDEF_(0x8004D008L) +#define XACT_E_NOASYNC _HRESULT_TYPEDEF_(0x8004D009L) +#define XACT_E_NOENLIST _HRESULT_TYPEDEF_(0x8004D00AL) +#define XACT_E_NOISORETAIN _HRESULT_TYPEDEF_(0x8004D00BL) +#define XACT_E_NORESOURCE _HRESULT_TYPEDEF_(0x8004D00CL) +#define XACT_E_NOTCURRENT _HRESULT_TYPEDEF_(0x8004D00DL) +#define XACT_E_NOTRANSACTION _HRESULT_TYPEDEF_(0x8004D00EL) +#define XACT_E_NOTSUPPORTED _HRESULT_TYPEDEF_(0x8004D00FL) +#define XACT_E_UNKNOWNRMGRID _HRESULT_TYPEDEF_(0x8004D010L) +#define XACT_E_WRONGSTATE _HRESULT_TYPEDEF_(0x8004D011L) +#define XACT_E_WRONGUOW _HRESULT_TYPEDEF_(0x8004D012L) +#define XACT_E_XTIONEXISTS _HRESULT_TYPEDEF_(0x8004D013L) +#define XACT_E_NOIMPORTOBJECT _HRESULT_TYPEDEF_(0x8004D014L) +#define XACT_E_INVALIDCOOKIE _HRESULT_TYPEDEF_(0x8004D015L) +#define XACT_E_INDOUBT _HRESULT_TYPEDEF_(0x8004D016L) +#define XACT_E_NOTIMEOUT _HRESULT_TYPEDEF_(0x8004D017L) +#define XACT_E_ALREADYINPROGRESS _HRESULT_TYPEDEF_(0x8004D018L) +#define XACT_E_ABORTED _HRESULT_TYPEDEF_(0x8004D019L) +#define XACT_E_LOGFULL _HRESULT_TYPEDEF_(0x8004D01AL) +#define XACT_E_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004D01BL) +#define XACT_E_CONNECTION_DOWN _HRESULT_TYPEDEF_(0x8004D01CL) +#define XACT_E_CONNECTION_DENIED _HRESULT_TYPEDEF_(0x8004D01DL) +#define XACT_E_REENLISTTIMEOUT _HRESULT_TYPEDEF_(0x8004D01EL) +#define XACT_E_TIP_CONNECT_FAILED _HRESULT_TYPEDEF_(0x8004D01FL) +#define XACT_E_TIP_PROTOCOL_ERROR _HRESULT_TYPEDEF_(0x8004D020L) +#define XACT_E_TIP_PULL_FAILED _HRESULT_TYPEDEF_(0x8004D021L) +#define XACT_E_DEST_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004D022L) +#define XACT_E_TIP_DISABLED _HRESULT_TYPEDEF_(0x8004D023L) +#define XACT_E_NETWORK_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D024L) +#define XACT_E_PARTNER_NETWORK_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D025L) +#define XACT_E_XA_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D026L) +#define XACT_E_UNABLE_TO_READ_DTC_CONFIG _HRESULT_TYPEDEF_(0x8004D027L) +#define XACT_E_UNABLE_TO_LOAD_DTC_PROXY _HRESULT_TYPEDEF_(0x8004D028L) +#define XACT_E_ABORTING _HRESULT_TYPEDEF_(0x8004D029L) +#define XACT_E_CLERKNOTFOUND _HRESULT_TYPEDEF_(0x8004D080L) +#define XACT_E_CLERKEXISTS _HRESULT_TYPEDEF_(0x8004D081L) +#define XACT_E_RECOVERYINPROGRESS _HRESULT_TYPEDEF_(0x8004D082L) +#define XACT_E_TRANSACTIONCLOSED _HRESULT_TYPEDEF_(0x8004D083L) +#define XACT_E_INVALIDLSN _HRESULT_TYPEDEF_(0x8004D084L) +#define XACT_E_REPLAYREQUEST _HRESULT_TYPEDEF_(0x8004D085L) +#define XACT_S_ASYNC _HRESULT_TYPEDEF_(0x0004D000L) +#define XACT_S_DEFECT _HRESULT_TYPEDEF_(0x0004D001L) +#define XACT_S_READONLY _HRESULT_TYPEDEF_(0x0004D002L) +#define XACT_S_SOMENORETAIN _HRESULT_TYPEDEF_(0x0004D003L) +#define XACT_S_OKINFORM _HRESULT_TYPEDEF_(0x0004D004L) +#define XACT_S_MADECHANGESCONTENT _HRESULT_TYPEDEF_(0x0004D005L) +#define XACT_S_MADECHANGESINFORM _HRESULT_TYPEDEF_(0x0004D006L) +#define XACT_S_ALLNORETAIN _HRESULT_TYPEDEF_(0x0004D007L) +#define XACT_S_ABORTING _HRESULT_TYPEDEF_(0x0004D008L) +#define XACT_S_SINGLEPHASE _HRESULT_TYPEDEF_(0x0004D009L) +#define XACT_S_LOCALLY_OK _HRESULT_TYPEDEF_(0x0004D00AL) +#define XACT_S_LASTRESOURCEMANAGER _HRESULT_TYPEDEF_(0x0004D010L) +#define CONTEXT_E_FIRST 0x8004E000L +#define CONTEXT_E_LAST 0x8004E02FL +#define CONTEXT_S_FIRST 0x0004E000L +#define CONTEXT_S_LAST 0x0004E02FL +#define CONTEXT_E_ABORTED _HRESULT_TYPEDEF_(0x8004E002L) +#define CONTEXT_E_ABORTING _HRESULT_TYPEDEF_(0x8004E003L) +#define CONTEXT_E_NOCONTEXT _HRESULT_TYPEDEF_(0x8004E004L) +#define CONTEXT_E_WOULD_DEADLOCK _HRESULT_TYPEDEF_(0x8004E005L) +#define CONTEXT_E_SYNCH_TIMEOUT _HRESULT_TYPEDEF_(0x8004E006L) +#define CONTEXT_E_OLDREF _HRESULT_TYPEDEF_(0x8004E007L) +#define CONTEXT_E_ROLENOTFOUND _HRESULT_TYPEDEF_(0x8004E00CL) +#define CONTEXT_E_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004E00FL) +#define CO_E_ACTIVATIONFAILED _HRESULT_TYPEDEF_(0x8004E021L) +#define CO_E_ACTIVATIONFAILED_EVENTLOGGED _HRESULT_TYPEDEF_(0x8004E022L) +#define CO_E_ACTIVATIONFAILED_CATALOGERROR _HRESULT_TYPEDEF_(0x8004E023L) +#define CO_E_ACTIVATIONFAILED_TIMEOUT _HRESULT_TYPEDEF_(0x8004E024L) +#define CO_E_INITIALIZATIONFAILED _HRESULT_TYPEDEF_(0x8004E025L) +#define CONTEXT_E_NOJIT _HRESULT_TYPEDEF_(0x8004E026L) +#define CONTEXT_E_NOTRANSACTION _HRESULT_TYPEDEF_(0x8004E027L) +#define CO_E_THREADINGMODEL_CHANGED _HRESULT_TYPEDEF_(0x8004E028L) +#define CO_E_NOIISINTRINSICS _HRESULT_TYPEDEF_(0x8004E029L) +#define CO_E_NOCOOKIES _HRESULT_TYPEDEF_(0x8004E02AL) +#define CO_E_DBERROR _HRESULT_TYPEDEF_(0x8004E02BL) +#define CO_E_NOTPOOLED _HRESULT_TYPEDEF_(0x8004E02CL) +#define CO_E_NOTCONSTRUCTED _HRESULT_TYPEDEF_(0x8004E02DL) +#define CO_E_NOSYNCHRONIZATION _HRESULT_TYPEDEF_(0x8004E02EL) +#define CO_E_ISOLEVELMISMATCH _HRESULT_TYPEDEF_(0x8004E02FL) +#define OLE_S_USEREG _HRESULT_TYPEDEF_(0x00040000L) +#define OLE_S_STATIC _HRESULT_TYPEDEF_(0x00040001L) +#define OLE_S_MAC_CLIPFORMAT _HRESULT_TYPEDEF_(0x00040002L) +#define DRAGDROP_S_DROP _HRESULT_TYPEDEF_(0x00040100L) +#define DRAGDROP_S_CANCEL _HRESULT_TYPEDEF_(0x00040101L) +#define DRAGDROP_S_USEDEFAULTCURSORS _HRESULT_TYPEDEF_(0x00040102L) +#define DATA_S_SAMEFORMATETC _HRESULT_TYPEDEF_(0x00040130L) +#define VIEW_S_ALREADY_FROZEN _HRESULT_TYPEDEF_(0x00040140L) +#define CACHE_S_FORMATETC_NOTSUPPORTED _HRESULT_TYPEDEF_(0x00040170L) +#define CACHE_S_SAMECACHE _HRESULT_TYPEDEF_(0x00040171L) +#define CACHE_S_SOMECACHES_NOTUPDATED _HRESULT_TYPEDEF_(0x00040172L) +#define OLEOBJ_S_INVALIDVERB _HRESULT_TYPEDEF_(0x00040180L) +#define OLEOBJ_S_CANNOT_DOVERB_NOW _HRESULT_TYPEDEF_(0x00040181L) +#define OLEOBJ_S_INVALIDHWND _HRESULT_TYPEDEF_(0x00040182L) +#define INPLACE_S_TRUNCATED _HRESULT_TYPEDEF_(0x000401A0L) +#define CONVERT10_S_NO_PRESENTATION _HRESULT_TYPEDEF_(0x000401C0L) +#define MK_S_REDUCED_TO_SELF _HRESULT_TYPEDEF_(0x000401E2L) +#define MK_S_ME _HRESULT_TYPEDEF_(0x000401E4L) +#define MK_S_HIM _HRESULT_TYPEDEF_(0x000401E5L) +#define MK_S_US _HRESULT_TYPEDEF_(0x000401E6L) +#define MK_S_MONIKERALREADYREGISTERED _HRESULT_TYPEDEF_(0x000401E7L) +#define SCHED_S_TASK_READY _HRESULT_TYPEDEF_(0x00041300L) +#define SCHED_S_TASK_RUNNING _HRESULT_TYPEDEF_(0x00041301L) +#define SCHED_S_TASK_DISABLED _HRESULT_TYPEDEF_(0x00041302L) +#define SCHED_S_TASK_HAS_NOT_RUN _HRESULT_TYPEDEF_(0x00041303L) +#define SCHED_S_TASK_NO_MORE_RUNS _HRESULT_TYPEDEF_(0x00041304L) +#define SCHED_S_TASK_NOT_SCHEDULED _HRESULT_TYPEDEF_(0x00041305L) +#define SCHED_S_TASK_TERMINATED _HRESULT_TYPEDEF_(0x00041306L) +#define SCHED_S_TASK_NO_VALID_TRIGGERS _HRESULT_TYPEDEF_(0x00041307L) +#define SCHED_S_EVENT_TRIGGER _HRESULT_TYPEDEF_(0x00041308L) +#define SCHED_E_TRIGGER_NOT_FOUND _HRESULT_TYPEDEF_(0x80041309L) +#define SCHED_E_TASK_NOT_READY _HRESULT_TYPEDEF_(0x8004130AL) +#define SCHED_E_TASK_NOT_RUNNING _HRESULT_TYPEDEF_(0x8004130BL) +#define SCHED_E_SERVICE_NOT_INSTALLED _HRESULT_TYPEDEF_(0x8004130CL) +#define SCHED_E_CANNOT_OPEN_TASK _HRESULT_TYPEDEF_(0x8004130DL) +#define SCHED_E_INVALID_TASK _HRESULT_TYPEDEF_(0x8004130EL) +#define SCHED_E_ACCOUNT_INFORMATION_NOT_SET _HRESULT_TYPEDEF_(0x8004130FL) +#define SCHED_E_ACCOUNT_NAME_NOT_FOUND _HRESULT_TYPEDEF_(0x80041310L) +#define SCHED_E_ACCOUNT_DBASE_CORRUPT _HRESULT_TYPEDEF_(0x80041311L) +#define SCHED_E_NO_SECURITY_SERVICES _HRESULT_TYPEDEF_(0x80041312L) +#define SCHED_E_UNKNOWN_OBJECT_VERSION _HRESULT_TYPEDEF_(0x80041313L) +#define SCHED_E_UNSUPPORTED_ACCOUNT_OPTION _HRESULT_TYPEDEF_(0x80041314L) +#define SCHED_E_SERVICE_NOT_RUNNING _HRESULT_TYPEDEF_(0x80041315L) +#define CO_E_CLASS_CREATE_FAILED _HRESULT_TYPEDEF_(0x80080001L) +#define CO_E_SCM_ERROR _HRESULT_TYPEDEF_(0x80080002L) +#define CO_E_SCM_RPC_FAILURE _HRESULT_TYPEDEF_(0x80080003L) +#define CO_E_BAD_PATH _HRESULT_TYPEDEF_(0x80080004L) +#define CO_E_SERVER_EXEC_FAILURE _HRESULT_TYPEDEF_(0x80080005L) +#define CO_E_OBJSRV_RPC_FAILURE _HRESULT_TYPEDEF_(0x80080006L) +#define MK_E_NO_NORMALIZED _HRESULT_TYPEDEF_(0x80080007L) +#define CO_E_SERVER_STOPPING _HRESULT_TYPEDEF_(0x80080008L) +#define MEM_E_INVALID_ROOT _HRESULT_TYPEDEF_(0x80080009L) +#define MEM_E_INVALID_LINK _HRESULT_TYPEDEF_(0x80080010L) +#define MEM_E_INVALID_SIZE _HRESULT_TYPEDEF_(0x80080011L) +#define CO_S_NOTALLINTERFACES _HRESULT_TYPEDEF_(0x00080012L) +#define CO_S_MACHINENAMENOTFOUND _HRESULT_TYPEDEF_(0x00080013L) +#define DISP_E_UNKNOWNINTERFACE _HRESULT_TYPEDEF_(0x80020001L) +#define DISP_E_MEMBERNOTFOUND _HRESULT_TYPEDEF_(0x80020003L) +#define DISP_E_PARAMNOTFOUND _HRESULT_TYPEDEF_(0x80020004L) +#define DISP_E_TYPEMISMATCH _HRESULT_TYPEDEF_(0x80020005L) +#define DISP_E_UNKNOWNNAME _HRESULT_TYPEDEF_(0x80020006L) +#define DISP_E_NONAMEDARGS _HRESULT_TYPEDEF_(0x80020007L) +#define DISP_E_BADVARTYPE _HRESULT_TYPEDEF_(0x80020008L) +#define DISP_E_EXCEPTION _HRESULT_TYPEDEF_(0x80020009L) +#define DISP_E_OVERFLOW _HRESULT_TYPEDEF_(0x8002000AL) +#define DISP_E_BADINDEX _HRESULT_TYPEDEF_(0x8002000BL) +#define DISP_E_UNKNOWNLCID _HRESULT_TYPEDEF_(0x8002000CL) +#define DISP_E_ARRAYISLOCKED _HRESULT_TYPEDEF_(0x8002000DL) +#define DISP_E_BADPARAMCOUNT _HRESULT_TYPEDEF_(0x8002000EL) +#define DISP_E_PARAMNOTOPTIONAL _HRESULT_TYPEDEF_(0x8002000FL) +#define DISP_E_BADCALLEE _HRESULT_TYPEDEF_(0x80020010L) +#define DISP_E_NOTACOLLECTION _HRESULT_TYPEDEF_(0x80020011L) +#define DISP_E_DIVBYZERO _HRESULT_TYPEDEF_(0x80020012L) +#define DISP_E_BUFFERTOOSMALL _HRESULT_TYPEDEF_(0x80020013L) +#define TYPE_E_BUFFERTOOSMALL _HRESULT_TYPEDEF_(0x80028016L) +#define TYPE_E_FIELDNOTFOUND _HRESULT_TYPEDEF_(0x80028017L) +#define TYPE_E_INVDATAREAD _HRESULT_TYPEDEF_(0x80028018L) +#define TYPE_E_UNSUPFORMAT _HRESULT_TYPEDEF_(0x80028019L) +#define TYPE_E_REGISTRYACCESS _HRESULT_TYPEDEF_(0x8002801CL) +#define TYPE_E_LIBNOTREGISTERED _HRESULT_TYPEDEF_(0x8002801DL) +#define TYPE_E_UNDEFINEDTYPE _HRESULT_TYPEDEF_(0x80028027L) +#define TYPE_E_QUALIFIEDNAMEDISALLOWED _HRESULT_TYPEDEF_(0x80028028L) +#define TYPE_E_INVALIDSTATE _HRESULT_TYPEDEF_(0x80028029L) +#define TYPE_E_WRONGTYPEKIND _HRESULT_TYPEDEF_(0x8002802AL) +#define TYPE_E_ELEMENTNOTFOUND _HRESULT_TYPEDEF_(0x8002802BL) +#define TYPE_E_AMBIGUOUSNAME _HRESULT_TYPEDEF_(0x8002802CL) +#define TYPE_E_NAMECONFLICT _HRESULT_TYPEDEF_(0x8002802DL) +#define TYPE_E_UNKNOWNLCID _HRESULT_TYPEDEF_(0x8002802EL) +#define TYPE_E_DLLFUNCTIONNOTFOUND _HRESULT_TYPEDEF_(0x8002802FL) +#define TYPE_E_BADMODULEKIND _HRESULT_TYPEDEF_(0x800288BDL) +#define TYPE_E_SIZETOOBIG _HRESULT_TYPEDEF_(0x800288C5L) +#define TYPE_E_DUPLICATEID _HRESULT_TYPEDEF_(0x800288C6L) +#define TYPE_E_INVALIDID _HRESULT_TYPEDEF_(0x800288CFL) +#define TYPE_E_TYPEMISMATCH _HRESULT_TYPEDEF_(0x80028CA0L) +#define TYPE_E_OUTOFBOUNDS _HRESULT_TYPEDEF_(0x80028CA1L) +#define TYPE_E_IOERROR _HRESULT_TYPEDEF_(0x80028CA2L) +#define TYPE_E_CANTCREATETMPFILE _HRESULT_TYPEDEF_(0x80028CA3L) +#define TYPE_E_CANTLOADLIBRARY _HRESULT_TYPEDEF_(0x80029C4AL) +#define TYPE_E_INCONSISTENTPROPFUNCS _HRESULT_TYPEDEF_(0x80029C83L) +#define TYPE_E_CIRCULARTYPE _HRESULT_TYPEDEF_(0x80029C84L) +#define STG_E_INVALIDFUNCTION _HRESULT_TYPEDEF_(0x80030001L) +#define STG_E_FILENOTFOUND _HRESULT_TYPEDEF_(0x80030002L) +#define STG_E_PATHNOTFOUND _HRESULT_TYPEDEF_(0x80030003L) +#define STG_E_TOOMANYOPENFILES _HRESULT_TYPEDEF_(0x80030004L) +#define STG_E_ACCESSDENIED _HRESULT_TYPEDEF_(0x80030005L) +#define STG_E_INVALIDHANDLE _HRESULT_TYPEDEF_(0x80030006L) +#define STG_E_INSUFFICIENTMEMORY _HRESULT_TYPEDEF_(0x80030008L) +#define STG_E_INVALIDPOINTER _HRESULT_TYPEDEF_(0x80030009L) +#define STG_E_NOMOREFILES _HRESULT_TYPEDEF_(0x80030012L) +#define STG_E_DISKISWRITEPROTECTED _HRESULT_TYPEDEF_(0x80030013L) +#define STG_E_SEEKERROR _HRESULT_TYPEDEF_(0x80030019L) +#define STG_E_WRITEFAULT _HRESULT_TYPEDEF_(0x8003001DL) +#define STG_E_READFAULT _HRESULT_TYPEDEF_(0x8003001EL) +#define STG_E_SHAREVIOLATION _HRESULT_TYPEDEF_(0x80030020L) +#define STG_E_LOCKVIOLATION _HRESULT_TYPEDEF_(0x80030021L) +#define STG_E_FILEALREADYEXISTS _HRESULT_TYPEDEF_(0x80030050L) +#define STG_E_INVALIDPARAMETER _HRESULT_TYPEDEF_(0x80030057L) +#define STG_E_MEDIUMFULL _HRESULT_TYPEDEF_(0x80030070L) +#define STG_E_PROPSETMISMATCHED _HRESULT_TYPEDEF_(0x800300F0L) +#define STG_E_ABNORMALAPIEXIT _HRESULT_TYPEDEF_(0x800300FAL) +#define STG_E_INVALIDHEADER _HRESULT_TYPEDEF_(0x800300FBL) +#define STG_E_INVALIDNAME _HRESULT_TYPEDEF_(0x800300FCL) +#define STG_E_UNKNOWN _HRESULT_TYPEDEF_(0x800300FDL) +#define STG_E_UNIMPLEMENTEDFUNCTION _HRESULT_TYPEDEF_(0x800300FEL) +#define STG_E_INVALIDFLAG _HRESULT_TYPEDEF_(0x800300FFL) +#define STG_E_INUSE _HRESULT_TYPEDEF_(0x80030100L) +#define STG_E_NOTCURRENT _HRESULT_TYPEDEF_(0x80030101L) +#define STG_E_REVERTED _HRESULT_TYPEDEF_(0x80030102L) +#define STG_E_CANTSAVE _HRESULT_TYPEDEF_(0x80030103L) +#define STG_E_OLDFORMAT _HRESULT_TYPEDEF_(0x80030104L) +#define STG_E_OLDDLL _HRESULT_TYPEDEF_(0x80030105L) +#define STG_E_SHAREREQUIRED _HRESULT_TYPEDEF_(0x80030106L) +#define STG_E_NOTFILEBASEDSTORAGE _HRESULT_TYPEDEF_(0x80030107L) +#define STG_E_EXTANTMARSHALLINGS _HRESULT_TYPEDEF_(0x80030108L) +#define STG_E_DOCFILECORRUPT _HRESULT_TYPEDEF_(0x80030109L) +#define STG_E_BADBASEADDRESS _HRESULT_TYPEDEF_(0x80030110L) +#define STG_E_DOCFILETOOLARGE _HRESULT_TYPEDEF_(0x80030111L) +#define STG_E_NOTSIMPLEFORMAT _HRESULT_TYPEDEF_(0x80030112L) +#define STG_E_INCOMPLETE _HRESULT_TYPEDEF_(0x80030201L) +#define STG_E_TERMINATED _HRESULT_TYPEDEF_(0x80030202L) +#define STG_S_CONVERTED _HRESULT_TYPEDEF_(0x00030200L) +#define STG_S_BLOCK _HRESULT_TYPEDEF_(0x00030201L) +#define STG_S_RETRYNOW _HRESULT_TYPEDEF_(0x00030202L) +#define STG_S_MONITORING _HRESULT_TYPEDEF_(0x00030203L) +#define STG_S_MULTIPLEOPENS _HRESULT_TYPEDEF_(0x00030204L) +#define STG_S_CONSOLIDATIONFAILED _HRESULT_TYPEDEF_(0x00030205L) +#define STG_S_CANNOTCONSOLIDATE _HRESULT_TYPEDEF_(0x00030206L) +#define STG_E_STATUS_COPY_PROTECTION_FAILURE _HRESULT_TYPEDEF_(0x80030305L) +#define STG_E_CSS_AUTHENTICATION_FAILURE _HRESULT_TYPEDEF_(0x80030306L) +#define STG_E_CSS_KEY_NOT_PRESENT _HRESULT_TYPEDEF_(0x80030307L) +#define STG_E_CSS_KEY_NOT_ESTABLISHED _HRESULT_TYPEDEF_(0x80030308L) +#define STG_E_CSS_SCRAMBLED_SECTOR _HRESULT_TYPEDEF_(0x80030309L) +#define STG_E_CSS_REGION_MISMATCH _HRESULT_TYPEDEF_(0x8003030AL) +#define STG_E_RESETS_EXHAUSTED _HRESULT_TYPEDEF_(0x8003030BL) +#define RPC_E_CALL_REJECTED _HRESULT_TYPEDEF_(0x80010001L) +#define RPC_E_CALL_CANCELED _HRESULT_TYPEDEF_(0x80010002L) +#define RPC_E_CANTPOST_INSENDCALL _HRESULT_TYPEDEF_(0x80010003L) +#define RPC_E_CANTCALLOUT_INASYNCCALL _HRESULT_TYPEDEF_(0x80010004L) +#define RPC_E_CANTCALLOUT_INEXTERNALCALL _HRESULT_TYPEDEF_(0x80010005L) +#define RPC_E_CONNECTION_TERMINATED _HRESULT_TYPEDEF_(0x80010006L) +#define RPC_E_SERVER_DIED _HRESULT_TYPEDEF_(0x80010007L) +#define RPC_E_CLIENT_DIED _HRESULT_TYPEDEF_(0x80010008L) +#define RPC_E_INVALID_DATAPACKET _HRESULT_TYPEDEF_(0x80010009L) +#define RPC_E_CANTTRANSMIT_CALL _HRESULT_TYPEDEF_(0x8001000AL) +#define RPC_E_CLIENT_CANTMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000BL) +#define RPC_E_CLIENT_CANTUNMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000CL) +#define RPC_E_SERVER_CANTMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000DL) +#define RPC_E_SERVER_CANTUNMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000EL) +#define RPC_E_INVALID_DATA _HRESULT_TYPEDEF_(0x8001000FL) +#define RPC_E_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80010010L) +#define RPC_E_CANTCALLOUT_AGAIN _HRESULT_TYPEDEF_(0x80010011L) +#define RPC_E_SERVER_DIED_DNE _HRESULT_TYPEDEF_(0x80010012L) +#define RPC_E_SYS_CALL_FAILED _HRESULT_TYPEDEF_(0x80010100L) +#define RPC_E_OUT_OF_RESOURCES _HRESULT_TYPEDEF_(0x80010101L) +#define RPC_E_ATTEMPTED_MULTITHREAD _HRESULT_TYPEDEF_(0x80010102L) +#define RPC_E_NOT_REGISTERED _HRESULT_TYPEDEF_(0x80010103L) +#define RPC_E_FAULT _HRESULT_TYPEDEF_(0x80010104L) +#define RPC_E_SERVERFAULT _HRESULT_TYPEDEF_(0x80010105L) +#define RPC_E_CHANGED_MODE _HRESULT_TYPEDEF_(0x80010106L) +#define RPC_E_INVALIDMETHOD _HRESULT_TYPEDEF_(0x80010107L) +#define RPC_E_DISCONNECTED _HRESULT_TYPEDEF_(0x80010108L) +#define RPC_E_RETRY _HRESULT_TYPEDEF_(0x80010109L) +#define RPC_E_SERVERCALL_RETRYLATER _HRESULT_TYPEDEF_(0x8001010AL) +#define RPC_E_SERVERCALL_REJECTED _HRESULT_TYPEDEF_(0x8001010BL) +#define RPC_E_INVALID_CALLDATA _HRESULT_TYPEDEF_(0x8001010CL) +#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL _HRESULT_TYPEDEF_(0x8001010DL) +#define RPC_E_WRONG_THREAD _HRESULT_TYPEDEF_(0x8001010EL) +#define RPC_E_THREAD_NOT_INIT _HRESULT_TYPEDEF_(0x8001010FL) +#define RPC_E_VERSION_MISMATCH _HRESULT_TYPEDEF_(0x80010110L) +#define RPC_E_INVALID_HEADER _HRESULT_TYPEDEF_(0x80010111L) +#define RPC_E_INVALID_EXTENSION _HRESULT_TYPEDEF_(0x80010112L) +#define RPC_E_INVALID_IPID _HRESULT_TYPEDEF_(0x80010113L) +#define RPC_E_INVALID_OBJECT _HRESULT_TYPEDEF_(0x80010114L) +#define RPC_S_CALLPENDING _HRESULT_TYPEDEF_(0x80010115L) +#define RPC_S_WAITONTIMER _HRESULT_TYPEDEF_(0x80010116L) +#define RPC_E_CALL_COMPLETE _HRESULT_TYPEDEF_(0x80010117L) +#define RPC_E_UNSECURE_CALL _HRESULT_TYPEDEF_(0x80010118L) +#define RPC_E_TOO_LATE _HRESULT_TYPEDEF_(0x80010119L) +#define RPC_E_NO_GOOD_SECURITY_PACKAGES _HRESULT_TYPEDEF_(0x8001011AL) +#define RPC_E_ACCESS_DENIED _HRESULT_TYPEDEF_(0x8001011BL) +#define RPC_E_REMOTE_DISABLED _HRESULT_TYPEDEF_(0x8001011CL) +#define RPC_E_INVALID_OBJREF _HRESULT_TYPEDEF_(0x8001011DL) +#define RPC_E_NO_CONTEXT _HRESULT_TYPEDEF_(0x8001011EL) +#define RPC_E_TIMEOUT _HRESULT_TYPEDEF_(0x8001011FL) +#define RPC_E_NO_SYNC _HRESULT_TYPEDEF_(0x80010120L) +#define RPC_E_FULLSIC_REQUIRED _HRESULT_TYPEDEF_(0x80010121L) +#define RPC_E_INVALID_STD_NAME _HRESULT_TYPEDEF_(0x80010122L) +#define CO_E_FAILEDTOIMPERSONATE _HRESULT_TYPEDEF_(0x80010123L) +#define CO_E_FAILEDTOGETSECCTX _HRESULT_TYPEDEF_(0x80010124L) +#define CO_E_FAILEDTOOPENTHREADTOKEN _HRESULT_TYPEDEF_(0x80010125L) +#define CO_E_FAILEDTOGETTOKENINFO _HRESULT_TYPEDEF_(0x80010126L) +#define CO_E_TRUSTEEDOESNTMATCHCLIENT _HRESULT_TYPEDEF_(0x80010127L) +#define CO_E_FAILEDTOQUERYCLIENTBLANKET _HRESULT_TYPEDEF_(0x80010128L) +#define CO_E_FAILEDTOSETDACL _HRESULT_TYPEDEF_(0x80010129L) +#define CO_E_ACCESSCHECKFAILED _HRESULT_TYPEDEF_(0x8001012AL) +#define CO_E_NETACCESSAPIFAILED _HRESULT_TYPEDEF_(0x8001012BL) +#define CO_E_WRONGTRUSTEENAMESYNTAX _HRESULT_TYPEDEF_(0x8001012CL) +#define CO_E_INVALIDSID _HRESULT_TYPEDEF_(0x8001012DL) +#define CO_E_CONVERSIONFAILED _HRESULT_TYPEDEF_(0x8001012EL) +#define CO_E_NOMATCHINGSIDFOUND _HRESULT_TYPEDEF_(0x8001012FL) +#define CO_E_LOOKUPACCSIDFAILED _HRESULT_TYPEDEF_(0x80010130L) +#define CO_E_NOMATCHINGNAMEFOUND _HRESULT_TYPEDEF_(0x80010131L) +#define CO_E_LOOKUPACCNAMEFAILED _HRESULT_TYPEDEF_(0x80010132L) +#define CO_E_SETSERLHNDLFAILED _HRESULT_TYPEDEF_(0x80010133L) +#define CO_E_FAILEDTOGETWINDIR _HRESULT_TYPEDEF_(0x80010134L) +#define CO_E_PATHTOOLONG _HRESULT_TYPEDEF_(0x80010135L) +#define CO_E_FAILEDTOGENUUID _HRESULT_TYPEDEF_(0x80010136L) +#define CO_E_FAILEDTOCREATEFILE _HRESULT_TYPEDEF_(0x80010137L) +#define CO_E_FAILEDTOCLOSEHANDLE _HRESULT_TYPEDEF_(0x80010138L) +#define CO_E_EXCEEDSYSACLLIMIT _HRESULT_TYPEDEF_(0x80010139L) +#define CO_E_ACESINWRONGORDER _HRESULT_TYPEDEF_(0x8001013AL) +#define CO_E_INCOMPATIBLESTREAMVERSION _HRESULT_TYPEDEF_(0x8001013BL) +#define CO_E_FAILEDTOOPENPROCESSTOKEN _HRESULT_TYPEDEF_(0x8001013CL) +#define CO_E_DECODEFAILED _HRESULT_TYPEDEF_(0x8001013DL) +#define CO_E_ACNOTINITIALIZED _HRESULT_TYPEDEF_(0x8001013FL) +#define CO_E_CANCEL_DISABLED _HRESULT_TYPEDEF_(0x80010140L) +#define RPC_E_UNEXPECTED _HRESULT_TYPEDEF_(0x8001FFFFL) +#define ERROR_AUDITING_DISABLED _HRESULT_TYPEDEF_(0xC0090001L) +#define ERROR_ALL_SIDS_FILTERED _HRESULT_TYPEDEF_(0xC0090002L) +#define NTE_BAD_UID _HRESULT_TYPEDEF_(0x80090001L) +#define NTE_BAD_HASH _HRESULT_TYPEDEF_(0x80090002L) +#define NTE_BAD_KEY _HRESULT_TYPEDEF_(0x80090003L) +#define NTE_BAD_LEN _HRESULT_TYPEDEF_(0x80090004L) +#define NTE_BAD_DATA _HRESULT_TYPEDEF_(0x80090005L) +#define NTE_BAD_SIGNATURE _HRESULT_TYPEDEF_(0x80090006L) +#define NTE_BAD_VER _HRESULT_TYPEDEF_(0x80090007L) +#define NTE_BAD_ALGID _HRESULT_TYPEDEF_(0x80090008L) +#define NTE_BAD_FLAGS _HRESULT_TYPEDEF_(0x80090009L) +#define NTE_BAD_TYPE _HRESULT_TYPEDEF_(0x8009000AL) +#define NTE_BAD_KEY_STATE _HRESULT_TYPEDEF_(0x8009000BL) +#define NTE_BAD_HASH_STATE _HRESULT_TYPEDEF_(0x8009000CL) +#define NTE_NO_KEY _HRESULT_TYPEDEF_(0x8009000DL) +#define NTE_NO_MEMORY _HRESULT_TYPEDEF_(0x8009000EL) +#define NTE_EXISTS _HRESULT_TYPEDEF_(0x8009000FL) +#define NTE_PERM _HRESULT_TYPEDEF_(0x80090010L) +#define NTE_NOT_FOUND _HRESULT_TYPEDEF_(0x80090011L) +#define NTE_DOUBLE_ENCRYPT _HRESULT_TYPEDEF_(0x80090012L) +#define NTE_BAD_PROVIDER _HRESULT_TYPEDEF_(0x80090013L) +#define NTE_BAD_PROV_TYPE _HRESULT_TYPEDEF_(0x80090014L) +#define NTE_BAD_PUBLIC_KEY _HRESULT_TYPEDEF_(0x80090015L) +#define NTE_BAD_KEYSET _HRESULT_TYPEDEF_(0x80090016L) +#define NTE_PROV_TYPE_NOT_DEF _HRESULT_TYPEDEF_(0x80090017L) +#define NTE_PROV_TYPE_ENTRY_BAD _HRESULT_TYPEDEF_(0x80090018L) +#define NTE_KEYSET_NOT_DEF _HRESULT_TYPEDEF_(0x80090019L) +#define NTE_KEYSET_ENTRY_BAD _HRESULT_TYPEDEF_(0x8009001AL) +#define NTE_PROV_TYPE_NO_MATCH _HRESULT_TYPEDEF_(0x8009001BL) +#define NTE_SIGNATURE_FILE_BAD _HRESULT_TYPEDEF_(0x8009001CL) +#define NTE_PROVIDER_DLL_FAIL _HRESULT_TYPEDEF_(0x8009001DL) +#define NTE_PROV_DLL_NOT_FOUND _HRESULT_TYPEDEF_(0x8009001EL) +#define NTE_BAD_KEYSET_PARAM _HRESULT_TYPEDEF_(0x8009001FL) +#define NTE_FAIL _HRESULT_TYPEDEF_(0x80090020L) +#define NTE_SYS_ERR _HRESULT_TYPEDEF_(0x80090021L) +#define NTE_SILENT_CONTEXT _HRESULT_TYPEDEF_(0x80090022L) +#define NTE_TOKEN_KEYSET_STORAGE_FULL _HRESULT_TYPEDEF_(0x80090023L) +#define NTE_TEMPORARY_PROFILE _HRESULT_TYPEDEF_(0x80090024L) +#define NTE_FIXEDPARAMETER _HRESULT_TYPEDEF_(0x80090025L) +#define SEC_E_INSUFFICIENT_MEMORY _HRESULT_TYPEDEF_(0x80090300L) +#define SEC_E_INVALID_HANDLE _HRESULT_TYPEDEF_(0x80090301L) +#define SEC_E_UNSUPPORTED_FUNCTION _HRESULT_TYPEDEF_(0x80090302L) +#define SEC_E_TARGET_UNKNOWN _HRESULT_TYPEDEF_(0x80090303L) +#define SEC_E_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80090304L) +#define SEC_E_SECPKG_NOT_FOUND _HRESULT_TYPEDEF_(0x80090305L) +#define SEC_E_NOT_OWNER _HRESULT_TYPEDEF_(0x80090306L) +#define SEC_E_CANNOT_INSTALL _HRESULT_TYPEDEF_(0x80090307L) +#define SEC_E_INVALID_TOKEN _HRESULT_TYPEDEF_(0x80090308L) +#define SEC_E_CANNOT_PACK _HRESULT_TYPEDEF_(0x80090309L) +#define SEC_E_QOP_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009030AL) +#define SEC_E_NO_IMPERSONATION _HRESULT_TYPEDEF_(0x8009030BL) +#define SEC_E_LOGON_DENIED _HRESULT_TYPEDEF_(0x8009030CL) +#define SEC_E_UNKNOWN_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030DL) +#define SEC_E_NO_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030EL) +#define SEC_E_MESSAGE_ALTERED _HRESULT_TYPEDEF_(0x8009030FL) +#define SEC_E_OUT_OF_SEQUENCE _HRESULT_TYPEDEF_(0x80090310L) +#define SEC_E_NO_AUTHENTICATING_AUTHORITY _HRESULT_TYPEDEF_(0x80090311L) +#define SEC_I_CONTINUE_NEEDED _HRESULT_TYPEDEF_(0x00090312L) +#define SEC_I_COMPLETE_NEEDED _HRESULT_TYPEDEF_(0x00090313L) +#define SEC_I_COMPLETE_AND_CONTINUE _HRESULT_TYPEDEF_(0x00090314L) +#define SEC_I_LOCAL_LOGON _HRESULT_TYPEDEF_(0x00090315L) +#define SEC_E_BAD_PKGID _HRESULT_TYPEDEF_(0x80090316L) +#define SEC_E_CONTEXT_EXPIRED _HRESULT_TYPEDEF_(0x80090317L) +#define SEC_I_CONTEXT_EXPIRED _HRESULT_TYPEDEF_(0x00090317L) +#define SEC_E_INCOMPLETE_MESSAGE _HRESULT_TYPEDEF_(0x80090318L) +#define SEC_E_INCOMPLETE_CREDENTIALS _HRESULT_TYPEDEF_(0x80090320L) +#define SEC_E_BUFFER_TOO_SMALL _HRESULT_TYPEDEF_(0x80090321L) +#define SEC_I_INCOMPLETE_CREDENTIALS _HRESULT_TYPEDEF_(0x00090320L) +#define SEC_I_RENEGOTIATE _HRESULT_TYPEDEF_(0x00090321L) +#define SEC_E_WRONG_PRINCIPAL _HRESULT_TYPEDEF_(0x80090322L) +#define SEC_I_NO_LSA_CONTEXT _HRESULT_TYPEDEF_(0x00090323L) +#define SEC_E_TIME_SKEW _HRESULT_TYPEDEF_(0x80090324L) +#define SEC_E_UNTRUSTED_ROOT _HRESULT_TYPEDEF_(0x80090325L) +#define SEC_E_ILLEGAL_MESSAGE _HRESULT_TYPEDEF_(0x80090326L) +#define SEC_E_CERT_UNKNOWN _HRESULT_TYPEDEF_(0x80090327L) +#define SEC_E_CERT_EXPIRED _HRESULT_TYPEDEF_(0x80090328L) +#define SEC_E_ENCRYPT_FAILURE _HRESULT_TYPEDEF_(0x80090329L) +#define SEC_E_DECRYPT_FAILURE _HRESULT_TYPEDEF_(0x80090330L) +#define SEC_E_ALGORITHM_MISMATCH _HRESULT_TYPEDEF_(0x80090331L) +#define SEC_E_SECURITY_QOS_FAILED _HRESULT_TYPEDEF_(0x80090332L) +#define SEC_E_UNFINISHED_CONTEXT_DELETED _HRESULT_TYPEDEF_(0x80090333L) +#define SEC_E_NO_TGT_REPLY _HRESULT_TYPEDEF_(0x80090334L) +#define SEC_E_NO_IP_ADDRESSES _HRESULT_TYPEDEF_(0x80090335L) +#define SEC_E_WRONG_CREDENTIAL_HANDLE _HRESULT_TYPEDEF_(0x80090336L) +#define SEC_E_CRYPTO_SYSTEM_INVALID _HRESULT_TYPEDEF_(0x80090337L) +#define SEC_E_MAX_REFERRALS_EXCEEDED _HRESULT_TYPEDEF_(0x80090338L) +#define SEC_E_MUST_BE_KDC _HRESULT_TYPEDEF_(0x80090339L) +#define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009033AL) +#define SEC_E_TOO_MANY_PRINCIPALS _HRESULT_TYPEDEF_(0x8009033BL) +#define SEC_E_NO_PA_DATA _HRESULT_TYPEDEF_(0x8009033CL) +#define SEC_E_PKINIT_NAME_MISMATCH _HRESULT_TYPEDEF_(0x8009033DL) +#define SEC_E_SMARTCARD_LOGON_REQUIRED _HRESULT_TYPEDEF_(0x8009033EL) +#define SEC_E_SHUTDOWN_IN_PROGRESS _HRESULT_TYPEDEF_(0x8009033FL) +#define SEC_E_KDC_INVALID_REQUEST _HRESULT_TYPEDEF_(0x80090340L) +#define SEC_E_KDC_UNABLE_TO_REFER _HRESULT_TYPEDEF_(0x80090341L) +#define SEC_E_KDC_UNKNOWN_ETYPE _HRESULT_TYPEDEF_(0x80090342L) +#define SEC_E_UNSUPPORTED_PREAUTH _HRESULT_TYPEDEF_(0x80090343L) +#define SEC_E_DELEGATION_REQUIRED _HRESULT_TYPEDEF_(0x80090345L) +#define SEC_E_BAD_BINDINGS _HRESULT_TYPEDEF_(0x80090346L) +#define SEC_E_MULTIPLE_ACCOUNTS _HRESULT_TYPEDEF_(0x80090347L) +#define SEC_E_NO_KERB_KEY _HRESULT_TYPEDEF_(0x80090348L) +#define SEC_E_CERT_WRONG_USAGE _HRESULT_TYPEDEF_(0x80090349L) +#define SEC_E_DOWNGRADE_DETECTED _HRESULT_TYPEDEF_(0x80090350L) +#define SEC_E_SMARTCARD_CERT_REVOKED _HRESULT_TYPEDEF_(0x80090351L) +#define SEC_E_ISSUING_CA_UNTRUSTED _HRESULT_TYPEDEF_(0x80090352L) +#define SEC_E_REVOCATION_OFFLINE_C _HRESULT_TYPEDEF_(0x80090353L) +#define SEC_E_PKINIT_CLIENT_FAILURE _HRESULT_TYPEDEF_(0x80090354L) +#define SEC_E_SMARTCARD_CERT_EXPIRED _HRESULT_TYPEDEF_(0x80090355L) +#define SEC_E_NO_S4U_PROT_SUPPORT _HRESULT_TYPEDEF_(0x80090356L) +#define SEC_E_CROSSREALM_DELEGATION_FAILURE _HRESULT_TYPEDEF_(0x80090357L) +#define SEC_E_REVOCATION_OFFLINE_KDC _HRESULT_TYPEDEF_(0x80090358L) +#define SEC_E_ISSUING_CA_UNTRUSTED_KDC _HRESULT_TYPEDEF_(0x80090359L) +#define SEC_E_KDC_CERT_EXPIRED _HRESULT_TYPEDEF_(0x8009035AL) +#define SEC_E_KDC_CERT_REVOKED _HRESULT_TYPEDEF_(0x8009035BL) +#define SEC_E_NO_SPM SEC_E_INTERNAL_ERROR +#define SEC_E_NOT_SUPPORTED SEC_E_UNSUPPORTED_FUNCTION +#define CRYPT_E_MSG_ERROR _HRESULT_TYPEDEF_(0x80091001L) +#define CRYPT_E_UNKNOWN_ALGO _HRESULT_TYPEDEF_(0x80091002L) +#define CRYPT_E_OID_FORMAT _HRESULT_TYPEDEF_(0x80091003L) +#define CRYPT_E_INVALID_MSG_TYPE _HRESULT_TYPEDEF_(0x80091004L) +#define CRYPT_E_UNEXPECTED_ENCODING _HRESULT_TYPEDEF_(0x80091005L) +#define CRYPT_E_AUTH_ATTR_MISSING _HRESULT_TYPEDEF_(0x80091006L) +#define CRYPT_E_HASH_VALUE _HRESULT_TYPEDEF_(0x80091007L) +#define CRYPT_E_INVALID_INDEX _HRESULT_TYPEDEF_(0x80091008L) +#define CRYPT_E_ALREADY_DECRYPTED _HRESULT_TYPEDEF_(0x80091009L) +#define CRYPT_E_NOT_DECRYPTED _HRESULT_TYPEDEF_(0x8009100AL) +#define CRYPT_E_RECIPIENT_NOT_FOUND _HRESULT_TYPEDEF_(0x8009100BL) +#define CRYPT_E_CONTROL_TYPE _HRESULT_TYPEDEF_(0x8009100CL) +#define CRYPT_E_ISSUER_SERIALNUMBER _HRESULT_TYPEDEF_(0x8009100DL) +#define CRYPT_E_SIGNER_NOT_FOUND _HRESULT_TYPEDEF_(0x8009100EL) +#define CRYPT_E_ATTRIBUTES_MISSING _HRESULT_TYPEDEF_(0x8009100FL) +#define CRYPT_E_STREAM_MSG_NOT_READY _HRESULT_TYPEDEF_(0x80091010L) +#define CRYPT_E_STREAM_INSUFFICIENT_DATA _HRESULT_TYPEDEF_(0x80091011L) +#define CRYPT_I_NEW_PROTECTION_REQUIRED _HRESULT_TYPEDEF_(0x00091012L) +#define CRYPT_E_BAD_LEN _HRESULT_TYPEDEF_(0x80092001L) +#define CRYPT_E_BAD_ENCODE _HRESULT_TYPEDEF_(0x80092002L) +#define CRYPT_E_FILE_ERROR _HRESULT_TYPEDEF_(0x80092003L) +#define CRYPT_E_NOT_FOUND _HRESULT_TYPEDEF_(0x80092004L) +#define CRYPT_E_EXISTS _HRESULT_TYPEDEF_(0x80092005L) +#define CRYPT_E_NO_PROVIDER _HRESULT_TYPEDEF_(0x80092006L) +#define CRYPT_E_SELF_SIGNED _HRESULT_TYPEDEF_(0x80092007L) +#define CRYPT_E_DELETED_PREV _HRESULT_TYPEDEF_(0x80092008L) +#define CRYPT_E_NO_MATCH _HRESULT_TYPEDEF_(0x80092009L) +#define CRYPT_E_UNEXPECTED_MSG_TYPE _HRESULT_TYPEDEF_(0x8009200AL) +#define CRYPT_E_NO_KEY_PROPERTY _HRESULT_TYPEDEF_(0x8009200BL) +#define CRYPT_E_NO_DECRYPT_CERT _HRESULT_TYPEDEF_(0x8009200CL) +#define CRYPT_E_BAD_MSG _HRESULT_TYPEDEF_(0x8009200DL) +#define CRYPT_E_NO_SIGNER _HRESULT_TYPEDEF_(0x8009200EL) +#define CRYPT_E_PENDING_CLOSE _HRESULT_TYPEDEF_(0x8009200FL) +#define CRYPT_E_REVOKED _HRESULT_TYPEDEF_(0x80092010L) +#define CRYPT_E_NO_REVOCATION_DLL _HRESULT_TYPEDEF_(0x80092011L) +#define CRYPT_E_NO_REVOCATION_CHECK _HRESULT_TYPEDEF_(0x80092012L) +#define CRYPT_E_REVOCATION_OFFLINE _HRESULT_TYPEDEF_(0x80092013L) +#define CRYPT_E_NOT_IN_REVOCATION_DATABASE _HRESULT_TYPEDEF_(0x80092014L) +#define CRYPT_E_INVALID_NUMERIC_STRING _HRESULT_TYPEDEF_(0x80092020L) +#define CRYPT_E_INVALID_PRINTABLE_STRING _HRESULT_TYPEDEF_(0x80092021L) +#define CRYPT_E_INVALID_IA5_STRING _HRESULT_TYPEDEF_(0x80092022L) +#define CRYPT_E_INVALID_X500_STRING _HRESULT_TYPEDEF_(0x80092023L) +#define CRYPT_E_NOT_CHAR_STRING _HRESULT_TYPEDEF_(0x80092024L) +#define CRYPT_E_FILERESIZED _HRESULT_TYPEDEF_(0x80092025L) +#define CRYPT_E_SECURITY_SETTINGS _HRESULT_TYPEDEF_(0x80092026L) +#define CRYPT_E_NO_VERIFY_USAGE_DLL _HRESULT_TYPEDEF_(0x80092027L) +#define CRYPT_E_NO_VERIFY_USAGE_CHECK _HRESULT_TYPEDEF_(0x80092028L) +#define CRYPT_E_VERIFY_USAGE_OFFLINE _HRESULT_TYPEDEF_(0x80092029L) +#define CRYPT_E_NOT_IN_CTL _HRESULT_TYPEDEF_(0x8009202AL) +#define CRYPT_E_NO_TRUSTED_SIGNER _HRESULT_TYPEDEF_(0x8009202BL) +#define CRYPT_E_MISSING_PUBKEY_PARA _HRESULT_TYPEDEF_(0x8009202CL) +#define CRYPT_E_OSS_ERROR _HRESULT_TYPEDEF_(0x80093000L) +#define OSS_MORE_BUF _HRESULT_TYPEDEF_(0x80093001L) +#define OSS_NEGATIVE_UINTEGER _HRESULT_TYPEDEF_(0x80093002L) +#define OSS_PDU_RANGE _HRESULT_TYPEDEF_(0x80093003L) +#define OSS_MORE_INPUT _HRESULT_TYPEDEF_(0x80093004L) +#define OSS_DATA_ERROR _HRESULT_TYPEDEF_(0x80093005L) +#define OSS_BAD_ARG _HRESULT_TYPEDEF_(0x80093006L) +#define OSS_BAD_VERSION _HRESULT_TYPEDEF_(0x80093007L) +#define OSS_OUT_MEMORY _HRESULT_TYPEDEF_(0x80093008L) +#define OSS_PDU_MISMATCH _HRESULT_TYPEDEF_(0x80093009L) +#define OSS_LIMITED _HRESULT_TYPEDEF_(0x8009300AL) +#define OSS_BAD_PTR _HRESULT_TYPEDEF_(0x8009300BL) +#define OSS_BAD_TIME _HRESULT_TYPEDEF_(0x8009300CL) +#define OSS_INDEFINITE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009300DL) +#define OSS_MEM_ERROR _HRESULT_TYPEDEF_(0x8009300EL) +#define OSS_BAD_TABLE _HRESULT_TYPEDEF_(0x8009300FL) +#define OSS_TOO_LONG _HRESULT_TYPEDEF_(0x80093010L) +#define OSS_CONSTRAINT_VIOLATED _HRESULT_TYPEDEF_(0x80093011L) +#define OSS_FATAL_ERROR _HRESULT_TYPEDEF_(0x80093012L) +#define OSS_ACCESS_SERIALIZATION_ERROR _HRESULT_TYPEDEF_(0x80093013L) +#define OSS_NULL_TBL _HRESULT_TYPEDEF_(0x80093014L) +#define OSS_NULL_FCN _HRESULT_TYPEDEF_(0x80093015L) +#define OSS_BAD_ENCRULES _HRESULT_TYPEDEF_(0x80093016L) +#define OSS_UNAVAIL_ENCRULES _HRESULT_TYPEDEF_(0x80093017L) +#define OSS_CANT_OPEN_TRACE_WINDOW _HRESULT_TYPEDEF_(0x80093018L) +#define OSS_UNIMPLEMENTED _HRESULT_TYPEDEF_(0x80093019L) +#define OSS_OID_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009301AL) +#define OSS_CANT_OPEN_TRACE_FILE _HRESULT_TYPEDEF_(0x8009301BL) +#define OSS_TRACE_FILE_ALREADY_OPEN _HRESULT_TYPEDEF_(0x8009301CL) +#define OSS_TABLE_MISMATCH _HRESULT_TYPEDEF_(0x8009301DL) +#define OSS_TYPE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009301EL) +#define OSS_REAL_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009301FL) +#define OSS_REAL_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093020L) +#define OSS_OUT_OF_RANGE _HRESULT_TYPEDEF_(0x80093021L) +#define OSS_COPIER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093022L) +#define OSS_CONSTRAINT_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093023L) +#define OSS_COMPARATOR_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093024L) +#define OSS_COMPARATOR_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093025L) +#define OSS_MEM_MGR_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093026L) +#define OSS_PDV_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093027L) +#define OSS_PDV_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093028L) +#define OSS_API_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093029L) +#define OSS_BERDER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009302AL) +#define OSS_PER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009302BL) +#define OSS_OPEN_TYPE_ERROR _HRESULT_TYPEDEF_(0x8009302CL) +#define OSS_MUTEX_NOT_CREATED _HRESULT_TYPEDEF_(0x8009302DL) +#define OSS_CANT_CLOSE_TRACE_FILE _HRESULT_TYPEDEF_(0x8009302EL) +#define CRYPT_E_ASN1_ERROR _HRESULT_TYPEDEF_(0x80093100L) +#define CRYPT_E_ASN1_INTERNAL _HRESULT_TYPEDEF_(0x80093101L) +#define CRYPT_E_ASN1_EOD _HRESULT_TYPEDEF_(0x80093102L) +#define CRYPT_E_ASN1_CORRUPT _HRESULT_TYPEDEF_(0x80093103L) +#define CRYPT_E_ASN1_LARGE _HRESULT_TYPEDEF_(0x80093104L) +#define CRYPT_E_ASN1_CONSTRAINT _HRESULT_TYPEDEF_(0x80093105L) +#define CRYPT_E_ASN1_MEMORY _HRESULT_TYPEDEF_(0x80093106L) +#define CRYPT_E_ASN1_OVERFLOW _HRESULT_TYPEDEF_(0x80093107L) +#define CRYPT_E_ASN1_BADPDU _HRESULT_TYPEDEF_(0x80093108L) +#define CRYPT_E_ASN1_BADARGS _HRESULT_TYPEDEF_(0x80093109L) +#define CRYPT_E_ASN1_BADREAL _HRESULT_TYPEDEF_(0x8009310AL) +#define CRYPT_E_ASN1_BADTAG _HRESULT_TYPEDEF_(0x8009310BL) +#define CRYPT_E_ASN1_CHOICE _HRESULT_TYPEDEF_(0x8009310CL) +#define CRYPT_E_ASN1_RULE _HRESULT_TYPEDEF_(0x8009310DL) +#define CRYPT_E_ASN1_UTF8 _HRESULT_TYPEDEF_(0x8009310EL) +#define CRYPT_E_ASN1_PDU_TYPE _HRESULT_TYPEDEF_(0x80093133L) +#define CRYPT_E_ASN1_NYI _HRESULT_TYPEDEF_(0x80093134L) +#define CRYPT_E_ASN1_EXTENDED _HRESULT_TYPEDEF_(0x80093201L) +#define CRYPT_E_ASN1_NOEOD _HRESULT_TYPEDEF_(0x80093202L) +#define CERTSRV_E_BAD_REQUESTSUBJECT _HRESULT_TYPEDEF_(0x80094001L) +#define CERTSRV_E_NO_REQUEST _HRESULT_TYPEDEF_(0x80094002L) +#define CERTSRV_E_BAD_REQUESTSTATUS _HRESULT_TYPEDEF_(0x80094003L) +#define CERTSRV_E_PROPERTY_EMPTY _HRESULT_TYPEDEF_(0x80094004L) +#define CERTSRV_E_INVALID_CA_CERTIFICATE _HRESULT_TYPEDEF_(0x80094005L) +#define CERTSRV_E_SERVER_SUSPENDED _HRESULT_TYPEDEF_(0x80094006L) +#define CERTSRV_E_ENCODING_LENGTH _HRESULT_TYPEDEF_(0x80094007L) +#define CERTSRV_E_ROLECONFLICT _HRESULT_TYPEDEF_(0x80094008L) +#define CERTSRV_E_RESTRICTEDOFFICER _HRESULT_TYPEDEF_(0x80094009L) +#define CERTSRV_E_KEY_ARCHIVAL_NOT_CONFIGURED _HRESULT_TYPEDEF_(0x8009400AL) +#define CERTSRV_E_NO_VALID_KRA _HRESULT_TYPEDEF_(0x8009400BL) +#define CERTSRV_E_BAD_REQUEST_KEY_ARCHIVAL _HRESULT_TYPEDEF_(0x8009400CL) +#define CERTSRV_E_NO_CAADMIN_DEFINED _HRESULT_TYPEDEF_(0x8009400DL) +#define CERTSRV_E_BAD_RENEWAL_CERT_ATTRIBUTE _HRESULT_TYPEDEF_(0x8009400EL) +#define CERTSRV_E_NO_DB_SESSIONS _HRESULT_TYPEDEF_(0x8009400FL) +#define CERTSRV_E_ALIGNMENT_FAULT _HRESULT_TYPEDEF_(0x80094010L) +#define CERTSRV_E_ENROLL_DENIED _HRESULT_TYPEDEF_(0x80094011L) +#define CERTSRV_E_TEMPLATE_DENIED _HRESULT_TYPEDEF_(0x80094012L) +#define CERTSRV_E_DOWNLEVEL_DC_SSL_OR_UPGRADE _HRESULT_TYPEDEF_(0x80094013L) +#define CERTSRV_E_UNSUPPORTED_CERT_TYPE _HRESULT_TYPEDEF_(0x80094800L) +#define CERTSRV_E_NO_CERT_TYPE _HRESULT_TYPEDEF_(0x80094801L) +#define CERTSRV_E_TEMPLATE_CONFLICT _HRESULT_TYPEDEF_(0x80094802L) +#define CERTSRV_E_SUBJECT_ALT_NAME_REQUIRED _HRESULT_TYPEDEF_(0x80094803L) +#define CERTSRV_E_ARCHIVED_KEY_REQUIRED _HRESULT_TYPEDEF_(0x80094804L) +#define CERTSRV_E_SMIME_REQUIRED _HRESULT_TYPEDEF_(0x80094805L) +#define CERTSRV_E_BAD_RENEWAL_SUBJECT _HRESULT_TYPEDEF_(0x80094806L) +#define CERTSRV_E_BAD_TEMPLATE_VERSION _HRESULT_TYPEDEF_(0x80094807L) +#define CERTSRV_E_TEMPLATE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x80094808L) +#define CERTSRV_E_SIGNATURE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x80094809L) +#define CERTSRV_E_SIGNATURE_COUNT _HRESULT_TYPEDEF_(0x8009480AL) +#define CERTSRV_E_SIGNATURE_REJECTED _HRESULT_TYPEDEF_(0x8009480BL) +#define CERTSRV_E_ISSUANCE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x8009480CL) +#define CERTSRV_E_SUBJECT_UPN_REQUIRED _HRESULT_TYPEDEF_(0x8009480DL) +#define CERTSRV_E_SUBJECT_DIRECTORY_GUID_REQUIRED _HRESULT_TYPEDEF_(0x8009480EL) +#define CERTSRV_E_SUBJECT_DNS_REQUIRED _HRESULT_TYPEDEF_(0x8009480FL) +#define CERTSRV_E_ARCHIVED_KEY_UNEXPECTED _HRESULT_TYPEDEF_(0x80094810L) +#define CERTSRV_E_KEY_LENGTH _HRESULT_TYPEDEF_(0x80094811L) +#define CERTSRV_E_SUBJECT_EMAIL_REQUIRED _HRESULT_TYPEDEF_(0x80094812L) +#define CERTSRV_E_UNKNOWN_CERT_TYPE _HRESULT_TYPEDEF_(0x80094813L) +#define CERTSRV_E_CERT_TYPE_OVERLAP _HRESULT_TYPEDEF_(0x80094814L) +#define XENROLL_E_KEY_NOT_EXPORTABLE _HRESULT_TYPEDEF_(0x80095000L) +#define XENROLL_E_CANNOT_ADD_ROOT_CERT _HRESULT_TYPEDEF_(0x80095001L) +#define XENROLL_E_RESPONSE_KA_HASH_NOT_FOUND _HRESULT_TYPEDEF_(0x80095002L) +#define XENROLL_E_RESPONSE_UNEXPECTED_KA_HASH _HRESULT_TYPEDEF_(0x80095003L) +#define XENROLL_E_RESPONSE_KA_HASH_MISMATCH _HRESULT_TYPEDEF_(0x80095004L) +#define XENROLL_E_KEYSPEC_SMIME_MISMATCH _HRESULT_TYPEDEF_(0x80095005L) +#define TRUST_E_SYSTEM_ERROR _HRESULT_TYPEDEF_(0x80096001L) +#define TRUST_E_NO_SIGNER_CERT _HRESULT_TYPEDEF_(0x80096002L) +#define TRUST_E_COUNTER_SIGNER _HRESULT_TYPEDEF_(0x80096003L) +#define TRUST_E_CERT_SIGNATURE _HRESULT_TYPEDEF_(0x80096004L) +#define TRUST_E_TIME_STAMP _HRESULT_TYPEDEF_(0x80096005L) +#define TRUST_E_BAD_DIGEST _HRESULT_TYPEDEF_(0x80096010L) +#define TRUST_E_BASIC_CONSTRAINTS _HRESULT_TYPEDEF_(0x80096019L) +#define TRUST_E_FINANCIAL_CRITERIA _HRESULT_TYPEDEF_(0x8009601EL) +#define MSSIPOTF_E_OUTOFMEMRANGE _HRESULT_TYPEDEF_(0x80097001L) +#define MSSIPOTF_E_CANTGETOBJECT _HRESULT_TYPEDEF_(0x80097002L) +#define MSSIPOTF_E_NOHEADTABLE _HRESULT_TYPEDEF_(0x80097003L) +#define MSSIPOTF_E_BAD_MAGICNUMBER _HRESULT_TYPEDEF_(0x80097004L) +#define MSSIPOTF_E_BAD_OFFSET_TABLE _HRESULT_TYPEDEF_(0x80097005L) +#define MSSIPOTF_E_TABLE_TAGORDER _HRESULT_TYPEDEF_(0x80097006L) +#define MSSIPOTF_E_TABLE_LONGWORD _HRESULT_TYPEDEF_(0x80097007L) +#define MSSIPOTF_E_BAD_FIRST_TABLE_PLACEMENT _HRESULT_TYPEDEF_(0x80097008L) +#define MSSIPOTF_E_TABLES_OVERLAP _HRESULT_TYPEDEF_(0x80097009L) +#define MSSIPOTF_E_TABLE_PADBYTES _HRESULT_TYPEDEF_(0x8009700AL) +#define MSSIPOTF_E_FILETOOSMALL _HRESULT_TYPEDEF_(0x8009700BL) +#define MSSIPOTF_E_TABLE_CHECKSUM _HRESULT_TYPEDEF_(0x8009700CL) +#define MSSIPOTF_E_FILE_CHECKSUM _HRESULT_TYPEDEF_(0x8009700DL) +#define MSSIPOTF_E_FAILED_POLICY _HRESULT_TYPEDEF_(0x80097010L) +#define MSSIPOTF_E_FAILED_HINTS_CHECK _HRESULT_TYPEDEF_(0x80097011L) +#define MSSIPOTF_E_NOT_OPENTYPE _HRESULT_TYPEDEF_(0x80097012L) +#define MSSIPOTF_E_FILE _HRESULT_TYPEDEF_(0x80097013L) +#define MSSIPOTF_E_CRYPT _HRESULT_TYPEDEF_(0x80097014L) +#define MSSIPOTF_E_BADVERSION _HRESULT_TYPEDEF_(0x80097015L) +#define MSSIPOTF_E_DSIG_STRUCTURE _HRESULT_TYPEDEF_(0x80097016L) +#define MSSIPOTF_E_PCONST_CHECK _HRESULT_TYPEDEF_(0x80097017L) +#define MSSIPOTF_E_STRUCTURE _HRESULT_TYPEDEF_(0x80097018L) +#define NTE_OP_OK 0 +#define TRUST_E_PROVIDER_UNKNOWN _HRESULT_TYPEDEF_(0x800B0001L) +#define TRUST_E_ACTION_UNKNOWN _HRESULT_TYPEDEF_(0x800B0002L) +#define TRUST_E_SUBJECT_FORM_UNKNOWN _HRESULT_TYPEDEF_(0x800B0003L) +#define TRUST_E_SUBJECT_NOT_TRUSTED _HRESULT_TYPEDEF_(0x800B0004L) +#define DIGSIG_E_ENCODE _HRESULT_TYPEDEF_(0x800B0005L) +#define DIGSIG_E_DECODE _HRESULT_TYPEDEF_(0x800B0006L) +#define DIGSIG_E_EXTENSIBILITY _HRESULT_TYPEDEF_(0x800B0007L) +#define DIGSIG_E_CRYPTO _HRESULT_TYPEDEF_(0x800B0008L) +#define PERSIST_E_SIZEDEFINITE _HRESULT_TYPEDEF_(0x800B0009L) +#define PERSIST_E_SIZEINDEFINITE _HRESULT_TYPEDEF_(0x800B000AL) +#define PERSIST_E_NOTSELFSIZING _HRESULT_TYPEDEF_(0x800B000BL) +#define TRUST_E_NOSIGNATURE _HRESULT_TYPEDEF_(0x800B0100L) +#define CERT_E_EXPIRED _HRESULT_TYPEDEF_(0x800B0101L) +#define CERT_E_VALIDITYPERIODNESTING _HRESULT_TYPEDEF_(0x800B0102L) +#define CERT_E_ROLE _HRESULT_TYPEDEF_(0x800B0103L) +#define CERT_E_PATHLENCONST _HRESULT_TYPEDEF_(0x800B0104L) +#define CERT_E_CRITICAL _HRESULT_TYPEDEF_(0x800B0105L) +#define CERT_E_PURPOSE _HRESULT_TYPEDEF_(0x800B0106L) +#define CERT_E_ISSUERCHAINING _HRESULT_TYPEDEF_(0x800B0107L) +#define CERT_E_MALFORMED _HRESULT_TYPEDEF_(0x800B0108L) +#define CERT_E_UNTRUSTEDROOT _HRESULT_TYPEDEF_(0x800B0109L) +#define CERT_E_CHAINING _HRESULT_TYPEDEF_(0x800B010AL) +#define TRUST_E_FAIL _HRESULT_TYPEDEF_(0x800B010BL) +#define CERT_E_REVOKED _HRESULT_TYPEDEF_(0x800B010CL) +#define CERT_E_UNTRUSTEDTESTROOT _HRESULT_TYPEDEF_(0x800B010DL) +#define CERT_E_REVOCATION_FAILURE _HRESULT_TYPEDEF_(0x800B010EL) +#define CERT_E_CN_NO_MATCH _HRESULT_TYPEDEF_(0x800B010FL) +#define CERT_E_WRONG_USAGE _HRESULT_TYPEDEF_(0x800B0110L) +#define TRUST_E_EXPLICIT_DISTRUST _HRESULT_TYPEDEF_(0x800B0111L) +#define CERT_E_UNTRUSTEDCA _HRESULT_TYPEDEF_(0x800B0112L) +#define CERT_E_INVALID_POLICY _HRESULT_TYPEDEF_(0x800B0113L) +#define CERT_E_INVALID_NAME _HRESULT_TYPEDEF_(0x800B0114L) +#define HRESULT_FROM_SETUPAPI(x) ((((x) & (APPLICATION_ERROR_MASK|ERROR_SEVERITY_ERROR))==(APPLICATION_ERROR_MASK|ERROR_SEVERITY_ERROR)) ? ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_SETUPAPI << 16) | 0x80000000)) : HRESULT_FROM_WIN32(x)) +#define SPAPI_E_EXPECTED_SECTION_NAME _HRESULT_TYPEDEF_(0x800F0000L) +#define SPAPI_E_BAD_SECTION_NAME_LINE _HRESULT_TYPEDEF_(0x800F0001L) +#define SPAPI_E_SECTION_NAME_TOO_LONG _HRESULT_TYPEDEF_(0x800F0002L) +#define SPAPI_E_GENERAL_SYNTAX _HRESULT_TYPEDEF_(0x800F0003L) +#define SPAPI_E_WRONG_INF_STYLE _HRESULT_TYPEDEF_(0x800F0100L) +#define SPAPI_E_SECTION_NOT_FOUND _HRESULT_TYPEDEF_(0x800F0101L) +#define SPAPI_E_LINE_NOT_FOUND _HRESULT_TYPEDEF_(0x800F0102L) +#define SPAPI_E_NO_BACKUP _HRESULT_TYPEDEF_(0x800F0103L) +#define SPAPI_E_NO_ASSOCIATED_CLASS _HRESULT_TYPEDEF_(0x800F0200L) +#define SPAPI_E_CLASS_MISMATCH _HRESULT_TYPEDEF_(0x800F0201L) +#define SPAPI_E_DUPLICATE_FOUND _HRESULT_TYPEDEF_(0x800F0202L) +#define SPAPI_E_NO_DRIVER_SELECTED _HRESULT_TYPEDEF_(0x800F0203L) +#define SPAPI_E_KEY_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x800F0204L) +#define SPAPI_E_INVALID_DEVINST_NAME _HRESULT_TYPEDEF_(0x800F0205L) +#define SPAPI_E_INVALID_CLASS _HRESULT_TYPEDEF_(0x800F0206L) +#define SPAPI_E_DEVINST_ALREADY_EXISTS _HRESULT_TYPEDEF_(0x800F0207L) +#define SPAPI_E_DEVINFO_NOT_REGISTERED _HRESULT_TYPEDEF_(0x800F0208L) +#define SPAPI_E_INVALID_REG_PROPERTY _HRESULT_TYPEDEF_(0x800F0209L) +#define SPAPI_E_NO_INF _HRESULT_TYPEDEF_(0x800F020AL) +#define SPAPI_E_NO_SUCH_DEVINST _HRESULT_TYPEDEF_(0x800F020BL) +#define SPAPI_E_CANT_LOAD_CLASS_ICON _HRESULT_TYPEDEF_(0x800F020CL) +#define SPAPI_E_INVALID_CLASS_INSTALLER _HRESULT_TYPEDEF_(0x800F020DL) +#define SPAPI_E_DI_DO_DEFAULT _HRESULT_TYPEDEF_(0x800F020EL) +#define SPAPI_E_DI_NOFILECOPY _HRESULT_TYPEDEF_(0x800F020FL) +#define SPAPI_E_INVALID_HWPROFILE _HRESULT_TYPEDEF_(0x800F0210L) +#define SPAPI_E_NO_DEVICE_SELECTED _HRESULT_TYPEDEF_(0x800F0211L) +#define SPAPI_E_DEVINFO_LIST_LOCKED _HRESULT_TYPEDEF_(0x800F0212L) +#define SPAPI_E_DEVINFO_DATA_LOCKED _HRESULT_TYPEDEF_(0x800F0213L) +#define SPAPI_E_DI_BAD_PATH _HRESULT_TYPEDEF_(0x800F0214L) +#define SPAPI_E_NO_CLASSINSTALL_PARAMS _HRESULT_TYPEDEF_(0x800F0215L) +#define SPAPI_E_FILEQUEUE_LOCKED _HRESULT_TYPEDEF_(0x800F0216L) +#define SPAPI_E_BAD_SERVICE_INSTALLSECT _HRESULT_TYPEDEF_(0x800F0217L) +#define SPAPI_E_NO_CLASS_DRIVER_LIST _HRESULT_TYPEDEF_(0x800F0218L) +#define SPAPI_E_NO_ASSOCIATED_SERVICE _HRESULT_TYPEDEF_(0x800F0219L) +#define SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE _HRESULT_TYPEDEF_(0x800F021AL) +#define SPAPI_E_DEVICE_INTERFACE_ACTIVE _HRESULT_TYPEDEF_(0x800F021BL) +#define SPAPI_E_DEVICE_INTERFACE_REMOVED _HRESULT_TYPEDEF_(0x800F021CL) +#define SPAPI_E_BAD_INTERFACE_INSTALLSECT _HRESULT_TYPEDEF_(0x800F021DL) +#define SPAPI_E_NO_SUCH_INTERFACE_CLASS _HRESULT_TYPEDEF_(0x800F021EL) +#define SPAPI_E_INVALID_REFERENCE_STRING _HRESULT_TYPEDEF_(0x800F021FL) +#define SPAPI_E_INVALID_MACHINENAME _HRESULT_TYPEDEF_(0x800F0220L) +#define SPAPI_E_REMOTE_COMM_FAILURE _HRESULT_TYPEDEF_(0x800F0221L) +#define SPAPI_E_MACHINE_UNAVAILABLE _HRESULT_TYPEDEF_(0x800F0222L) +#define SPAPI_E_NO_CONFIGMGR_SERVICES _HRESULT_TYPEDEF_(0x800F0223L) +#define SPAPI_E_INVALID_PROPPAGE_PROVIDER _HRESULT_TYPEDEF_(0x800F0224L) +#define SPAPI_E_NO_SUCH_DEVICE_INTERFACE _HRESULT_TYPEDEF_(0x800F0225L) +#define SPAPI_E_DI_POSTPROCESSING_REQUIRED _HRESULT_TYPEDEF_(0x800F0226L) +#define SPAPI_E_INVALID_COINSTALLER _HRESULT_TYPEDEF_(0x800F0227L) +#define SPAPI_E_NO_COMPAT_DRIVERS _HRESULT_TYPEDEF_(0x800F0228L) +#define SPAPI_E_NO_DEVICE_ICON _HRESULT_TYPEDEF_(0x800F0229L) +#define SPAPI_E_INVALID_INF_LOGCONFIG _HRESULT_TYPEDEF_(0x800F022AL) +#define SPAPI_E_DI_DONT_INSTALL _HRESULT_TYPEDEF_(0x800F022BL) +#define SPAPI_E_INVALID_FILTER_DRIVER _HRESULT_TYPEDEF_(0x800F022CL) +#define SPAPI_E_NON_WINDOWS_NT_DRIVER _HRESULT_TYPEDEF_(0x800F022DL) +#define SPAPI_E_NON_WINDOWS_DRIVER _HRESULT_TYPEDEF_(0x800F022EL) +#define SPAPI_E_NO_CATALOG_FOR_OEM_INF _HRESULT_TYPEDEF_(0x800F022FL) +#define SPAPI_E_DEVINSTALL_QUEUE_NONNATIVE _HRESULT_TYPEDEF_(0x800F0230L) +#define SPAPI_E_NOT_DISABLEABLE _HRESULT_TYPEDEF_(0x800F0231L) +#define SPAPI_E_CANT_REMOVE_DEVINST _HRESULT_TYPEDEF_(0x800F0232L) +#define SPAPI_E_INVALID_TARGET _HRESULT_TYPEDEF_(0x800F0233L) +#define SPAPI_E_DRIVER_NONNATIVE _HRESULT_TYPEDEF_(0x800F0234L) +#define SPAPI_E_IN_WOW64 _HRESULT_TYPEDEF_(0x800F0235L) +#define SPAPI_E_SET_SYSTEM_RESTORE_POINT _HRESULT_TYPEDEF_(0x800F0236L) +#define SPAPI_E_INCORRECTLY_COPIED_INF _HRESULT_TYPEDEF_(0x800F0237L) +#define SPAPI_E_SCE_DISABLED _HRESULT_TYPEDEF_(0x800F0238L) +#define SPAPI_E_UNKNOWN_EXCEPTION _HRESULT_TYPEDEF_(0x800F0239L) +#define SPAPI_E_PNP_REGISTRY_ERROR _HRESULT_TYPEDEF_(0x800F023AL) +#define SPAPI_E_REMOTE_REQUEST_UNSUPPORTED _HRESULT_TYPEDEF_(0x800F023BL) +#define SPAPI_E_NOT_AN_INSTALLED_OEM_INF _HRESULT_TYPEDEF_(0x800F023CL) +#define SPAPI_E_INF_IN_USE_BY_DEVICES _HRESULT_TYPEDEF_(0x800F023DL) +#define SPAPI_E_DI_FUNCTION_OBSOLETE _HRESULT_TYPEDEF_(0x800F023EL) +#define SPAPI_E_NO_AUTHENTICODE_CATALOG _HRESULT_TYPEDEF_(0x800F023FL) +#define SPAPI_E_AUTHENTICODE_DISALLOWED _HRESULT_TYPEDEF_(0x800F0240L) +#define SPAPI_E_AUTHENTICODE_TRUSTED_PUBLISHER _HRESULT_TYPEDEF_(0x800F0241L) +#define SPAPI_E_AUTHENTICODE_TRUST_NOT_ESTABLISHED _HRESULT_TYPEDEF_(0x800F0242L) +#define SPAPI_E_AUTHENTICODE_PUBLISHER_NOT_TRUSTED _HRESULT_TYPEDEF_(0x800F0243L) +#define SPAPI_E_SIGNATURE_OSATTRIBUTE_MISMATCH _HRESULT_TYPEDEF_(0x800F0244L) +#define SPAPI_E_ONLY_VALIDATE_VIA_AUTHENTICODE _HRESULT_TYPEDEF_(0x800F0245L) +#define SPAPI_E_UNRECOVERABLE_STACK_OVERFLOW _HRESULT_TYPEDEF_(0x800F0300L) +#define SPAPI_E_ERROR_NOT_INSTALLED _HRESULT_TYPEDEF_(0x800F1000L) +#define SCARD_S_SUCCESS NO_ERROR +#define SCARD_F_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80100001L) +#define SCARD_E_CANCELLED _HRESULT_TYPEDEF_(0x80100002L) +#define SCARD_E_INVALID_HANDLE _HRESULT_TYPEDEF_(0x80100003L) +#define SCARD_E_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80100004L) +#define SCARD_E_INVALID_TARGET _HRESULT_TYPEDEF_(0x80100005L) +#define SCARD_E_NO_MEMORY _HRESULT_TYPEDEF_(0x80100006L) +#define SCARD_F_WAITED_TOO_LONG _HRESULT_TYPEDEF_(0x80100007L) +#define SCARD_E_INSUFFICIENT_BUFFER _HRESULT_TYPEDEF_(0x80100008L) +#define SCARD_E_UNKNOWN_READER _HRESULT_TYPEDEF_(0x80100009L) +#define SCARD_E_TIMEOUT _HRESULT_TYPEDEF_(0x8010000AL) +#define SCARD_E_SHARING_VIOLATION _HRESULT_TYPEDEF_(0x8010000BL) +#define SCARD_E_NO_SMARTCARD _HRESULT_TYPEDEF_(0x8010000CL) +#define SCARD_E_UNKNOWN_CARD _HRESULT_TYPEDEF_(0x8010000DL) +#define SCARD_E_CANT_DISPOSE _HRESULT_TYPEDEF_(0x8010000EL) +#define SCARD_E_PROTO_MISMATCH _HRESULT_TYPEDEF_(0x8010000FL) +#define SCARD_E_NOT_READY _HRESULT_TYPEDEF_(0x80100010L) +#define SCARD_E_INVALID_VALUE _HRESULT_TYPEDEF_(0x80100011L) +#define SCARD_E_SYSTEM_CANCELLED _HRESULT_TYPEDEF_(0x80100012L) +#define SCARD_F_COMM_ERROR _HRESULT_TYPEDEF_(0x80100013L) +#define SCARD_F_UNKNOWN_ERROR _HRESULT_TYPEDEF_(0x80100014L) +#define SCARD_E_INVALID_ATR _HRESULT_TYPEDEF_(0x80100015L) +#define SCARD_E_NOT_TRANSACTED _HRESULT_TYPEDEF_(0x80100016L) +#define SCARD_E_READER_UNAVAILABLE _HRESULT_TYPEDEF_(0x80100017L) +#define SCARD_P_SHUTDOWN _HRESULT_TYPEDEF_(0x80100018L) +#define SCARD_E_PCI_TOO_SMALL _HRESULT_TYPEDEF_(0x80100019L) +#define SCARD_E_READER_UNSUPPORTED _HRESULT_TYPEDEF_(0x8010001AL) +#define SCARD_E_DUPLICATE_READER _HRESULT_TYPEDEF_(0x8010001BL) +#define SCARD_E_CARD_UNSUPPORTED _HRESULT_TYPEDEF_(0x8010001CL) +#define SCARD_E_NO_SERVICE _HRESULT_TYPEDEF_(0x8010001DL) +#define SCARD_E_SERVICE_STOPPED _HRESULT_TYPEDEF_(0x8010001EL) +#define SCARD_E_UNEXPECTED _HRESULT_TYPEDEF_(0x8010001FL) +#define SCARD_E_ICC_INSTALLATION _HRESULT_TYPEDEF_(0x80100020L) +#define SCARD_E_ICC_CREATEORDER _HRESULT_TYPEDEF_(0x80100021L) +#define SCARD_E_UNSUPPORTED_FEATURE _HRESULT_TYPEDEF_(0x80100022L) +#define SCARD_E_DIR_NOT_FOUND _HRESULT_TYPEDEF_(0x80100023L) +#define SCARD_E_FILE_NOT_FOUND _HRESULT_TYPEDEF_(0x80100024L) +#define SCARD_E_NO_DIR _HRESULT_TYPEDEF_(0x80100025L) +#define SCARD_E_NO_FILE _HRESULT_TYPEDEF_(0x80100026L) +#define SCARD_E_NO_ACCESS _HRESULT_TYPEDEF_(0x80100027L) +#define SCARD_E_WRITE_TOO_MANY _HRESULT_TYPEDEF_(0x80100028L) +#define SCARD_E_BAD_SEEK _HRESULT_TYPEDEF_(0x80100029L) +#define SCARD_E_INVALID_CHV _HRESULT_TYPEDEF_(0x8010002AL) +#define SCARD_E_UNKNOWN_RES_MNG _HRESULT_TYPEDEF_(0x8010002BL) +#define SCARD_E_NO_SUCH_CERTIFICATE _HRESULT_TYPEDEF_(0x8010002CL) +#define SCARD_E_CERTIFICATE_UNAVAILABLE _HRESULT_TYPEDEF_(0x8010002DL) +#define SCARD_E_NO_READERS_AVAILABLE _HRESULT_TYPEDEF_(0x8010002EL) +#define SCARD_E_COMM_DATA_LOST _HRESULT_TYPEDEF_(0x8010002FL) +#define SCARD_E_NO_KEY_CONTAINER _HRESULT_TYPEDEF_(0x80100030L) +#define SCARD_E_SERVER_TOO_BUSY _HRESULT_TYPEDEF_(0x80100031L) +#define SCARD_W_UNSUPPORTED_CARD _HRESULT_TYPEDEF_(0x80100065L) +#define SCARD_W_UNRESPONSIVE_CARD _HRESULT_TYPEDEF_(0x80100066L) +#define SCARD_W_UNPOWERED_CARD _HRESULT_TYPEDEF_(0x80100067L) +#define SCARD_W_RESET_CARD _HRESULT_TYPEDEF_(0x80100068L) +#define SCARD_W_REMOVED_CARD _HRESULT_TYPEDEF_(0x80100069L) +#define SCARD_W_SECURITY_VIOLATION _HRESULT_TYPEDEF_(0x8010006AL) +#define SCARD_W_WRONG_CHV _HRESULT_TYPEDEF_(0x8010006BL) +#define SCARD_W_CHV_BLOCKED _HRESULT_TYPEDEF_(0x8010006CL) +#define SCARD_W_EOF _HRESULT_TYPEDEF_(0x8010006DL) +#define SCARD_W_CANCELLED_BY_USER _HRESULT_TYPEDEF_(0x8010006EL) +#define SCARD_W_CARD_NOT_AUTHENTICATED _HRESULT_TYPEDEF_(0x8010006FL) +#define COMADMIN_E_OBJECTERRORS _HRESULT_TYPEDEF_(0x80110401L) +#define COMADMIN_E_OBJECTINVALID _HRESULT_TYPEDEF_(0x80110402L) +#define COMADMIN_E_KEYMISSING _HRESULT_TYPEDEF_(0x80110403L) +#define COMADMIN_E_ALREADYINSTALLED _HRESULT_TYPEDEF_(0x80110404L) +#define COMADMIN_E_APP_FILE_WRITEFAIL _HRESULT_TYPEDEF_(0x80110407L) +#define COMADMIN_E_APP_FILE_READFAIL _HRESULT_TYPEDEF_(0x80110408L) +#define COMADMIN_E_APP_FILE_VERSION _HRESULT_TYPEDEF_(0x80110409L) +#define COMADMIN_E_BADPATH _HRESULT_TYPEDEF_(0x8011040AL) +#define COMADMIN_E_APPLICATIONEXISTS _HRESULT_TYPEDEF_(0x8011040BL) +#define COMADMIN_E_ROLEEXISTS _HRESULT_TYPEDEF_(0x8011040CL) +#define COMADMIN_E_CANTCOPYFILE _HRESULT_TYPEDEF_(0x8011040DL) +#define COMADMIN_E_NOUSER _HRESULT_TYPEDEF_(0x8011040FL) +#define COMADMIN_E_INVALIDUSERIDS _HRESULT_TYPEDEF_(0x80110410L) +#define COMADMIN_E_NOREGISTRYCLSID _HRESULT_TYPEDEF_(0x80110411L) +#define COMADMIN_E_BADREGISTRYPROGID _HRESULT_TYPEDEF_(0x80110412L) +#define COMADMIN_E_AUTHENTICATIONLEVEL _HRESULT_TYPEDEF_(0x80110413L) +#define COMADMIN_E_USERPASSWDNOTVALID _HRESULT_TYPEDEF_(0x80110414L) +#define COMADMIN_E_CLSIDORIIDMISMATCH _HRESULT_TYPEDEF_(0x80110418L) +#define COMADMIN_E_REMOTEINTERFACE _HRESULT_TYPEDEF_(0x80110419L) +#define COMADMIN_E_DLLREGISTERSERVER _HRESULT_TYPEDEF_(0x8011041AL) +#define COMADMIN_E_NOSERVERSHARE _HRESULT_TYPEDEF_(0x8011041BL) +#define COMADMIN_E_DLLLOADFAILED _HRESULT_TYPEDEF_(0x8011041DL) +#define COMADMIN_E_BADREGISTRYLIBID _HRESULT_TYPEDEF_(0x8011041EL) +#define COMADMIN_E_APPDIRNOTFOUND _HRESULT_TYPEDEF_(0x8011041FL) +#define COMADMIN_E_REGISTRARFAILED _HRESULT_TYPEDEF_(0x80110423L) +#define COMADMIN_E_COMPFILE_DOESNOTEXIST _HRESULT_TYPEDEF_(0x80110424L) +#define COMADMIN_E_COMPFILE_LOADDLLFAIL _HRESULT_TYPEDEF_(0x80110425L) +#define COMADMIN_E_COMPFILE_GETCLASSOBJ _HRESULT_TYPEDEF_(0x80110426L) +#define COMADMIN_E_COMPFILE_CLASSNOTAVAIL _HRESULT_TYPEDEF_(0x80110427L) +#define COMADMIN_E_COMPFILE_BADTLB _HRESULT_TYPEDEF_(0x80110428L) +#define COMADMIN_E_COMPFILE_NOTINSTALLABLE _HRESULT_TYPEDEF_(0x80110429L) +#define COMADMIN_E_NOTCHANGEABLE _HRESULT_TYPEDEF_(0x8011042AL) +#define COMADMIN_E_NOTDELETEABLE _HRESULT_TYPEDEF_(0x8011042BL) +#define COMADMIN_E_SESSION _HRESULT_TYPEDEF_(0x8011042CL) +#define COMADMIN_E_COMP_MOVE_LOCKED _HRESULT_TYPEDEF_(0x8011042DL) +#define COMADMIN_E_COMP_MOVE_BAD_DEST _HRESULT_TYPEDEF_(0x8011042EL) +#define COMADMIN_E_REGISTERTLB _HRESULT_TYPEDEF_(0x80110430L) +#define COMADMIN_E_SYSTEMAPP _HRESULT_TYPEDEF_(0x80110433L) +#define COMADMIN_E_COMPFILE_NOREGISTRAR _HRESULT_TYPEDEF_(0x80110434L) +#define COMADMIN_E_COREQCOMPINSTALLED _HRESULT_TYPEDEF_(0x80110435L) +#define COMADMIN_E_SERVICENOTINSTALLED _HRESULT_TYPEDEF_(0x80110436L) +#define COMADMIN_E_PROPERTYSAVEFAILED _HRESULT_TYPEDEF_(0x80110437L) +#define COMADMIN_E_OBJECTEXISTS _HRESULT_TYPEDEF_(0x80110438L) +#define COMADMIN_E_COMPONENTEXISTS _HRESULT_TYPEDEF_(0x80110439L) +#define COMADMIN_E_REGFILE_CORRUPT _HRESULT_TYPEDEF_(0x8011043BL) +#define COMADMIN_E_PROPERTY_OVERFLOW _HRESULT_TYPEDEF_(0x8011043CL) +#define COMADMIN_E_NOTINREGISTRY _HRESULT_TYPEDEF_(0x8011043EL) +#define COMADMIN_E_OBJECTNOTPOOLABLE _HRESULT_TYPEDEF_(0x8011043FL) +#define COMADMIN_E_APPLID_MATCHES_CLSID _HRESULT_TYPEDEF_(0x80110446L) +#define COMADMIN_E_ROLE_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x80110447L) +#define COMADMIN_E_START_APP_NEEDS_COMPONENTS _HRESULT_TYPEDEF_(0x80110448L) +#define COMADMIN_E_REQUIRES_DIFFERENT_PLATFORM _HRESULT_TYPEDEF_(0x80110449L) +#define COMADMIN_E_CAN_NOT_EXPORT_APP_PROXY _HRESULT_TYPEDEF_(0x8011044AL) +#define COMADMIN_E_CAN_NOT_START_APP _HRESULT_TYPEDEF_(0x8011044BL) +#define COMADMIN_E_CAN_NOT_EXPORT_SYS_APP _HRESULT_TYPEDEF_(0x8011044CL) +#define COMADMIN_E_CANT_SUBSCRIBE_TO_COMPONENT _HRESULT_TYPEDEF_(0x8011044DL) +#define COMADMIN_E_EVENTCLASS_CANT_BE_SUBSCRIBER _HRESULT_TYPEDEF_(0x8011044EL) +#define COMADMIN_E_LIB_APP_PROXY_INCOMPATIBLE _HRESULT_TYPEDEF_(0x8011044FL) +#define COMADMIN_E_BASE_PARTITION_ONLY _HRESULT_TYPEDEF_(0x80110450L) +#define COMADMIN_E_START_APP_DISABLED _HRESULT_TYPEDEF_(0x80110451L) +#define COMADMIN_E_CAT_DUPLICATE_PARTITION_NAME _HRESULT_TYPEDEF_(0x80110457L) +#define COMADMIN_E_CAT_INVALID_PARTITION_NAME _HRESULT_TYPEDEF_(0x80110458L) +#define COMADMIN_E_CAT_PARTITION_IN_USE _HRESULT_TYPEDEF_(0x80110459L) +#define COMADMIN_E_FILE_PARTITION_DUPLICATE_FILES _HRESULT_TYPEDEF_(0x8011045AL) +#define COMADMIN_E_CAT_IMPORTED_COMPONENTS_NOT_ALLOWED _HRESULT_TYPEDEF_(0x8011045BL) +#define COMADMIN_E_AMBIGUOUS_APPLICATION_NAME _HRESULT_TYPEDEF_(0x8011045CL) +#define COMADMIN_E_AMBIGUOUS_PARTITION_NAME _HRESULT_TYPEDEF_(0x8011045DL) +#define COMADMIN_E_REGDB_NOTINITIALIZED _HRESULT_TYPEDEF_(0x80110472L) +#define COMADMIN_E_REGDB_NOTOPEN _HRESULT_TYPEDEF_(0x80110473L) +#define COMADMIN_E_REGDB_SYSTEMERR _HRESULT_TYPEDEF_(0x80110474L) +#define COMADMIN_E_REGDB_ALREADYRUNNING _HRESULT_TYPEDEF_(0x80110475L) +#define COMADMIN_E_MIG_VERSIONNOTSUPPORTED _HRESULT_TYPEDEF_(0x80110480L) +#define COMADMIN_E_MIG_SCHEMANOTFOUND _HRESULT_TYPEDEF_(0x80110481L) +#define COMADMIN_E_CAT_BITNESSMISMATCH _HRESULT_TYPEDEF_(0x80110482L) +#define COMADMIN_E_CAT_UNACCEPTABLEBITNESS _HRESULT_TYPEDEF_(0x80110483L) +#define COMADMIN_E_CAT_WRONGAPPBITNESS _HRESULT_TYPEDEF_(0x80110484L) +#define COMADMIN_E_CAT_PAUSE_RESUME_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80110485L) +#define COMADMIN_E_CAT_SERVERFAULT _HRESULT_TYPEDEF_(0x80110486L) +#define COMQC_E_APPLICATION_NOT_QUEUED _HRESULT_TYPEDEF_(0x80110600L) +#define COMQC_E_NO_QUEUEABLE_INTERFACES _HRESULT_TYPEDEF_(0x80110601L) +#define COMQC_E_QUEUING_SERVICE_NOT_AVAILABLE _HRESULT_TYPEDEF_(0x80110602L) +#define COMQC_E_NO_IPERSISTSTREAM _HRESULT_TYPEDEF_(0x80110603L) +#define COMQC_E_BAD_MESSAGE _HRESULT_TYPEDEF_(0x80110604L) +#define COMQC_E_UNAUTHENTICATED _HRESULT_TYPEDEF_(0x80110605L) +#define COMQC_E_UNTRUSTED_ENQUEUER _HRESULT_TYPEDEF_(0x80110606L) +#define MSDTC_E_DUPLICATE_RESOURCE _HRESULT_TYPEDEF_(0x80110701L) +#define COMADMIN_E_OBJECT_PARENT_MISSING _HRESULT_TYPEDEF_(0x80110808L) +#define COMADMIN_E_OBJECT_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x80110809L) +#define COMADMIN_E_APP_NOT_RUNNING _HRESULT_TYPEDEF_(0x8011080AL) +#define COMADMIN_E_INVALID_PARTITION _HRESULT_TYPEDEF_(0x8011080BL) +#define COMADMIN_E_SVCAPP_NOT_POOLABLE_OR_RECYCLABLE _HRESULT_TYPEDEF_(0x8011080DL) +#define COMADMIN_E_USER_IN_SET _HRESULT_TYPEDEF_(0x8011080EL) +#define COMADMIN_E_CANTRECYCLELIBRARYAPPS _HRESULT_TYPEDEF_(0x8011080FL) +#define COMADMIN_E_CANTRECYCLESERVICEAPPS _HRESULT_TYPEDEF_(0x80110811L) +#define COMADMIN_E_PROCESSALREADYRECYCLED _HRESULT_TYPEDEF_(0x80110812L) +#define COMADMIN_E_PAUSEDPROCESSMAYNOTBERECYCLED _HRESULT_TYPEDEF_(0x80110813L) +#define COMADMIN_E_CANTMAKEINPROCSERVICE _HRESULT_TYPEDEF_(0x80110814L) +#define COMADMIN_E_PROGIDINUSEBYCLSID _HRESULT_TYPEDEF_(0x80110815L) +#define COMADMIN_E_DEFAULT_PARTITION_NOT_IN_SET _HRESULT_TYPEDEF_(0x80110816L) +#define COMADMIN_E_RECYCLEDPROCESSMAYNOTBEPAUSED _HRESULT_TYPEDEF_(0x80110817L) +#define COMADMIN_E_PARTITION_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110818L) +#define COMADMIN_E_PARTITION_MSI_ONLY _HRESULT_TYPEDEF_(0x80110819L) +#define COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_1_0_FORMAT _HRESULT_TYPEDEF_(0x8011081AL) +#define COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_NONBASE_PARTITIONS _HRESULT_TYPEDEF_(0x8011081BL) +#define COMADMIN_E_COMP_MOVE_SOURCE _HRESULT_TYPEDEF_(0x8011081CL) +#define COMADMIN_E_COMP_MOVE_DEST _HRESULT_TYPEDEF_(0x8011081DL) +#define COMADMIN_E_COMP_MOVE_PRIVATE _HRESULT_TYPEDEF_(0x8011081EL) +#define COMADMIN_E_BASEPARTITION_REQUIRED_IN_SET _HRESULT_TYPEDEF_(0x8011081FL) +#define COMADMIN_E_CANNOT_ALIAS_EVENTCLASS _HRESULT_TYPEDEF_(0x80110820L) +#define COMADMIN_E_PRIVATE_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110821L) +#define COMADMIN_E_SAFERINVALID _HRESULT_TYPEDEF_(0x80110822L) +#define COMADMIN_E_REGISTRY_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110823L) +#define COMADMIN_E_PARTITIONS_DISABLED _HRESULT_TYPEDEF_(0x80110824L) +#endif /* _WINERROR_ */ diff --git a/tinyc/win32/include/winapi/wingdi.h b/tinyc/win32/include/winapi/wingdi.h index b0af5adeb..63d389178 100644 --- a/tinyc/win32/include/winapi/wingdi.h +++ b/tinyc/win32/include/winapi/wingdi.h @@ -1,373 +1,1152 @@ -#ifndef _WINGDI_H -#define _WINGDI_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINGDI_ +#define _WINGDI_ + +#define WINGDIAPI DECLSPEC_IMPORT +#define WINSPOOLAPI DECLSPEC_IMPORT #ifdef __cplusplus extern "C" { #endif -#define WINGDIAPI -#define BI_RGB 0 -#define BI_RLE8 1 -#define BI_RLE4 2 -#define BI_BITFIELDS 3 -#define BI_JPEG 4 -#define BI_PNG 5 -#define LF_FACESIZE 32 -#define LF_FULLFACESIZE 64 -#define CA_NEGATIVE 1 -#define CA_LOG_FILTER 2 -#define ILLUMINANT_DEVICE_DEFAULT 0 -#define ILLUMINANT_A 1 -#define ILLUMINANT_B 2 -#define ILLUMINANT_C 3 -#define ILLUMINANT_D50 4 -#define ILLUMINANT_D55 5 -#define ILLUMINANT_D65 6 -#define ILLUMINANT_D75 7 -#define ILLUMINANT_F2 8 -#define ILLUMINANT_MAX_INDEX ILLUMINANT_F2 -#define ILLUMINANT_TUNGSTEN ILLUMINANT_A -#define ILLUMINANT_DAYLIGHT ILLUMINANT_C -#define ILLUMINANT_FLUORESCENT ILLUMINANT_F2 -#define ILLUMINANT_NTSC ILLUMINANT_C -#define RGB_GAMMA_MIN 2500 -#define RGB_GAMMA_MAX 65000 -#define REFERENCE_WHITE_MIN 6000 -#define REFERENCE_WHITE_MAX 10000 -#define REFERENCE_BLACK_MIN 0 -#define REFERENCE_BLACK_MAX 4000 -#define COLOR_ADJ_MIN (-100) -#define COLOR_ADJ_MAX 100 -#define CCHDEVICENAME 32 -#define CCHFORMNAME 32 -#define DI_COMPAT 4 -#define DI_DEFAULTSIZE 8 -#define DI_IMAGE 2 -#define DI_MASK 1 -#define DI_NORMAL 3 -#define DI_APPBANDING 1 -#define EMR_HEADER 1 -#define EMR_POLYBEZIER 2 -#define EMR_POLYGON 3 -#define EMR_POLYLINE 4 -#define EMR_POLYBEZIERTO 5 -#define EMR_POLYLINETO 6 -#define EMR_POLYPOLYLINE 7 -#define EMR_POLYPOLYGON 8 -#define EMR_SETWINDOWEXTEX 9 -#define EMR_SETWINDOWORGEX 10 -#define EMR_SETVIEWPORTEXTEX 11 -#define EMR_SETVIEWPORTORGEX 12 -#define EMR_SETBRUSHORGEX 13 -#define EMR_EOF 14 -#define EMR_SETPIXELV 15 -#define EMR_SETMAPPERFLAGS 16 -#define EMR_SETMAPMODE 17 -#define EMR_SETBKMODE 18 -#define EMR_SETPOLYFILLMODE 19 -#define EMR_SETROP2 20 -#define EMR_SETSTRETCHBLTMODE 21 -#define EMR_SETTEXTALIGN 22 -#define EMR_SETCOLORADJUSTMENT 23 -#define EMR_SETTEXTCOLOR 24 -#define EMR_SETBKCOLOR 25 -#define EMR_OFFSETCLIPRGN 26 -#define EMR_MOVETOEX 27 -#define EMR_SETMETARGN 28 -#define EMR_EXCLUDECLIPRECT 29 -#define EMR_INTERSECTCLIPRECT 30 -#define EMR_SCALEVIEWPORTEXTEX 31 -#define EMR_SCALEWINDOWEXTEX 32 -#define EMR_SAVEDC 33 -#define EMR_RESTOREDC 34 -#define EMR_SETWORLDTRANSFORM 35 -#define EMR_MODIFYWORLDTRANSFORM 36 -#define EMR_SELECTOBJECT 37 -#define EMR_CREATEPEN 38 -#define EMR_CREATEBRUSHINDIRECT 39 -#define EMR_DELETEOBJECT 40 -#define EMR_ANGLEARC 41 -#define EMR_ELLIPSE 42 -#define EMR_RECTANGLE 43 -#define EMR_ROUNDRECT 44 -#define EMR_ARC 45 -#define EMR_CHORD 46 -#define EMR_PIE 47 -#define EMR_SELECTPALETTE 48 -#define EMR_CREATEPALETTE 49 -#define EMR_SETPALETTEENTRIES 50 -#define EMR_RESIZEPALETTE 51 -#define EMR_REALIZEPALETTE 52 -#define EMR_EXTFLOODFILL 53 -#define EMR_LINETO 54 -#define EMR_ARCTO 55 -#define EMR_POLYDRAW 56 -#define EMR_SETARCDIRECTION 57 -#define EMR_SETMITERLIMIT 58 -#define EMR_BEGINPATH 59 -#define EMR_ENDPATH 60 -#define EMR_CLOSEFIGURE 61 -#define EMR_FILLPATH 62 -#define EMR_STROKEANDFILLPATH 63 -#define EMR_STROKEPATH 64 -#define EMR_FLATTENPATH 65 -#define EMR_WIDENPATH 66 -#define EMR_SELECTCLIPPATH 67 -#define EMR_ABORTPATH 68 -#define EMR_GDICOMMENT 70 -#define EMR_FILLRGN 71 -#define EMR_FRAMERGN 72 -#define EMR_INVERTRGN 73 -#define EMR_PAINTRGN 74 -#define EMR_EXTSELECTCLIPRGN 75 -#define EMR_BITBLT 76 -#define EMR_STRETCHBLT 77 -#define EMR_MASKBLT 78 -#define EMR_PLGBLT 79 -#define EMR_SETDIBITSTODEVICE 80 -#define EMR_STRETCHDIBITS 81 -#define EMR_EXTCREATEFONTINDIRECTW 82 -#define EMR_EXTTEXTOUTA 83 -#define EMR_EXTTEXTOUTW 84 -#define EMR_POLYBEZIER16 85 -#define EMR_POLYGON16 86 -#define EMR_POLYLINE16 87 -#define EMR_POLYBEZIERTO16 88 -#define EMR_POLYLINETO16 89 -#define EMR_POLYPOLYLINE16 90 -#define EMR_POLYPOLYGON16 91 -#define EMR_POLYDRAW16 92 -#define EMR_CREATEMONOBRUSH 93 -#define EMR_CREATEDIBPATTERNBRUSHPT 94 -#define EMR_EXTCREATEPEN 95 -#define EMR_POLYTEXTOUTA 96 -#define EMR_POLYTEXTOUTW 97 -#define EMR_SETICMMODE 98 -#define EMR_CREATECOLORSPACE 99 -#define EMR_SETCOLORSPACE 100 -#define EMR_DELETECOLORSPACE 101 -#define EMR_GLSRECORD 102 -#define EMR_GLSBOUNDEDRECORD 103 -#define EMR_PIXELFORMAT 104 -#define ENHMETA_SIGNATURE 1179469088 -#define EPS_SIGNATURE 0x46535045 -#define META_SETBKCOLOR 0x201 -#define META_SETBKMODE 0x102 -#define META_SETMAPMODE 0x103 -#define META_SETROP2 0x104 -#define META_SETRELABS 0x105 -#define META_SETPOLYFILLMODE 0x106 -#define META_SETSTRETCHBLTMODE 0x107 -#define META_SETTEXTCHAREXTRA 0x108 -#define META_SETTEXTCOLOR 0x209 -#define META_SETTEXTJUSTIFICATION 0x20A -#define META_SETWINDOWORG 0x20B -#define META_SETWINDOWEXT 0x20C -#define META_SETVIEWPORTORG 0x20D -#define META_SETVIEWPORTEXT 0x20E -#define META_OFFSETWINDOWORG 0x20F -#define META_SCALEWINDOWEXT 0x410 -#define META_OFFSETVIEWPORTORG 0x211 -#define META_SCALEVIEWPORTEXT 0x412 -#define META_LINETO 0x213 -#define META_MOVETO 0x214 -#define META_EXCLUDECLIPRECT 0x415 -#define META_INTERSECTCLIPRECT 0x416 -#define META_ARC 0x817 -#define META_ELLIPSE 0x418 -#define META_FLOODFILL 0x419 -#define META_PIE 0x81A -#define META_RECTANGLE 0x41B -#define META_ROUNDRECT 0x61C -#define META_PATBLT 0x61D -#define META_SAVEDC 0x1E -#define META_SETPIXEL 0x41F -#define META_OFFSETCLIPRGN 0x220 -#define META_TEXTOUT 0x521 -#define META_BITBLT 0x922 -#define META_STRETCHBLT 0xB23 -#define META_POLYGON 0x324 -#define META_POLYLINE 0x325 -#define META_ESCAPE 0x626 -#define META_RESTOREDC 0x127 -#define META_FILLREGION 0x228 -#define META_FRAMEREGION 0x429 -#define META_INVERTREGION 0x12A -#define META_PAINTREGION 0x12B -#define META_SELECTCLIPREGION 0x12C -#define META_SELECTOBJECT 0x12D -#define META_SETTEXTALIGN 0x12E -#define META_CHORD 0x830 -#define META_SETMAPPERFLAGS 0x231 -#define META_EXTTEXTOUT 0xa32 -#define META_SETDIBTODEV 0xd33 -#define META_SELECTPALETTE 0x234 -#define META_REALIZEPALETTE 0x35 -#define META_ANIMATEPALETTE 0x436 -#define META_SETPALENTRIES 0x37 -#define META_POLYPOLYGON 0x538 -#define META_RESIZEPALETTE 0x139 -#define META_DIBBITBLT 0x940 -#define META_DIBSTRETCHBLT 0xb41 -#define META_DIBCREATEPATTERNBRUSH 0x142 -#define META_STRETCHDIB 0xf43 -#define META_EXTFLOODFILL 0x548 -#define META_DELETEOBJECT 0x1f0 -#define META_CREATEPALETTE 0xf7 -#define META_CREATEPATTERNBRUSH 0x1F9 -#define META_CREATEPENINDIRECT 0x2FA -#define META_CREATEFONTINDIRECT 0x2FB -#define META_CREATEBRUSHINDIRECT 0x2FC -#define META_CREATEREGION 0x6FF -#define PT_MOVETO 6 -#define PT_LINETO 2 -#define PT_BEZIERTO 4 -#define PT_CLOSEFIGURE 1 -#define ELF_VENDOR_SIZE 4 -#define ELF_VERSION 0 -#define ELF_CULTURE_LATIN 0 -#define PFD_TYPE_RGBA 0 -#define PFD_TYPE_COLORINDEX 1 -#define PFD_MAIN_PLANE 0 -#define PFD_OVERLAY_PLANE 1 -#define PFD_UNDERLAY_PLANE (-1) -#define PFD_DOUBLEBUFFER 1 -#define PFD_STEREO 2 -#define PFD_DRAW_TO_WINDOW 4 -#define PFD_DRAW_TO_BITMAP 8 -#define PFD_SUPPORT_GDI 16 -#define PFD_SUPPORT_OPENGL 32 -#define PFD_GENERIC_FORMAT 64 -#define PFD_NEED_PALETTE 128 -#define PFD_NEED_SYSTEM_PALETTE 0x00000100 -#define PFD_SWAP_EXCHANGE 0x00000200 -#define PFD_SWAP_COPY 0x00000400 -#define PFD_GENERIC_ACCELERATED 0x00001000 -#define PFD_DEPTH_DONTCARE 0x20000000 -#define PFD_DOUBLEBUFFER_DONTCARE 0x40000000 -#define PFD_STEREO_DONTCARE 0x80000000 -#define SP_ERROR (-1) -#define SP_OUTOFDISK (-4) -#define SP_OUTOFMEMORY (-5) -#define SP_USERABORT (-3) -#define SP_APPABORT (-2) -#define BLACKNESS 0x42 -#define NOTSRCERASE 0x1100A6 -#define NOTSRCCOPY 0x330008 -#define SRCERASE 0x440328 -#define DSTINVERT 0x550009 -#define PATINVERT 0x5A0049 -#define SRCINVERT 0x660046 -#define SRCAND 0x8800C6 -#define MERGEPAINT 0xBB0226 -#define MERGECOPY 0xC000CA -#define SRCCOPY 0xCC0020 -#define SRCPAINT 0xEE0086 -#define PATCOPY 0xF00021 -#define PATPAINT 0xFB0A09 -#define WHITENESS 0xFF0062 -#define R2_BLACK 1 -#define R2_COPYPEN 13 -#define R2_MASKNOTPEN 3 -#define R2_MASKPEN 9 -#define R2_MASKPENNOT 5 -#define R2_MERGENOTPEN 12 -#define R2_MERGEPEN 15 -#define R2_MERGEPENNOT 14 -#define R2_NOP 11 -#define R2_NOT 6 -#define R2_NOTCOPYPEN 4 -#define R2_NOTMASKPEN 8 -#define R2_NOTMERGEPEN 2 -#define R2_NOTXORPEN 10 -#define R2_WHITE 16 -#define R2_XORPEN 7 -#define CM_OUT_OF_GAMUT 255 -#define CM_IN_GAMUT 0 -#define RGN_AND 1 -#define RGN_COPY 5 -#define RGN_DIFF 4 -#define RGN_OR 2 -#define RGN_XOR 3 -#define NULLREGION 1 -#define SIMPLEREGION 2 -#define COMPLEXREGION 3 +#ifndef WINVER +#define WINVER 0x0502 +#endif + +#ifndef NOGDI +#ifndef NORASTEROPS +#define R2_BLACK 1 +#define R2_NOTMERGEPEN 2 +#define R2_MASKNOTPEN 3 +#define R2_NOTCOPYPEN 4 +#define R2_MASKPENNOT 5 +#define R2_NOT 6 +#define R2_XORPEN 7 +#define R2_NOTMASKPEN 8 +#define R2_MASKPEN 9 +#define R2_NOTXORPEN 10 +#define R2_NOP 11 +#define R2_MERGENOTPEN 12 +#define R2_COPYPEN 13 +#define R2_MERGEPENNOT 14 +#define R2_MERGEPEN 15 +#define R2_WHITE 16 +#define R2_LAST 16 + +#define SRCCOPY (DWORD)0x00CC0020 +#define SRCPAINT (DWORD)0x00EE0086 +#define SRCAND (DWORD)0x008800C6 +#define SRCINVERT (DWORD)0x00660046 +#define SRCERASE (DWORD)0x00440328 +#define NOTSRCCOPY (DWORD)0x00330008 +#define NOTSRCERASE (DWORD)0x001100A6 +#define MERGECOPY (DWORD)0x00C000CA +#define MERGEPAINT (DWORD)0x00BB0226 +#define PATCOPY (DWORD)0x00F00021 +#define PATPAINT (DWORD)0x00FB0A09 +#define PATINVERT (DWORD)0x005A0049 +#define DSTINVERT (DWORD)0x00550009 +#define BLACKNESS (DWORD)0x00000042 +#define WHITENESS (DWORD)0x00FF0062 +#define NOMIRRORBITMAP (DWORD)0x80000000 +#define CAPTUREBLT (DWORD)0x40000000 +#define MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore)) +#endif + +#define GDI_ERROR (0xFFFFFFFFL) +#define HGDI_ERROR (LongToHandle(0xFFFFFFFFL)) + #define ERROR 0 -#define CBM_INIT 4 -#define DIB_PAL_COLORS 1 -#define DIB_RGB_COLORS 0 -#define FW_DONTCARE 0 -#define FW_THIN 100 -#define FW_EXTRALIGHT 200 -#define FW_ULTRALIGHT FW_EXTRALIGHT -#define FW_LIGHT 300 -#define FW_NORMAL 400 -#define FW_REGULAR 400 -#define FW_MEDIUM 500 -#define FW_SEMIBOLD 600 -#define FW_DEMIBOLD FW_SEMIBOLD -#define FW_BOLD 700 -#define FW_EXTRABOLD 800 -#define FW_ULTRABOLD FW_EXTRABOLD -#define FW_HEAVY 900 -#define FW_BLACK FW_HEAVY -#define ANSI_CHARSET 0 -#define DEFAULT_CHARSET 1 -#define SYMBOL_CHARSET 2 -#define SHIFTJIS_CHARSET 128 -#define HANGEUL_CHARSET 129 -#define HANGUL_CHARSET 129 -#define GB2312_CHARSET 134 -#define CHINESEBIG5_CHARSET 136 -#define GREEK_CHARSET 161 -#define TURKISH_CHARSET 162 -#define HEBREW_CHARSET 177 -#define ARABIC_CHARSET 178 -#define BALTIC_CHARSET 186 -#define RUSSIAN_CHARSET 204 -#define THAI_CHARSET 222 -#define EASTEUROPE_CHARSET 238 -#define OEM_CHARSET 255 -#define JOHAB_CHARSET 130 -#define VIETNAMESE_CHARSET 163 -#define MAC_CHARSET 77 -#define BALTIC_CHARSET 186 -#define JOHAB_CHARSET 130 -#define VIETNAMESE_CHARSET 163 -#define OUT_DEFAULT_PRECIS 0 -#define OUT_STRING_PRECIS 1 -#define OUT_CHARACTER_PRECIS 2 -#define OUT_STROKE_PRECIS 3 -#define OUT_TT_PRECIS 4 -#define OUT_DEVICE_PRECIS 5 -#define OUT_RASTER_PRECIS 6 -#define OUT_TT_ONLY_PRECIS 7 -#define OUT_OUTLINE_PRECIS 8 -#define CLIP_DEFAULT_PRECIS 0 -#define CLIP_CHARACTER_PRECIS 1 -#define CLIP_STROKE_PRECIS 2 -#define CLIP_MASK 15 -#define CLIP_LH_ANGLES 16 -#define CLIP_TT_ALWAYS 32 -#define CLIP_EMBEDDED 128 -#define DEFAULT_QUALITY 0 -#define DRAFT_QUALITY 1 -#define PROOF_QUALITY 2 +#define NULLREGION 1 +#define SIMPLEREGION 2 +#define COMPLEXREGION 3 +#define RGN_ERROR ERROR + +#define RGN_AND 1 +#define RGN_OR 2 +#define RGN_XOR 3 +#define RGN_DIFF 4 +#define RGN_COPY 5 +#define RGN_MIN RGN_AND +#define RGN_MAX RGN_COPY + +#define BLACKONWHITE 1 +#define WHITEONBLACK 2 +#define COLORONCOLOR 3 +#define HALFTONE 4 +#define MAXSTRETCHBLTMODE 4 + +#define STRETCH_ANDSCANS BLACKONWHITE +#define STRETCH_ORSCANS WHITEONBLACK +#define STRETCH_DELETESCANS COLORONCOLOR +#define STRETCH_HALFTONE HALFTONE + +#define ALTERNATE 1 +#define WINDING 2 +#define POLYFILL_LAST 2 + +#define LAYOUT_RTL 0x00000001 +#define LAYOUT_BTT 0x00000002 +#define LAYOUT_VBH 0x00000004 +#define LAYOUT_ORIENTATIONMASK (LAYOUT_RTL | LAYOUT_BTT | LAYOUT_VBH) +#define LAYOUT_BITMAPORIENTATIONPRESERVED 0x00000008 + +#define TA_NOUPDATECP 0 +#define TA_UPDATECP 1 + +#define TA_LEFT 0 +#define TA_RIGHT 2 +#define TA_CENTER 6 + +#define TA_TOP 0 +#define TA_BOTTOM 8 +#define TA_BASELINE 24 +#define TA_RTLREADING 256 +#define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING) + +#define VTA_BASELINE TA_BASELINE +#define VTA_LEFT TA_BOTTOM +#define VTA_RIGHT TA_TOP +#define VTA_CENTER TA_CENTER +#define VTA_BOTTOM TA_RIGHT +#define VTA_TOP TA_LEFT + +#define ETO_OPAQUE 0x0002 +#define ETO_CLIPPED 0x0004 +#define ETO_GLYPH_INDEX 0x0010 +#define ETO_RTLREADING 0x0080 +#define ETO_NUMERICSLOCAL 0x0400 +#define ETO_NUMERICSLATIN 0x0800 +#define ETO_IGNORELANGUAGE 0x1000 +#define ETO_PDY 0x2000 + +#define ASPECT_FILTERING 0x0001 + +#define DCB_RESET 0x0001 +#define DCB_ACCUMULATE 0x0002 +#define DCB_DIRTY DCB_ACCUMULATE +#define DCB_SET (DCB_RESET | DCB_ACCUMULATE) +#define DCB_ENABLE 0x0004 +#define DCB_DISABLE 0x0008 + +#ifndef NOMETAFILE + +#define META_SETBKCOLOR 0x0201 +#define META_SETBKMODE 0x0102 +#define META_SETMAPMODE 0x0103 +#define META_SETROP2 0x0104 +#define META_SETRELABS 0x0105 +#define META_SETPOLYFILLMODE 0x0106 +#define META_SETSTRETCHBLTMODE 0x0107 +#define META_SETTEXTCHAREXTRA 0x0108 +#define META_SETTEXTCOLOR 0x0209 +#define META_SETTEXTJUSTIFICATION 0x020A +#define META_SETWINDOWORG 0x020B +#define META_SETWINDOWEXT 0x020C +#define META_SETVIEWPORTORG 0x020D +#define META_SETVIEWPORTEXT 0x020E +#define META_OFFSETWINDOWORG 0x020F +#define META_SCALEWINDOWEXT 0x0410 +#define META_OFFSETVIEWPORTORG 0x0211 +#define META_SCALEVIEWPORTEXT 0x0412 +#define META_LINETO 0x0213 +#define META_MOVETO 0x0214 +#define META_EXCLUDECLIPRECT 0x0415 +#define META_INTERSECTCLIPRECT 0x0416 +#define META_ARC 0x0817 +#define META_ELLIPSE 0x0418 +#define META_FLOODFILL 0x0419 +#define META_PIE 0x081A +#define META_RECTANGLE 0x041B +#define META_ROUNDRECT 0x061C +#define META_PATBLT 0x061D +#define META_SAVEDC 0x001E +#define META_SETPIXEL 0x041F +#define META_OFFSETCLIPRGN 0x0220 +#define META_TEXTOUT 0x0521 +#define META_BITBLT 0x0922 +#define META_STRETCHBLT 0x0B23 +#define META_POLYGON 0x0324 +#define META_POLYLINE 0x0325 +#define META_ESCAPE 0x0626 +#define META_RESTOREDC 0x0127 +#define META_FILLREGION 0x0228 +#define META_FRAMEREGION 0x0429 +#define META_INVERTREGION 0x012A +#define META_PAINTREGION 0x012B +#define META_SELECTCLIPREGION 0x012C +#define META_SELECTOBJECT 0x012D +#define META_SETTEXTALIGN 0x012E +#define META_CHORD 0x0830 +#define META_SETMAPPERFLAGS 0x0231 +#define META_EXTTEXTOUT 0x0a32 +#define META_SETDIBTODEV 0x0d33 +#define META_SELECTPALETTE 0x0234 +#define META_REALIZEPALETTE 0x0035 +#define META_ANIMATEPALETTE 0x0436 +#define META_SETPALENTRIES 0x0037 +#define META_POLYPOLYGON 0x0538 +#define META_RESIZEPALETTE 0x0139 +#define META_DIBBITBLT 0x0940 +#define META_DIBSTRETCHBLT 0x0b41 +#define META_DIBCREATEPATTERNBRUSH 0x0142 +#define META_STRETCHDIB 0x0f43 +#define META_EXTFLOODFILL 0x0548 +#define META_SETLAYOUT 0x0149 +#define META_DELETEOBJECT 0x01f0 +#define META_CREATEPALETTE 0x00f7 +#define META_CREATEPATTERNBRUSH 0x01F9 +#define META_CREATEPENINDIRECT 0x02FA +#define META_CREATEFONTINDIRECT 0x02FB +#define META_CREATEBRUSHINDIRECT 0x02FC +#define META_CREATEREGION 0x06FF + + typedef struct _DRAWPATRECT { + POINT ptPosition; + POINT ptSize; + WORD wStyle; + WORD wPattern; + } DRAWPATRECT,*PDRAWPATRECT; +#endif + +#define NEWFRAME 1 +#define ABORTDOC 2 +#define NEXTBAND 3 +#define SETCOLORTABLE 4 +#define GETCOLORTABLE 5 +#define FLUSHOUTPUT 6 +#define DRAFTMODE 7 +#define QUERYESCSUPPORT 8 +#define SETABORTPROC 9 +#define STARTDOC 10 +#define ENDDOC 11 +#define GETPHYSPAGESIZE 12 +#define GETPRINTINGOFFSET 13 +#define GETSCALINGFACTOR 14 +#define MFCOMMENT 15 +#define GETPENWIDTH 16 +#define SETCOPYCOUNT 17 +#define SELECTPAPERSOURCE 18 +#define DEVICEDATA 19 +#define PASSTHROUGH 19 +#define GETTECHNOLGY 20 +#define GETTECHNOLOGY 20 +#define SETLINECAP 21 +#define SETLINEJOIN 22 +#define SETMITERLIMIT 23 +#define BANDINFO 24 +#define DRAWPATTERNRECT 25 +#define GETVECTORPENSIZE 26 +#define GETVECTORBRUSHSIZE 27 +#define ENABLEDUPLEX 28 +#define GETSETPAPERBINS 29 +#define GETSETPRINTORIENT 30 +#define ENUMPAPERBINS 31 +#define SETDIBSCALING 32 +#define EPSPRINTING 33 +#define ENUMPAPERMETRICS 34 +#define GETSETPAPERMETRICS 35 +#define POSTSCRIPT_DATA 37 +#define POSTSCRIPT_IGNORE 38 +#define MOUSETRAILS 39 +#define GETDEVICEUNITS 42 + +#define GETEXTENDEDTEXTMETRICS 256 +#define GETEXTENTTABLE 257 +#define GETPAIRKERNTABLE 258 +#define GETTRACKKERNTABLE 259 +#define EXTTEXTOUT 512 +#define GETFACENAME 513 +#define DOWNLOADFACE 514 +#define ENABLERELATIVEWIDTHS 768 +#define ENABLEPAIRKERNING 769 +#define SETKERNTRACK 770 +#define SETALLJUSTVALUES 771 +#define SETCHARSET 772 + +#define STRETCHBLT 2048 +#define METAFILE_DRIVER 2049 +#define GETSETSCREENPARAMS 3072 +#define QUERYDIBSUPPORT 3073 +#define BEGIN_PATH 4096 +#define CLIP_TO_PATH 4097 +#define END_PATH 4098 +#define EXT_DEVICE_CAPS 4099 +#define RESTORE_CTM 4100 +#define SAVE_CTM 4101 +#define SET_ARC_DIRECTION 4102 +#define SET_BACKGROUND_COLOR 4103 +#define SET_POLY_MODE 4104 +#define SET_SCREEN_ANGLE 4105 +#define SET_SPREAD 4106 +#define TRANSFORM_CTM 4107 +#define SET_CLIP_BOX 4108 +#define SET_BOUNDS 4109 +#define SET_MIRROR_MODE 4110 +#define OPENCHANNEL 4110 +#define DOWNLOADHEADER 4111 +#define CLOSECHANNEL 4112 +#define POSTSCRIPT_PASSTHROUGH 4115 +#define ENCAPSULATED_POSTSCRIPT 4116 + +#define POSTSCRIPT_IDENTIFY 4117 +#define POSTSCRIPT_INJECTION 4118 + +#define CHECKJPEGFORMAT 4119 +#define CHECKPNGFORMAT 4120 + +#define GET_PS_FEATURESETTING 4121 + +#define SPCLPASSTHROUGH2 4568 + +#define PSIDENT_GDICENTRIC 0 +#define PSIDENT_PSCENTRIC 1 + + typedef struct _PSINJECTDATA { + DWORD DataBytes; + WORD InjectionPoint; + WORD PageNumber; + } PSINJECTDATA,*PPSINJECTDATA; + +#define PSINJECT_BEGINSTREAM 1 +#define PSINJECT_PSADOBE 2 +#define PSINJECT_PAGESATEND 3 +#define PSINJECT_PAGES 4 + +#define PSINJECT_DOCNEEDEDRES 5 +#define PSINJECT_DOCSUPPLIEDRES 6 +#define PSINJECT_PAGEORDER 7 +#define PSINJECT_ORIENTATION 8 +#define PSINJECT_BOUNDINGBOX 9 +#define PSINJECT_DOCUMENTPROCESSCOLORS 10 + +#define PSINJECT_COMMENTS 11 +#define PSINJECT_BEGINDEFAULTS 12 +#define PSINJECT_ENDDEFAULTS 13 +#define PSINJECT_BEGINPROLOG 14 +#define PSINJECT_ENDPROLOG 15 +#define PSINJECT_BEGINSETUP 16 +#define PSINJECT_ENDSETUP 17 +#define PSINJECT_TRAILER 18 +#define PSINJECT_EOF 19 +#define PSINJECT_ENDSTREAM 20 +#define PSINJECT_DOCUMENTPROCESSCOLORSATEND 21 + +#define PSINJECT_PAGENUMBER 100 +#define PSINJECT_BEGINPAGESETUP 101 +#define PSINJECT_ENDPAGESETUP 102 +#define PSINJECT_PAGETRAILER 103 +#define PSINJECT_PLATECOLOR 104 + +#define PSINJECT_SHOWPAGE 105 +#define PSINJECT_PAGEBBOX 106 +#define PSINJECT_ENDPAGECOMMENTS 107 + +#define PSINJECT_VMSAVE 200 +#define PSINJECT_VMRESTORE 201 + +#define FEATURESETTING_NUP 0 +#define FEATURESETTING_OUTPUT 1 +#define FEATURESETTING_PSLEVEL 2 +#define FEATURESETTING_CUSTPAPER 3 +#define FEATURESETTING_MIRROR 4 +#define FEATURESETTING_NEGATIVE 5 +#define FEATURESETTING_PROTOCOL 6 + +#define FEATURESETTING_PRIVATE_BEGIN 0x1000 +#define FEATURESETTING_PRIVATE_END 0x1FFF + + typedef struct _PSFEATURE_OUTPUT { + WINBOOL bPageIndependent; + WINBOOL bSetPageDevice; + } PSFEATURE_OUTPUT,*PPSFEATURE_OUTPUT; + + typedef struct _PSFEATURE_CUSTPAPER { + LONG lOrientation; + LONG lWidth; + LONG lHeight; + LONG lWidthOffset; + LONG lHeightOffset; + } PSFEATURE_CUSTPAPER,*PPSFEATURE_CUSTPAPER; + +#define PSPROTOCOL_ASCII 0 +#define PSPROTOCOL_BCP 1 +#define PSPROTOCOL_TBCP 2 +#define PSPROTOCOL_BINARY 3 + +#define QDI_SETDIBITS 1 +#define QDI_GETDIBITS 2 +#define QDI_DIBTOSCREEN 4 +#define QDI_STRETCHDIB 8 + +#define SP_NOTREPORTED 0x4000 +#define SP_ERROR (-1) +#define SP_APPABORT (-2) +#define SP_USERABORT (-3) +#define SP_OUTOFDISK (-4) +#define SP_OUTOFMEMORY (-5) + +#define PR_JOBSTATUS 0x0000 + +#define OBJ_PEN 1 +#define OBJ_BRUSH 2 +#define OBJ_DC 3 +#define OBJ_METADC 4 +#define OBJ_PAL 5 +#define OBJ_FONT 6 +#define OBJ_BITMAP 7 +#define OBJ_REGION 8 +#define OBJ_METAFILE 9 +#define OBJ_MEMDC 10 +#define OBJ_EXTPEN 11 +#define OBJ_ENHMETADC 12 +#define OBJ_ENHMETAFILE 13 +#define OBJ_COLORSPACE 14 + +#define MWT_IDENTITY 1 +#define MWT_LEFTMULTIPLY 2 +#define MWT_RIGHTMULTIPLY 3 + +#define MWT_MIN MWT_IDENTITY +#define MWT_MAX MWT_RIGHTMULTIPLY + +#define _XFORM_ + typedef struct tagXFORM { + FLOAT eM11; + FLOAT eM12; + FLOAT eM21; + FLOAT eM22; + FLOAT eDx; + FLOAT eDy; + } XFORM,*PXFORM,*LPXFORM; + + typedef struct tagBITMAP { + LONG bmType; + LONG bmWidth; + LONG bmHeight; + LONG bmWidthBytes; + WORD bmPlanes; + WORD bmBitsPixel; + LPVOID bmBits; + } BITMAP,*PBITMAP,*NPBITMAP,*LPBITMAP; + +#include <pshpack1.h> + typedef struct tagRGBTRIPLE { + BYTE rgbtBlue; + BYTE rgbtGreen; + BYTE rgbtRed; + } RGBTRIPLE; +#include <poppack.h> + + typedef struct tagRGBQUAD { + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; + BYTE rgbReserved; + } RGBQUAD; + typedef RGBQUAD *LPRGBQUAD; + +#define CS_ENABLE 0x00000001L +#define CS_DISABLE 0x00000002L +#define CS_DELETE_TRANSFORM 0x00000003L + +//!__TINYC__: #define LCS_SIGNATURE 'PSOC' +//!__TINYC__: #define LCS_sRGB 'sRGB' +//!__TINYC__: #define LCS_WINDOWS_COLOR_SPACE 'Win ' + + typedef LONG LCSCSTYPE; +#define LCS_CALIBRATED_RGB 0x00000000L + + typedef LONG LCSGAMUTMATCH; +#define LCS_GM_BUSINESS 0x00000001L +#define LCS_GM_GRAPHICS 0x00000002L +#define LCS_GM_IMAGES 0x00000004L +#define LCS_GM_ABS_COLORIMETRIC 0x00000008L + +#define CM_OUT_OF_GAMUT 255 +#define CM_IN_GAMUT 0 + +#define ICM_ADDPROFILE 1 +#define ICM_DELETEPROFILE 2 +#define ICM_QUERYPROFILE 3 +#define ICM_SETDEFAULTPROFILE 4 +#define ICM_REGISTERICMATCHER 5 +#define ICM_UNREGISTERICMATCHER 6 +#define ICM_QUERYMATCH 7 + +#define GetKValue(cmyk) ((BYTE)(cmyk)) +#define GetYValue(cmyk) ((BYTE)((cmyk)>> 8)) +#define GetMValue(cmyk) ((BYTE)((cmyk)>>16)) +#define GetCValue(cmyk) ((BYTE)((cmyk)>>24)) + +#define CMYK(c,m,y,k) ((COLORREF)((((BYTE)(k)|((WORD)((BYTE)(y))<<8))|(((DWORD)(BYTE)(m))<<16))|(((DWORD)(BYTE)(c))<<24))) + + typedef long FXPT16DOT16,*LPFXPT16DOT16; + typedef long FXPT2DOT30,*LPFXPT2DOT30; + + typedef struct tagCIEXYZ { + FXPT2DOT30 ciexyzX; + FXPT2DOT30 ciexyzY; + FXPT2DOT30 ciexyzZ; + } CIEXYZ; + typedef CIEXYZ *LPCIEXYZ; + + typedef struct tagICEXYZTRIPLE { + CIEXYZ ciexyzRed; + CIEXYZ ciexyzGreen; + CIEXYZ ciexyzBlue; + } CIEXYZTRIPLE; + + typedef CIEXYZTRIPLE *LPCIEXYZTRIPLE; + + typedef struct tagLOGCOLORSPACEA { + DWORD lcsSignature; + DWORD lcsVersion; + DWORD lcsSize; + LCSCSTYPE lcsCSType; + LCSGAMUTMATCH lcsIntent; + CIEXYZTRIPLE lcsEndpoints; + DWORD lcsGammaRed; + DWORD lcsGammaGreen; + DWORD lcsGammaBlue; + CHAR lcsFilename[MAX_PATH]; + } LOGCOLORSPACEA,*LPLOGCOLORSPACEA; + + typedef struct tagLOGCOLORSPACEW { + DWORD lcsSignature; + DWORD lcsVersion; + DWORD lcsSize; + LCSCSTYPE lcsCSType; + LCSGAMUTMATCH lcsIntent; + CIEXYZTRIPLE lcsEndpoints; + DWORD lcsGammaRed; + DWORD lcsGammaGreen; + DWORD lcsGammaBlue; + WCHAR lcsFilename[MAX_PATH]; + } LOGCOLORSPACEW,*LPLOGCOLORSPACEW; + +#ifdef UNICODE + typedef LOGCOLORSPACEW LOGCOLORSPACE; + typedef LPLOGCOLORSPACEW LPLOGCOLORSPACE; +#else + typedef LOGCOLORSPACEA LOGCOLORSPACE; + typedef LPLOGCOLORSPACEA LPLOGCOLORSPACE; +#endif + + typedef struct tagBITMAPCOREHEADER { + DWORD bcSize; + WORD bcWidth; + WORD bcHeight; + WORD bcPlanes; + WORD bcBitCount; + } BITMAPCOREHEADER,*LPBITMAPCOREHEADER,*PBITMAPCOREHEADER; + + typedef struct tagBITMAPINFOHEADER { + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; + } BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER; + + typedef struct { + DWORD bV4Size; + LONG bV4Width; + LONG bV4Height; + WORD bV4Planes; + WORD bV4BitCount; + DWORD bV4V4Compression; + DWORD bV4SizeImage; + LONG bV4XPelsPerMeter; + LONG bV4YPelsPerMeter; + DWORD bV4ClrUsed; + DWORD bV4ClrImportant; + DWORD bV4RedMask; + DWORD bV4GreenMask; + DWORD bV4BlueMask; + DWORD bV4AlphaMask; + DWORD bV4CSType; + CIEXYZTRIPLE bV4Endpoints; + DWORD bV4GammaRed; + DWORD bV4GammaGreen; + DWORD bV4GammaBlue; + } BITMAPV4HEADER,*LPBITMAPV4HEADER,*PBITMAPV4HEADER; + + typedef struct { + DWORD bV5Size; + LONG bV5Width; + LONG bV5Height; + WORD bV5Planes; + WORD bV5BitCount; + DWORD bV5Compression; + DWORD bV5SizeImage; + LONG bV5XPelsPerMeter; + LONG bV5YPelsPerMeter; + DWORD bV5ClrUsed; + DWORD bV5ClrImportant; + DWORD bV5RedMask; + DWORD bV5GreenMask; + DWORD bV5BlueMask; + DWORD bV5AlphaMask; + DWORD bV5CSType; + CIEXYZTRIPLE bV5Endpoints; + DWORD bV5GammaRed; + DWORD bV5GammaGreen; + DWORD bV5GammaBlue; + DWORD bV5Intent; + DWORD bV5ProfileData; + DWORD bV5ProfileSize; + DWORD bV5Reserved; + } BITMAPV5HEADER,*LPBITMAPV5HEADER,*PBITMAPV5HEADER; + +//!__TINYC__: #define PROFILE_LINKED 'LINK' +//!__TINYC__: #define PROFILE_EMBEDDED 'MBED' + +#define BI_RGB 0L +#define BI_RLE8 1L +#define BI_RLE4 2L +#define BI_BITFIELDS 3L +#define BI_JPEG 4L +#define BI_PNG 5L + + typedef struct tagBITMAPINFO { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[1]; + } BITMAPINFO,*LPBITMAPINFO,*PBITMAPINFO; + + typedef struct tagBITMAPCOREINFO { + BITMAPCOREHEADER bmciHeader; + RGBTRIPLE bmciColors[1]; + } BITMAPCOREINFO,*LPBITMAPCOREINFO,*PBITMAPCOREINFO; + +#include <pshpack2.h> + typedef struct tagBITMAPFILEHEADER { + WORD bfType; + DWORD bfSize; + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; + } BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER; +#include <poppack.h> + +#define MAKEPOINTS(l) (*((POINTS *)&(l))) + +#ifndef NOFONTSIG + typedef struct tagFONTSIGNATURE { + DWORD fsUsb[4]; + DWORD fsCsb[2]; + } FONTSIGNATURE,*PFONTSIGNATURE,*LPFONTSIGNATURE; + + typedef struct tagCHARSETINFO { + UINT ciCharset; + UINT ciACP; + FONTSIGNATURE fs; + } CHARSETINFO,*PCHARSETINFO,*NPCHARSETINFO,*LPCHARSETINFO; + +#define TCI_SRCCHARSET 1 +#define TCI_SRCCODEPAGE 2 +#define TCI_SRCFONTSIG 3 +#define TCI_SRCLOCALE 0x1000 + + typedef struct tagLOCALESIGNATURE { + DWORD lsUsb[4]; + DWORD lsCsbDefault[2]; + DWORD lsCsbSupported[2]; + } LOCALESIGNATURE,*PLOCALESIGNATURE,*LPLOCALESIGNATURE; +#endif + + +#ifndef NOMETAFILE + typedef struct tagHANDLETABLE { + HGDIOBJ objectHandle[1]; + } HANDLETABLE,*PHANDLETABLE,*LPHANDLETABLE; + + typedef struct tagMETARECORD { + DWORD rdSize; + WORD rdFunction; + WORD rdParm[1]; + } METARECORD; + typedef struct tagMETARECORD UNALIGNED *PMETARECORD; + typedef struct tagMETARECORD UNALIGNED *LPMETARECORD; + + typedef struct tagMETAFILEPICT { + LONG mm; + LONG xExt; + LONG yExt; + HMETAFILE hMF; + } METAFILEPICT,*LPMETAFILEPICT; + +#include <pshpack2.h> + typedef struct tagMETAHEADER { + WORD mtType; + WORD mtHeaderSize; + WORD mtVersion; + DWORD mtSize; + WORD mtNoObjects; + DWORD mtMaxRecord; + WORD mtNoParameters; + } METAHEADER; + typedef struct tagMETAHEADER UNALIGNED *PMETAHEADER; + typedef struct tagMETAHEADER UNALIGNED *LPMETAHEADER; + +#include <poppack.h> + + typedef struct tagENHMETARECORD { + DWORD iType; + DWORD nSize; + DWORD dParm[1]; + } ENHMETARECORD,*PENHMETARECORD,*LPENHMETARECORD; + + typedef struct tagENHMETAHEADER { + DWORD iType; + DWORD nSize; + RECTL rclBounds; + RECTL rclFrame; + DWORD dSignature; + DWORD nVersion; + DWORD nBytes; + DWORD nRecords; + WORD nHandles; + WORD sReserved; + DWORD nDescription; + DWORD offDescription; + DWORD nPalEntries; + SIZEL szlDevice; + SIZEL szlMillimeters; + DWORD cbPixelFormat; + DWORD offPixelFormat; + DWORD bOpenGL; + SIZEL szlMicrometers; + } ENHMETAHEADER,*PENHMETAHEADER,*LPENHMETAHEADER; +#endif + +#ifndef NOTEXTMETRIC +#define TMPF_FIXED_PITCH 0x01 +#define TMPF_VECTOR 0x02 +#define TMPF_DEVICE 0x08 +#define TMPF_TRUETYPE 0x04 + +#ifdef UNICODE + typedef WCHAR BCHAR; +#else + typedef BYTE BCHAR; +#endif + +#ifndef _TEXTMETRIC_DEFINED +#define _TEXTMETRIC_DEFINED + typedef struct tagTEXTMETRICA { + LONG tmHeight; + LONG tmAscent; + LONG tmDescent; + LONG tmInternalLeading; + LONG tmExternalLeading; + LONG tmAveCharWidth; + LONG tmMaxCharWidth; + LONG tmWeight; + LONG tmOverhang; + LONG tmDigitizedAspectX; + LONG tmDigitizedAspectY; + BYTE tmFirstChar; + BYTE tmLastChar; + BYTE tmDefaultChar; + BYTE tmBreakChar; + BYTE tmItalic; + BYTE tmUnderlined; + BYTE tmStruckOut; + BYTE tmPitchAndFamily; + BYTE tmCharSet; + } TEXTMETRICA,*PTEXTMETRICA,*NPTEXTMETRICA,*LPTEXTMETRICA; + + typedef struct tagTEXTMETRICW { + LONG tmHeight; + LONG tmAscent; + LONG tmDescent; + LONG tmInternalLeading; + LONG tmExternalLeading; + LONG tmAveCharWidth; + LONG tmMaxCharWidth; + LONG tmWeight; + LONG tmOverhang; + LONG tmDigitizedAspectX; + LONG tmDigitizedAspectY; + WCHAR tmFirstChar; + WCHAR tmLastChar; + WCHAR tmDefaultChar; + WCHAR tmBreakChar; + BYTE tmItalic; + BYTE tmUnderlined; + BYTE tmStruckOut; + BYTE tmPitchAndFamily; + BYTE tmCharSet; + } TEXTMETRICW,*PTEXTMETRICW,*NPTEXTMETRICW,*LPTEXTMETRICW; +#ifdef UNICODE + typedef TEXTMETRICW TEXTMETRIC; + typedef PTEXTMETRICW PTEXTMETRIC; + typedef NPTEXTMETRICW NPTEXTMETRIC; + typedef LPTEXTMETRICW LPTEXTMETRIC; +#else + typedef TEXTMETRICA TEXTMETRIC; + typedef PTEXTMETRICA PTEXTMETRIC; + typedef NPTEXTMETRICA NPTEXTMETRIC; + typedef LPTEXTMETRICA LPTEXTMETRIC; +#endif +#endif + +#define NTM_REGULAR 0x00000040L +#define NTM_BOLD 0x00000020L +#define NTM_ITALIC 0x00000001L + +#define NTM_NONNEGATIVE_AC 0x00010000 +#define NTM_PS_OPENTYPE 0x00020000 +#define NTM_TT_OPENTYPE 0x00040000 +#define NTM_MULTIPLEMASTER 0x00080000 +#define NTM_TYPE1 0x00100000 +#define NTM_DSIG 0x00200000 + +#include <pshpack4.h> + typedef struct tagNEWTEXTMETRICA { + LONG tmHeight; + LONG tmAscent; + LONG tmDescent; + LONG tmInternalLeading; + LONG tmExternalLeading; + LONG tmAveCharWidth; + LONG tmMaxCharWidth; + LONG tmWeight; + LONG tmOverhang; + LONG tmDigitizedAspectX; + LONG tmDigitizedAspectY; + BYTE tmFirstChar; + BYTE tmLastChar; + BYTE tmDefaultChar; + BYTE tmBreakChar; + BYTE tmItalic; + BYTE tmUnderlined; + BYTE tmStruckOut; + BYTE tmPitchAndFamily; + BYTE tmCharSet; + DWORD ntmFlags; + UINT ntmSizeEM; + UINT ntmCellHeight; + UINT ntmAvgWidth; + } NEWTEXTMETRICA,*PNEWTEXTMETRICA,*NPNEWTEXTMETRICA,*LPNEWTEXTMETRICA; + + typedef struct tagNEWTEXTMETRICW { + LONG tmHeight; + LONG tmAscent; + LONG tmDescent; + LONG tmInternalLeading; + LONG tmExternalLeading; + LONG tmAveCharWidth; + LONG tmMaxCharWidth; + LONG tmWeight; + LONG tmOverhang; + LONG tmDigitizedAspectX; + LONG tmDigitizedAspectY; + WCHAR tmFirstChar; + WCHAR tmLastChar; + WCHAR tmDefaultChar; + WCHAR tmBreakChar; + BYTE tmItalic; + BYTE tmUnderlined; + BYTE tmStruckOut; + BYTE tmPitchAndFamily; + BYTE tmCharSet; + DWORD ntmFlags; + UINT ntmSizeEM; + UINT ntmCellHeight; + UINT ntmAvgWidth; + } NEWTEXTMETRICW,*PNEWTEXTMETRICW,*NPNEWTEXTMETRICW,*LPNEWTEXTMETRICW; +#ifdef UNICODE + typedef NEWTEXTMETRICW NEWTEXTMETRIC; + typedef PNEWTEXTMETRICW PNEWTEXTMETRIC; + typedef NPNEWTEXTMETRICW NPNEWTEXTMETRIC; + typedef LPNEWTEXTMETRICW LPNEWTEXTMETRIC; +#else + typedef NEWTEXTMETRICA NEWTEXTMETRIC; + typedef PNEWTEXTMETRICA PNEWTEXTMETRIC; + typedef NPNEWTEXTMETRICA NPNEWTEXTMETRIC; + typedef LPNEWTEXTMETRICA LPNEWTEXTMETRIC; +#endif +#include <poppack.h> + + typedef struct tagNEWTEXTMETRICEXA { + NEWTEXTMETRICA ntmTm; + FONTSIGNATURE ntmFontSig; + } NEWTEXTMETRICEXA; + + typedef struct tagNEWTEXTMETRICEXW { + NEWTEXTMETRICW ntmTm; + FONTSIGNATURE ntmFontSig; + } NEWTEXTMETRICEXW; +#ifdef UNICODE + typedef NEWTEXTMETRICEXW NEWTEXTMETRICEX; +#else + typedef NEWTEXTMETRICEXA NEWTEXTMETRICEX; +#endif +#endif + + typedef struct tagPELARRAY { + LONG paXCount; + LONG paYCount; + LONG paXExt; + LONG paYExt; + BYTE paRGBs; + } PELARRAY,*PPELARRAY,*NPPELARRAY,*LPPELARRAY; + + typedef struct tagLOGBRUSH { + UINT lbStyle; + COLORREF lbColor; + ULONG_PTR lbHatch; + } LOGBRUSH,*PLOGBRUSH,*NPLOGBRUSH,*LPLOGBRUSH; + + typedef struct tagLOGBRUSH32 { + UINT lbStyle; + COLORREF lbColor; + ULONG lbHatch; + } LOGBRUSH32,*PLOGBRUSH32,*NPLOGBRUSH32,*LPLOGBRUSH32; + + typedef LOGBRUSH PATTERN; + typedef PATTERN *PPATTERN; + typedef PATTERN *NPPATTERN; + typedef PATTERN *LPPATTERN; + + typedef struct tagLOGPEN { + UINT lopnStyle; + POINT lopnWidth; + COLORREF lopnColor; + } LOGPEN,*PLOGPEN,*NPLOGPEN,*LPLOGPEN; + + typedef struct tagEXTLOGPEN { + DWORD elpPenStyle; + DWORD elpWidth; + UINT elpBrushStyle; + COLORREF elpColor; + ULONG_PTR elpHatch; + DWORD elpNumEntries; + DWORD elpStyleEntry[1]; + } EXTLOGPEN,*PEXTLOGPEN,*NPEXTLOGPEN,*LPEXTLOGPEN; + +#ifndef _PALETTEENTRY_DEFINED +#define _PALETTEENTRY_DEFINED + typedef struct tagPALETTEENTRY { + BYTE peRed; + BYTE peGreen; + BYTE peBlue; + BYTE peFlags; + } PALETTEENTRY,*PPALETTEENTRY,*LPPALETTEENTRY; +#endif + +#ifndef _LOGPALETTE_DEFINED +#define _LOGPALETTE_DEFINED + + typedef struct tagLOGPALETTE { + WORD palVersion; + WORD palNumEntries; + PALETTEENTRY palPalEntry[1]; + } LOGPALETTE,*PLOGPALETTE,*NPLOGPALETTE,*LPLOGPALETTE; +#endif + +#define LF_FACESIZE 32 + + typedef struct tagLOGFONTA { + LONG lfHeight; + LONG lfWidth; + LONG lfEscapement; + LONG lfOrientation; + LONG lfWeight; + BYTE lfItalic; + BYTE lfUnderline; + BYTE lfStrikeOut; + BYTE lfCharSet; + BYTE lfOutPrecision; + BYTE lfClipPrecision; + BYTE lfQuality; + BYTE lfPitchAndFamily; + CHAR lfFaceName[LF_FACESIZE]; + } LOGFONTA,*PLOGFONTA,*NPLOGFONTA,*LPLOGFONTA; + + typedef struct tagLOGFONTW { + LONG lfHeight; + LONG lfWidth; + LONG lfEscapement; + LONG lfOrientation; + LONG lfWeight; + BYTE lfItalic; + BYTE lfUnderline; + BYTE lfStrikeOut; + BYTE lfCharSet; + BYTE lfOutPrecision; + BYTE lfClipPrecision; + BYTE lfQuality; + BYTE lfPitchAndFamily; + WCHAR lfFaceName[LF_FACESIZE]; + } LOGFONTW,*PLOGFONTW,*NPLOGFONTW,*LPLOGFONTW; +#ifdef UNICODE + typedef LOGFONTW LOGFONT; + typedef PLOGFONTW PLOGFONT; + typedef NPLOGFONTW NPLOGFONT; + typedef LPLOGFONTW LPLOGFONT; +#else + typedef LOGFONTA LOGFONT; + typedef PLOGFONTA PLOGFONT; + typedef NPLOGFONTA NPLOGFONT; + typedef LPLOGFONTA LPLOGFONT; +#endif + +#define LF_FULLFACESIZE 64 + + typedef struct tagENUMLOGFONTA { + LOGFONTA elfLogFont; + BYTE elfFullName[LF_FULLFACESIZE]; + BYTE elfStyle[LF_FACESIZE]; + } ENUMLOGFONTA,*LPENUMLOGFONTA; + + typedef struct tagENUMLOGFONTW { + LOGFONTW elfLogFont; + WCHAR elfFullName[LF_FULLFACESIZE]; + WCHAR elfStyle[LF_FACESIZE]; + } ENUMLOGFONTW,*LPENUMLOGFONTW; +#ifdef UNICODE + typedef ENUMLOGFONTW ENUMLOGFONT; + typedef LPENUMLOGFONTW LPENUMLOGFONT; +#else + typedef ENUMLOGFONTA ENUMLOGFONT; + typedef LPENUMLOGFONTA LPENUMLOGFONT; +#endif + + typedef struct tagENUMLOGFONTEXA { + LOGFONTA elfLogFont; + BYTE elfFullName[LF_FULLFACESIZE]; + BYTE elfStyle[LF_FACESIZE]; + BYTE elfScript[LF_FACESIZE]; + } ENUMLOGFONTEXA,*LPENUMLOGFONTEXA; + + typedef struct tagENUMLOGFONTEXW { + LOGFONTW elfLogFont; + WCHAR elfFullName[LF_FULLFACESIZE]; + WCHAR elfStyle[LF_FACESIZE]; + WCHAR elfScript[LF_FACESIZE]; + } ENUMLOGFONTEXW,*LPENUMLOGFONTEXW; +#ifdef UNICODE + typedef ENUMLOGFONTEXW ENUMLOGFONTEX; + typedef LPENUMLOGFONTEXW LPENUMLOGFONTEX; +#else + typedef ENUMLOGFONTEXA ENUMLOGFONTEX; + typedef LPENUMLOGFONTEXA LPENUMLOGFONTEX; +#endif + +#define OUT_DEFAULT_PRECIS 0 +#define OUT_STRING_PRECIS 1 +#define OUT_CHARACTER_PRECIS 2 +#define OUT_STROKE_PRECIS 3 +#define OUT_TT_PRECIS 4 +#define OUT_DEVICE_PRECIS 5 +#define OUT_RASTER_PRECIS 6 +#define OUT_TT_ONLY_PRECIS 7 +#define OUT_OUTLINE_PRECIS 8 +#define OUT_SCREEN_OUTLINE_PRECIS 9 +#define OUT_PS_ONLY_PRECIS 10 + +#define CLIP_DEFAULT_PRECIS 0 +#define CLIP_CHARACTER_PRECIS 1 +#define CLIP_STROKE_PRECIS 2 +#define CLIP_MASK 0xf +#define CLIP_LH_ANGLES (1<<4) +#define CLIP_TT_ALWAYS (2<<4) +#define CLIP_DFA_DISABLE (4<<4) +#define CLIP_EMBEDDED (8<<4) + +#define DEFAULT_QUALITY 0 +#define DRAFT_QUALITY 1 +#define PROOF_QUALITY 2 #define NONANTIALIASED_QUALITY 3 #define ANTIALIASED_QUALITY 4 -#define DEFAULT_PITCH 0 -#define FIXED_PITCH 1 -#define VARIABLE_PITCH 2 + +#define CLEARTYPE_QUALITY 5 +#define CLEARTYPE_NATURAL_QUALITY 6 + +#define DEFAULT_PITCH 0 +#define FIXED_PITCH 1 +#define VARIABLE_PITCH 2 #define MONO_FONT 8 -#define FF_DECORATIVE 80 -#define FF_DONTCARE 0 -#define FF_MODERN 48 -#define FF_ROMAN 16 -#define FF_SCRIPT 64 -#define FF_SWISS 32 + +#define ANSI_CHARSET 0 +#define DEFAULT_CHARSET 1 +#define SYMBOL_CHARSET 2 +#define SHIFTJIS_CHARSET 128 +#define HANGEUL_CHARSET 129 +#define HANGUL_CHARSET 129 +#define GB2312_CHARSET 134 +#define CHINESEBIG5_CHARSET 136 +#define OEM_CHARSET 255 +#define JOHAB_CHARSET 130 +#define HEBREW_CHARSET 177 +#define ARABIC_CHARSET 178 +#define GREEK_CHARSET 161 +#define TURKISH_CHARSET 162 +#define VIETNAMESE_CHARSET 163 +#define THAI_CHARSET 222 +#define EASTEUROPE_CHARSET 238 +#define RUSSIAN_CHARSET 204 + +#define MAC_CHARSET 77 +#define BALTIC_CHARSET 186 + +#define FS_LATIN1 0x00000001L +#define FS_LATIN2 0x00000002L +#define FS_CYRILLIC 0x00000004L +#define FS_GREEK 0x00000008L +#define FS_TURKISH 0x00000010L +#define FS_HEBREW 0x00000020L +#define FS_ARABIC 0x00000040L +#define FS_BALTIC 0x00000080L +#define FS_VIETNAMESE 0x00000100L +#define FS_THAI 0x00010000L +#define FS_JISJAPAN 0x00020000L +#define FS_CHINESESIMP 0x00040000L +#define FS_WANSUNG 0x00080000L +#define FS_CHINESETRAD 0x00100000L +#define FS_JOHAB 0x00200000L +#define FS_SYMBOL 0x80000000L + +#define FF_DONTCARE (0<<4) +#define FF_ROMAN (1<<4) + +#define FF_SWISS (2<<4) + +#define FF_MODERN (3<<4) + +#define FF_SCRIPT (4<<4) +#define FF_DECORATIVE (5<<4) + +#define FW_DONTCARE 0 +#define FW_THIN 100 +#define FW_EXTRALIGHT 200 +#define FW_LIGHT 300 +#define FW_NORMAL 400 +#define FW_MEDIUM 500 +#define FW_SEMIBOLD 600 +#define FW_BOLD 700 +#define FW_EXTRABOLD 800 +#define FW_HEAVY 900 + +#define FW_ULTRALIGHT FW_EXTRALIGHT +#define FW_REGULAR FW_NORMAL +#define FW_DEMIBOLD FW_SEMIBOLD +#define FW_ULTRABOLD FW_EXTRABOLD +#define FW_BLACK FW_HEAVY + #define PANOSE_COUNT 10 #define PAN_FAMILYTYPE_INDEX 0 #define PAN_SERIFSTYLE_INDEX 1 @@ -379,13 +1158,30 @@ extern "C" { #define PAN_LETTERFORM_INDEX 7 #define PAN_MIDLINE_INDEX 8 #define PAN_XHEIGHT_INDEX 9 + #define PAN_CULTURE_LATIN 0 + + typedef struct tagPANOSE { + BYTE bFamilyType; + BYTE bSerifStyle; + BYTE bWeight; + BYTE bProportion; + BYTE bContrast; + BYTE bStrokeVariation; + BYTE bArmStyle; + BYTE bLetterform; + BYTE bMidline; + BYTE bXHeight; + } PANOSE,*LPPANOSE; + #define PAN_ANY 0 #define PAN_NO_FIT 1 + #define PAN_FAMILY_TEXT_DISPLAY 2 #define PAN_FAMILY_SCRIPT 3 #define PAN_FAMILY_DECORATIVE 4 #define PAN_FAMILY_PICTORIAL 5 + #define PAN_SERIF_COVE 2 #define PAN_SERIF_OBTUSE_COVE 3 #define PAN_SERIF_SQUARE_COVE 4 @@ -400,6 +1196,7 @@ extern "C" { #define PAN_SERIF_PERP_SANS 13 #define PAN_SERIF_FLARED 14 #define PAN_SERIF_ROUNDED 15 + #define PAN_WEIGHT_VERY_LIGHT 2 #define PAN_WEIGHT_LIGHT 3 #define PAN_WEIGHT_THIN 4 @@ -410,6 +1207,7 @@ extern "C" { #define PAN_WEIGHT_HEAVY 9 #define PAN_WEIGHT_BLACK 10 #define PAN_WEIGHT_NORD 11 + #define PAN_PROP_OLD_STYLE 2 #define PAN_PROP_MODERN 3 #define PAN_PROP_EVEN_WIDTH 4 @@ -418,6 +1216,7 @@ extern "C" { #define PAN_PROP_VERY_EXPANDED 7 #define PAN_PROP_VERY_CONDENSED 8 #define PAN_PROP_MONOSPACED 9 + #define PAN_CONTRAST_NONE 2 #define PAN_CONTRAST_VERY_LOW 3 #define PAN_CONTRAST_LOW 4 @@ -426,6 +1225,7 @@ extern "C" { #define PAN_CONTRAST_MEDIUM_HIGH 7 #define PAN_CONTRAST_HIGH 8 #define PAN_CONTRAST_VERY_HIGH 9 + #define PAN_STROKE_GRADUAL_DIAG 2 #define PAN_STROKE_GRADUAL_TRAN 3 #define PAN_STROKE_GRADUAL_VERT 4 @@ -433,6 +1233,7 @@ extern "C" { #define PAN_STROKE_RAPID_VERT 6 #define PAN_STROKE_RAPID_HORZ 7 #define PAN_STROKE_INSTANT_VERT 8 + #define PAN_STRAIGHT_ARMS_HORZ 2 #define PAN_STRAIGHT_ARMS_WEDGE 3 #define PAN_STRAIGHT_ARMS_VERT 4 @@ -443,6 +1244,7 @@ extern "C" { #define PAN_BENT_ARMS_VERT 9 #define PAN_BENT_ARMS_SINGLE_SERIF 10 #define PAN_BENT_ARMS_DOUBLE_SERIF 11 + #define PAN_LETT_NORMAL_CONTACT 2 #define PAN_LETT_NORMAL_WEIGHTED 3 #define PAN_LETT_NORMAL_BOXED 4 @@ -457,6 +1259,7 @@ extern "C" { #define PAN_LETT_OBLIQUE_ROUNDED 13 #define PAN_LETT_OBLIQUE_OFF_CENTER 14 #define PAN_LETT_OBLIQUE_SQUARE 15 + #define PAN_MIDLINE_STANDARD_TRIMMED 2 #define PAN_MIDLINE_STANDARD_POINTED 3 #define PAN_MIDLINE_STANDARD_SERIFED 4 @@ -469,195 +1272,233 @@ extern "C" { #define PAN_MIDLINE_LOW_TRIMMED 11 #define PAN_MIDLINE_LOW_POINTED 12 #define PAN_MIDLINE_LOW_SERIFED 13 + #define PAN_XHEIGHT_CONSTANT_SMALL 2 #define PAN_XHEIGHT_CONSTANT_STD 3 #define PAN_XHEIGHT_CONSTANT_LARGE 4 #define PAN_XHEIGHT_DUCKING_SMALL 5 #define PAN_XHEIGHT_DUCKING_STD 6 #define PAN_XHEIGHT_DUCKING_LARGE 7 -#define FS_LATIN1 1 -#define FS_LATIN2 2 -#define FS_CYRILLIC 4 -#define FS_GREEK 8 -#define FS_TURKISH 16 -#define FS_HEBREW 32 -#define FS_ARABIC 64 -#define FS_BALTIC 128 -#define FS_THAI 0x10000 -#define FS_JISJAPAN 0x20000 -#define FS_CHINESESIMP 0x40000 -#define FS_WANSUNG 0x80000 -#define FS_CHINESETRAD 0x100000 -#define FS_JOHAB 0x200000 -#define FS_SYMBOL 0x80000000 -#define HS_BDIAGONAL 3 -#define HS_CROSS 4 -#define HS_DIAGCROSS 5 -#define HS_FDIAGONAL 2 -#define HS_HORIZONTAL 0 -#define HS_VERTICAL 1 -#define PS_GEOMETRIC 65536 -#define PS_COSMETIC 0 -#define PS_ALTERNATE 8 -#define PS_SOLID 0 -#define PS_DASH 1 -#define PS_DOT 2 -#define PS_DASHDOT 3 -#define PS_DASHDOTDOT 4 -#define PS_NULL 5 -#define PS_USERSTYLE 7 -#define PS_INSIDEFRAME 6 -#define PS_ENDCAP_ROUND 0 -#define PS_ENDCAP_SQUARE 256 -#define PS_ENDCAP_FLAT 512 -#define PS_JOIN_BEVEL 4096 -#define PS_JOIN_MITER 8192 -#define PS_JOIN_ROUND 0 -#define PS_STYLE_MASK 15 -#define PS_ENDCAP_MASK 3840 -#define PS_TYPE_MASK 983040 -#define ALTERNATE 1 -#define WINDING 2 -#define DC_BINNAMES 12 -#define DC_BINS 6 -#define DC_COPIES 18 -#define DC_DRIVER 11 -#define DC_DATATYPE_PRODUCED 21 -#define DC_DUPLEX 7 -#define DC_EMF_COMPLIANT 20 -#define DC_ENUMRESOLUTIONS 13 -#define DC_EXTRA 9 -#define DC_FIELDS 1 -#define DC_FILEDEPENDENCIES 14 -#define DC_MAXEXTENT 5 -#define DC_MINEXTENT 4 -#define DC_ORIENTATION 17 -#define DC_PAPERNAMES 16 -#define DC_PAPERS 2 -#define DC_PAPERSIZE 3 -#define DC_SIZE 8 -#define DC_TRUETYPE 15 -#define DCTT_BITMAP 1 -#define DCTT_DOWNLOAD 2 -#define DCTT_SUBDEV 4 -#define DCTT_DOWNLOAD_OUTLINE 8 -#define DC_VERSION 10 -#define DC_BINADJUST 19 -#define DC_EMF_COMPLIANT 20 -#define DC_DATATYPE_PRODUCED 21 -#define DC_MANUFACTURER 23 -#define DC_MODEL 24 -#define DCBA_FACEUPNONE 0 -#define DCBA_FACEUPCENTER 1 -#define DCBA_FACEUPLEFT 2 -#define DCBA_FACEUPRIGHT 3 -#define DCBA_FACEDOWNNONE 256 -#define DCBA_FACEDOWNCENTER 257 -#define DCBA_FACEDOWNLEFT 258 -#define DCBA_FACEDOWNRIGHT 259 -#define FLOODFILLBORDER 0 -#define FLOODFILLSURFACE 1 -#define ETO_CLIPPED 4 -#define ETO_GLYPH_INDEX 16 -#define ETO_OPAQUE 2 -#define ETO_RTLREADING 128 -#define GDICOMMENT_WINDOWS_METAFILE (-2147483647) -#define GDICOMMENT_BEGINGROUP 2 -#define GDICOMMENT_ENDGROUP 3 -#define GDICOMMENT_MULTIFORMATS 1073741828 -#define GDICOMMENT_IDENTIFIER 1128875079 + +#define ELF_VENDOR_SIZE 4 + + typedef struct tagEXTLOGFONTA { + LOGFONTA elfLogFont; + BYTE elfFullName[LF_FULLFACESIZE]; + BYTE elfStyle[LF_FACESIZE]; + DWORD elfVersion; + DWORD elfStyleSize; + DWORD elfMatch; + DWORD elfReserved; + BYTE elfVendorId[ELF_VENDOR_SIZE]; + DWORD elfCulture; + PANOSE elfPanose; + } EXTLOGFONTA,*PEXTLOGFONTA,*NPEXTLOGFONTA,*LPEXTLOGFONTA; + + typedef struct tagEXTLOGFONTW { + LOGFONTW elfLogFont; + WCHAR elfFullName[LF_FULLFACESIZE]; + WCHAR elfStyle[LF_FACESIZE]; + DWORD elfVersion; + DWORD elfStyleSize; + DWORD elfMatch; + DWORD elfReserved; + BYTE elfVendorId[ELF_VENDOR_SIZE]; + DWORD elfCulture; + PANOSE elfPanose; + } EXTLOGFONTW,*PEXTLOGFONTW,*NPEXTLOGFONTW,*LPEXTLOGFONTW; +#ifdef UNICODE + typedef EXTLOGFONTW EXTLOGFONT; + typedef PEXTLOGFONTW PEXTLOGFONT; + typedef NPEXTLOGFONTW NPEXTLOGFONT; + typedef LPEXTLOGFONTW LPEXTLOGFONT; +#else + typedef EXTLOGFONTA EXTLOGFONT; + typedef PEXTLOGFONTA PEXTLOGFONT; + typedef NPEXTLOGFONTA NPEXTLOGFONT; + typedef LPEXTLOGFONTA LPEXTLOGFONT; +#endif + +#define ELF_VERSION 0 +#define ELF_CULTURE_LATIN 0 + +#define RASTER_FONTTYPE 0x0001 +#define DEVICE_FONTTYPE 0x002 +#define TRUETYPE_FONTTYPE 0x004 + +#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) +#define PALETTERGB(r,g,b) (0x02000000 | RGB(r,g,b)) +#define PALETTEINDEX(i) ((COLORREF)(0x01000000 | (DWORD)(WORD)(i))) + +#define PC_RESERVED 0x01 +#define PC_EXPLICIT 0x02 +#define PC_NOCOLLAPSE 0x04 + +#define GetRValue(rgb) (LOBYTE(rgb)) +#define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8)) +#define GetBValue(rgb) (LOBYTE((rgb)>>16)) + +#define TRANSPARENT 1 +#define OPAQUE 2 +#define BKMODE_LAST 2 + +#define GM_COMPATIBLE 1 +#define GM_ADVANCED 2 +#define GM_LAST 2 + +#define PT_CLOSEFIGURE 0x01 +#define PT_LINETO 0x02 +#define PT_BEZIERTO 0x04 +#define PT_MOVETO 0x06 + +#define MM_TEXT 1 +#define MM_LOMETRIC 2 +#define MM_HIMETRIC 3 +#define MM_LOENGLISH 4 +#define MM_HIENGLISH 5 +#define MM_TWIPS 6 +#define MM_ISOTROPIC 7 +#define MM_ANISOTROPIC 8 + +#define MM_MIN MM_TEXT +#define MM_MAX MM_ANISOTROPIC +#define MM_MAX_FIXEDSCALE MM_TWIPS + +#define ABSOLUTE 1 +#define RELATIVE 2 + +#define WHITE_BRUSH 0 +#define LTGRAY_BRUSH 1 +#define GRAY_BRUSH 2 +#define DKGRAY_BRUSH 3 +#define BLACK_BRUSH 4 +#define NULL_BRUSH 5 +#define HOLLOW_BRUSH NULL_BRUSH +#define WHITE_PEN 6 +#define BLACK_PEN 7 +#define NULL_PEN 8 +#define OEM_FIXED_FONT 10 +#define ANSI_FIXED_FONT 11 +#define ANSI_VAR_FONT 12 +#define SYSTEM_FONT 13 +#define DEVICE_DEFAULT_FONT 14 +#define DEFAULT_PALETTE 15 +#define SYSTEM_FIXED_FONT 16 + +#define DEFAULT_GUI_FONT 17 + +#define DC_BRUSH 18 +#define DC_PEN 19 + +#define STOCK_LAST 19 + +#define CLR_INVALID 0xFFFFFFFF + +#define BS_SOLID 0 +#define BS_NULL 1 +#define BS_HOLLOW BS_NULL +#define BS_HATCHED 2 +#define BS_PATTERN 3 +#define BS_INDEXED 4 +#define BS_DIBPATTERN 5 +#define BS_DIBPATTERNPT 6 +#define BS_PATTERN8X8 7 +#define BS_DIBPATTERN8X8 8 +#define BS_MONOPATTERN 9 + +#define HS_HORIZONTAL 0 +#define HS_VERTICAL 1 +#define HS_FDIAGONAL 2 +#define HS_BDIAGONAL 3 +#define HS_CROSS 4 +#define HS_DIAGCROSS 5 + +#define PS_SOLID 0 +#define PS_DASH 1 +#define PS_DOT 2 +#define PS_DASHDOT 3 +#define PS_DASHDOTDOT 4 +#define PS_NULL 5 +#define PS_INSIDEFRAME 6 +#define PS_USERSTYLE 7 +#define PS_ALTERNATE 8 +#define PS_STYLE_MASK 0x0000000F + +#define PS_ENDCAP_ROUND 0x00000000 +#define PS_ENDCAP_SQUARE 0x00000100 +#define PS_ENDCAP_FLAT 0x00000200 +#define PS_ENDCAP_MASK 0x00000F00 + +#define PS_JOIN_ROUND 0x00000000 +#define PS_JOIN_BEVEL 0x00001000 +#define PS_JOIN_MITER 0x00002000 +#define PS_JOIN_MASK 0x0000F000 + +#define PS_COSMETIC 0x00000000 +#define PS_GEOMETRIC 0x00010000 +#define PS_TYPE_MASK 0x000F0000 + #define AD_COUNTERCLOCKWISE 1 #define AD_CLOCKWISE 2 -#define RDH_RECTANGLES 1 -#define GCPCLASS_LATIN 1 -#define GCPCLASS_HEBREW 2 -#define GCPCLASS_ARABIC 2 -#define GCPCLASS_NEUTRAL 3 -#define GCPCLASS_LOCALNUMBER 4 -#define GCPCLASS_LATINNUMBER 5 -#define GCPCLASS_LATINNUMERICTERMINATOR 6 -#define GCPCLASS_LATINNUMERICSEPARATOR 7 -#define GCPCLASS_NUMERICSEPARATOR 8 -#define GCPCLASS_PREBOUNDLTR 128 -#define GCPCLASS_PREBOUNDRTL 64 -#define GCPCLASS_POSTBOUNDLTR 32 -#define GCPCLASS_POSTBOUNDRTL 16 -#define GCPGLYPH_LINKBEFORE 0x8000 -#define GCPGLYPH_LINKAFTER 0x4000 -#define DCB_DISABLE 8 -#define DCB_ENABLE 4 -#define DCB_RESET 1 -#define DCB_SET 3 -#define DCB_ACCUMULATE 2 -#define DCB_DIRTY 2 -#define OBJ_BRUSH 2 -#define OBJ_PEN 1 -#define OBJ_PAL 5 -#define OBJ_FONT 6 -#define OBJ_BITMAP 7 -#define OBJ_EXTPEN 11 -#define OBJ_REGION 8 -#define OBJ_DC 3 -#define OBJ_MEMDC 10 -#define OBJ_METAFILE 9 -#define OBJ_METADC 4 -#define OBJ_ENHMETAFILE 13 -#define OBJ_ENHMETADC 12 + #define DRIVERVERSION 0 #define TECHNOLOGY 2 -#define DT_PLOTTER 0 -#define DT_RASDISPLAY 1 -#define DT_RASPRINTER 2 -#define DT_RASCAMERA 3 -#define DT_CHARSTREAM 4 -#define DT_METAFILE 5 -#define DT_DISPFILE 6 #define HORZSIZE 4 #define VERTSIZE 6 #define HORZRES 8 #define VERTRES 10 -#define LOGPIXELSX 88 -#define LOGPIXELSY 90 #define BITSPIXEL 12 #define PLANES 14 #define NUMBRUSHES 16 #define NUMPENS 18 +#define NUMMARKERS 20 #define NUMFONTS 22 #define NUMCOLORS 24 -#define NUMMARKERS 20 +#define PDEVICESIZE 26 +#define CURVECAPS 28 +#define LINECAPS 30 +#define POLYGONALCAPS 32 +#define TEXTCAPS 34 +#define CLIPCAPS 36 +#define RASTERCAPS 38 #define ASPECTX 40 #define ASPECTY 42 #define ASPECTXY 44 -#define PDEVICESIZE 26 -#define CLIPCAPS 36 + +#define LOGPIXELSX 88 +#define LOGPIXELSY 90 + #define SIZEPALETTE 104 #define NUMRESERVED 106 #define COLORRES 108 + #define PHYSICALWIDTH 110 #define PHYSICALHEIGHT 111 #define PHYSICALOFFSETX 112 #define PHYSICALOFFSETY 113 #define SCALINGFACTORX 114 #define SCALINGFACTORY 115 + #define VREFRESH 116 -#define DESKTOPHORZRES 118 + #define DESKTOPVERTRES 117 + +#define DESKTOPHORZRES 118 + #define BLTALIGNMENT 119 -#define RASTERCAPS 38 -#define RC_BANDING 2 -#define RC_BITBLT 1 -#define RC_BITMAP64 8 -#define RC_DI_BITMAP 128 -#define RC_DIBTODEV 512 -#define RC_FLOODFILL 4096 -#define RC_GDI20_OUTPUT 16 -#define RC_PALETTE 256 -#define RC_SCALING 4 -#define RC_STRETCHBLT 2048 -#define RC_STRETCHDIB 8192 -#define RC_DEVBITS 0x8000 -#define RC_OP_DX_OUTPUT 0x4000 -#define CURVECAPS 28 + +#define SHADEBLENDCAPS 120 +#define COLORMGMTCAPS 121 + +#ifndef NOGDICAPMASKS +#define DT_PLOTTER 0 +#define DT_RASDISPLAY 1 +#define DT_RASPRINTER 2 +#define DT_RASCAMERA 3 +#define DT_CHARSTREAM 4 +#define DT_METAFILE 5 +#define DT_DISPFILE 6 + #define CC_NONE 0 #define CC_CIRCLES 1 #define CC_PIE 2 @@ -668,7 +1509,7 @@ extern "C" { #define CC_WIDESTYLED 64 #define CC_INTERIORS 128 #define CC_ROUNDRECT 256 -#define LINECAPS 30 + #define LC_NONE 0 #define LC_POLYLINE 2 #define LC_MARKER 4 @@ -677,2166 +1518,2562 @@ extern "C" { #define LC_STYLED 32 #define LC_WIDESTYLED 64 #define LC_INTERIORS 128 -#define POLYGONALCAPS 32 -#define RC_BANDING 2 -#define RC_BIGFONT 1024 -#define RC_BITBLT 1 -#define RC_BITMAP64 8 -#define RC_DEVBITS 0x8000 -#define RC_DI_BITMAP 128 -#define RC_GDI20_OUTPUT 16 -#define RC_GDI20_STATE 32 -#define RC_NONE 0 -#define RC_OP_DX_OUTPUT 0x4000 -#define RC_PALETTE 256 -#define RC_SAVEBITMAP 64 -#define RC_SCALING 4 + #define PC_NONE 0 #define PC_POLYGON 1 -#define PC_POLYPOLYGON 256 -#define PC_PATHS 512 #define PC_RECTANGLE 2 #define PC_WINDPOLYGON 4 -#define PC_SCANLINE 8 #define PC_TRAPEZOID 4 +#define PC_SCANLINE 8 #define PC_WIDE 16 #define PC_STYLED 32 #define PC_WIDESTYLED 64 #define PC_INTERIORS 128 +#define PC_POLYPOLYGON 256 #define PC_PATHS 512 -#define TEXTCAPS 34 -#define TC_OP_CHARACTER 1 -#define TC_OP_STROKE 2 -#define TC_CP_STROKE 4 -#define TC_CR_90 8 -#define TC_CR_ANY 16 -#define TC_SF_X_YINDEP 32 -#define TC_SA_DOUBLE 64 -#define TC_SA_INTEGER 128 -#define TC_SA_CONTIN 256 -#define TC_EA_DOUBLE 512 -#define TC_IA_ABLE 1024 -#define TC_UA_ABLE 2048 -#define TC_SO_ABLE 4096 -#define TC_RA_ABLE 8192 -#define TC_VA_ABLE 16384 -#define TC_RESERVED 32768 -#define TC_SCROLLBLT 65536 -#define GCP_DBCS 1 -#define GCP_ERROR 0x8000 -#define GCP_CLASSIN 0x80000 -#define GCP_DIACRITIC 256 -#define GCP_DISPLAYZWG 0x400000 -#define GCP_GLYPHSHAPE 16 -#define GCP_JUSTIFY 0x10000 -#define GCP_JUSTIFYIN 0x200000 -#define GCP_KASHIDA 1024 -#define GCP_LIGATE 32 -#define GCP_MAXEXTENT 0x100000 -#define GCP_NEUTRALOVERRIDE 0x2000000 -#define GCP_NUMERICOVERRIDE 0x1000000 -#define GCP_NUMERICSLATIN 0x4000000 -#define GCP_NUMERICSLOCAL 0x8000000 -#define GCP_REORDER 2 -#define GCP_SYMSWAPOFF 0x800000 -#define GCP_USEKERNING 8 -#define FLI_GLYPHS 0x40000 -#define FLI_MASK 0x103b + +#define CP_NONE 0 +#define CP_RECTANGLE 1 +#define CP_REGION 2 + +#define TC_OP_CHARACTER 0x00000001 +#define TC_OP_STROKE 0x00000002 +#define TC_CP_STROKE 0x00000004 +#define TC_CR_90 0x00000008 +#define TC_CR_ANY 0x00000010 +#define TC_SF_X_YINDEP 0x00000020 +#define TC_SA_DOUBLE 0x00000040 +#define TC_SA_INTEGER 0x00000080 +#define TC_SA_CONTIN 0x00000100 +#define TC_EA_DOUBLE 0x00000200 +#define TC_IA_ABLE 0x00000400 +#define TC_UA_ABLE 0x00000800 +#define TC_SO_ABLE 0x00001000 +#define TC_RA_ABLE 0x00002000 +#define TC_VA_ABLE 0x00004000 +#define TC_RESERVED 0x00008000 +#define TC_SCROLLBLT 0x00010000 +#endif + +#define RC_NONE +#define RC_BITBLT 1 +#define RC_BANDING 2 +#define RC_SCALING 4 +#define RC_BITMAP64 8 +#define RC_GDI20_OUTPUT 0x0010 +#define RC_GDI20_STATE 0x0020 +#define RC_SAVEBITMAP 0x0040 +#define RC_DI_BITMAP 0x0080 +#define RC_PALETTE 0x0100 +#define RC_DIBTODEV 0x0200 +#define RC_BIGFONT 0x0400 +#define RC_STRETCHBLT 0x0800 +#define RC_FLOODFILL 0x1000 +#define RC_STRETCHDIB 0x2000 +#define RC_OP_DX_OUTPUT 0x4000 +#define RC_DEVBITS 0x8000 + +#define SB_NONE 0x00000000 +#define SB_CONST_ALPHA 0x00000001 +#define SB_PIXEL_ALPHA 0x00000002 +#define SB_PREMULT_ALPHA 0x00000004 + +#define SB_GRAD_RECT 0x00000010 +#define SB_GRAD_TRI 0x00000020 + +#define CM_NONE 0x00000000 +#define CM_DEVICE_ICM 0x00000001 +#define CM_GAMMA_RAMP 0x00000002 +#define CM_CMYK_COLOR 0x00000004 + +#define DIB_RGB_COLORS 0 +#define DIB_PAL_COLORS 1 + +#define SYSPAL_ERROR 0 +#define SYSPAL_STATIC 1 +#define SYSPAL_NOSTATIC 2 +#define SYSPAL_NOSTATIC256 3 + +#define CBM_INIT 0x04L + +#define FLOODFILLBORDER 0 +#define FLOODFILLSURFACE 1 + +#define CCHDEVICENAME 32 + +#define CCHFORMNAME 32 + + typedef struct _devicemodeA { + BYTE dmDeviceName[CCHDEVICENAME]; + WORD dmSpecVersion; + WORD dmDriverVersion; + WORD dmSize; + WORD dmDriverExtra; + DWORD dmFields; + union { + struct { + short dmOrientation; + short dmPaperSize; + short dmPaperLength; + short dmPaperWidth; + short dmScale; + short dmCopies; + short dmDefaultSource; + short dmPrintQuality; + }; + struct { + POINTL dmPosition; + DWORD dmDisplayOrientation; + DWORD dmDisplayFixedOutput; + }; + }; + short dmColor; + short dmDuplex; + short dmYResolution; + short dmTTOption; + short dmCollate; + BYTE dmFormName[CCHFORMNAME]; + WORD dmLogPixels; + DWORD dmBitsPerPel; + DWORD dmPelsWidth; + DWORD dmPelsHeight; + union { + DWORD dmDisplayFlags; + DWORD dmNup; + }; + DWORD dmDisplayFrequency; + DWORD dmICMMethod; + DWORD dmICMIntent; + DWORD dmMediaType; + DWORD dmDitherType; + DWORD dmReserved1; + DWORD dmReserved2; + DWORD dmPanningWidth; + DWORD dmPanningHeight; + } DEVMODEA,*PDEVMODEA,*NPDEVMODEA,*LPDEVMODEA; + + typedef struct _devicemodeW { + WCHAR dmDeviceName[CCHDEVICENAME]; + WORD dmSpecVersion; + WORD dmDriverVersion; + WORD dmSize; + WORD dmDriverExtra; + DWORD dmFields; + union { + struct { + short dmOrientation; + short dmPaperSize; + short dmPaperLength; + short dmPaperWidth; + short dmScale; + short dmCopies; + short dmDefaultSource; + short dmPrintQuality; + }; + struct { + POINTL dmPosition; + DWORD dmDisplayOrientation; + DWORD dmDisplayFixedOutput; + }; + }; + short dmColor; + short dmDuplex; + short dmYResolution; + short dmTTOption; + short dmCollate; + WCHAR dmFormName[CCHFORMNAME]; + WORD dmLogPixels; + DWORD dmBitsPerPel; + DWORD dmPelsWidth; + DWORD dmPelsHeight; + union { + DWORD dmDisplayFlags; + DWORD dmNup; + }; + DWORD dmDisplayFrequency; + DWORD dmICMMethod; + DWORD dmICMIntent; + DWORD dmMediaType; + DWORD dmDitherType; + DWORD dmReserved1; + DWORD dmReserved2; + DWORD dmPanningWidth; + DWORD dmPanningHeight; + } DEVMODEW,*PDEVMODEW,*NPDEVMODEW,*LPDEVMODEW; +#ifdef UNICODE + typedef DEVMODEW DEVMODE; + typedef PDEVMODEW PDEVMODE; + typedef NPDEVMODEW NPDEVMODE; + typedef LPDEVMODEW LPDEVMODE; +#else + typedef DEVMODEA DEVMODE; + typedef PDEVMODEA PDEVMODE; + typedef NPDEVMODEA NPDEVMODE; + typedef LPDEVMODEA LPDEVMODE; +#endif + +#define DM_SPECVERSION 0x0401 + +#define DM_ORIENTATION 0x00000001L +#define DM_PAPERSIZE 0x00000002L +#define DM_PAPERLENGTH 0x00000004L +#define DM_PAPERWIDTH 0x00000008L +#define DM_SCALE 0x00000010L +#define DM_POSITION 0x00000020L +#define DM_NUP 0x00000040L +#define DM_DISPLAYORIENTATION 0x00000080L +#define DM_COPIES 0x00000100L +#define DM_DEFAULTSOURCE 0x00000200L +#define DM_PRINTQUALITY 0x00000400L +#define DM_COLOR 0x00000800L +#define DM_DUPLEX 0x00001000L +#define DM_YRESOLUTION 0x00002000L +#define DM_TTOPTION 0x00004000L +#define DM_COLLATE 0x00008000L +#define DM_FORMNAME 0x00010000L +#define DM_LOGPIXELS 0x00020000L +#define DM_BITSPERPEL 0x00040000L +#define DM_PELSWIDTH 0x00080000L +#define DM_PELSHEIGHT 0x00100000L +#define DM_DISPLAYFLAGS 0x00200000L +#define DM_DISPLAYFREQUENCY 0x00400000L +#define DM_ICMMETHOD 0x00800000L +#define DM_ICMINTENT 0x01000000L +#define DM_MEDIATYPE 0x02000000L +#define DM_DITHERTYPE 0x04000000L +#define DM_PANNINGWIDTH 0x08000000L +#define DM_PANNINGHEIGHT 0x10000000L +#define DM_DISPLAYFIXEDOUTPUT 0x20000000L + +#define DMORIENT_PORTRAIT 1 +#define DMORIENT_LANDSCAPE 2 + +#define DMPAPER_FIRST DMPAPER_LETTER +#define DMPAPER_LETTER 1 +#define DMPAPER_LETTERSMALL 2 +#define DMPAPER_TABLOID 3 +#define DMPAPER_LEDGER 4 +#define DMPAPER_LEGAL 5 +#define DMPAPER_STATEMENT 6 +#define DMPAPER_EXECUTIVE 7 +#define DMPAPER_A3 8 +#define DMPAPER_A4 9 +#define DMPAPER_A4SMALL 10 +#define DMPAPER_A5 11 +#define DMPAPER_B4 12 +#define DMPAPER_B5 13 +#define DMPAPER_FOLIO 14 +#define DMPAPER_QUARTO 15 +#define DMPAPER_10X14 16 +#define DMPAPER_11X17 17 +#define DMPAPER_NOTE 18 +#define DMPAPER_ENV_9 19 +#define DMPAPER_ENV_10 20 +#define DMPAPER_ENV_11 21 +#define DMPAPER_ENV_12 22 +#define DMPAPER_ENV_14 23 +#define DMPAPER_CSHEET 24 +#define DMPAPER_DSHEET 25 +#define DMPAPER_ESHEET 26 +#define DMPAPER_ENV_DL 27 +#define DMPAPER_ENV_C5 28 +#define DMPAPER_ENV_C3 29 +#define DMPAPER_ENV_C4 30 +#define DMPAPER_ENV_C6 31 +#define DMPAPER_ENV_C65 32 +#define DMPAPER_ENV_B4 33 +#define DMPAPER_ENV_B5 34 +#define DMPAPER_ENV_B6 35 +#define DMPAPER_ENV_ITALY 36 +#define DMPAPER_ENV_MONARCH 37 +#define DMPAPER_ENV_PERSONAL 38 +#define DMPAPER_FANFOLD_US 39 +#define DMPAPER_FANFOLD_STD_GERMAN 40 +#define DMPAPER_FANFOLD_LGL_GERMAN 41 +#define DMPAPER_ISO_B4 42 +#define DMPAPER_JAPANESE_POSTCARD 43 +#define DMPAPER_9X11 44 +#define DMPAPER_10X11 45 +#define DMPAPER_15X11 46 +#define DMPAPER_ENV_INVITE 47 +#define DMPAPER_RESERVED_48 48 +#define DMPAPER_RESERVED_49 49 +#define DMPAPER_LETTER_EXTRA 50 +#define DMPAPER_LEGAL_EXTRA 51 +#define DMPAPER_TABLOID_EXTRA 52 +#define DMPAPER_A4_EXTRA 53 +#define DMPAPER_LETTER_TRANSVERSE 54 +#define DMPAPER_A4_TRANSVERSE 55 +#define DMPAPER_LETTER_EXTRA_TRANSVERSE 56 +#define DMPAPER_A_PLUS 57 +#define DMPAPER_B_PLUS 58 +#define DMPAPER_LETTER_PLUS 59 +#define DMPAPER_A4_PLUS 60 +#define DMPAPER_A5_TRANSVERSE 61 +#define DMPAPER_B5_TRANSVERSE 62 +#define DMPAPER_A3_EXTRA 63 +#define DMPAPER_A5_EXTRA 64 +#define DMPAPER_B5_EXTRA 65 +#define DMPAPER_A2 66 +#define DMPAPER_A3_TRANSVERSE 67 +#define DMPAPER_A3_EXTRA_TRANSVERSE 68 +#define DMPAPER_DBL_JAPANESE_POSTCARD 69 +#define DMPAPER_A6 70 +#define DMPAPER_JENV_KAKU2 71 +#define DMPAPER_JENV_KAKU3 72 +#define DMPAPER_JENV_CHOU3 73 +#define DMPAPER_JENV_CHOU4 74 +#define DMPAPER_LETTER_ROTATED 75 +#define DMPAPER_A3_ROTATED 76 +#define DMPAPER_A4_ROTATED 77 +#define DMPAPER_A5_ROTATED 78 +#define DMPAPER_B4_JIS_ROTATED 79 +#define DMPAPER_B5_JIS_ROTATED 80 +#define DMPAPER_JAPANESE_POSTCARD_ROTATED 81 +#define DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED 82 +#define DMPAPER_A6_ROTATED 83 +#define DMPAPER_JENV_KAKU2_ROTATED 84 +#define DMPAPER_JENV_KAKU3_ROTATED 85 +#define DMPAPER_JENV_CHOU3_ROTATED 86 +#define DMPAPER_JENV_CHOU4_ROTATED 87 +#define DMPAPER_B6_JIS 88 +#define DMPAPER_B6_JIS_ROTATED 89 +#define DMPAPER_12X11 90 +#define DMPAPER_JENV_YOU4 91 +#define DMPAPER_JENV_YOU4_ROTATED 92 +#define DMPAPER_P16K 93 +#define DMPAPER_P32K 94 +#define DMPAPER_P32KBIG 95 +#define DMPAPER_PENV_1 96 +#define DMPAPER_PENV_2 97 +#define DMPAPER_PENV_3 98 +#define DMPAPER_PENV_4 99 +#define DMPAPER_PENV_5 100 +#define DMPAPER_PENV_6 101 +#define DMPAPER_PENV_7 102 +#define DMPAPER_PENV_8 103 +#define DMPAPER_PENV_9 104 +#define DMPAPER_PENV_10 105 +#define DMPAPER_P16K_ROTATED 106 +#define DMPAPER_P32K_ROTATED 107 +#define DMPAPER_P32KBIG_ROTATED 108 +#define DMPAPER_PENV_1_ROTATED 109 +#define DMPAPER_PENV_2_ROTATED 110 +#define DMPAPER_PENV_3_ROTATED 111 +#define DMPAPER_PENV_4_ROTATED 112 +#define DMPAPER_PENV_5_ROTATED 113 +#define DMPAPER_PENV_6_ROTATED 114 +#define DMPAPER_PENV_7_ROTATED 115 +#define DMPAPER_PENV_8_ROTATED 116 +#define DMPAPER_PENV_9_ROTATED 117 +#define DMPAPER_PENV_10_ROTATED 118 + +#define DMPAPER_LAST DMPAPER_PENV_10_ROTATED + +#define DMPAPER_USER 256 + +#define DMBIN_FIRST DMBIN_UPPER +#define DMBIN_UPPER 1 +#define DMBIN_ONLYONE 1 +#define DMBIN_LOWER 2 +#define DMBIN_MIDDLE 3 +#define DMBIN_MANUAL 4 +#define DMBIN_ENVELOPE 5 +#define DMBIN_ENVMANUAL 6 +#define DMBIN_AUTO 7 +#define DMBIN_TRACTOR 8 +#define DMBIN_SMALLFMT 9 +#define DMBIN_LARGEFMT 10 +#define DMBIN_LARGECAPACITY 11 +#define DMBIN_CASSETTE 14 +#define DMBIN_FORMSOURCE 15 +#define DMBIN_LAST DMBIN_FORMSOURCE + +#define DMBIN_USER 256 + +#define DMRES_DRAFT (-1) +#define DMRES_LOW (-2) +#define DMRES_MEDIUM (-3) +#define DMRES_HIGH (-4) + +#define DMCOLOR_MONOCHROME 1 +#define DMCOLOR_COLOR 2 + +#define DMDUP_SIMPLEX 1 +#define DMDUP_VERTICAL 2 +#define DMDUP_HORIZONTAL 3 + +#define DMTT_BITMAP 1 +#define DMTT_DOWNLOAD 2 +#define DMTT_SUBDEV 3 +#define DMTT_DOWNLOAD_OUTLINE 4 + +#define DMCOLLATE_FALSE 0 +#define DMCOLLATE_TRUE 1 + +#define DMDO_DEFAULT 0 +#define DMDO_90 1 +#define DMDO_180 2 +#define DMDO_270 3 + +#define DMDFO_DEFAULT 0 +#define DMDFO_STRETCH 1 +#define DMDFO_CENTER 2 + +#define DMDISPLAYFLAGS_TEXTMODE 0x00000004 + +#define DMNUP_SYSTEM 1 +#define DMNUP_ONEUP 2 + +#define DMICMMETHOD_NONE 1 +#define DMICMMETHOD_SYSTEM 2 +#define DMICMMETHOD_DRIVER 3 +#define DMICMMETHOD_DEVICE 4 + +#define DMICMMETHOD_USER 256 + +#define DMICM_SATURATE 1 +#define DMICM_CONTRAST 2 +#define DMICM_COLORIMETRIC 3 +#define DMICM_ABS_COLORIMETRIC 4 + +#define DMICM_USER 256 + +#define DMMEDIA_STANDARD 1 +#define DMMEDIA_TRANSPARENCY 2 +#define DMMEDIA_GLOSSY 3 + +#define DMMEDIA_USER 256 + +#define DMDITHER_NONE 1 +#define DMDITHER_COARSE 2 +#define DMDITHER_FINE 3 +#define DMDITHER_LINEART 4 +#define DMDITHER_ERRORDIFFUSION 5 +#define DMDITHER_RESERVED6 6 +#define DMDITHER_RESERVED7 7 +#define DMDITHER_RESERVED8 8 +#define DMDITHER_RESERVED9 9 +#define DMDITHER_GRAYSCALE 10 + +#define DMDITHER_USER 256 + + typedef struct _DISPLAY_DEVICEA { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD StateFlags; + CHAR DeviceID[128]; + CHAR DeviceKey[128]; + } DISPLAY_DEVICEA,*PDISPLAY_DEVICEA,*LPDISPLAY_DEVICEA; + typedef struct _DISPLAY_DEVICEW { + DWORD cb; + WCHAR DeviceName[32]; + WCHAR DeviceString[128]; + DWORD StateFlags; + WCHAR DeviceID[128]; + WCHAR DeviceKey[128]; + } DISPLAY_DEVICEW,*PDISPLAY_DEVICEW,*LPDISPLAY_DEVICEW; +#ifdef UNICODE + typedef DISPLAY_DEVICEW DISPLAY_DEVICE; + typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE; + typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE; +#else + typedef DISPLAY_DEVICEA DISPLAY_DEVICE; + typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE; + typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE; +#endif + +#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001 +#define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002 +#define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004 +#define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008 +#define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010 +#define DISPLAY_DEVICE_REMOVABLE 0x00000020 +#define DISPLAY_DEVICE_MODESPRUNED 0x08000000 +#define DISPLAY_DEVICE_REMOTE 0x04000000 +#define DISPLAY_DEVICE_DISCONNECT 0x02000000 + +#define DISPLAY_DEVICE_ACTIVE 0x00000001 +#define DISPLAY_DEVICE_ATTACHED 0x00000002 + +#define RDH_RECTANGLES 1 + + typedef struct _RGNDATAHEADER { + DWORD dwSize; + DWORD iType; + DWORD nCount; + DWORD nRgnSize; + RECT rcBound; + } RGNDATAHEADER,*PRGNDATAHEADER; + + typedef struct _RGNDATA { + RGNDATAHEADER rdh; + char Buffer[1]; + } RGNDATA,*PRGNDATA,*NPRGNDATA,*LPRGNDATA; + +#define SYSRGN 4 + + typedef struct _ABC { + int abcA; + UINT abcB; + int abcC; + } ABC,*PABC,*NPABC,*LPABC; + + typedef struct _ABCFLOAT { + FLOAT abcfA; + FLOAT abcfB; + FLOAT abcfC; + } ABCFLOAT,*PABCFLOAT,*NPABCFLOAT,*LPABCFLOAT; + +#ifndef NOTEXTMETRIC + + typedef struct _OUTLINETEXTMETRICA { + UINT otmSize; + TEXTMETRICA otmTextMetrics; + BYTE otmFiller; + PANOSE otmPanoseNumber; + UINT otmfsSelection; + UINT otmfsType; + int otmsCharSlopeRise; + int otmsCharSlopeRun; + int otmItalicAngle; + UINT otmEMSquare; + int otmAscent; + int otmDescent; + UINT otmLineGap; + UINT otmsCapEmHeight; + UINT otmsXHeight; + RECT otmrcFontBox; + int otmMacAscent; + int otmMacDescent; + UINT otmMacLineGap; + UINT otmusMinimumPPEM; + POINT otmptSubscriptSize; + POINT otmptSubscriptOffset; + POINT otmptSuperscriptSize; + POINT otmptSuperscriptOffset; + UINT otmsStrikeoutSize; + int otmsStrikeoutPosition; + int otmsUnderscoreSize; + int otmsUnderscorePosition; + PSTR otmpFamilyName; + PSTR otmpFaceName; + PSTR otmpStyleName; + PSTR otmpFullName; + } OUTLINETEXTMETRICA,*POUTLINETEXTMETRICA,*NPOUTLINETEXTMETRICA,*LPOUTLINETEXTMETRICA; + + typedef struct _OUTLINETEXTMETRICW { + UINT otmSize; + TEXTMETRICW otmTextMetrics; + BYTE otmFiller; + PANOSE otmPanoseNumber; + UINT otmfsSelection; + UINT otmfsType; + int otmsCharSlopeRise; + int otmsCharSlopeRun; + int otmItalicAngle; + UINT otmEMSquare; + int otmAscent; + int otmDescent; + UINT otmLineGap; + UINT otmsCapEmHeight; + UINT otmsXHeight; + RECT otmrcFontBox; + int otmMacAscent; + int otmMacDescent; + UINT otmMacLineGap; + UINT otmusMinimumPPEM; + POINT otmptSubscriptSize; + POINT otmptSubscriptOffset; + POINT otmptSuperscriptSize; + POINT otmptSuperscriptOffset; + UINT otmsStrikeoutSize; + int otmsStrikeoutPosition; + int otmsUnderscoreSize; + int otmsUnderscorePosition; + PSTR otmpFamilyName; + PSTR otmpFaceName; + PSTR otmpStyleName; + PSTR otmpFullName; + } OUTLINETEXTMETRICW,*POUTLINETEXTMETRICW,*NPOUTLINETEXTMETRICW,*LPOUTLINETEXTMETRICW; +#ifdef UNICODE + typedef OUTLINETEXTMETRICW OUTLINETEXTMETRIC; + typedef POUTLINETEXTMETRICW POUTLINETEXTMETRIC; + typedef NPOUTLINETEXTMETRICW NPOUTLINETEXTMETRIC; + typedef LPOUTLINETEXTMETRICW LPOUTLINETEXTMETRIC; +#else + typedef OUTLINETEXTMETRICA OUTLINETEXTMETRIC; + typedef POUTLINETEXTMETRICA POUTLINETEXTMETRIC; + typedef NPOUTLINETEXTMETRICA NPOUTLINETEXTMETRIC; + typedef LPOUTLINETEXTMETRICA LPOUTLINETEXTMETRIC; +#endif +#endif + + typedef struct tagPOLYTEXTA { + int x; + int y; + UINT n; + LPCSTR lpstr; + UINT uiFlags; + RECT rcl; + int *pdx; + } POLYTEXTA,*PPOLYTEXTA,*NPPOLYTEXTA,*LPPOLYTEXTA; + + typedef struct tagPOLYTEXTW { + int x; + int y; + UINT n; + LPCWSTR lpstr; + UINT uiFlags; + RECT rcl; + int *pdx; + } POLYTEXTW,*PPOLYTEXTW,*NPPOLYTEXTW,*LPPOLYTEXTW; +#ifdef UNICODE + typedef POLYTEXTW POLYTEXT; + typedef PPOLYTEXTW PPOLYTEXT; + typedef NPPOLYTEXTW NPPOLYTEXT; + typedef LPPOLYTEXTW LPPOLYTEXT; +#else + typedef POLYTEXTA POLYTEXT; + typedef PPOLYTEXTA PPOLYTEXT; + typedef NPPOLYTEXTA NPPOLYTEXT; + typedef LPPOLYTEXTA LPPOLYTEXT; +#endif + + typedef struct _FIXED { + WORD fract; + short value; + } FIXED; + + typedef struct _MAT2 { + FIXED eM11; + FIXED eM12; + FIXED eM21; + FIXED eM22; + } MAT2,*LPMAT2; + + typedef struct _GLYPHMETRICS { + UINT gmBlackBoxX; + UINT gmBlackBoxY; + POINT gmptGlyphOrigin; + short gmCellIncX; + short gmCellIncY; + } GLYPHMETRICS,*LPGLYPHMETRICS; + #define GGO_METRICS 0 #define GGO_BITMAP 1 #define GGO_NATIVE 2 #define GGO_BEZIER 3 + #define GGO_GRAY2_BITMAP 4 #define GGO_GRAY4_BITMAP 5 #define GGO_GRAY8_BITMAP 6 -#define GGO_GLYPH_INDEX 128 -#define GGO_UNHINTED 256 -#define GM_COMPATIBLE 1 -#define GM_ADVANCED 2 -#define MM_ANISOTROPIC 8 -#define MM_HIENGLISH 5 -#define MM_HIMETRIC 3 -#define MM_ISOTROPIC 7 -#define MM_LOENGLISH 4 -#define MM_LOMETRIC 2 -#define MM_TEXT 1 -#define MM_TWIPS 6 -#define MM_MAX_FIXEDSCALE MM_TWIPS -#define ABSOLUTE 1 -#define RELATIVE 2 -#define PC_EXPLICIT 2 -#define PC_NOCOLLAPSE 4 -#define PC_RESERVED 1 -#define CLR_NONE 0xffffffff -#define CLR_INVALID CLR_NONE -#define CLR_DEFAULT 0xff000000 -#define PT_MOVETO 6 -#define PT_LINETO 2 -#define PT_BEZIERTO 4 -#define PT_CLOSEFIGURE 1 -#define TT_AVAILABLE 1 -#define TT_ENABLED 2 -#define BLACK_BRUSH 4 -#define DKGRAY_BRUSH 3 -#define GRAY_BRUSH 2 -#define HOLLOW_BRUSH 5 -#define LTGRAY_BRUSH 1 -#define NULL_BRUSH 5 -#define WHITE_BRUSH 0 -#define BLACK_PEN 7 -#define NULL_PEN 8 -#define WHITE_PEN 6 -#define ANSI_FIXED_FONT 11 -#define ANSI_VAR_FONT 12 -#define DEVICE_DEFAULT_FONT 14 -#define DEFAULT_GUI_FONT 17 -#define OEM_FIXED_FONT 10 -#define SYSTEM_FONT 13 -#define SYSTEM_FIXED_FONT 16 -#define DEFAULT_PALETTE 15 -#define SYSPAL_NOSTATIC 2 -#define SYSPAL_STATIC 1 -#define SYSPAL_ERROR 0 -#define TA_BASELINE 24 -#define TA_BOTTOM 8 -#define TA_TOP 0 -#define TA_CENTER 6 -#define TA_LEFT 0 -#define TA_RIGHT 2 -#define TA_RTLREADING 256 -#define TA_NOUPDATECP 0 -#define TA_UPDATECP 1 -#define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING) -#define VTA_BASELINE 24 -#define VTA_CENTER 6 -#define VTA_LEFT TA_BOTTOM -#define VTA_RIGHT TA_TOP -#define VTA_BOTTOM TA_RIGHT -#define VTA_TOP TA_LEFT -#define MWT_IDENTITY 1 -#define MWT_LEFTMULTIPLY 2 -#define MWT_RIGHTMULTIPLY 3 -#define OPAQUE 2 -#define TRANSPARENT 1 -#define BLACKONWHITE 1 -#define WHITEONBLACK 2 -#define COLORONCOLOR 3 -#define HALFTONE 4 -#define MAXSTRETCHBLTMODE 4 -#define STRETCH_ANDSCANS 1 -#define STRETCH_DELETESCANS 3 -#define STRETCH_HALFTONE 4 -#define STRETCH_ORSCANS 2 -#define TCI_SRCCHARSET 1 -#define TCI_SRCCODEPAGE 2 -#define TCI_SRCFONTSIG 3 -#define ICM_ON 2 -#define ICM_OFF 1 -#define ICM_QUERY 3 -#define NEWFRAME 1 -#define ABORTDOC 2 -#define NEXTBAND 3 -#define SETCOLORTABLE 4 -#define GETCOLORTABLE 5 -#define FLUSHOUTPUT 6 -#define DRAFTMODE 7 -#define QUERYESCSUPPORT 8 -#define SETABORTPROC 9 -#define STARTDOC 10 -#define ENDDOC 11 -#define GETPHYSPAGESIZE 12 -#define GETPRINTINGOFFSET 13 -#define GETSCALINGFACTOR 14 -#define MFCOMMENT 15 -#define GETPENWIDTH 16 -#define SETCOPYCOUNT 17 -#define SELECTPAPERSOURCE 18 -#define DEVICEDATA 19 -#define PASSTHROUGH 19 -#define GETTECHNOLGY 20 -#define GETTECHNOLOGY 20 -#define SETLINECAP 21 -#define SETLINEJOIN 22 -#define SETMITERLIMIT 23 -#define BANDINFO 24 -#define DRAWPATTERNRECT 25 -#define GETVECTORPENSIZE 26 -#define GETVECTORBRUSHSIZE 27 -#define ENABLEDUPLEX 28 -#define GETSETPAPERBINS 29 -#define GETSETPRINTORIENT 30 -#define ENUMPAPERBINS 31 -#define SETDIBSCALING 32 -#define EPSPRINTING 33 -#define ENUMPAPERMETRICS 34 -#define GETSETPAPERMETRICS 35 -#define POSTSCRIPT_DATA 37 -#define POSTSCRIPT_IGNORE 38 -#define MOUSETRAILS 39 -#define GETDEVICEUNITS 42 -#define GETEXTENDEDTEXTMETRICS 256 -#define GETEXTENTTABLE 257 -#define GETPAIRKERNTABLE 258 -#define GETTRACKKERNTABLE 259 -#define EXTTEXTOUT 512 -#define GETFACENAME 513 -#define DOWNLOADFACE 514 -#define ENABLERELATIVEWIDTHS 768 -#define ENABLEPAIRKERNING 769 -#define SETKERNTRACK 770 -#define SETALLJUSTVALUES 771 -#define SETCHARSET 772 -#define STRETCHBLT 2048 -#define GETSETSCREENPARAMS 3072 -#define QUERYDIBSUPPORT 3073 -#define BEGIN_PATH 4096 -#define CLIP_TO_PATH 4097 -#define END_PATH 4098 -#define EXT_DEVICE_CAPS 4099 -#define RESTORE_CTM 4100 -#define SAVE_CTM 4101 -#define SET_ARC_DIRECTION 4102 -#define SET_BACKGROUND_COLOR 4103 -#define SET_POLY_MODE 4104 -#define SET_SCREEN_ANGLE 4105 -#define SET_SPREAD 4106 -#define TRANSFORM_CTM 4107 -#define SET_CLIP_BOX 4108 -#define SET_BOUNDS 4109 -#define SET_MIRROR_MODE 4110 -#define OPENCHANNEL 4110 -#define DOWNLOADHEADER 4111 -#define CLOSECHANNEL 4112 -#define POSTSCRIPT_PASSTHROUGH 4115 -#define ENCAPSULATED_POSTSCRIPT 4116 -#define QDI_SETDIBITS 1 -#define QDI_GETDIBITS 2 -#define QDI_DIBTOSCREEN 4 -#define QDI_STRETCHDIB 8 -#define SP_NOTREPORTED 0x4000 -#define PR_JOBSTATUS 0 -#define ASPECT_FILTERING 1 -#define BS_SOLID 0 -#define BS_NULL 1 -#define BS_HOLLOW 1 -#define BS_HATCHED 2 -#define BS_PATTERN 3 -#define BS_INDEXED 4 -#define BS_DIBPATTERN 5 -#define BS_DIBPATTERNPT 6 -#define BS_PATTERN8X8 7 -#define BS_DIBPATTERN8X8 8 -#define LCS_CALIBRATED_RGB 0 -#define LCS_DEVICE_RGB 1 -#define LCS_DEVICE_CMYK 2 -#define LCS_GM_BUSINESS 1 -#define LCS_GM_GRAPHICS 2 -#define LCS_GM_IMAGES 4 -#define RASTER_FONTTYPE 1 -#define DEVICE_FONTTYPE 2 -#define TRUETYPE_FONTTYPE 4 -#define DMORIENT_PORTRAIT 1 -#define DMORIENT_LANDSCAPE 2 -#define DMPAPER_FIRST 1 -#define DMPAPER_LETTER 1 -#define DMPAPER_LETTERSMALL 2 -#define DMPAPER_TABLOID 3 -#define DMPAPER_LEDGER 4 -#define DMPAPER_LEGAL 5 -#define DMPAPER_STATEMENT 6 -#define DMPAPER_EXECUTIVE 7 -#define DMPAPER_A3 8 -#define DMPAPER_A4 9 -#define DMPAPER_A4SMALL 10 -#define DMPAPER_A5 11 -#define DMPAPER_B4 12 -#define DMPAPER_B5 13 -#define DMPAPER_FOLIO 14 -#define DMPAPER_QUARTO 15 -#define DMPAPER_10X14 16 -#define DMPAPER_11X17 17 -#define DMPAPER_NOTE 18 -#define DMPAPER_ENV_9 19 -#define DMPAPER_ENV_10 20 -#define DMPAPER_ENV_11 21 -#define DMPAPER_ENV_12 22 -#define DMPAPER_ENV_14 23 -#define DMPAPER_CSHEET 24 -#define DMPAPER_DSHEET 25 -#define DMPAPER_ESHEET 26 -#define DMPAPER_ENV_DL 27 -#define DMPAPER_ENV_C5 28 -#define DMPAPER_ENV_C3 29 -#define DMPAPER_ENV_C4 30 -#define DMPAPER_ENV_C6 31 -#define DMPAPER_ENV_C65 32 -#define DMPAPER_ENV_B4 33 -#define DMPAPER_ENV_B5 34 -#define DMPAPER_ENV_B6 35 -#define DMPAPER_ENV_ITALY 36 -#define DMPAPER_ENV_MONARCH 37 -#define DMPAPER_ENV_PERSONAL 38 -#define DMPAPER_FANFOLD_US 39 -#define DMPAPER_FANFOLD_STD_GERMAN 40 -#define DMPAPER_FANFOLD_LGL_GERMAN 41 -#define DMPAPER_ISO_B4 42 -#define DMPAPER_JAPANESE_POSTCARD 43 -#define DMPAPER_9X11 44 -#define DMPAPER_10X11 45 -#define DMPAPER_15X11 46 -#define DMPAPER_ENV_INVITE 47 -#define DMPAPER_RESERVED_48 48 -#define DMPAPER_RESERVED_49 49 -#define DMPAPER_LETTER_EXTRA 50 -#define DMPAPER_LEGAL_EXTRA 51 -#define DMPAPER_TABLOID_EXTRA 52 -#define DMPAPER_A4_EXTRA 53 -#define DMPAPER_LETTER_TRANSVERSE 54 -#define DMPAPER_A4_TRANSVERSE 55 -#define DMPAPER_LETTER_EXTRA_TRANSVERSE 56 -#define DMPAPER_A_PLUS 57 -#define DMPAPER_B_PLUS 58 -#define DMPAPER_LETTER_PLUS 59 -#define DMPAPER_A4_PLUS 60 -#define DMPAPER_A5_TRANSVERSE 61 -#define DMPAPER_B5_TRANSVERSE 62 -#define DMPAPER_A3_EXTRA 63 -#define DMPAPER_A5_EXTRA 64 -#define DMPAPER_B5_EXTRA 65 -#define DMPAPER_A2 66 -#define DMPAPER_A3_TRANSVERSE 67 -#define DMPAPER_A3_EXTRA_TRANSVERSE 68 -#define DMPAPER_LAST 68 -#define DMPAPER_USER 256 -#define DMBIN_FIRST 1 -#define DMBIN_UPPER 1 -#define DMBIN_ONLYONE 1 -#define DMBIN_LOWER 2 -#define DMBIN_MIDDLE 3 -#define DMBIN_MANUAL 4 -#define DMBIN_ENVELOPE 5 -#define DMBIN_ENVMANUAL 6 -#define DMBIN_AUTO 7 -#define DMBIN_TRACTOR 8 -#define DMBIN_SMALLFMT 9 -#define DMBIN_LARGEFMT 10 -#define DMBIN_LARGECAPACITY 11 -#define DMBIN_CASSETTE 14 -#define DMBIN_FORMSOURCE 15 -#define DMBIN_LAST 15 -#define DMBIN_USER 256 -#define DMRES_DRAFT (-1) -#define DMRES_LOW (-2) -#define DMRES_MEDIUM (-3) -#define DMRES_HIGH (-4) -#define DMCOLOR_MONOCHROME 1 -#define DMCOLOR_COLOR 2 -#define DMDUP_SIMPLEX 1 -#define DMDUP_VERTICAL 2 -#define DMDUP_HORIZONTAL 3 -#define DMTT_BITMAP 1 -#define DMTT_DOWNLOAD 2 -#define DMTT_SUBDEV 3 -#define DMTT_DOWNLOAD_OUTLINE 4 -#define DMCOLLATE_FALSE 0 -#define DMCOLLATE_TRUE 1 -#define DM_GRAYSCALE 1 -#define DM_INTERLACED 2 -#define DM_UPDATE 1 -#define DM_COPY 2 -#define DM_PROMPT 4 -#define DM_MODIFY 8 -#define DM_IN_BUFFER DM_MODIFY -#define DM_IN_PROMPT DM_PROMPT -#define DM_OUT_BUFFER DM_COPY -#define DM_OUT_DEFAULT DM_UPDATE -#define DM_ORIENTATION 1 -#define DM_PAPERSIZE 2 -#define DM_PAPERLENGTH 4 -#define DM_PAPERWIDTH 8 -#define DM_SCALE 16 -#define DM_COPIES 256 -#define DM_DEFAULTSOURCE 512 -#define DM_PRINTQUALITY 1024 -#define DM_COLOR 2048 -#define DM_DUPLEX 4096 -#define DM_YRESOLUTION 8192 -#define DM_TTOPTION 16384 -#define DM_COLLATE 32768 -#define DM_FORMNAME 65536 -#define DM_LOGPIXELS 0x20000 -#define DM_BITSPERPEL 0x40000 -#define DM_PELSWIDTH 0x80000 -#define DM_PELSHEIGHT 0x100000 -#define DM_DISPLAYFLAGS 0x200000 -#define DM_DISPLAYFREQUENCY 0x400000 -#define DM_ICMMETHOD 0x800000 -#define DM_ICMINTENT 0x1000000 -#define DM_MEDIATYPE 0x2000000 -#define DM_DITHERTYPE 0x4000000 -#define DMICMMETHOD_NONE 1 -#define DMICMMETHOD_SYSTEM 2 -#define DMICMMETHOD_DRIVER 3 -#define DMICMMETHOD_DEVICE 4 -#define DMICMMETHOD_USER 256 -#define DMICM_SATURATE 1 -#define DMICM_CONTRAST 2 -#define DMICM_COLORMETRIC 3 -#define DMICM_USER 256 -#define DMMEDIA_STANDARD 1 -#define DMMEDIA_TRANSPARENCY 2 -#define DMMEDIA_GLOSSY 3 -#define DMMEDIA_USER 256 -#define DMDITHER_NONE 1 -#define DMDITHER_COARSE 2 -#define DMDITHER_FINE 3 -#define DMDITHER_LINEART 4 -#define DMDITHER_ERRORDIFFUSION 5 -#define DMDITHER_RESERVED6 6 -#define DMDITHER_RESERVED7 7 -#define DMDITHER_RESERVED8 8 -#define DMDITHER_RESERVED9 9 -#define DMDITHER_GRAYSCALE 10 -#define DMDITHER_USER 256 -#define GDI_ERROR 0xFFFFFFFF -#define HGDI_ERROR ((HANDLE)GDI_ERROR) -#define TMPF_FIXED_PITCH 1 -#define TMPF_VECTOR 2 -#define TMPF_TRUETYPE 4 -#define TMPF_DEVICE 8 -#define NTM_ITALIC 1 -#define NTM_BOLD 32 -#define NTM_REGULAR 64 +#define GGO_GLYPH_INDEX 0x0080 +#define GGO_UNHINTED 0x0100 + #define TT_POLYGON_TYPE 24 + #define TT_PRIM_LINE 1 #define TT_PRIM_QSPLINE 2 -#define FONTMAPPER_MAX 10 -#define ENHMETA_STOCK_OBJECT 0x80000000 -#define WGL_FONT_LINES 0 -#define WGL_FONT_POLYGONS 1 -#define LPD_DOUBLEBUFFER 1 -#define LPD_STEREO 2 -#define LPD_SUPPORT_GDI 16 -#define LPD_SUPPORT_OPENGL 32 -#define LPD_SHARE_DEPTH 64 -#define LPD_SHARE_STENCIL 128 -#define LPD_SHARE_ACCUM 256 -#define LPD_SWAP_EXCHANGE 512 -#define LPD_SWAP_COPY 1024 -#define LPD_TRANSPARENT 4096 -#define LPD_TYPE_RGBA 0 -#define LPD_TYPE_COLORINDEX 1 -#define WGL_SWAP_MAIN_PLANE 1 -#define WGL_SWAP_OVERLAY1 2 -#define WGL_SWAP_OVERLAY2 4 -#define WGL_SWAP_OVERLAY3 8 -#define WGL_SWAP_OVERLAY4 16 -#define WGL_SWAP_OVERLAY5 32 -#define WGL_SWAP_OVERLAY6 64 -#define WGL_SWAP_OVERLAY7 128 -#define WGL_SWAP_OVERLAY8 256 -#define WGL_SWAP_OVERLAY9 512 -#define WGL_SWAP_OVERLAY10 1024 -#define WGL_SWAP_OVERLAY11 2048 -#define WGL_SWAP_OVERLAY12 4096 -#define WGL_SWAP_OVERLAY13 8192 -#define WGL_SWAP_OVERLAY14 16384 -#define WGL_SWAP_OVERLAY15 32768 -#define WGL_SWAP_UNDERLAY1 65536 -#define WGL_SWAP_UNDERLAY2 0x20000 -#define WGL_SWAP_UNDERLAY3 0x40000 -#define WGL_SWAP_UNDERLAY4 0x80000 -#define WGL_SWAP_UNDERLAY5 0x100000 -#define WGL_SWAP_UNDERLAY6 0x200000 -#define WGL_SWAP_UNDERLAY7 0x400000 -#define WGL_SWAP_UNDERLAY8 0x800000 -#define WGL_SWAP_UNDERLAY9 0x1000000 -#define WGL_SWAP_UNDERLAY10 0x2000000 -#define WGL_SWAP_UNDERLAY11 0x4000000 -#define WGL_SWAP_UNDERLAY12 0x8000000 -#define WGL_SWAP_UNDERLAY13 0x10000000 -#define WGL_SWAP_UNDERLAY14 0x20000000 -#define WGL_SWAP_UNDERLAY15 0x40000000 -#define AC_SRC_OVER 0 -#define LAYOUT_RTL 1 -#define LAYOUT_BITMAPORIENTATIONPRESERVED 8 - -#ifndef RC_INVOKED -typedef struct _ABC { - int abcA; - UINT abcB; - int abcC; -} ABC,*LPABC; -typedef struct _ABCFLOAT { - FLOAT abcfA; - FLOAT abcfB; - FLOAT abcfC; -} ABCFLOAT,*LPABCFLOAT; -typedef struct tagBITMAP { - LONG bmType; - LONG bmWidth; - LONG bmHeight; - LONG bmWidthBytes; - WORD bmPlanes; - WORD bmBitsPixel; - LPVOID bmBits; -} BITMAP,*PBITMAP,*LPBITMAP; -typedef struct tagBITMAPCOREHEADER { - DWORD bcSize; - WORD bcWidth; - WORD bcHeight; - WORD bcPlanes; - WORD bcBitCount; -} BITMAPCOREHEADER,*LPBITMAPCOREHEADER,*PBITMAPCOREHEADER; -#pragma pack(push,1) -typedef struct tagRGBTRIPLE { - BYTE rgbtBlue; - BYTE rgbtGreen; - BYTE rgbtRed; -} RGBTRIPLE; -#pragma pack(pop) -#pragma pack(push,2) -typedef struct tagBITMAPFILEHEADER { - WORD bfType; - DWORD bfSize; - WORD bfReserved1; - WORD bfReserved2; - DWORD bfOffBits; -} BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER; -#pragma pack(pop) -typedef struct _BITMAPCOREINFO { - BITMAPCOREHEADER bmciHeader; - RGBTRIPLE bmciColors[1]; -} BITMAPCOREINFO,*LPBITMAPCOREINFO,*PBITMAPCOREINFO; -typedef struct tagBITMAPINFOHEADER{ - DWORD biSize; - LONG biWidth; - LONG biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - LONG biXPelsPerMeter; - LONG biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; -} BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER; -typedef struct tagRGBQUAD { - BYTE rgbBlue; - BYTE rgbGreen; - BYTE rgbRed; - BYTE rgbReserved; -} RGBQUAD; -typedef struct tagBITMAPINFO { - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[1]; -} BITMAPINFO,*LPBITMAPINFO,*PBITMAPINFO; -typedef long FXPT16DOT16,*LPFXPT16DOT16; -typedef long FXPT2DOT30,*LPFXPT2DOT30; -typedef struct tagCIEXYZ { - FXPT2DOT30 ciexyzX; - FXPT2DOT30 ciexyzY; - FXPT2DOT30 ciexyzZ; -} CIEXYZ,*LPCIEXYZ; -typedef struct tagCIEXYZTRIPLE { - CIEXYZ ciexyzRed; - CIEXYZ ciexyzGreen; - CIEXYZ ciexyzBlue; -} CIEXYZTRIPLE,*LPCIEXYZTRIPLE; -typedef struct { - DWORD bV4Size; - LONG bV4Width; - LONG bV4Height; - WORD bV4Planes; - WORD bV4BitCount; - DWORD bV4V4Compression; - DWORD bV4SizeImage; - LONG bV4XPelsPerMeter; - LONG bV4YPelsPerMeter; - DWORD bV4ClrUsed; - DWORD bV4ClrImportant; - DWORD bV4RedMask; - DWORD bV4GreenMask; - DWORD bV4BlueMask; - DWORD bV4AlphaMask; - DWORD bV4CSType; - CIEXYZTRIPLE bV4Endpoints; - DWORD bV4GammaRed; - DWORD bV4GammaGreen; - DWORD bV4GammaBlue; -} BITMAPV4HEADER,*LPBITMAPV4HEADER,*PBITMAPV4HEADER; -typedef struct tagFONTSIGNATURE { - DWORD fsUsb[4]; - DWORD fsCsb[2]; -} FONTSIGNATURE,*LPFONTSIGNATURE; -typedef struct { - UINT ciCharset; - UINT ciACP; - FONTSIGNATURE fs; -} CHARSETINFO,*LPCHARSETINFO; -typedef struct tagCOLORADJUSTMENT { - WORD caSize; - WORD caFlags; - WORD caIlluminantIndex; - WORD caRedGamma; - WORD caGreenGamma; - WORD caBlueGamma; - WORD caReferenceBlack; - WORD caReferenceWhite; - SHORT caContrast; - SHORT caBrightness; - SHORT caColorfulness; - SHORT caRedGreenTint; -} COLORADJUSTMENT,*LPCOLORADJUSTMENT; -typedef struct _devicemodeA { - BYTE dmDeviceName[CCHDEVICENAME]; - WORD dmSpecVersion; - WORD dmDriverVersion; - WORD dmSize; - WORD dmDriverExtra; - DWORD dmFields; - short dmOrientation; - short dmPaperSize; - short dmPaperLength; - short dmPaperWidth; - short dmScale; - short dmCopies; - short dmDefaultSource; - short dmPrintQuality; - short dmColor; - short dmDuplex; - short dmYResolution; - short dmTTOption; - short dmCollate; - BYTE dmFormName[CCHFORMNAME]; - WORD dmLogPixels; - DWORD dmBitsPerPel; - DWORD dmPelsWidth; - DWORD dmPelsHeight; - DWORD dmDisplayFlags; - DWORD dmDisplayFrequency; - DWORD dmICMMethod; - DWORD dmICMIntent; - DWORD dmMediaType; - DWORD dmDitherType; - DWORD dmICCManufacturer; - DWORD dmICCModel; -} DEVMODEA,*LPDEVMODEA,*PDEVMODEA; -typedef struct _devicemodeW { - WCHAR dmDeviceName[CCHDEVICENAME]; - WORD dmSpecVersion; - WORD dmDriverVersion; - WORD dmSize; - WORD dmDriverExtra; - DWORD dmFields; - short dmOrientation; - short dmPaperSize; - short dmPaperLength; - short dmPaperWidth; - short dmScale; - short dmCopies; - short dmDefaultSource; - short dmPrintQuality; - short dmColor; - short dmDuplex; - short dmYResolution; - short dmTTOption; - short dmCollate; - WCHAR dmFormName[CCHFORMNAME]; - WORD dmLogPixels; - DWORD dmBitsPerPel; - DWORD dmPelsWidth; - DWORD dmPelsHeight; - DWORD dmDisplayFlags; - DWORD dmDisplayFrequency; - DWORD dmICMMethod; - DWORD dmICMIntent; - DWORD dmMediaType; - DWORD dmDitherType; - DWORD dmICCManufacturer; - DWORD dmICCModel; -} DEVMODEW,*LPDEVMODEW,*PDEVMODEW; -typedef struct tagDIBSECTION { - BITMAP dsBm; - BITMAPINFOHEADER dsBmih; - DWORD dsBitfields[3]; - HANDLE dshSection; - DWORD dsOffset; -} DIBSECTION; -typedef struct _DOCINFOA { - int cbSize; - LPCTSTR lpszDocName; - LPCTSTR lpszOutput; - LPCTSTR lpszDatatype; - DWORD fwType; -} DOCINFOA,*LPDOCINFOA; -typedef struct _DOCINFOW { - int cbSize; - LPCWSTR lpszDocName; - LPCWSTR lpszOutput; - LPCWSTR lpszDatatype; - DWORD fwType; -} DOCINFOW,*LPDOCINFOW; -typedef struct tagEMR { - DWORD iType; - DWORD nSize; -} EMR,*PEMR; -typedef struct tagEMRANGLEARC { - EMR emr; - POINTL ptlCenter; - DWORD nRadius; - FLOAT eStartAngle; - FLOAT eSweepAngle; -} EMRANGLEARC,*PEMRANGLEARC; -typedef struct tagEMRARC { - EMR emr; - RECTL rclBox; - POINTL ptlStart; - POINTL ptlEnd; -} EMRARC,*PEMRARC,EMRARCTO,*PEMRARCTO,EMRCHORD,*PEMRCHORD,EMRPIE,*PEMRPIE; -typedef struct _XFORM { - FLOAT eM11; - FLOAT eM12; - FLOAT eM21; - FLOAT eM22; - FLOAT eDx; - FLOAT eDy; -} XFORM,*LPXFORM; -typedef struct tagEMRBITBLT { - EMR emr; - RECTL rclBounds; - LONG xDest; - LONG yDest; - LONG cxDest; - LONG cyDest; - DWORD dwRop; - LONG xSrc; - LONG ySrc; - XFORM xformSrc; - COLORREF crBkColorSrc; - DWORD iUsageSrc; - DWORD offBmiSrc; - DWORD offBitsSrc; - DWORD cbBitsSrc; -} EMRBITBLT,*PEMRBITBLT; -typedef struct tagLOGBRUSH { - UINT lbStyle; - COLORREF lbColor; - LONG lbHatch; -} LOGBRUSH,*LPLOGBRUSH; -typedef LOGBRUSH PATTERN,*PPATTERN,*LPPATTERN; -typedef struct tagEMRCREATEBRUSHINDIRECT { - EMR emr; - DWORD ihBrush; - LOGBRUSH lb; -} EMRCREATEBRUSHINDIRECT,*PEMRCREATEBRUSHINDIRECT; -typedef LONG LCSCSTYPE; -typedef LONG LCSGAMUTMATCH; -typedef struct tagLOGCOLORSPACEA { - DWORD lcsSignature; - DWORD lcsVersion; - DWORD lcsSize; - LCSCSTYPE lcsCSType; - LCSGAMUTMATCH lcsIntent; - CIEXYZTRIPLE lcsEndpoints; - DWORD lcsGammaRed; - DWORD lcsGammaGreen; - DWORD lcsGammaBlue; - CHAR lcsFilename[MAX_PATH]; -} LOGCOLORSPACEA,*LPLOGCOLORSPACEA; -typedef struct tagLOGCOLORSPACEW { - DWORD lcsSignature; - DWORD lcsVersion; - DWORD lcsSize; - LCSCSTYPE lcsCSType; - LCSGAMUTMATCH lcsIntent; - CIEXYZTRIPLE lcsEndpoints; - DWORD lcsGammaRed; - DWORD lcsGammaGreen; - DWORD lcsGammaBlue; - WCHAR lcsFilename[MAX_PATH]; -} LOGCOLORSPACEW,*LPLOGCOLORSPACEW; -typedef struct tagEMRCREATECOLORSPACE { - EMR emr; - DWORD ihCS; - LOGCOLORSPACEW lcs; -} EMRCREATECOLORSPACE,*PEMRCREATECOLORSPACE; -typedef struct tagEMRCREATEDIBPATTERNBRUSHPT { - EMR emr; - DWORD ihBrush; - DWORD iUsage; - DWORD offBmi; - DWORD cbBmi; - DWORD offBits; - DWORD cbBits; -} EMRCREATEDIBPATTERNBRUSHPT,*PEMRCREATEDIBPATTERNBRUSHPT; -typedef struct tagEMRCREATEMONOBRUSH { - EMR emr; - DWORD ihBrush; - DWORD iUsage; - DWORD offBmi; - DWORD cbBmi; - DWORD offBits; - DWORD cbBits; -} EMRCREATEMONOBRUSH,*PEMRCREATEMONOBRUSH; -typedef struct tagPALETTEENTRY { - BYTE peRed; - BYTE peGreen; - BYTE peBlue; - BYTE peFlags; -} PALETTEENTRY,*LPPALETTEENTRY,*PPALETTEENTRY; -typedef struct tagLOGPALETTE { - WORD palVersion; - WORD palNumEntries; - PALETTEENTRY palPalEntry[1]; -} LOGPALETTE,*NPLOGPALETTE,*PLOGPALETTE,*LPLOGPALETTE; -typedef struct tagEMRCREATEPALETTE { - EMR emr; - DWORD ihPal; - LOGPALETTE lgpl; -} EMRCREATEPALETTE,*PEMRCREATEPALETTE; -typedef struct tagLOGPEN { - UINT lopnStyle; - POINT lopnWidth; - COLORREF lopnColor; -} LOGPEN,*LPLOGPEN; -typedef struct tagEMRCREATEPEN { - EMR emr; - DWORD ihPen; - LOGPEN lopn; -} EMRCREATEPEN,*PEMRCREATEPEN; -typedef struct tagEMRELLIPSE { - EMR emr; - RECTL rclBox; -} EMRELLIPSE,*PEMRELLIPSE,EMRRECTANGLE,*PEMRRECTANGLE; -typedef struct tagEMREOF { - EMR emr; - DWORD nPalEntries; - DWORD offPalEntries; - DWORD nSizeLast; -} EMREOF,*PEMREOF; -typedef struct tagEMREXCLUDECLIPRECT { - EMR emr; - RECTL rclClip; -} EMREXCLUDECLIPRECT,*PEMREXCLUDECLIPRECT,EMRINTERSECTCLIPRECT,*PEMRINTERSECTCLIPRECT; -typedef struct tagPANOSE { - BYTE bFamilyType; - BYTE bSerifStyle; - BYTE bWeight; - BYTE bProportion; - BYTE bContrast; - BYTE bStrokeVariation; - BYTE bArmStyle; - BYTE bLetterform; - BYTE bMidline; - BYTE bXHeight; -} PANOSE; -typedef struct tagLOGFONTA { - LONG lfHeight; - LONG lfWidth; - LONG lfEscapement; - LONG lfOrientation; - LONG lfWeight; - BYTE lfItalic; - BYTE lfUnderline; - BYTE lfStrikeOut; - BYTE lfCharSet; - BYTE lfOutPrecision; - BYTE lfClipPrecision; - BYTE lfQuality; - BYTE lfPitchAndFamily; - CHAR lfFaceName[LF_FACESIZE]; -} LOGFONTA,*PLOGFONTA,*LPLOGFONTA; -typedef struct tagLOGFONTW { - LONG lfHeight; - LONG lfWidth; - LONG lfEscapement; - LONG lfOrientation; - LONG lfWeight; - BYTE lfItalic; - BYTE lfUnderline; - BYTE lfStrikeOut; - BYTE lfCharSet; - BYTE lfOutPrecision; - BYTE lfClipPrecision; - BYTE lfQuality; - BYTE lfPitchAndFamily; - WCHAR lfFaceName[LF_FACESIZE]; -} LOGFONTW,*PLOGFONTW,*LPLOGFONTW; -typedef struct tagEXTLOGFONTA { - LOGFONTA elfLogFont; - BYTE elfFullName[LF_FULLFACESIZE]; - BYTE elfStyle[LF_FACESIZE]; - DWORD elfVersion; - DWORD elfStyleSize; - DWORD elfMatch; - DWORD elfReserved; - BYTE elfVendorId[ELF_VENDOR_SIZE]; - DWORD elfCulture; - PANOSE elfPanose; -} EXTLOGFONTA,*PEXTLOGFONTA,*LPEXTLOGFONTA; -typedef struct tagEXTLOGFONTW { - LOGFONTW elfLogFont; - WCHAR elfFullName[LF_FULLFACESIZE]; - WCHAR elfStyle[LF_FACESIZE]; - DWORD elfVersion; - DWORD elfStyleSize; - DWORD elfMatch; - DWORD elfReserved; - BYTE elfVendorId[ELF_VENDOR_SIZE]; - DWORD elfCulture; - PANOSE elfPanose; -} EXTLOGFONTW,*PEXTLOGFONTW,*LPEXTLOGFONTW; -typedef struct tagEMREXTCREATEFONTINDIRECTW { - EMR emr; - DWORD ihFont; - EXTLOGFONTW elfw; -} EMREXTCREATEFONTINDIRECTW,*PEMREXTCREATEFONTINDIRECTW; -typedef struct tagEXTLOGPEN { - UINT elpPenStyle; - UINT elpWidth; - UINT elpBrushStyle; - COLORREF elpColor; - LONG elpHatch; - DWORD elpNumEntries; - DWORD elpStyleEntry[1]; -} EXTLOGPEN,*PEXTLOGPEN,*LPEXTLOGPEN; -typedef struct tagEMREXTCREATEPEN { - EMR emr; - DWORD ihPen; - DWORD offBmi; - DWORD cbBmi; - DWORD offBits; - DWORD cbBits; - EXTLOGPEN elp; -} EMREXTCREATEPEN,*PEMREXTCREATEPEN; -typedef struct tagEMREXTFLOODFILL { - EMR emr; - POINTL ptlStart; - COLORREF crColor; - DWORD iMode; -} EMREXTFLOODFILL,*PEMREXTFLOODFILL; -typedef struct tagEMREXTSELECTCLIPRGN { - EMR emr; - DWORD cbRgnData; - DWORD iMode; - BYTE RgnData[1]; -} EMREXTSELECTCLIPRGN,*PEMREXTSELECTCLIPRGN; -typedef struct tagEMRTEXT { - POINTL ptlReference; - DWORD nChars; - DWORD offString; - DWORD fOptions; - RECTL rcl; - DWORD offDx; -} EMRTEXT,*PEMRTEXT; -typedef struct tagEMREXTTEXTOUTA { - EMR emr; - RECTL rclBounds; - DWORD iGraphicsMode; - FLOAT exScale; - FLOAT eyScale; - EMRTEXT emrtext; -} EMREXTTEXTOUTA,*PEMREXTTEXTOUTA,EMREXTTEXTOUTW,*PEMREXTTEXTOUTW; -typedef struct tagEMRFILLPATH { - EMR emr; - RECTL rclBounds; -} EMRFILLPATH,*PEMRFILLPATH,EMRSTROKEANDFILLPATH,*PEMRSTROKEANDFILLPATH,EMRSTROKEPATH,*PEMRSTROKEPATH; -typedef struct tagEMRFILLRGN { - EMR emr; - RECTL rclBounds; - DWORD cbRgnData; - DWORD ihBrush; - BYTE RgnData[1]; -} EMRFILLRGN,*PEMRFILLRGN; -typedef struct tagEMRFORMAT { - DWORD dSignature; - DWORD nVersion; - DWORD cbData; - DWORD offData; -} EMRFORMAT; -typedef struct tagEMRFRAMERGN { - EMR emr; - RECTL rclBounds; - DWORD cbRgnData; - DWORD ihBrush; - SIZEL szlStroke; - BYTE RgnData[1]; -} EMRFRAMERGN,*PEMRFRAMERGN; -typedef struct tagEMRGDICOMMENT { - EMR emr; - DWORD cbData; - BYTE Data[1]; -} EMRGDICOMMENT,*PEMRGDICOMMENT; -typedef struct tagEMRINVERTRGN { - EMR emr; - RECTL rclBounds; - DWORD cbRgnData; - BYTE RgnData[1]; -} EMRINVERTRGN,*PEMRINVERTRGN,EMRPAINTRGN,*PEMRPAINTRGN; -typedef struct tagEMRLINETO { - EMR emr; - POINTL ptl; -} EMRLINETO,*PEMRLINETO,EMRMOVETOEX,*PEMRMOVETOEX; -typedef struct tagEMRMASKBLT { - EMR emr; - RECTL rclBounds; - LONG xDest; - LONG yDest; - LONG cxDest; - LONG cyDest; - DWORD dwRop; - LONG xSrc; - LONG ySrc; - XFORM xformSrc; - COLORREF crBkColorSrc; - DWORD iUsageSrc; - DWORD offBmiSrc; - DWORD cbBmiSrc; - DWORD offBitsSrc; - DWORD cbBitsSrc; - LONG xMask; - LONG yMask; - DWORD iUsageMask; - DWORD offBmiMask; - DWORD cbBmiMask; - DWORD offBitsMask; - DWORD cbBitsMask; -} EMRMASKBLT,*PEMRMASKBLT; -typedef struct tagEMRMODIFYWORLDTRANSFORM { - EMR emr; - XFORM xform; - DWORD iMode; -} EMRMODIFYWORLDTRANSFORM,*PEMRMODIFYWORLDTRANSFORM; -typedef struct tagEMROFFSETCLIPRGN { - EMR emr; - POINTL ptlOffset; -} EMROFFSETCLIPRGN,*PEMROFFSETCLIPRGN; -typedef struct tagEMRPLGBLT { - EMR emr; - RECTL rclBounds; - POINTL aptlDest[3]; - LONG xSrc; - LONG ySrc; - LONG cxSrc; - LONG cySrc; - XFORM xformSrc; - COLORREF crBkColorSrc; - DWORD iUsageSrc; - DWORD offBmiSrc; - DWORD cbBmiSrc; - DWORD offBitsSrc; - DWORD cbBitsSrc; - LONG xMask; - LONG yMask; - DWORD iUsageMask; - DWORD offBmiMask; - DWORD cbBmiMask; - DWORD offBitsMask; - DWORD cbBitsMask; -} EMRPLGBLT,*PEMRPLGBLT; -typedef struct tagEMRPOLYDRAW { - EMR emr; - RECTL rclBounds; - DWORD cptl; - POINTL aptl[1]; - BYTE abTypes[1]; -} EMRPOLYDRAW,*PEMRPOLYDRAW; -typedef struct tagEMRPOLYDRAW16 { - EMR emr; - RECTL rclBounds; - DWORD cpts; - POINTS apts[1]; - BYTE abTypes[1]; -} EMRPOLYDRAW16,*PEMRPOLYDRAW16; -typedef struct tagEMRPOLYLINE { - EMR emr; - RECTL rclBounds; - DWORD cptl; - POINTL aptl[1]; -} EMRPOLYLINE,*PEMRPOLYLINE,EMRPOLYBEZIER,*PEMRPOLYBEZIER,EMRPOLYGON,*PEMRPOLYGON,EMRPOLYBEZIERTO,*PEMRPOLYBEZIERTO,EMRPOLYLINETO,*PEMRPOLYLINETO; -typedef struct tagEMRPOLYLINE16 { - EMR emr; - RECTL rclBounds; - DWORD cpts; - POINTL apts[1]; -} EMRPOLYLINE16,*PEMRPOLYLINE16,EMRPOLYBEZIER16,*PEMRPOLYBEZIER16,EMRPOLYGON16,*PEMRPOLYGON16,EMRPOLYBEZIERTO16,*PEMRPOLYBEZIERTO16,EMRPOLYLINETO16,*PEMRPOLYLINETO16; -typedef struct tagEMRPOLYPOLYLINE { - EMR emr; - RECTL rclBounds; - DWORD nPolys; - DWORD cptl; - DWORD aPolyCounts[1]; - POINTL aptl[1]; -} EMRPOLYPOLYLINE,*PEMRPOLYPOLYLINE,EMRPOLYPOLYGON,*PEMRPOLYPOLYGON; -typedef struct tagEMRPOLYPOLYLINE16 { - EMR emr; - RECTL rclBounds; - DWORD nPolys; - DWORD cpts; - DWORD aPolyCounts[1]; - POINTS apts[1]; -} EMRPOLYPOLYLINE16,*PEMRPOLYPOLYLINE16,EMRPOLYPOLYGON16,*PEMRPOLYPOLYGON16; -typedef struct tagEMRPOLYTEXTOUTA { - EMR emr; - RECTL rclBounds; - DWORD iGraphicsMode; - FLOAT exScale; - FLOAT eyScale; - LONG cStrings; - EMRTEXT aemrtext[1]; -} EMRPOLYTEXTOUTA,*PEMRPOLYTEXTOUTA,EMRPOLYTEXTOUTW,*PEMRPOLYTEXTOUTW; -typedef struct tagEMRRESIZEPALETTE { - EMR emr; - DWORD ihPal; - DWORD cEntries; -} EMRRESIZEPALETTE,*PEMRRESIZEPALETTE; -typedef struct tagEMRRESTOREDC { - EMR emr; - LONG iRelative; -} EMRRESTOREDC,*PEMRRESTOREDC; -typedef struct tagEMRROUNDRECT { - EMR emr; - RECTL rclBox; - SIZEL szlCorner; -} EMRROUNDRECT,*PEMRROUNDRECT; -typedef struct tagEMRSCALEVIEWPORTEXTEX { - EMR emr; - LONG xNum; - LONG xDenom; - LONG yNum; - LONG yDenom; -} EMRSCALEVIEWPORTEXTEX,*PEMRSCALEVIEWPORTEXTEX,EMRSCALEWINDOWEXTEX,*PEMRSCALEWINDOWEXTEX; -typedef struct tagEMRSELECTCOLORSPACE { - EMR emr; - DWORD ihCS; -} EMRSELECTCOLORSPACE,*PEMRSELECTCOLORSPACE,EMRDELETECOLORSPACE,*PEMRDELETECOLORSPACE; -typedef struct tagEMRSELECTOBJECT { - EMR emr; - DWORD ihObject; -} EMRSELECTOBJECT,*PEMRSELECTOBJECT,EMRDELETEOBJECT,*PEMRDELETEOBJECT; -typedef struct tagEMRSELECTPALETTE { - EMR emr; - DWORD ihPal; -} EMRSELECTPALETTE,*PEMRSELECTPALETTE; -typedef struct tagEMRSETARCDIRECTION { - EMR emr; - DWORD iArcDirection; -} EMRSETARCDIRECTION,*PEMRSETARCDIRECTION; -typedef struct tagEMRSETTEXTCOLOR { - EMR emr; - COLORREF crColor; -} EMRSETBKCOLOR,*PEMRSETBKCOLOR,EMRSETTEXTCOLOR,*PEMRSETTEXTCOLOR; -typedef struct tagEMRSETCOLORADJUSTMENT { - EMR emr; - COLORADJUSTMENT ColorAdjustment; -} EMRSETCOLORADJUSTMENT,*PEMRSETCOLORADJUSTMENT; -typedef struct tagEMRSETDIBITSTODEVICE { - EMR emr; - RECTL rclBounds; - LONG xDest; - LONG yDest; - LONG xSrc; - LONG ySrc; - LONG cxSrc; - LONG cySrc; - DWORD offBmiSrc; - DWORD cbBmiSrc; - DWORD offBitsSrc; - DWORD cbBitsSrc; - DWORD iUsageSrc; - DWORD iStartScan; - DWORD cScans; -} EMRSETDIBITSTODEVICE,*PEMRSETDIBITSTODEVICE; -typedef struct tagEMRSETMAPPERFLAGS { - EMR emr; - DWORD dwFlags; -} EMRSETMAPPERFLAGS,*PEMRSETMAPPERFLAGS; -typedef struct tagEMRSETMITERLIMIT { - EMR emr; - FLOAT eMiterLimit; -} EMRSETMITERLIMIT,*PEMRSETMITERLIMIT; -typedef struct tagEMRSETPALETTEENTRIES { - EMR emr; - DWORD ihPal; - DWORD iStart; - DWORD cEntries; - PALETTEENTRY aPalEntries[1]; -} EMRSETPALETTEENTRIES,*PEMRSETPALETTEENTRIES; -typedef struct tagEMRSETPIXELV { - EMR emr; - POINTL ptlPixel; - COLORREF crColor; -} EMRSETPIXELV,*PEMRSETPIXELV; -typedef struct tagEMRSETVIEWPORTEXTEX { - EMR emr; - SIZEL szlExtent; -} EMRSETVIEWPORTEXTEX,*PEMRSETVIEWPORTEXTEX,EMRSETWINDOWEXTEX,*PEMRSETWINDOWEXTEX; -typedef struct tagEMRSETVIEWPORTORGEX { - EMR emr; - POINTL ptlOrigin; -} EMRSETVIEWPORTORGEX,*PEMRSETVIEWPORTORGEX,EMRSETWINDOWORGEX,*PEMRSETWINDOWORGEX,EMRSETBRUSHORGEX,*PEMRSETBRUSHORGEX; -typedef struct tagEMRSETWORLDTRANSFORM { - EMR emr; - XFORM xform; -} EMRSETWORLDTRANSFORM,*PEMRSETWORLDTRANSFORM; -typedef struct tagEMRSTRETCHBLT { - EMR emr; - RECTL rclBounds; - LONG xDest; - LONG yDest; - LONG cxDest; - LONG cyDest; - DWORD dwRop; - LONG xSrc; - LONG ySrc; - XFORM xformSrc; - COLORREF crBkColorSrc; - DWORD iUsageSrc; - DWORD offBmiSrc; - DWORD cbBmiSrc; - DWORD offBitsSrc; - DWORD cbBitsSrc; - LONG cxSrc; - LONG cySrc; -} EMRSTRETCHBLT,*PEMRSTRETCHBLT; -typedef struct tagEMRSTRETCHDIBITS { - EMR emr; - RECTL rclBounds; - LONG xDest; - LONG yDest; - LONG xSrc; - LONG ySrc; - LONG cxSrc; - LONG cySrc; - DWORD offBmiSrc; - DWORD cbBmiSrc; - DWORD offBitsSrc; - DWORD cbBitsSrc; - DWORD iUsageSrc; - DWORD dwRop; - LONG cxDest; - LONG cyDest; -} EMRSTRETCHDIBITS,*PEMRSTRETCHDIBITS; -typedef struct tagABORTPATH { - EMR emr; -} EMRABORTPATH,*PEMRABORTPATH,EMRBEGINPATH,*PEMRBEGINPATH,EMRENDPATH,*PEMRENDPATH,EMRCLOSEFIGURE,*PEMRCLOSEFIGURE,EMRFLATTENPATH,*PEMRFLATTENPATH,EMRWIDENPATH,*PEMRWIDENPATH,EMRSETMETARGN,*PEMRSETMETARGN,EMRSAVEDC,*PEMRSAVEDC,EMRREALIZEPALETTE,*PEMRREALIZEPALETTE; -typedef struct tagEMRSELECTCLIPPATH { - EMR emr; - DWORD iMode; -} EMRSELECTCLIPPATH,*PEMRSELECTCLIPPATH,EMRSETBKMODE,*PEMRSETBKMODE,EMRSETMAPMODE,*PEMRSETMAPMODE,EMRSETPOLYFILLMODE,*PEMRSETPOLYFILLMODE,EMRSETROP2,*PEMRSETROP2,EMRSETSTRETCHBLTMODE,*PEMRSETSTRETCHBLTMODE,EMRSETTEXTALIGN,*PEMRSETTEXTALIGN,EMRENABLEICM,*PEMRENABLEICM; -#pragma pack(push,2) -typedef struct tagMETAHEADER { - WORD mtType; - WORD mtHeaderSize; - WORD mtVersion; - DWORD mtSize; - WORD mtNoObjects; - DWORD mtMaxRecord; - WORD mtNoParameters; -} METAHEADER,*PMETAHEADER,*LPMETAHEADER; -#pragma pack(pop) -typedef struct tagENHMETAHEADER { - DWORD iType; - DWORD nSize; - RECTL rclBounds; - RECTL rclFrame; - DWORD dSignature; - DWORD nVersion; - DWORD nBytes; - DWORD nRecords; - WORD nHandles; - WORD sReserved; - DWORD nDescription; - DWORD offDescription; - DWORD nPalEntries; - SIZEL szlDevice; - SIZEL szlMillimeters; -} ENHMETAHEADER,*LPENHMETAHEADER; -typedef struct tagMETARECORD { - DWORD rdSize; - WORD rdFunction; - WORD rdParm[1]; -} METARECORD,*PMETARECORD,*LPMETARECORD; -typedef struct tagENHMETARECORD { - DWORD iType; - DWORD nSize; - DWORD dParm[1]; -} ENHMETARECORD,*LPENHMETARECORD; -typedef struct tagHANDLETABLE { - HGDIOBJ objectHandle[1]; -} HANDLETABLE,*LPHANDLETABLE; -typedef struct tagTEXTMETRICA { - LONG tmHeight; - LONG tmAscent; - LONG tmDescent; - LONG tmInternalLeading; - LONG tmExternalLeading; - LONG tmAveCharWidth; - LONG tmMaxCharWidth; - LONG tmWeight; - LONG tmOverhang; - LONG tmDigitizedAspectX; - LONG tmDigitizedAspectY; - BYTE tmFirstChar; - BYTE tmLastChar; - BYTE tmDefaultChar; - BYTE tmBreakChar; - BYTE tmItalic; - BYTE tmUnderlined; - BYTE tmStruckOut; - BYTE tmPitchAndFamily; - BYTE tmCharSet; -} TEXTMETRICA,*PTEXTMETRICA,*LPTEXTMETRICA; -typedef struct tagTEXTMETRICW { - LONG tmHeight; - LONG tmAscent; - LONG tmDescent; - LONG tmInternalLeading; - LONG tmExternalLeading; - LONG tmAveCharWidth; - LONG tmMaxCharWidth; - LONG tmWeight; - LONG tmOverhang; - LONG tmDigitizedAspectX; - LONG tmDigitizedAspectY; - WCHAR tmFirstChar; - WCHAR tmLastChar; - WCHAR tmDefaultChar; - WCHAR tmBreakChar; - BYTE tmItalic; - BYTE tmUnderlined; - BYTE tmStruckOut; - BYTE tmPitchAndFamily; - BYTE tmCharSet; -} TEXTMETRICW,*PTEXTMETRICW,*LPTEXTMETRICW; -typedef struct _RGNDATAHEADER { - DWORD dwSize; - DWORD iType; - DWORD nCount; - DWORD nRgnSize; - RECT rcBound; -} RGNDATAHEADER; -typedef struct _RGNDATA { - RGNDATAHEADER rdh; - char Buffer[1]; -} RGNDATA,*LPRGNDATA; -/* for GetRandomRgn */ -#define SYSRGN 4 -typedef struct tagGCP_RESULTSA { - DWORD lStructSize; - LPSTR lpOutString; - UINT *lpOrder; - INT *lpDx; - INT *lpCaretPos; - LPSTR lpClass; - UINT *lpGlyphs; - UINT nGlyphs; - UINT nMaxFit; -} GCP_RESULTSA,*LPGCP_RESULTSA; -typedef struct tagGCP_RESULTSW { - DWORD lStructSize; - LPWSTR lpOutString; - UINT *lpOrder; - INT *lpDx; - INT *lpCaretPos; - LPWSTR lpClass; - UINT *lpGlyphs; - UINT nGlyphs; - UINT nMaxFit; -} GCP_RESULTSW,*LPGCP_RESULTSW; -typedef struct _GLYPHMETRICS { - UINT gmBlackBoxX; - UINT gmBlackBoxY; - POINT gmptGlyphOrigin; - short gmCellIncX; - short gmCellIncY; -} GLYPHMETRICS,*LPGLYPHMETRICS; -typedef struct tagKERNINGPAIR { - WORD wFirst; - WORD wSecond; - int iKernAmount; -} KERNINGPAIR,*LPKERNINGPAIR; -typedef struct _FIXED { - WORD fract; - short value; -} FIXED; -typedef struct _MAT2 { - FIXED eM11; - FIXED eM12; - FIXED eM21; - FIXED eM22; -} MAT2,*LPMAT2; -typedef struct _OUTLINETEXTMETRICA { - UINT otmSize; - TEXTMETRICA otmTextMetrics; - BYTE otmFiller; - PANOSE otmPanoseNumber; - UINT otmfsSelection; - UINT otmfsType; - int otmsCharSlopeRise; - int otmsCharSlopeRun; - int otmItalicAngle; - UINT otmEMSquare; - int otmAscent; - int otmDescent; - UINT otmLineGap; - UINT otmsCapEmHeight; - UINT otmsXHeight; - RECT otmrcFontBox; - int otmMacAscent; - int otmMacDescent; - UINT otmMacLineGap; - UINT otmusMinimumPPEM; - POINT otmptSubscriptSize; - POINT otmptSubscriptOffset; - POINT otmptSuperscriptSize; - POINT otmptSuperscriptOffset; - UINT otmsStrikeoutSize; - int otmsStrikeoutPosition; - int otmsUnderscoreSize; - int otmsUnderscorePosition; - PSTR otmpFamilyName; - PSTR otmpFaceName; - PSTR otmpStyleName; - PSTR otmpFullName; -} OUTLINETEXTMETRICA,*POUTLINETEXTMETRICA,*LPOUTLINETEXTMETRICA; -typedef struct _OUTLINETEXTMETRICW { - UINT otmSize; - TEXTMETRICW otmTextMetrics; - BYTE otmFiller; - PANOSE otmPanoseNumber; - UINT otmfsSelection; - UINT otmfsType; - int otmsCharSlopeRise; - int otmsCharSlopeRun; - int otmItalicAngle; - UINT otmEMSquare; - int otmAscent; - int otmDescent; - UINT otmLineGap; - UINT otmsCapEmHeight; - UINT otmsXHeight; - RECT otmrcFontBox; - int otmMacAscent; - int otmMacDescent; - UINT otmMacLineGap; - UINT otmusMinimumPPEM; - POINT otmptSubscriptSize; - POINT otmptSubscriptOffset; - POINT otmptSuperscriptSize; - POINT otmptSuperscriptOffset; - UINT otmsStrikeoutSize; - int otmsStrikeoutPosition; - int otmsUnderscoreSize; - int otmsUnderscorePosition; - PSTR otmpFamilyName; - PSTR otmpFaceName; - PSTR otmpStyleName; - PSTR otmpFullName; -} OUTLINETEXTMETRICW,*POUTLINETEXTMETRICW,*LPOUTLINETEXTMETRICW; -typedef struct _RASTERIZER_STATUS { - short nSize; - short wFlags; - short nLanguageID; -} RASTERIZER_STATUS,*LPRASTERIZER_STATUS; -typedef struct _POLYTEXTA { - int x; - int y; - UINT n; - LPCSTR lpstr; - UINT uiFlags; - RECT rcl; - int *pdx; -} POLYTEXTA; -typedef struct _POLYTEXTW { - int x; - int y; - UINT n; - LPCWSTR lpstr; - UINT uiFlags; - RECT rcl; - int *pdx; -} POLYTEXTW; -typedef struct tagPIXELFORMATDESCRIPTOR { - WORD nSize; - WORD nVersion; - DWORD dwFlags; - BYTE iPixelType; - BYTE cColorBits; - BYTE cRedBits; - BYTE cRedShift; - BYTE cGreenBits; - BYTE cGreenShift; - BYTE cBlueBits; - BYTE cBlueShift; - BYTE cAlphaBits; - BYTE cAlphaShift; - BYTE cAccumBits; - BYTE cAccumRedBits; - BYTE cAccumGreenBits; - BYTE cAccumBlueBits; - BYTE cAccumAlphaBits; - BYTE cDepthBits; - BYTE cStencilBits; - BYTE cAuxBuffers; - BYTE iLayerType; - BYTE bReserved; - DWORD dwLayerMask; - DWORD dwVisibleMask; - DWORD dwDamageMask; -} PIXELFORMATDESCRIPTOR,*PPIXELFORMATDESCRIPTOR,*LPPIXELFORMATDESCRIPTOR; -typedef struct tagMETAFILEPICT { - LONG mm; - LONG xExt; - LONG yExt; - HMETAFILE hMF; -} METAFILEPICT,*LPMETAFILEPICT; -typedef struct tagLOCALESIGNATURE { - DWORD lsUsb[4]; - DWORD lsCsbDefault[2]; - DWORD lsCsbSupported[2]; -} LOCALESIGNATURE,*PLOCALESIGNATURE,*LPLOCALESIGNATURE; -typedef LONG LCSTYPE; -#pragma pack(push,4) -typedef struct tagNEWTEXTMETRICA { - LONG tmHeight; - LONG tmAscent; - LONG tmDescent; - LONG tmInternalLeading; - LONG tmExternalLeading; - LONG tmAveCharWidth; - LONG tmMaxCharWidth; - LONG tmWeight; - LONG tmOverhang; - LONG tmDigitizedAspectX; - LONG tmDigitizedAspectY; - BYTE tmFirstChar; - BYTE tmLastChar; - BYTE tmDefaultChar; - BYTE tmBreakChar; - BYTE tmItalic; - BYTE tmUnderlined; - BYTE tmStruckOut; - BYTE tmPitchAndFamily; - BYTE tmCharSet; - DWORD ntmFlags; - UINT ntmSizeEM; - UINT ntmCellHeight; - UINT ntmAvgWidth; -} NEWTEXTMETRICA,*PNEWTEXTMETRICA,*LPNEWTEXTMETRICA; -typedef struct tagNEWTEXTMETRICW { - LONG tmHeight; - LONG tmAscent; - LONG tmDescent; - LONG tmInternalLeading; - LONG tmExternalLeading; - LONG tmAveCharWidth; - LONG tmMaxCharWidth; - LONG tmWeight; - LONG tmOverhang; - LONG tmDigitizedAspectX; - LONG tmDigitizedAspectY; - WCHAR tmFirstChar; - WCHAR tmLastChar; - WCHAR tmDefaultChar; - WCHAR tmBreakChar; - BYTE tmItalic; - BYTE tmUnderlined; - BYTE tmStruckOut; - BYTE tmPitchAndFamily; - BYTE tmCharSet; - DWORD ntmFlags; - UINT ntmSizeEM; - UINT ntmCellHeight; - UINT ntmAvgWidth; -} NEWTEXTMETRICW,*PNEWTEXTMETRICW,*LPNEWTEXTMETRICW; -#pragma pack(pop) -typedef struct tagNEWTEXTMETRICEXA { - NEWTEXTMETRICA ntmTm; - FONTSIGNATURE ntmFontSig; -} NEWTEXTMETRICEXA; -typedef struct tagNEWTEXTMETRICEXW { - NEWTEXTMETRICW ntmTm; - FONTSIGNATURE ntmFontSig; -} NEWTEXTMETRICEXW; -typedef struct tagPELARRAY { - LONG paXCount; - LONG paYCount; - LONG paXExt; - LONG paYExt; - BYTE paRGBs; -} PELARRAY,*PPELARRAY,*LPPELARRAY; -typedef struct tagENUMLOGFONTA { - LOGFONTA elfLogFont; - BYTE elfFullName[LF_FULLFACESIZE]; - BYTE elfStyle[LF_FACESIZE]; -} ENUMLOGFONTA,*LPENUMLOGFONTA; -typedef struct tagENUMLOGFONTW { - LOGFONTW elfLogFont; - WCHAR elfFullName[LF_FULLFACESIZE]; - WCHAR elfStyle[LF_FACESIZE]; -} ENUMLOGFONTW,*LPENUMLOGFONTW; -typedef struct tagENUMLOGFONTEXA { - LOGFONTA elfLogFont; - BYTE elfFullName[LF_FULLFACESIZE]; - BYTE elfStyle[LF_FACESIZE]; - BYTE elfScript[LF_FACESIZE]; -} ENUMLOGFONTEXA,*LPENUMLOGFONTEXA; -typedef struct tagENUMLOGFONTEXW { - LOGFONTW elfLogFont; - WCHAR elfFullName[LF_FULLFACESIZE]; - BYTE elfStyle[LF_FACESIZE]; - BYTE elfScript[LF_FACESIZE]; -} ENUMLOGFONTEXW,*LPENUMLOGFONTEXW; -typedef struct tagPOINTFX { - FIXED x; - FIXED y; -} POINTFX,*LPPOINTFX; -typedef struct tagTTPOLYCURVE { - WORD wType; - WORD cpfx; - POINTFX apfx[1]; -} TTPOLYCURVE,*LPTTPOLYCURVE; -typedef struct tagTTPOLYGONHEADER { - DWORD cb; - DWORD dwType; - POINTFX pfxStart; -} TTPOLYGONHEADER,*LPTTPOLYGONHEADER; -typedef struct _POINTFLOAT { - FLOAT x; - FLOAT y; -} POINTFLOAT,*PPOINTFLOAT; -typedef struct _GLYPHMETRICSFLOAT { - FLOAT gmfBlackBoxX; - FLOAT gmfBlackBoxY; - POINTFLOAT gmfptGlyphOrigin; - FLOAT gmfCellIncX; - FLOAT gmfCellIncY; -} GLYPHMETRICSFLOAT,*PGLYPHMETRICSFLOAT,*LPGLYPHMETRICSFLOAT; -typedef struct tagLAYERPLANEDESCRIPTOR { - WORD nSize; - WORD nVersion; - DWORD dwFlags; - BYTE iPixelType; - BYTE cColorBits; - BYTE cRedBits; - BYTE cRedShift; - BYTE cGreenBits; - BYTE cGreenShift; - BYTE cBlueBits; - BYTE cBlueShift; - BYTE cAlphaBits; - BYTE cAlphaShift; - BYTE cAccumBits; - BYTE cAccumRedBits; - BYTE cAccumGreenBits; - BYTE cAccumBlueBits; - BYTE cAccumAlphaBits; - BYTE cDepthBits; - BYTE cStencilBits; - BYTE cAuxBuffers; - BYTE iLayerPlane; - BYTE bReserved; - COLORREF crTransparent; -} LAYERPLANEDESCRIPTOR,*PLAYERPLANEDESCRIPTOR,*LPLAYERPLANEDESCRIPTOR; -typedef struct _BLENDFUNCTION { - BYTE BlendOp; - BYTE BlendFlags; - BYTE SourceConstantAlpha; - BYTE AlphaFormat; -} BLENDFUNCTION,*PBLENDFUNCTION,*LPBLENDFUNCTION; -typedef BOOL (CALLBACK *ABORTPROC)(HDC,int); -typedef int (CALLBACK *MFENUMPROC)(HDC,HANDLETABLE*,METARECORD*,int,LPARAM); -typedef int (CALLBACK *ENHMFENUMPROC)(HDC,HANDLETABLE*,ENHMETARECORD*,int,LPARAM); -typedef int (CALLBACK *OLDFONTENUMPROCA)(const LOGFONTA*,const TEXTMETRICA*,DWORD,LPARAM); -typedef int (CALLBACK *OLDFONTENUMPROCW)(const LOGFONTW*,const TEXTMETRICW*,DWORD,LPARAM); -typedef OLDFONTENUMPROCA FONTENUMPROCA; -typedef OLDFONTENUMPROCW FONTENUMPROCW; -typedef int (CALLBACK *ICMENUMPROCA)(LPSTR,LPARAM); -typedef int (CALLBACK *ICMENUMPROCW)(LPWSTR,LPARAM); -typedef void (CALLBACK *GOBJENUMPROC)(LPVOID,LPARAM); -typedef void (CALLBACK *LINEDDAPROC)(int,int,LPARAM); -typedef UINT (CALLBACK *LPFNDEVMODE)(HWND,HMODULE,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,UINT); -typedef DWORD (CALLBACK *LPFNDEVCAPS)(LPSTR,LPSTR,UINT,LPSTR,LPDEVMODEA); - - -#define RGB(r,g,b) ((DWORD)(((BYTE)(r)|((WORD)(g)<<8))|(((DWORD)(BYTE)(b))<<16))) -#define MAKEPOINTS(l) (*((POINTS*)&(l))) -#define MAKEROP4(f,b) (DWORD)((((b)<<8)&0xFF000000)|(f)) -#define PALETTEINDEX(i) ((0x01000000|(COLORREF)(WORD)(i))) -#define PALETTERGB(r,g,b) (0x02000000|RGB(r,g,b)) -int WINAPI AbortDoc(HDC); -BOOL WINAPI AbortPath(HDC); -int WINAPI AddFontResourceA(LPCSTR); -int WINAPI AddFontResourceW(LPCWSTR); -BOOL WINAPI AngleArc(HDC,int,int,DWORD,FLOAT,FLOAT); -BOOL WINAPI AnimatePalette(HPALETTE,UINT,UINT,const PALETTEENTRY*); -BOOL WINAPI Arc(HDC,int,int,int,int,int,int,int,int); -BOOL WINAPI ArcTo(HDC,int,int,int,int,int,int,int,int); -BOOL WINAPI BeginPath(HDC); -BOOL WINAPI BitBlt(HDC,int,int,int,int,HDC,int,int,DWORD); -BOOL WINAPI CancelDC(HDC); -BOOL WINAPI CheckColorsInGamut(HDC,PVOID,PVOID,DWORD); -BOOL WINAPI Chord(HDC,int,int,int,int,int,int,int,int); -int WINAPI ChoosePixelFormat(HDC,CONST PIXELFORMATDESCRIPTOR*); -HENHMETAFILE WINAPI CloseEnhMetaFile(HDC); -BOOL WINAPI CloseFigure(HDC); -HMETAFILE WINAPI CloseMetaFile(HDC); -BOOL WINAPI ColorMatchToTarget(HDC,HDC,DWORD); -int WINAPI CombineRgn(HRGN,HRGN,HRGN,int); -BOOL WINAPI CombineTransform(LPXFORM,const XFORM*,const XFORM*); -HENHMETAFILE WINAPI CopyEnhMetaFileA(HENHMETAFILE,LPCSTR); -HENHMETAFILE WINAPI CopyEnhMetaFileW(HENHMETAFILE,LPCWSTR); -HMETAFILE WINAPI CopyMetaFileA(HMETAFILE,LPCSTR); -HMETAFILE WINAPI CopyMetaFileW(HMETAFILE,LPCWSTR); -HBITMAP WINAPI CreateBitmap(int,int,UINT,UINT,PCVOID); -HBITMAP WINAPI CreateBitmapIndirect(const BITMAP*); -HBRUSH WINAPI CreateBrushIndirect(const LOGBRUSH*); -HCOLORSPACE WINAPI CreateColorSpaceA(LPLOGCOLORSPACEA); -HCOLORSPACE WINAPI CreateColorSpaceW(LPLOGCOLORSPACEW); -HBITMAP WINAPI CreateCompatibleBitmap(HDC,int,int); -HDC WINAPI CreateCompatibleDC(HDC); -HDC WINAPI CreateDCA(LPCSTR,LPCSTR,LPCSTR,const DEVMODEA*); -HDC WINAPI CreateDCW(LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*); -HBITMAP WINAPI CreateDIBitmap(HDC,const BITMAPINFOHEADER*,DWORD,PCVOID,const BITMAPINFO*,UINT); -HBRUSH WINAPI CreateDIBPatternBrush(HGLOBAL,UINT); -HBRUSH WINAPI CreateDIBPatternBrushPt(PCVOID,UINT); -HBITMAP WINAPI CreateDIBSection(HDC,const BITMAPINFO*,UINT,void**,HANDLE,DWORD); -HBITMAP WINAPI CreateDiscardableBitmap(HDC,int,int); -HRGN WINAPI CreateEllipticRgn(int,int,int,int); -HRGN WINAPI CreateEllipticRgnIndirect(LPCRECT); -HDC WINAPI CreateEnhMetaFileA(HDC,LPCSTR,LPCRECT,LPCSTR); -HDC WINAPI CreateEnhMetaFileW(HDC,LPCWSTR,LPCRECT,LPCWSTR); -HFONT WINAPI CreateFontA(int,int,int,int,int,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,LPCSTR); -HFONT WINAPI CreateFontW(int,int,int,int,int,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,LPCWSTR); -HFONT WINAPI CreateFontIndirectA(const LOGFONTA*); -HFONT WINAPI CreateFontIndirectW(const LOGFONTW*); -HPALETTE WINAPI CreateHalftonePalette(HDC); -HBRUSH WINAPI CreateHatchBrush(int,COLORREF); -HDC WINAPI CreateICA(LPCSTR,LPCSTR,LPCSTR,const DEVMODEA*); -HDC WINAPI CreateICW(LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*); -HDC WINAPI CreateMetaFileA(LPCSTR); -HDC WINAPI CreateMetaFileW(LPCWSTR); -HPALETTE WINAPI CreatePalette(const LOGPALETTE*); -HBRUSH WINAPI CreatePatternBrush(HBITMAP); -HPEN WINAPI CreatePen(int,int,COLORREF); -HPEN WINAPI CreatePenIndirect(const LOGPEN*); -HRGN WINAPI CreatePolygonRgn(const POINT*,int,int); -HRGN WINAPI CreatePolyPolygonRgn(const POINT*,const INT*,int,int); -HRGN WINAPI CreateRectRgn(int,int,int,int); -HRGN WINAPI CreateRectRgnIndirect(LPCRECT); -HRGN WINAPI CreateRoundRectRgn(int,int,int,int,int,int); -BOOL WINAPI CreateScalableFontResourceA(DWORD,LPCSTR,LPCSTR,LPCSTR); -BOOL WINAPI CreateScalableFontResourceW(DWORD,LPCWSTR,LPCWSTR,LPCWSTR); -HBRUSH WINAPI CreateSolidBrush(COLORREF); -BOOL WINAPI DeleteColorSpace(HCOLORSPACE); -BOOL WINAPI DeleteDC(HDC); -BOOL WINAPI DeleteEnhMetaFile(HENHMETAFILE); -BOOL WINAPI DeleteMetaFile(HMETAFILE); -BOOL WINAPI DeleteObject(HGDIOBJ); -int WINAPI DescribePixelFormat(HDC,int,UINT,LPPIXELFORMATDESCRIPTOR); -DWORD WINAPI DeviceCapabilitiesA(LPCSTR,LPCSTR,WORD,LPSTR,const DEVMODEA*); -DWORD WINAPI DeviceCapabilitiesW(LPCWSTR,LPCWSTR,WORD,LPWSTR,const DEVMODEW*); -BOOL WINAPI DPtoLP(HDC,LPPOINT,int); -int WINAPI DrawEscape(HDC,int,int,LPCSTR); -BOOL WINAPI Ellipse(HDC,int,int,int,int); -int WINAPI EndDoc(HDC); -int WINAPI EndPage(HDC); -BOOL WINAPI EndPath(HDC); -BOOL WINAPI EnumEnhMetaFile(HDC,HENHMETAFILE,ENHMFENUMPROC,PVOID,LPCRECT); -int WINAPI EnumFontFamiliesA(HDC,LPCSTR,FONTENUMPROCA,LPARAM); -int WINAPI EnumFontFamiliesW(HDC,LPCWSTR,FONTENUMPROCW,LPARAM); -int WINAPI EnumFontFamiliesExA(HDC,PLOGFONTA,FONTENUMPROCA,LPARAM,DWORD); -int WINAPI EnumFontFamiliesExW(HDC,PLOGFONTW,FONTENUMPROCW,LPARAM,DWORD); -int WINAPI EnumFontsA(HDC,LPCSTR,FONTENUMPROCA,LPARAM); -int WINAPI EnumFontsW(HDC,LPCWSTR,FONTENUMPROCA,LPARAM); -int WINAPI EnumICMProfilesA(HDC,ICMENUMPROCA,LPARAM); -int WINAPI EnumICMProfilesW(HDC,ICMENUMPROCW,LPARAM); -BOOL WINAPI EnumMetaFile(HDC,HMETAFILE,MFENUMPROC,LPARAM); -int WINAPI EnumObjects(HDC,int,GOBJENUMPROC,LPARAM); -BOOL WINAPI EqualRgn(HRGN,HRGN); -int WINAPI Escape(HDC,int,int,LPCSTR,PVOID); -int WINAPI ExcludeClipRect(HDC,int,int,int,int); -int WINAPI ExcludeUpdateRgn(HDC,HWND); -HPEN WINAPI ExtCreatePen(DWORD,DWORD,const LOGBRUSH*,DWORD,const DWORD*); -HRGN WINAPI ExtCreateRegion(const XFORM*,DWORD,const RGNDATA*); -int WINAPI ExtEscape(HDC,int,int,LPCSTR,int,LPSTR); -BOOL WINAPI ExtFloodFill(HDC,int,int,COLORREF,UINT); -int WINAPI ExtSelectClipRgn(HDC,HRGN,int); -BOOL WINAPI ExtTextOutA(HDC,int,int,UINT,LPCRECT,LPCSTR,UINT,const INT*); -BOOL WINAPI ExtTextOutW(HDC,int,int,UINT,LPCRECT,LPCWSTR,UINT,const INT*); -BOOL WINAPI FillPath(HDC); -int WINAPI FillRect(HDC,LPCRECT,HBRUSH); -int WINAPI FillRgn(HDC,HRGN,HBRUSH); -BOOL WINAPI FixBrushOrgEx(HDC,int,int,LPPOINT); -BOOL WINAPI FlattenPath(HDC); -BOOL WINAPI FloodFill(HDC,int,int,COLORREF); -BOOL WINAPI GdiComment(HDC,UINT,const BYTE*); -BOOL WINAPI GdiFlush(void); -DWORD WINAPI GdiGetBatchLimit(void); -DWORD WINAPI GdiSetBatchLimit(DWORD); -#define GetCValue(cmyk) ((BYTE)(cmyk)) -#define GetMValue(cmyk) ((BYTE)((cmyk)>> 8)) -#define GetYValue(cmyk) ((BYTE)((cmyk)>>16)) -#define GetKValue(cmyk) ((BYTE)((cmyk)>>24)) -#define CMYK(c,m,y,k) ((COLORREF)((((BYTE)(c)|((WORD)((BYTE)(m))<<8))|(((DWORD)(BYTE)(y))<<16))|(((DWORD)(BYTE)(k))<<24))) -#define GetRValue(c) ((BYTE)(c)) -#define GetGValue(c) ((BYTE)(((WORD)(c))>>8)) -#define GetBValue(c) ((BYTE)((c)>>16)) -int WINAPI GetArcDirection(HDC); -BOOL WINAPI GetAspectRatioFilterEx(HDC,LPSIZE); -LONG WINAPI GetBitmapBits(HBITMAP,LONG,PVOID); -BOOL WINAPI GetBitmapDimensionEx(HBITMAP,LPSIZE); -COLORREF WINAPI GetBkColor(HDC); -int WINAPI GetBkMode(HDC); -UINT WINAPI GetBoundsRect(HDC,LPRECT,UINT); -BOOL WINAPI GetBrushOrgEx(HDC,LPPOINT); -BOOL WINAPI GetCharABCWidthsA(HDC,UINT,UINT,LPABC); -BOOL WINAPI GetCharABCWidthsW(HDC,UINT,UINT,LPABC); -BOOL WINAPI GetCharABCWidthsFloatA(HDC,UINT,UINT,LPABCFLOAT); -BOOL WINAPI GetCharABCWidthsFloatW(HDC,UINT,UINT,LPABCFLOAT); -DWORD WINAPI GetCharacterPlacementA(HDC,LPCSTR,int,int,LPGCP_RESULTSA,DWORD); -DWORD WINAPI GetCharacterPlacementW(HDC,LPCWSTR,int,int,LPGCP_RESULTSW,DWORD); -BOOL WINAPI GetCharWidth32A(HDC,UINT,UINT,LPINT); -BOOL WINAPI GetCharWidth32W(HDC,UINT,UINT,LPINT); -BOOL WINAPI GetCharWidthA(HDC,UINT,UINT,LPINT); -BOOL WINAPI GetCharWidthW(HDC,UINT,UINT,LPINT); -BOOL WINAPI GetCharWidthFloatA(HDC,UINT,UINT,PFLOAT); -BOOL WINAPI GetCharWidthFloatW(HDC,UINT,UINT,PFLOAT); -int WINAPI GetClipBox(HDC,LPRECT); -int WINAPI GetClipRgn(HDC,HRGN); -BOOL WINAPI GetColorAdjustment(HDC,LPCOLORADJUSTMENT); -HANDLE WINAPI GetColorSpace(HDC); -HGDIOBJ WINAPI GetCurrentObject(HDC,UINT); -BOOL WINAPI GetCurrentPositionEx(HDC,LPPOINT); -HCURSOR WINAPI GetCursor(void); -BOOL WINAPI GetDCOrgEx(HDC,LPPOINT); -int WINAPI GetDeviceCaps(HDC,int); -BOOL WINAPI GetDeviceGammaRamp(HDC,PVOID); -UINT WINAPI GetDIBColorTable(HDC,UINT,UINT,RGBQUAD*); -int WINAPI GetDIBits(HDC,HBITMAP,UINT,UINT,PVOID,LPBITMAPINFO,UINT); -HENHMETAFILE WINAPI GetEnhMetaFileA(LPCSTR); -HENHMETAFILE WINAPI GetEnhMetaFileW(LPCWSTR); -UINT WINAPI GetEnhMetaFileDescriptionA(HENHMETAFILE,UINT,LPSTR); -UINT WINAPI GetEnhMetaFileDescriptionW(HENHMETAFILE,UINT,LPWSTR); -UINT WINAPI GetEnhMetaFileHeader(HENHMETAFILE,UINT,LPENHMETAHEADER); -UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE,UINT,LPPALETTEENTRY); -UINT WINAPI GetEnhMetaFilePixelFormat(HENHMETAFILE,DWORD,PIXELFORMATDESCRIPTOR*); -DWORD WINAPI GetFontData(HDC,DWORD,DWORD,PVOID,DWORD); -DWORD WINAPI GetFontLanguageInfo(HDC); -DWORD WINAPI GetGlyphOutlineA(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,PVOID,const MAT2*); -DWORD WINAPI GetGlyphOutlineW(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,PVOID,const MAT2*); -int WINAPI GetGraphicsMode(HDC); -BOOL WINAPI GetICMProfileA(HDC,DWORD,LPSTR); -BOOL WINAPI GetICMProfileW(HDC,DWORD,LPWSTR); -DWORD WINAPI GetKerningPairsA(HDC,DWORD,LPKERNINGPAIR); -DWORD WINAPI GetKerningPairsW(HDC,DWORD,LPKERNINGPAIR); -BOOL WINAPI GetLogColorSpaceA(HCOLORSPACE,LPLOGCOLORSPACEA,DWORD); -BOOL WINAPI GetLogColorSpaceW(HCOLORSPACE,LPLOGCOLORSPACEW,DWORD); -int WINAPI GetMapMode(HDC); -HMETAFILE WINAPI GetMetaFileA(LPCSTR); -HMETAFILE WINAPI GetMetaFileW(LPCWSTR); -UINT WINAPI GetMetaFileBitsEx(HMETAFILE,UINT,PVOID); -int WINAPI GetMetaRgn(HDC,HRGN); -BOOL WINAPI GetMiterLimit(HDC,PFLOAT); -COLORREF WINAPI GetNearestColor(HDC,COLORREF); -UINT WINAPI GetNearestPaletteIndex(HPALETTE,COLORREF); -int WINAPI GetObjectA(HGDIOBJ,int,PVOID); -int WINAPI GetObjectW(HGDIOBJ,int,PVOID); -DWORD WINAPI GetObjectType(HGDIOBJ); -UINT WINAPI GetOutlineTextMetricsA(HDC,UINT,LPOUTLINETEXTMETRICA); -UINT WINAPI GetOutlineTextMetricsW(HDC,UINT,LPOUTLINETEXTMETRICW); -UINT WINAPI GetPaletteEntries(HPALETTE,UINT,UINT,LPPALETTEENTRY); -int WINAPI GetPath(HDC,LPPOINT,PBYTE,int); -COLORREF WINAPI GetPixel(HDC,int,int); -int WINAPI GetPixelFormat(HDC); -int WINAPI GetPolyFillMode(HDC); -BOOL WINAPI GetRasterizerCaps(LPRASTERIZER_STATUS,UINT); -int WINAPI GetRandomRgn (HDC,HRGN,INT); -DWORD WINAPI GetRegionData(HRGN,DWORD,LPRGNDATA); -int WINAPI GetRgnBox(HRGN,LPRECT); -int WINAPI GetROP2(HDC); -HGDIOBJ WINAPI GetStockObject(int); -int WINAPI GetStretchBltMode(HDC); -UINT WINAPI GetSystemPaletteEntries(HDC,UINT,UINT,LPPALETTEENTRY); -UINT WINAPI GetSystemPaletteUse(HDC); -UINT WINAPI GetTextAlign(HDC); -int WINAPI GetTextCharacterExtra(HDC); -int WINAPI GetTextCharset(HDC); -int WINAPI GetTextCharsetInfo(HDC,LPFONTSIGNATURE,DWORD); -COLORREF WINAPI GetTextColor(HDC); -BOOL WINAPI GetTextExtentExPointA(HDC,LPCSTR,int,int,LPINT,LPINT,LPSIZE); -BOOL WINAPI GetTextExtentExPointW( HDC,LPCWSTR,int,int,LPINT,LPINT,LPSIZE ); -BOOL WINAPI GetTextExtentPointA(HDC,LPCSTR,int,LPSIZE); -BOOL WINAPI GetTextExtentPointW(HDC,LPCWSTR,int,LPSIZE); -BOOL WINAPI GetTextExtentPoint32A(HDC,LPCSTR,int,LPSIZE); -BOOL WINAPI GetTextExtentPoint32W( HDC,LPCWSTR,int,LPSIZE); -int WINAPI GetTextFaceA(HDC,int,LPSTR); -int WINAPI GetTextFaceW(HDC,int,LPWSTR); -BOOL WINAPI GetTextMetricsA(HDC,LPTEXTMETRICA); -BOOL WINAPI GetTextMetricsW(HDC,LPTEXTMETRICW); -BOOL WINAPI GetViewportExtEx(HDC,LPSIZE); -BOOL WINAPI GetViewportOrgEx(HDC,LPPOINT); -BOOL WINAPI GetWindowExtEx(HDC,LPSIZE); -BOOL WINAPI GetWindowOrgEx(HDC,LPPOINT); -UINT WINAPI GetWinMetaFileBits(HENHMETAFILE,UINT,LPBYTE,INT,HDC); -BOOL WINAPI GetWorldTransform(HDC,LPXFORM); -int WINAPI IntersectClipRect(HDC,int,int,int,int); -BOOL WINAPI InvertRgn(HDC,HRGN); -BOOL WINAPI LineDDA(int,int,int,int,LINEDDAPROC,LPARAM); -BOOL WINAPI LineTo(HDC,int,int); -BOOL WINAPI LPtoDP(HDC,LPPOINT,int); -BOOL WINAPI MaskBlt(HDC,int,int,int,int,HDC,int,int,HBITMAP,int,int,DWORD); -BOOL WINAPI ModifyWorldTransform(HDC,const XFORM*,DWORD); -BOOL WINAPI MoveToEx(HDC,int,int,LPPOINT); -int WINAPI OffsetClipRgn(HDC,int,int); -int WINAPI OffsetRgn(HRGN,int,int); -BOOL WINAPI OffsetViewportOrgEx(HDC,int,int,LPPOINT); -BOOL WINAPI OffsetWindowOrgEx(HDC,int,int,LPPOINT); -BOOL WINAPI PaintRgn(HDC,HRGN); -BOOL WINAPI PatBlt(HDC,int,int,int,int,DWORD); -HRGN WINAPI PathToRegion(HDC); -BOOL WINAPI Pie(HDC,int,int,int,int,int,int,int,int); -BOOL WINAPI PlayEnhMetaFile(HDC,HENHMETAFILE,LPCRECT); -BOOL WINAPI PlayEnhMetaFileRecord(HDC,LPHANDLETABLE,const ENHMETARECORD*,UINT); -BOOL WINAPI PlayMetaFile(HDC,HMETAFILE); -BOOL WINAPI PlayMetaFileRecord(HDC,LPHANDLETABLE,LPMETARECORD,UINT); -BOOL WINAPI PlgBlt(HDC,const POINT*,HDC,int,int,int,int,HBITMAP,int,int); -BOOL WINAPI PolyBezier(HDC,const POINT*,DWORD); -BOOL WINAPI PolyBezierTo(HDC,const POINT*,DWORD); -BOOL WINAPI PolyDraw(HDC,const POINT*,const BYTE*,int); -BOOL WINAPI Polygon(HDC,const POINT*,int); -BOOL WINAPI Polyline(HDC,const POINT*,int); -BOOL WINAPI PolylineTo(HDC,const POINT*,DWORD); -BOOL WINAPI PolyPolygon(HDC,const POINT*,const INT*,int); -BOOL WINAPI PolyPolyline(HDC,const POINT*,const DWORD*,DWORD); -BOOL WINAPI PolyTextOutA(HDC,const POLYTEXTA*,int); -BOOL WINAPI PolyTextOutW(HDC,const POLYTEXTW*,int); -BOOL WINAPI PtInRegion(HRGN,int,int); -BOOL WINAPI PtVisible(HDC,int,int); -UINT WINAPI RealizePalette(HDC); -BOOL WINAPI Rectangle(HDC,int,int,int,int); -BOOL WINAPI RectInRegion(HRGN,LPCRECT); -BOOL WINAPI RectVisible(HDC,LPCRECT); -BOOL WINAPI RemoveFontResourceA(LPCSTR); -BOOL WINAPI RemoveFontResourceW(LPCWSTR); -HDC WINAPI ResetDCA(HDC,const DEVMODEA*); -HDC WINAPI ResetDCW(HDC,const DEVMODEW*); -BOOL WINAPI ResizePalette(HPALETTE,UINT); -BOOL WINAPI RestoreDC(HDC,int); -BOOL WINAPI RoundRect(HDC,int,int,int,int,int,int); -int WINAPI SaveDC(HDC); -BOOL WINAPI ScaleViewportExtEx(HDC,int,int,int,int,LPSIZE); -BOOL WINAPI ScaleWindowExtEx(HDC,int,int,int,int,LPSIZE); -BOOL WINAPI SelectClipPath(HDC,int); -int WINAPI SelectClipRgn(HDC,HRGN); -HGDIOBJ WINAPI SelectObject(HDC,HGDIOBJ); -HPALETTE WINAPI SelectPalette(HDC,HPALETTE,BOOL); -int WINAPI SetAbortProc(HDC,ABORTPROC); -int WINAPI SetArcDirection(HDC,int); -LONG WINAPI SetBitmapBits(HBITMAP,DWORD,PCVOID); -BOOL WINAPI SetBitmapDimensionEx(HBITMAP,int,int,LPSIZE); -COLORREF WINAPI SetBkColor(HDC,COLORREF); -int WINAPI SetBkMode(HDC,int); -UINT WINAPI SetBoundsRect(HDC,LPCRECT,UINT); -BOOL WINAPI SetBrushOrgEx(HDC,int,int,LPPOINT); -BOOL WINAPI SetColorAdjustment(HDC,const COLORADJUSTMENT*); -BOOL WINAPI SetColorSpace(HDC,HCOLORSPACE); -BOOL WINAPI SetDeviceGammaRamp(HDC,PVOID); -UINT WINAPI SetDIBColorTable(HDC,UINT,UINT,const RGBQUAD*); -int WINAPI SetDIBits(HDC,HBITMAP,UINT,UINT,PCVOID,const BITMAPINFO*,UINT); -int WINAPI SetDIBitsToDevice(HDC,int,int,DWORD,DWORD,int,int,UINT,UINT,PCVOID,const BITMAPINFO*,UINT); -HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT,const BYTE*); -int WINAPI SetGraphicsMode(HDC,int); -int WINAPI SetICMMode(HDC,int); -BOOL WINAPI SetICMProfileA(HDC,LPSTR); -BOOL WINAPI SetICMProfileW(HDC,LPWSTR); -int WINAPI SetMapMode(HDC,int); -DWORD WINAPI SetMapperFlags(HDC,DWORD); -HMETAFILE WINAPI SetMetaFileBitsEx(UINT,const BYTE *); -int WINAPI SetMetaRgn(HDC); -BOOL WINAPI SetMiterLimit(HDC,FLOAT,PFLOAT); -UINT WINAPI SetPaletteEntries(HPALETTE,UINT,UINT,const PALETTEENTRY*); -COLORREF WINAPI SetPixel(HDC,int,int,COLORREF); -BOOL WINAPI SetPixelFormat(HDC,int,const PIXELFORMATDESCRIPTOR*); -BOOL WINAPI SetPixelV(HDC,int,int,COLORREF); -int WINAPI SetPolyFillMode(HDC,int); -BOOL WINAPI SetRectRgn(HRGN,int,int,int,int); -int WINAPI SetROP2(HDC,int); -int WINAPI SetStretchBltMode(HDC,int); -UINT WINAPI SetSystemPaletteUse(HDC,UINT); -UINT WINAPI SetTextAlign(HDC,UINT); -int WINAPI SetTextCharacterExtra(HDC,int); -COLORREF WINAPI SetTextColor(HDC,COLORREF); -BOOL WINAPI SetTextJustification(HDC,int,int); -BOOL WINAPI SetViewportExtEx(HDC,int,int,LPSIZE); -BOOL WINAPI SetViewportOrgEx(HDC,int,int,LPPOINT); -BOOL WINAPI SetWindowExtEx(HDC,int,int,LPSIZE); -BOOL WINAPI SetWindowOrgEx(HDC,int,int,LPPOINT); -HENHMETAFILE WINAPI SetWinMetaFileBits(UINT,const BYTE*,HDC,const METAFILEPICT*); -BOOL WINAPI SetWorldTransform(HDC,const XFORM *); -int WINAPI StartDocA(HDC,const DOCINFOA*); -int WINAPI StartDocW(HDC,const DOCINFOW*); -int WINAPI StartPage(HDC); -BOOL WINAPI StretchBlt(HDC,int,int,int,int,HDC,int,int,int,int,DWORD); -int WINAPI StretchDIBits(HDC,int,int,int,int,int,int,int,int,const VOID *,const BITMAPINFO *,UINT,DWORD); -BOOL WINAPI StrokeAndFillPath(HDC); -BOOL WINAPI StrokePath(HDC); -BOOL WINAPI SwapBuffers(HDC); -BOOL WINAPI TextOutA(HDC,int,int,LPCSTR,int); -BOOL WINAPI TextOutW(HDC,int,int,LPCWSTR,int); -BOOL WINAPI TranslateCharsetInfo(PDWORD,LPCHARSETINFO,DWORD); -BOOL WINAPI UnrealizeObject(HGDIOBJ); -BOOL WINAPI UpdateColors(HDC); -BOOL WINAPI UpdateICMRegKeyA(DWORD,DWORD,LPSTR,UINT); -BOOL WINAPI UpdateICMRegKeyW(DWORD,DWORD,LPWSTR,UINT); -BOOL WINAPI WidenPath(HDC); -BOOL WINAPI wglCopyContext(HGLRC,HGLRC,UINT); -HGLRC WINAPI wglCreateContext(HDC); -HGLRC WINAPI wglCreateLayerContext(HDC,int); -BOOL WINAPI wglDeleteContext(HGLRC); -BOOL WINAPI wglDescribeLayerPlane(HDC,int,int,UINT,LPLAYERPLANEDESCRIPTOR); -HGLRC WINAPI wglGetCurrentContext(void); -HDC WINAPI wglGetCurrentDC(void); -int WINAPI wglGetLayerPaletteEntries(HDC,int,int,int,COLORREF*); -PROC WINAPI wglGetProcAddress(LPCSTR); -BOOL WINAPI wglMakeCurrent(HDC,HGLRC); -BOOL WINAPI wglRealizeLayerPalette(HDC,int,BOOL); -int WINAPI wglSetLayerPaletteEntries(HDC,int,int,int,const COLORREF*); -BOOL WINAPI wglShareLists(HGLRC,HGLRC); -BOOL WINAPI wglSwapLayerBuffers(HDC,UINT); -BOOL WINAPI wglUseFontBitmapsA(HDC,DWORD,DWORD,DWORD); -BOOL WINAPI wglUseFontBitmapsW(HDC,DWORD,DWORD,DWORD); -BOOL WINAPI wglUseFontOutlinesA(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT); -BOOL WINAPI wglUseFontOutlinesW(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT); +#define TT_PRIM_CSPLINE 3 + + typedef struct tagPOINTFX { + FIXED x; + FIXED y; + } POINTFX,*LPPOINTFX; + + typedef struct tagTTPOLYCURVE { + WORD wType; + WORD cpfx; + POINTFX apfx[1]; + } TTPOLYCURVE,*LPTTPOLYCURVE; + + typedef struct tagTTPOLYGONHEADER { + DWORD cb; + DWORD dwType; + POINTFX pfxStart; + } TTPOLYGONHEADER,*LPTTPOLYGONHEADER; + +#define GCP_DBCS 0x0001 +#define GCP_REORDER 0x0002 +#define GCP_USEKERNING 0x0008 +#define GCP_GLYPHSHAPE 0x0010 +#define GCP_LIGATE 0x0020 + +#define GCP_DIACRITIC 0x0100 +#define GCP_KASHIDA 0x0400 +#define GCP_ERROR 0x8000 +#define FLI_MASK 0x103B + +#define GCP_JUSTIFY 0x00010000L + +#define FLI_GLYPHS 0x00040000L +#define GCP_CLASSIN 0x00080000L +#define GCP_MAXEXTENT 0x00100000L +#define GCP_JUSTIFYIN 0x00200000L +#define GCP_DISPLAYZWG 0x00400000L +#define GCP_SYMSWAPOFF 0x00800000L +#define GCP_NUMERICOVERRIDE 0x01000000L +#define GCP_NEUTRALOVERRIDE 0x02000000L +#define GCP_NUMERICSLATIN 0x04000000L +#define GCP_NUMERICSLOCAL 0x08000000L + +#define GCPCLASS_LATIN 1 +#define GCPCLASS_HEBREW 2 +#define GCPCLASS_ARABIC 2 +#define GCPCLASS_NEUTRAL 3 +#define GCPCLASS_LOCALNUMBER 4 +#define GCPCLASS_LATINNUMBER 5 +#define GCPCLASS_LATINNUMERICTERMINATOR 6 +#define GCPCLASS_LATINNUMERICSEPARATOR 7 +#define GCPCLASS_NUMERICSEPARATOR 8 +#define GCPCLASS_PREBOUNDLTR 0x80 +#define GCPCLASS_PREBOUNDRTL 0x40 +#define GCPCLASS_POSTBOUNDLTR 0x20 +#define GCPCLASS_POSTBOUNDRTL 0x10 + +#define GCPGLYPH_LINKBEFORE 0x8000 +#define GCPGLYPH_LINKAFTER 0x4000 + + typedef struct tagGCP_RESULTSA { + DWORD lStructSize; + LPSTR lpOutString; + UINT *lpOrder; + int *lpDx; + int *lpCaretPos; + LPSTR lpClass; + LPWSTR lpGlyphs; + UINT nGlyphs; + int nMaxFit; + } GCP_RESULTSA,*LPGCP_RESULTSA; + typedef struct tagGCP_RESULTSW { + DWORD lStructSize; + LPWSTR lpOutString; + UINT *lpOrder; + int *lpDx; + int *lpCaretPos; + LPSTR lpClass; + LPWSTR lpGlyphs; + UINT nGlyphs; + int nMaxFit; + } GCP_RESULTSW,*LPGCP_RESULTSW; +#ifdef UNICODE + typedef GCP_RESULTSW GCP_RESULTS; + typedef LPGCP_RESULTSW LPGCP_RESULTS; +#else + typedef GCP_RESULTSA GCP_RESULTS; + typedef LPGCP_RESULTSA LPGCP_RESULTS; +#endif + + typedef struct _RASTERIZER_STATUS { + short nSize; + short wFlags; + short nLanguageID; + } RASTERIZER_STATUS,*LPRASTERIZER_STATUS; + +#define TT_AVAILABLE 0x0001 +#define TT_ENABLED 0x0002 + + typedef struct tagPIXELFORMATDESCRIPTOR { + WORD nSize; + WORD nVersion; + DWORD dwFlags; + BYTE iPixelType; + BYTE cColorBits; + BYTE cRedBits; + BYTE cRedShift; + BYTE cGreenBits; + BYTE cGreenShift; + BYTE cBlueBits; + BYTE cBlueShift; + BYTE cAlphaBits; + BYTE cAlphaShift; + BYTE cAccumBits; + BYTE cAccumRedBits; + BYTE cAccumGreenBits; + BYTE cAccumBlueBits; + BYTE cAccumAlphaBits; + BYTE cDepthBits; + BYTE cStencilBits; + BYTE cAuxBuffers; + BYTE iLayerType; + BYTE bReserved; + DWORD dwLayerMask; + DWORD dwVisibleMask; + DWORD dwDamageMask; + } PIXELFORMATDESCRIPTOR,*PPIXELFORMATDESCRIPTOR,*LPPIXELFORMATDESCRIPTOR; + +#define PFD_TYPE_RGBA 0 +#define PFD_TYPE_COLORINDEX 1 + +#define PFD_MAIN_PLANE 0 +#define PFD_OVERLAY_PLANE 1 +#define PFD_UNDERLAY_PLANE (-1) + +#define PFD_DOUBLEBUFFER 0x00000001 +#define PFD_STEREO 0x00000002 +#define PFD_DRAW_TO_WINDOW 0x00000004 +#define PFD_DRAW_TO_BITMAP 0x00000008 +#define PFD_SUPPORT_GDI 0x00000010 +#define PFD_SUPPORT_OPENGL 0x00000020 +#define PFD_GENERIC_FORMAT 0x00000040 +#define PFD_NEED_PALETTE 0x00000080 +#define PFD_NEED_SYSTEM_PALETTE 0x00000100 +#define PFD_SWAP_EXCHANGE 0x00000200 +#define PFD_SWAP_COPY 0x00000400 +#define PFD_SWAP_LAYER_BUFFERS 0x00000800 +#define PFD_GENERIC_ACCELERATED 0x00001000 +#define PFD_SUPPORT_DIRECTDRAW 0x00002000 + +#define PFD_DEPTH_DONTCARE 0x20000000 +#define PFD_DOUBLEBUFFER_DONTCARE 0x40000000 +#define PFD_STEREO_DONTCARE 0x80000000 + +#ifndef NOTEXTMETRIC + typedef int (CALLBACK *OLDFONTENUMPROCA)(CONST LOGFONTA *,CONST TEXTMETRICA *,DWORD,LPARAM); + typedef int (CALLBACK *OLDFONTENUMPROCW)(CONST LOGFONTW *,CONST TEXTMETRICW *,DWORD,LPARAM); +#ifdef UNICODE +#define OLDFONTENUMPROC OLDFONTENUMPROCW +#else +#define OLDFONTENUMPROC OLDFONTENUMPROCA +#endif +#else + typedef int (CALLBACK *OLDFONTENUMPROCA)(CONST LOGFONTA *,CONST VOID *,DWORD,LPARAM); + typedef int (CALLBACK *OLDFONTENUMPROCW)(CONST LOGFONTW *,CONST VOID *,DWORD,LPARAM); +#ifdef UNICODE +#define OLDFONTENUMPROC OLDFONTENUMPROCW +#else +#define OLDFONTENUMPROC OLDFONTENUMPROCA +#endif +#endif + + typedef OLDFONTENUMPROCA FONTENUMPROCA; + typedef OLDFONTENUMPROCW FONTENUMPROCW; +#ifdef UNICODE + typedef FONTENUMPROCW FONTENUMPROC; +#else + typedef FONTENUMPROCA FONTENUMPROC; +#endif + + typedef int (CALLBACK *GOBJENUMPROC)(LPVOID,LPARAM); + typedef VOID (CALLBACK *LINEDDAPROC)(int,int,LPARAM); #ifdef UNICODE -typedef WCHAR BCHAR; -typedef DOCINFOW DOCINFO, *LPDOCINFO; -typedef LOGFONTW LOGFONT,*PLOGFONT,*LPLOGFONT; -typedef TEXTMETRICW TEXTMETRIC,*PTEXTMETRIC,*LPTEXTMETRIC; -#define ICMENUMPROC ICMENUMPROCW -#define FONTENUMPROC FONTENUMPROCW -typedef DEVMODEW DEVMODE,*PDEVMODE,*LPDEVMODE; -typedef EXTLOGFONTW EXTLOGFONT,*PEXTLOGFONT,*LPEXTLOGFONT; -typedef GCP_RESULTSW GCP_RESULTS,*LPGCP_RESULTS; -typedef OUTLINETEXTMETRICW OUTLINETEXTMETRIC,*POUTLINETEXTMETRIC,*LPOUTLINETEXTMETRIC; -typedef POLYTEXTW POLYTEXT; -typedef LOGCOLORSPACEW LOGCOLORSPACE,*LPLOGCOLORSPACE; -typedef NEWTEXTMETRICW NEWTEXTMETRIC,*PNEWTEXTMETRIC,*LPNEWTEXTMETRIC; -typedef NEWTEXTMETRICEXW NEWTEXTMETRICEX; -typedef ENUMLOGFONTW ENUMLOGFONT,*LPENUMLOGFONT; -typedef ENUMLOGFONTEXW ENUMLOGFONTEX,*LPENUMLOGFONTEX; #define AddFontResource AddFontResourceW -#define CopyEnhMetaFile CopyEnhMetaFileW #define CopyMetaFile CopyMetaFileW #define CreateDC CreateDCW -#define CreateEnhMetaFile CreateEnhMetaFileW -#define CreateFont CreateFontW #define CreateFontIndirect CreateFontIndirectW +#define CreateFont CreateFontW #define CreateIC CreateICW #define CreateMetaFile CreateMetaFileW #define CreateScalableFontResource CreateScalableFontResourceW -#define DeviceCapabilities DeviceCapabilitiesW -#define EnumFontFamilies EnumFontFamiliesW -#define EnumFontFamiliesEx EnumFontFamiliesExW -#define EnumFonts EnumFontsW -#define EnumICMProfiles EnumICMProfilesW -#define ExtTextOut ExtTextOutW -#define GetCharABCWidthsFloat GetCharABCWidthsFloatW -#define GetCharABCWidths GetCharABCWidthsW -#define GetCharacterPlacement GetCharacterPlacementW -#define GetCharWidth32 GetCharWidth32W -#define GetCharWidthFloat GetCharWidthFloatW -#define GetCharWidth GetCharWidthW -#define GetEnhMetaFile GetEnhMetaFileW -#define GetEnhMetaFileDescription GetEnhMetaFileDescriptionW -#define GetGlyphOutline GetGlyphOutlineW -#define GetICMProfile GetICMProfileW -#define GetKerningPairs GetKerningPairsW -#define GetLogColorSpace GetLogColorSpaceW -#define GetMetaFile GetMetaFileW -#define GetObject GetObjectW -#define GetOutlineTextMetrics GetOutlineTextMetricsW -#define GetTextExtentPoint GetTextExtentPointW -#define GetTextExtentExPoint GetTextExtentExPointW -#define GetTextExtentPoint32 GetTextExtentPoint32W -#define GetTextFace GetTextFaceW -#define GetTextMetrics GetTextMetricsW -#define PolyTextOut PolyTextOutW -#define RemoveFontResource RemoveFontResourceW -#define ResetDC ResetDCW -#define SetICMProfile SetICMProfileW -#define StartDoc StartDocW -#define TextOut TextOutW -#define UpdateICMRegKey UpdateICMRegKeyW -#define wglUseFontBitmaps wglUseFontBitmapsW -#define wglUseFontOutlines wglUseFontOutlinesW #else -typedef BYTE BCHAR; -typedef DOCINFOA DOCINFO, *LPDOCINFO; -typedef LOGFONTA LOGFONT,*PLOGFONT,*LPLOGFONT; -typedef TEXTMETRICA TEXTMETRIC,*PTEXTMETRIC,*LPTEXTMETRIC; -#define ICMENUMPROC ICMENUMPROCA -#define FONTENUMPROC FONTENUMPROCA -typedef DEVMODEA DEVMODE,*PDEVMODE,*LPDEVMODE; -typedef EXTLOGFONTA EXTLOGFONT,*PEXTLOGFONT,*LPEXTLOGFONT; -typedef GCP_RESULTSA GCP_RESULTS,*LPGCP_RESULTS; -typedef OUTLINETEXTMETRICA OUTLINETEXTMETRIC,*POUTLINETEXTMETRIC,*LPOUTLINETEXTMETRIC; -typedef POLYTEXTA POLYTEXT; -typedef LOGCOLORSPACEA LOGCOLORSPACE,*LPLOGCOLORSPACE; -typedef NEWTEXTMETRICA NEWTEXTMETRIC,*PNEWTEXTMETRIC,*LPNEWTEXTMETRIC; -typedef NEWTEXTMETRICEXA NEWTEXTMETRICEX; -typedef ENUMLOGFONTA ENUMLOGFONT,*LPENUMLOGFONT; -typedef ENUMLOGFONTEXA ENUMLOGFONTEX,*LPENUMLOGFONTEX; #define AddFontResource AddFontResourceA -#define CopyEnhMetaFile CopyEnhMetaFileA #define CopyMetaFile CopyMetaFileA #define CreateDC CreateDCA -#define CreateEnhMetaFile CreateEnhMetaFileA -#define CreateFont CreateFontA #define CreateFontIndirect CreateFontIndirectA +#define CreateFont CreateFontA #define CreateIC CreateICA #define CreateMetaFile CreateMetaFileA #define CreateScalableFontResource CreateScalableFontResourceA +#endif + + WINGDIAPI int WINAPI AddFontResourceA(LPCSTR); + WINGDIAPI int WINAPI AddFontResourceW(LPCWSTR); + WINGDIAPI WINBOOL WINAPI AnimatePalette(HPALETTE hPal,UINT iStartIndex,UINT cEntries,CONST PALETTEENTRY *ppe); + WINGDIAPI WINBOOL WINAPI Arc(HDC hdc,int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4); + WINGDIAPI WINBOOL WINAPI BitBlt(HDC hdc,int x,int y,int cx,int cy,HDC hdcSrc,int x1,int y1,DWORD rop); + WINGDIAPI WINBOOL WINAPI CancelDC(HDC hdc); + WINGDIAPI WINBOOL WINAPI Chord(HDC hdc,int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4); + WINGDIAPI int WINAPI ChoosePixelFormat(HDC hdc,CONST PIXELFORMATDESCRIPTOR *ppfd); + WINGDIAPI HMETAFILE WINAPI CloseMetaFile(HDC hdc); + WINGDIAPI int WINAPI CombineRgn(HRGN hrgnDst,HRGN hrgnSrc1,HRGN hrgnSrc2,int iMode); + WINGDIAPI HMETAFILE WINAPI CopyMetaFileA(HMETAFILE,LPCSTR); + WINGDIAPI HMETAFILE WINAPI CopyMetaFileW(HMETAFILE,LPCWSTR); + WINGDIAPI HBITMAP WINAPI CreateBitmap(int nWidth,int nHeight,UINT nPlanes,UINT nBitCount,CONST VOID *lpBits); + WINGDIAPI HBITMAP WINAPI CreateBitmapIndirect(CONST BITMAP *pbm); + WINGDIAPI HBRUSH WINAPI CreateBrushIndirect(CONST LOGBRUSH *plbrush); + WINGDIAPI HBITMAP WINAPI CreateCompatibleBitmap(HDC hdc,int cx,int cy); + WINGDIAPI HBITMAP WINAPI CreateDiscardableBitmap(HDC hdc,int cx,int cy); + WINGDIAPI HDC WINAPI CreateCompatibleDC(HDC hdc); + WINGDIAPI HDC WINAPI CreateDCA(LPCSTR pwszDriver,LPCSTR pwszDevice,LPCSTR pszPort,CONST DEVMODEA *pdm); + WINGDIAPI HDC WINAPI CreateDCW(LPCWSTR pwszDriver,LPCWSTR pwszDevice,LPCWSTR pszPort,CONST DEVMODEW *pdm); + WINGDIAPI HBITMAP WINAPI CreateDIBitmap(HDC hdc,CONST BITMAPINFOHEADER *pbmih,DWORD flInit,CONST VOID *pjBits,CONST BITMAPINFO *pbmi,UINT iUsage); + WINGDIAPI HBRUSH WINAPI CreateDIBPatternBrush(HGLOBAL h,UINT iUsage); + WINGDIAPI HBRUSH WINAPI CreateDIBPatternBrushPt(CONST VOID *lpPackedDIB,UINT iUsage); + WINGDIAPI HRGN WINAPI CreateEllipticRgn(int x1,int y1,int x2,int y2); + WINGDIAPI HRGN WINAPI CreateEllipticRgnIndirect(CONST RECT *lprect); + WINGDIAPI HFONT WINAPI CreateFontIndirectA(CONST LOGFONTA *lplf); + WINGDIAPI HFONT WINAPI CreateFontIndirectW(CONST LOGFONTW *lplf); + WINGDIAPI HFONT WINAPI CreateFontA(int cHeight,int cWidth,int cEscapement,int cOrientation,int cWeight,DWORD bItalic,DWORD bUnderline,DWORD bStrikeOut,DWORD iCharSet,DWORD iOutPrecision,DWORD iClipPrecision,DWORD iQuality,DWORD iPitchAndFamily,LPCSTR pszFaceName); + WINGDIAPI HFONT WINAPI CreateFontW(int cHeight,int cWidth,int cEscapement,int cOrientation,int cWeight,DWORD bItalic,DWORD bUnderline,DWORD bStrikeOut,DWORD iCharSet,DWORD iOutPrecision,DWORD iClipPrecision,DWORD iQuality,DWORD iPitchAndFamily,LPCWSTR pszFaceName); + WINGDIAPI HBRUSH WINAPI CreateHatchBrush(int iHatch,COLORREF color); + WINGDIAPI HDC WINAPI CreateICA(LPCSTR pszDriver,LPCSTR pszDevice,LPCSTR pszPort,CONST DEVMODEA *pdm); + WINGDIAPI HDC WINAPI CreateICW(LPCWSTR pszDriver,LPCWSTR pszDevice,LPCWSTR pszPort,CONST DEVMODEW *pdm); + WINGDIAPI HDC WINAPI CreateMetaFileA(LPCSTR pszFile); + WINGDIAPI HDC WINAPI CreateMetaFileW(LPCWSTR pszFile); + WINGDIAPI HPALETTE WINAPI CreatePalette(CONST LOGPALETTE *plpal); + WINGDIAPI HPEN WINAPI CreatePen(int iStyle,int cWidth,COLORREF color); + WINGDIAPI HPEN WINAPI CreatePenIndirect(CONST LOGPEN *plpen); + WINGDIAPI HRGN WINAPI CreatePolyPolygonRgn(CONST POINT *pptl,CONST INT *pc,int cPoly,int iMode); + WINGDIAPI HBRUSH WINAPI CreatePatternBrush(HBITMAP hbm); + WINGDIAPI HRGN WINAPI CreateRectRgn(int x1,int y1,int x2,int y2); + WINGDIAPI HRGN WINAPI CreateRectRgnIndirect(CONST RECT *lprect); + WINGDIAPI HRGN WINAPI CreateRoundRectRgn(int x1,int y1,int x2,int y2,int w,int h); + WINGDIAPI WINBOOL WINAPI CreateScalableFontResourceA(DWORD fdwHidden,LPCSTR lpszFont,LPCSTR lpszFile,LPCSTR lpszPath); + WINGDIAPI WINBOOL WINAPI CreateScalableFontResourceW(DWORD fdwHidden,LPCWSTR lpszFont,LPCWSTR lpszFile,LPCWSTR lpszPath); + WINGDIAPI HBRUSH WINAPI CreateSolidBrush(COLORREF color); + WINGDIAPI WINBOOL WINAPI DeleteDC(HDC hdc); + WINGDIAPI WINBOOL WINAPI DeleteMetaFile(HMETAFILE hmf); + WINGDIAPI WINBOOL WINAPI DeleteObject(HGDIOBJ ho); + WINGDIAPI int WINAPI DescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,LPPIXELFORMATDESCRIPTOR ppfd); + + typedef UINT (CALLBACK *LPFNDEVMODE)(HWND,HMODULE,LPDEVMODE,LPSTR,LPSTR,LPDEVMODE,LPSTR,UINT); + typedef DWORD (CALLBACK *LPFNDEVCAPS)(LPSTR,LPSTR,UINT,LPSTR,LPDEVMODE); + +#define DM_UPDATE 1 +#define DM_COPY 2 +#define DM_PROMPT 4 +#define DM_MODIFY 8 + +#define DM_IN_BUFFER DM_MODIFY +#define DM_IN_PROMPT DM_PROMPT +#define DM_OUT_BUFFER DM_COPY +#define DM_OUT_DEFAULT DM_UPDATE + +#define DC_FIELDS 1 +#define DC_PAPERS 2 +#define DC_PAPERSIZE 3 +#define DC_MINEXTENT 4 +#define DC_MAXEXTENT 5 +#define DC_BINS 6 +#define DC_DUPLEX 7 +#define DC_SIZE 8 +#define DC_EXTRA 9 +#define DC_VERSION 10 +#define DC_DRIVER 11 +#define DC_BINNAMES 12 +#define DC_ENUMRESOLUTIONS 13 +#define DC_FILEDEPENDENCIES 14 +#define DC_TRUETYPE 15 +#define DC_PAPERNAMES 16 +#define DC_ORIENTATION 17 +#define DC_COPIES 18 +#define DC_BINADJUST 19 +#define DC_EMF_COMPLIANT 20 +#define DC_DATATYPE_PRODUCED 21 +#define DC_COLLATE 22 +#define DC_MANUFACTURER 23 +#define DC_MODEL 24 +#define DC_PERSONALITY 25 +#define DC_PRINTRATE 26 +#define DC_PRINTRATEUNIT 27 +#define PRINTRATEUNIT_PPM 1 +#define PRINTRATEUNIT_CPS 2 +#define PRINTRATEUNIT_LPM 3 +#define PRINTRATEUNIT_IPM 4 +#define DC_PRINTERMEM 28 +#define DC_MEDIAREADY 29 +#define DC_STAPLE 30 +#define DC_PRINTRATEPPM 31 +#define DC_COLORDEVICE 32 +#define DC_NUP 33 +#define DC_MEDIATYPENAMES 34 +#define DC_MEDIATYPES 35 + +#define DCTT_BITMAP 0x0000001L +#define DCTT_DOWNLOAD 0x0000002L +#define DCTT_SUBDEV 0x0000004L +#define DCTT_DOWNLOAD_OUTLINE 0x0000008L + +#define DCBA_FACEUPNONE 0x0000 +#define DCBA_FACEUPCENTER 0x0001 +#define DCBA_FACEUPLEFT 0x0002 +#define DCBA_FACEUPRIGHT 0x0003 +#define DCBA_FACEDOWNNONE 0x0100 +#define DCBA_FACEDOWNCENTER 0x0101 +#define DCBA_FACEDOWNLEFT 0x0102 +#define DCBA_FACEDOWNRIGHT 0x0103 + +#ifdef UNICODE +#define DeviceCapabilities DeviceCapabilitiesW +#define EnumFontFamiliesEx EnumFontFamiliesExW +#define EnumFontFamilies EnumFontFamiliesW +#define EnumFonts EnumFontsW +#define GetCharWidth GetCharWidthW +#define GetCharWidth32 GetCharWidth32W +#define GetCharWidthFloat GetCharWidthFloatW +#define GetCharABCWidths GetCharABCWidthsW +#define GetCharABCWidthsFloat GetCharABCWidthsFloatW +#define GetGlyphOutline GetGlyphOutlineW +#define GetMetaFile GetMetaFileW +#else #define DeviceCapabilities DeviceCapabilitiesA -#define EnumFontFamilies EnumFontFamiliesA #define EnumFontFamiliesEx EnumFontFamiliesExA +#define EnumFontFamilies EnumFontFamiliesA #define EnumFonts EnumFontsA -#define EnumICMProfiles EnumICMProfilesA -#define ExtTextOut ExtTextOutA -#define GetCharWidthFloat GetCharWidthFloatA #define GetCharWidth GetCharWidthA -#define GetCharacterPlacement GetCharacterPlacementA +#define GetCharWidth32 GetCharWidth32A +#define GetCharWidthFloat GetCharWidthFloatA #define GetCharABCWidths GetCharABCWidthsA #define GetCharABCWidthsFloat GetCharABCWidthsFloatA -#define GetCharWidth32 GetCharWidth32A -#define GetEnhMetaFile GetEnhMetaFileA -#define GetEnhMetaFileDescription GetEnhMetaFileDescriptionA #define GetGlyphOutline GetGlyphOutlineA -#define GetICMProfile GetICMProfileA -#define GetKerningPairs GetKerningPairsA -#define GetLogColorSpace GetLogColorSpaceA #define GetMetaFile GetMetaFileA -#define GetObject GetObjectA +#endif + + WINSPOOLAPI int WINAPI DeviceCapabilitiesA(LPCSTR pDevice,LPCSTR pPort,WORD fwCapability,LPSTR pOutput,CONST DEVMODEA *pDevMode); + WINSPOOLAPI int WINAPI DeviceCapabilitiesW(LPCWSTR pDevice,LPCWSTR pPort,WORD fwCapability,LPWSTR pOutput,CONST DEVMODEW *pDevMode); + WINGDIAPI int WINAPI DrawEscape(HDC hdc,int iEscape,int cjIn,LPCSTR lpIn); + WINGDIAPI WINBOOL WINAPI Ellipse(HDC hdc,int left,int top,int right,int bottom); + WINGDIAPI int WINAPI EnumFontFamiliesExA(HDC hdc,LPLOGFONTA lpLogfont,FONTENUMPROCA lpProc,LPARAM lParam,DWORD dwFlags); + WINGDIAPI int WINAPI EnumFontFamiliesExW(HDC hdc,LPLOGFONTW lpLogfont,FONTENUMPROCW lpProc,LPARAM lParam,DWORD dwFlags); + WINGDIAPI int WINAPI EnumFontFamiliesA(HDC hdc,LPCSTR lpLogfont,FONTENUMPROCA lpProc,LPARAM lParam); + WINGDIAPI int WINAPI EnumFontFamiliesW(HDC hdc,LPCWSTR lpLogfont,FONTENUMPROCW lpProc,LPARAM lParam); + WINGDIAPI int WINAPI EnumFontsA(HDC hdc,LPCSTR lpLogfont,FONTENUMPROCA lpProc,LPARAM lParam); + WINGDIAPI int WINAPI EnumFontsW(HDC hdc,LPCWSTR lpLogfont,FONTENUMPROCW lpProc,LPARAM lParam); + WINGDIAPI int WINAPI EnumObjects(HDC hdc,int nType,GOBJENUMPROC lpFunc,LPARAM lParam); + WINGDIAPI WINBOOL WINAPI EqualRgn(HRGN hrgn1,HRGN hrgn2); + WINGDIAPI int WINAPI Escape(HDC hdc,int iEscape,int cjIn,LPCSTR pvIn,LPVOID pvOut); + WINGDIAPI int WINAPI ExtEscape(HDC hdc,int iEscape,int cjInput,LPCSTR lpInData,int cjOutput,LPSTR lpOutData); + WINGDIAPI int WINAPI ExcludeClipRect(HDC hdc,int left,int top,int right,int bottom); + WINGDIAPI HRGN WINAPI ExtCreateRegion(CONST XFORM *lpx,DWORD nCount,CONST RGNDATA *lpData); + WINGDIAPI WINBOOL WINAPI ExtFloodFill(HDC hdc,int x,int y,COLORREF color,UINT type); + WINGDIAPI WINBOOL WINAPI FillRgn(HDC hdc,HRGN hrgn,HBRUSH hbr); + WINGDIAPI WINBOOL WINAPI FloodFill(HDC hdc,int x,int y,COLORREF color); + WINGDIAPI WINBOOL WINAPI FrameRgn(HDC hdc,HRGN hrgn,HBRUSH hbr,int w,int h); + WINGDIAPI int WINAPI GetROP2(HDC hdc); + WINGDIAPI WINBOOL WINAPI GetAspectRatioFilterEx(HDC hdc,LPSIZE lpsize); + WINGDIAPI COLORREF WINAPI GetBkColor(HDC hdc); + WINGDIAPI COLORREF WINAPI GetDCBrushColor(HDC hdc); + WINGDIAPI COLORREF WINAPI GetDCPenColor(HDC hdc); + WINGDIAPI int WINAPI GetBkMode(HDC hdc); + WINGDIAPI LONG WINAPI GetBitmapBits(HBITMAP hbit,LONG cb,LPVOID lpvBits); + WINGDIAPI WINBOOL WINAPI GetBitmapDimensionEx(HBITMAP hbit,LPSIZE lpsize); + WINGDIAPI UINT WINAPI GetBoundsRect(HDC hdc,LPRECT lprect,UINT flags); + WINGDIAPI WINBOOL WINAPI GetBrushOrgEx(HDC hdc,LPPOINT lppt); + WINGDIAPI WINBOOL WINAPI GetCharWidthA(HDC hdc,UINT iFirst,UINT iLast,LPINT lpBuffer); + WINGDIAPI WINBOOL WINAPI GetCharWidthW(HDC hdc,UINT iFirst,UINT iLast,LPINT lpBuffer); + WINGDIAPI WINBOOL WINAPI GetCharWidth32A(HDC hdc,UINT iFirst,UINT iLast,LPINT lpBuffer); + WINGDIAPI WINBOOL WINAPI GetCharWidth32W(HDC hdc,UINT iFirst,UINT iLast,LPINT lpBuffer); + WINGDIAPI WINBOOL WINAPI GetCharWidthFloatA(HDC hdc,UINT iFirst,UINT iLast,PFLOAT lpBuffer); + WINGDIAPI WINBOOL WINAPI GetCharWidthFloatW(HDC hdc,UINT iFirst,UINT iLast,PFLOAT lpBuffer); + WINGDIAPI WINBOOL WINAPI GetCharABCWidthsA(HDC hdc,UINT wFirst,UINT wLast,LPABC lpABC); + WINGDIAPI WINBOOL WINAPI GetCharABCWidthsW(HDC hdc,UINT wFirst,UINT wLast,LPABC lpABC); + WINGDIAPI WINBOOL WINAPI GetCharABCWidthsFloatA(HDC hdc,UINT iFirst,UINT iLast,LPABCFLOAT lpABC); + WINGDIAPI WINBOOL WINAPI GetCharABCWidthsFloatW(HDC hdc,UINT iFirst,UINT iLast,LPABCFLOAT lpABC); + WINGDIAPI int WINAPI GetClipBox(HDC hdc,LPRECT lprect); + WINGDIAPI int WINAPI GetClipRgn(HDC hdc,HRGN hrgn); + WINGDIAPI int WINAPI GetMetaRgn(HDC hdc,HRGN hrgn); + WINGDIAPI HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type); + WINGDIAPI WINBOOL WINAPI GetCurrentPositionEx(HDC hdc,LPPOINT lppt); + WINGDIAPI int WINAPI GetDeviceCaps(HDC hdc,int index); + WINGDIAPI int WINAPI GetDIBits(HDC hdc,HBITMAP hbm,UINT start,UINT cLines,LPVOID lpvBits,LPBITMAPINFO lpbmi,UINT usage); + WINGDIAPI DWORD WINAPI GetFontData (HDC hdc,DWORD dwTable,DWORD dwOffset,PVOID pvBuffer,DWORD cjBuffer); + WINGDIAPI DWORD WINAPI GetGlyphOutlineA(HDC hdc,UINT uChar,UINT fuFormat,LPGLYPHMETRICS lpgm,DWORD cjBuffer,LPVOID pvBuffer,CONST MAT2 *lpmat2); + WINGDIAPI DWORD WINAPI GetGlyphOutlineW(HDC hdc,UINT uChar,UINT fuFormat,LPGLYPHMETRICS lpgm,DWORD cjBuffer,LPVOID pvBuffer,CONST MAT2 *lpmat2); + WINGDIAPI int WINAPI GetGraphicsMode(HDC hdc); + WINGDIAPI int WINAPI GetMapMode(HDC hdc); + WINGDIAPI UINT WINAPI GetMetaFileBitsEx(HMETAFILE hMF,UINT cbBuffer,LPVOID lpData); + WINGDIAPI HMETAFILE WINAPI GetMetaFileA(LPCSTR lpName); + WINGDIAPI HMETAFILE WINAPI GetMetaFileW(LPCWSTR lpName); + WINGDIAPI COLORREF WINAPI GetNearestColor(HDC hdc,COLORREF color); + WINGDIAPI UINT WINAPI GetNearestPaletteIndex(HPALETTE h,COLORREF color); + WINGDIAPI DWORD WINAPI GetObjectType(HGDIOBJ h); + +#ifndef NOTEXTMETRIC +#ifdef UNICODE +#define GetOutlineTextMetrics GetOutlineTextMetricsW +#else #define GetOutlineTextMetrics GetOutlineTextMetricsA +#endif + + WINGDIAPI UINT WINAPI GetOutlineTextMetricsA(HDC hdc,UINT cjCopy,LPOUTLINETEXTMETRICA potm); + WINGDIAPI UINT WINAPI GetOutlineTextMetricsW(HDC hdc,UINT cjCopy,LPOUTLINETEXTMETRICW potm); +#endif + +#ifdef UNICODE +#define GetTextExtentPoint GetTextExtentPointW +#define GetTextExtentPoint32 GetTextExtentPoint32W +#define GetTextExtentExPoint GetTextExtentExPointW +#define GetCharacterPlacement GetCharacterPlacementW +#else #define GetTextExtentPoint GetTextExtentPointA -#define GetTextExtentExPoint GetTextExtentExPointA #define GetTextExtentPoint32 GetTextExtentPoint32A -#define GetTextFace GetTextFaceA -#define GetTextMetrics GetTextMetricsA -#define PolyTextOut PolyTextOutA -#define RemoveFontResource RemoveFontResourceA +#define GetTextExtentExPoint GetTextExtentExPointA +#define GetCharacterPlacement GetCharacterPlacementA +#endif + + WINGDIAPI UINT WINAPI GetPaletteEntries(HPALETTE hpal,UINT iStart,UINT cEntries,LPPALETTEENTRY pPalEntries); + WINGDIAPI COLORREF WINAPI GetPixel(HDC hdc,int x,int y); + WINGDIAPI int WINAPI GetPixelFormat(HDC hdc); + WINGDIAPI int WINAPI GetPolyFillMode(HDC hdc); + WINGDIAPI WINBOOL WINAPI GetRasterizerCaps(LPRASTERIZER_STATUS lpraststat,UINT cjBytes); + WINGDIAPI int WINAPI GetRandomRgn (HDC hdc,HRGN hrgn,INT i); + WINGDIAPI DWORD WINAPI GetRegionData(HRGN hrgn,DWORD nCount,LPRGNDATA lpRgnData); + WINGDIAPI int WINAPI GetRgnBox(HRGN hrgn,LPRECT lprc); + WINGDIAPI HGDIOBJ WINAPI GetStockObject(int i); + WINGDIAPI int WINAPI GetStretchBltMode(HDC hdc); + WINGDIAPI UINT WINAPI GetSystemPaletteEntries(HDC hdc,UINT iStart,UINT cEntries,LPPALETTEENTRY pPalEntries); + WINGDIAPI UINT WINAPI GetSystemPaletteUse(HDC hdc); + WINGDIAPI int WINAPI GetTextCharacterExtra(HDC hdc); + WINGDIAPI UINT WINAPI GetTextAlign(HDC hdc); + WINGDIAPI COLORREF WINAPI GetTextColor(HDC hdc); + WINGDIAPI WINBOOL WINAPI GetTextExtentPointA(HDC hdc,LPCSTR lpString,int c,LPSIZE lpsz); + WINGDIAPI WINBOOL WINAPI GetTextExtentPointW(HDC hdc,LPCWSTR lpString,int c,LPSIZE lpsz); + WINGDIAPI WINBOOL WINAPI GetTextExtentPoint32A(HDC hdc,LPCSTR lpString,int c,LPSIZE psizl); + WINGDIAPI WINBOOL WINAPI GetTextExtentPoint32W(HDC hdc,LPCWSTR lpString,int c,LPSIZE psizl); + WINGDIAPI WINBOOL WINAPI GetTextExtentExPointA(HDC hdc,LPCSTR lpszString,int cchString,int nMaxExtent,LPINT lpnFit,LPINT lpnDx,LPSIZE lpSize); + WINGDIAPI WINBOOL WINAPI GetTextExtentExPointW(HDC hdc,LPCWSTR lpszString,int cchString,int nMaxExtent,LPINT lpnFit,LPINT lpnDx,LPSIZE lpSize); + WINGDIAPI int WINAPI GetTextCharset(HDC hdc); + WINGDIAPI int WINAPI GetTextCharsetInfo(HDC hdc,LPFONTSIGNATURE lpSig,DWORD dwFlags); + WINGDIAPI WINBOOL WINAPI TranslateCharsetInfo(DWORD *lpSrc,LPCHARSETINFO lpCs,DWORD dwFlags); + WINGDIAPI DWORD WINAPI GetFontLanguageInfo(HDC hdc); + WINGDIAPI DWORD WINAPI GetCharacterPlacementA(HDC hdc,LPCSTR lpString,int nCount,int nMexExtent,LPGCP_RESULTSA lpResults,DWORD dwFlags); + WINGDIAPI DWORD WINAPI GetCharacterPlacementW(HDC hdc,LPCWSTR lpString,int nCount,int nMexExtent,LPGCP_RESULTSW lpResults,DWORD dwFlags); + + typedef struct tagWCRANGE { + WCHAR wcLow; + USHORT cGlyphs; + } WCRANGE,*PWCRANGE,*LPWCRANGE; + + typedef struct tagGLYPHSET { + DWORD cbThis; + DWORD flAccel; + DWORD cGlyphsSupported; + DWORD cRanges; + WCRANGE ranges[1]; + } GLYPHSET,*PGLYPHSET,*LPGLYPHSET; + +#define GS_8BIT_INDICES 0x00000001 + +#define GGI_MARK_NONEXISTING_GLYPHS 0X0001 + +#ifdef UNICODE +#define GetGlyphIndices GetGlyphIndicesW +#else +#define GetGlyphIndices GetGlyphIndicesA +#endif + + WINGDIAPI DWORD WINAPI GetFontUnicodeRanges(HDC hdc,LPGLYPHSET lpgs); + WINGDIAPI DWORD WINAPI GetGlyphIndicesA(HDC hdc,LPCSTR lpstr,int c,LPWORD pgi,DWORD fl); + WINGDIAPI DWORD WINAPI GetGlyphIndicesW(HDC hdc,LPCWSTR lpstr,int c,LPWORD pgi,DWORD fl); + WINGDIAPI WINBOOL WINAPI GetTextExtentPointI(HDC hdc,LPWORD pgiIn,int cgi,LPSIZE psize); + WINGDIAPI WINBOOL WINAPI GetTextExtentExPointI (HDC hdc,LPWORD lpwszString,int cwchString,int nMaxExtent,LPINT lpnFit,LPINT lpnDx,LPSIZE lpSize); + WINGDIAPI WINBOOL WINAPI GetCharWidthI(HDC hdc,UINT giFirst,UINT cgi,LPWORD pgi,LPINT piWidths); + WINGDIAPI WINBOOL WINAPI GetCharABCWidthsI(HDC hdc,UINT giFirst,UINT cgi,LPWORD pgi,LPABC pabc); + +#define STAMP_DESIGNVECTOR (0x8000000 + 'd' + ('v' << 8)) +#define STAMP_AXESLIST (0x8000000 + 'a' + ('l' << 8)) +#define MM_MAX_NUMAXES 16 + + typedef struct tagDESIGNVECTOR { + DWORD dvReserved; + DWORD dvNumAxes; + LONG dvValues[MM_MAX_NUMAXES]; + } DESIGNVECTOR,*PDESIGNVECTOR,*LPDESIGNVECTOR; + +#ifdef UNICODE +#define AddFontResourceEx AddFontResourceExW +#define RemoveFontResourceEx RemoveFontResourceExW +#else +#define AddFontResourceEx AddFontResourceExA +#define RemoveFontResourceEx RemoveFontResourceExA +#endif + + WINGDIAPI int WINAPI AddFontResourceExA(LPCSTR name,DWORD fl,PVOID res); + WINGDIAPI int WINAPI AddFontResourceExW(LPCWSTR name,DWORD fl,PVOID res); + WINGDIAPI WINBOOL WINAPI RemoveFontResourceExA(LPCSTR name,DWORD fl,PVOID pdv); + WINGDIAPI WINBOOL WINAPI RemoveFontResourceExW(LPCWSTR name,DWORD fl,PVOID pdv); + WINGDIAPI HANDLE WINAPI AddFontMemResourceEx(PVOID pFileView,DWORD cjSize,PVOID pvResrved,DWORD *pNumFonts); + WINGDIAPI WINBOOL WINAPI RemoveFontMemResourceEx(HANDLE h); + +#define FR_PRIVATE 0x10 +#define FR_NOT_ENUM 0x20 + +#define MM_MAX_AXES_NAMELEN 16 + + typedef struct tagAXISINFOA { + LONG axMinValue; + LONG axMaxValue; + BYTE axAxisName[MM_MAX_AXES_NAMELEN]; + } AXISINFOA,*PAXISINFOA,*LPAXISINFOA; + + typedef struct tagAXISINFOW { + LONG axMinValue; + LONG axMaxValue; + WCHAR axAxisName[MM_MAX_AXES_NAMELEN]; + } AXISINFOW,*PAXISINFOW,*LPAXISINFOW; +#ifdef UNICODE + typedef AXISINFOW AXISINFO; + typedef PAXISINFOW PAXISINFO; + typedef LPAXISINFOW LPAXISINFO; +#else + typedef AXISINFOA AXISINFO; + typedef PAXISINFOA PAXISINFO; + typedef LPAXISINFOA LPAXISINFO; +#endif + + typedef struct tagAXESLISTA { + DWORD axlReserved; + DWORD axlNumAxes; + AXISINFOA axlAxisInfo[MM_MAX_NUMAXES]; + } AXESLISTA,*PAXESLISTA,*LPAXESLISTA; + + typedef struct tagAXESLISTW { + DWORD axlReserved; + DWORD axlNumAxes; + AXISINFOW axlAxisInfo[MM_MAX_NUMAXES]; + } AXESLISTW,*PAXESLISTW,*LPAXESLISTW; +#ifdef UNICODE + typedef AXESLISTW AXESLIST; + typedef PAXESLISTW PAXESLIST; + typedef LPAXESLISTW LPAXESLIST; +#else + typedef AXESLISTA AXESLIST; + typedef PAXESLISTA PAXESLIST; + typedef LPAXESLISTA LPAXESLIST; +#endif + + typedef struct tagENUMLOGFONTEXDVA { + ENUMLOGFONTEXA elfEnumLogfontEx; + DESIGNVECTOR elfDesignVector; + } ENUMLOGFONTEXDVA,*PENUMLOGFONTEXDVA,*LPENUMLOGFONTEXDVA; + + typedef struct tagENUMLOGFONTEXDVW { + ENUMLOGFONTEXW elfEnumLogfontEx; + DESIGNVECTOR elfDesignVector; + } ENUMLOGFONTEXDVW,*PENUMLOGFONTEXDVW,*LPENUMLOGFONTEXDVW; +#ifdef UNICODE + typedef ENUMLOGFONTEXDVW ENUMLOGFONTEXDV; + typedef PENUMLOGFONTEXDVW PENUMLOGFONTEXDV; + typedef LPENUMLOGFONTEXDVW LPENUMLOGFONTEXDV; +#else + typedef ENUMLOGFONTEXDVA ENUMLOGFONTEXDV; + typedef PENUMLOGFONTEXDVA PENUMLOGFONTEXDV; + typedef LPENUMLOGFONTEXDVA LPENUMLOGFONTEXDV; +#endif + +#ifdef UNICODE +#define CreateFontIndirectEx CreateFontIndirectExW +#else +#define CreateFontIndirectEx CreateFontIndirectExA +#endif + + WINGDIAPI HFONT WINAPI CreateFontIndirectExA(CONST ENUMLOGFONTEXDVA *); + WINGDIAPI HFONT WINAPI CreateFontIndirectExW(CONST ENUMLOGFONTEXDVW *); + +#ifndef NOTEXTMETRIC + typedef struct tagENUMTEXTMETRICA { + NEWTEXTMETRICEXA etmNewTextMetricEx; + AXESLISTA etmAxesList; + } ENUMTEXTMETRICA,*PENUMTEXTMETRICA,*LPENUMTEXTMETRICA; + typedef struct tagENUMTEXTMETRICW + { + NEWTEXTMETRICEXW etmNewTextMetricEx; + AXESLISTW etmAxesList; + } ENUMTEXTMETRICW,*PENUMTEXTMETRICW,*LPENUMTEXTMETRICW; +#ifdef UNICODE + typedef ENUMTEXTMETRICW ENUMTEXTMETRIC; + typedef PENUMTEXTMETRICW PENUMTEXTMETRIC; + typedef LPENUMTEXTMETRICW LPENUMTEXTMETRIC; +#else + typedef ENUMTEXTMETRICA ENUMTEXTMETRIC; + typedef PENUMTEXTMETRICA PENUMTEXTMETRIC; + typedef LPENUMTEXTMETRICA LPENUMTEXTMETRIC; +#endif +#endif + +#ifdef UNICODE +#define ResetDC ResetDCW +#define RemoveFontResource RemoveFontResourceW +#else #define ResetDC ResetDCA -#define SetICMProfile SetICMProfileA +#define RemoveFontResource RemoveFontResourceA +#endif + + WINGDIAPI WINBOOL WINAPI GetViewportExtEx(HDC hdc,LPSIZE lpsize); + WINGDIAPI WINBOOL WINAPI GetViewportOrgEx(HDC hdc,LPPOINT lppoint); + WINGDIAPI WINBOOL WINAPI GetWindowExtEx(HDC hdc,LPSIZE lpsize); + WINGDIAPI WINBOOL WINAPI GetWindowOrgEx(HDC hdc,LPPOINT lppoint); + WINGDIAPI int WINAPI IntersectClipRect(HDC hdc,int left,int top,int right,int bottom); + WINGDIAPI WINBOOL WINAPI InvertRgn(HDC hdc,HRGN hrgn); + WINGDIAPI WINBOOL WINAPI LineDDA(int xStart,int yStart,int xEnd,int yEnd,LINEDDAPROC lpProc,LPARAM data); + WINGDIAPI WINBOOL WINAPI LineTo(HDC hdc,int x,int y); + WINGDIAPI WINBOOL WINAPI MaskBlt(HDC hdcDest,int xDest,int yDest,int width,int height,HDC hdcSrc,int xSrc,int ySrc,HBITMAP hbmMask,int xMask,int yMask,DWORD rop); + WINGDIAPI WINBOOL WINAPI PlgBlt(HDC hdcDest,CONST POINT *lpPoint,HDC hdcSrc,int xSrc,int ySrc,int width,int height,HBITMAP hbmMask,int xMask,int yMask); + WINGDIAPI int WINAPI OffsetClipRgn(HDC hdc,int x,int y); + WINGDIAPI int WINAPI OffsetRgn(HRGN hrgn,int x,int y); + WINGDIAPI WINBOOL WINAPI PatBlt(HDC hdc,int x,int y,int w,int h,DWORD rop); + WINGDIAPI WINBOOL WINAPI Pie(HDC hdc,int left,int top,int right,int bottom,int xr1,int yr1,int xr2,int yr2); + WINGDIAPI WINBOOL WINAPI PlayMetaFile(HDC hdc,HMETAFILE hmf); + WINGDIAPI WINBOOL WINAPI PaintRgn(HDC hdc,HRGN hrgn); + WINGDIAPI WINBOOL WINAPI PolyPolygon(HDC hdc,CONST POINT *apt,CONST INT *asz,int csz); + WINGDIAPI WINBOOL WINAPI PtInRegion(HRGN hrgn,int x,int y); + WINGDIAPI WINBOOL WINAPI PtVisible(HDC hdc,int x,int y); + WINGDIAPI WINBOOL WINAPI RectInRegion(HRGN hrgn,CONST RECT *lprect); + WINGDIAPI WINBOOL WINAPI RectVisible(HDC hdc,CONST RECT *lprect); + WINGDIAPI WINBOOL WINAPI Rectangle(HDC hdc,int left,int top,int right,int bottom); + WINGDIAPI WINBOOL WINAPI RestoreDC(HDC hdc,int nSavedDC); + WINGDIAPI HDC WINAPI ResetDCA(HDC hdc,CONST DEVMODEA *lpdm); + WINGDIAPI HDC WINAPI ResetDCW(HDC hdc,CONST DEVMODEW *lpdm); + WINGDIAPI UINT WINAPI RealizePalette(HDC hdc); + WINGDIAPI WINBOOL WINAPI RemoveFontResourceA(LPCSTR lpFileName); + WINGDIAPI WINBOOL WINAPI RemoveFontResourceW(LPCWSTR lpFileName); + WINGDIAPI WINBOOL WINAPI RoundRect(HDC hdc,int left,int top,int right,int bottom,int width,int height); + WINGDIAPI WINBOOL WINAPI ResizePalette(HPALETTE hpal,UINT n); + WINGDIAPI int WINAPI SaveDC(HDC hdc); + WINGDIAPI int WINAPI SelectClipRgn(HDC hdc,HRGN hrgn); + WINGDIAPI int WINAPI ExtSelectClipRgn(HDC hdc,HRGN hrgn,int mode); + WINGDIAPI int WINAPI SetMetaRgn(HDC hdc); + WINGDIAPI HGDIOBJ WINAPI SelectObject(HDC hdc,HGDIOBJ h); + WINGDIAPI HPALETTE WINAPI SelectPalette(HDC hdc,HPALETTE hPal,WINBOOL bForceBkgd); + WINGDIAPI COLORREF WINAPI SetBkColor(HDC hdc,COLORREF color); + WINGDIAPI COLORREF WINAPI SetDCBrushColor(HDC hdc,COLORREF color); + WINGDIAPI COLORREF WINAPI SetDCPenColor(HDC hdc,COLORREF color); + WINGDIAPI int WINAPI SetBkMode(HDC hdc,int mode); + WINGDIAPI LONG WINAPI SetBitmapBits(HBITMAP hbm,DWORD cb,CONST VOID *pvBits); + WINGDIAPI UINT WINAPI SetBoundsRect(HDC hdc,CONST RECT *lprect,UINT flags); + WINGDIAPI int WINAPI SetDIBits(HDC hdc,HBITMAP hbm,UINT start,UINT cLines,CONST VOID *lpBits,CONST BITMAPINFO *lpbmi,UINT ColorUse); + WINGDIAPI int WINAPI SetDIBitsToDevice(HDC hdc,int xDest,int yDest,DWORD w,DWORD h,int xSrc,int ySrc,UINT StartScan,UINT cLines,CONST VOID *lpvBits,CONST BITMAPINFO *lpbmi,UINT ColorUse); + WINGDIAPI DWORD WINAPI SetMapperFlags(HDC hdc,DWORD flags); + WINGDIAPI int WINAPI SetGraphicsMode(HDC hdc,int iMode); + WINGDIAPI int WINAPI SetMapMode(HDC hdc,int iMode); + WINGDIAPI DWORD WINAPI SetLayout(HDC hdc,DWORD l); + WINGDIAPI DWORD WINAPI GetLayout(HDC hdc); + WINGDIAPI HMETAFILE WINAPI SetMetaFileBitsEx(UINT cbBuffer,CONST BYTE *lpData); + WINGDIAPI UINT WINAPI SetPaletteEntries(HPALETTE hpal,UINT iStart,UINT cEntries,CONST PALETTEENTRY *pPalEntries); + WINGDIAPI COLORREF WINAPI SetPixel(HDC hdc,int x,int y,COLORREF color); + WINGDIAPI WINBOOL WINAPI SetPixelV(HDC hdc,int x,int y,COLORREF color); + WINGDIAPI WINBOOL WINAPI SetPixelFormat(HDC hdc,int format,CONST PIXELFORMATDESCRIPTOR *ppfd); + WINGDIAPI int WINAPI SetPolyFillMode(HDC hdc,int mode); + WINGDIAPI WINBOOL WINAPI StretchBlt(HDC hdcDest,int xDest,int yDest,int wDest,int hDest,HDC hdcSrc,int xSrc,int ySrc,int wSrc,int hSrc,DWORD rop); + WINGDIAPI WINBOOL WINAPI SetRectRgn(HRGN hrgn,int left,int top,int right,int bottom); + WINGDIAPI int WINAPI StretchDIBits(HDC hdc,int xDest,int yDest,int DestWidth,int DestHeight,int xSrc,int ySrc,int SrcWidth,int SrcHeight,CONST VOID *lpBits,CONST BITMAPINFO *lpbmi,UINT iUsage,DWORD rop); + WINGDIAPI int WINAPI SetROP2(HDC hdc,int rop2); + WINGDIAPI int WINAPI SetStretchBltMode(HDC hdc,int mode); + WINGDIAPI UINT WINAPI SetSystemPaletteUse(HDC hdc,UINT use); + WINGDIAPI int WINAPI SetTextCharacterExtra(HDC hdc,int extra); + WINGDIAPI COLORREF WINAPI SetTextColor(HDC hdc,COLORREF color); + WINGDIAPI UINT WINAPI SetTextAlign(HDC hdc,UINT align); + WINGDIAPI WINBOOL WINAPI SetTextJustification(HDC hdc,int extra,int count); + WINGDIAPI WINBOOL WINAPI UpdateColors(HDC hdc); + + typedef USHORT COLOR16; + + typedef struct _TRIVERTEX { + LONG x; + LONG y; + COLOR16 Red; + COLOR16 Green; + COLOR16 Blue; + COLOR16 Alpha; + } TRIVERTEX,*PTRIVERTEX,*LPTRIVERTEX; + + typedef struct _GRADIENT_TRIANGLE { + ULONG Vertex1; + ULONG Vertex2; + ULONG Vertex3; + } GRADIENT_TRIANGLE,*PGRADIENT_TRIANGLE,*LPGRADIENT_TRIANGLE; + + typedef struct _GRADIENT_RECT { + ULONG UpperLeft; + ULONG LowerRight; + } GRADIENT_RECT,*PGRADIENT_RECT,*LPGRADIENT_RECT; + + typedef struct _BLENDFUNCTION { + BYTE BlendOp; + BYTE BlendFlags; + BYTE SourceConstantAlpha; + BYTE AlphaFormat; + } BLENDFUNCTION,*PBLENDFUNCTION; + +#define AC_SRC_OVER 0x00 +#define AC_SRC_ALPHA 0x01 + + WINGDIAPI WINBOOL WINAPI AlphaBlend(HDC hdcDest,int xoriginDest,int yoriginDest,int wDest,int hDest,HDC hdcSrc,int xoriginSrc,int yoriginSrc,int wSrc,int hSrc,BLENDFUNCTION ftn); + WINGDIAPI WINBOOL WINAPI TransparentBlt(HDC hdcDest,int xoriginDest,int yoriginDest,int wDest,int hDest,HDC hdcSrc,int xoriginSrc,int yoriginSrc,int wSrc,int hSrc,UINT crTransparent); + +#define GRADIENT_FILL_RECT_H 0x00000000 +#define GRADIENT_FILL_RECT_V 0x00000001 +#define GRADIENT_FILL_TRIANGLE 0x00000002 +#define GRADIENT_FILL_OP_FLAG 0x000000ff + + WINGDIAPI WINBOOL WINAPI GradientFill(HDC hdc,PTRIVERTEX pVertex,ULONG nVertex,PVOID pMesh,ULONG nMesh,ULONG ulMode); + +#ifndef NOMETAFILE + +#ifdef UNICODE +#define CopyEnhMetaFile CopyEnhMetaFileW +#define CreateEnhMetaFile CreateEnhMetaFileW +#define GetEnhMetaFile GetEnhMetaFileW +#define GetEnhMetaFileDescription GetEnhMetaFileDescriptionW +#else +#define CopyEnhMetaFile CopyEnhMetaFileA +#define CreateEnhMetaFile CreateEnhMetaFileA +#define GetEnhMetaFile GetEnhMetaFileA +#define GetEnhMetaFileDescription GetEnhMetaFileDescriptionA +#endif + + WINGDIAPI WINBOOL WINAPI PlayMetaFileRecord(HDC hdc,LPHANDLETABLE lpHandleTable,LPMETARECORD lpMR,UINT noObjs); + + typedef int (CALLBACK *MFENUMPROC)(HDC hdc,HANDLETABLE *lpht,METARECORD *lpMR,int nObj,LPARAM param); + + WINGDIAPI WINBOOL WINAPI EnumMetaFile(HDC hdc,HMETAFILE hmf,MFENUMPROC proc,LPARAM param); + + typedef int (CALLBACK *ENHMFENUMPROC)(HDC hdc,HANDLETABLE *lpht,CONST ENHMETARECORD *lpmr,int hHandles,LPARAM data); + + WINGDIAPI HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc); + WINGDIAPI HENHMETAFILE WINAPI CopyEnhMetaFileA(HENHMETAFILE hEnh,LPCSTR lpFileName); + WINGDIAPI HENHMETAFILE WINAPI CopyEnhMetaFileW(HENHMETAFILE hEnh,LPCWSTR lpFileName); + WINGDIAPI HDC WINAPI CreateEnhMetaFileA(HDC hdc,LPCSTR lpFilename,CONST RECT *lprc,LPCSTR lpDesc); + WINGDIAPI HDC WINAPI CreateEnhMetaFileW(HDC hdc,LPCWSTR lpFilename,CONST RECT *lprc,LPCWSTR lpDesc); + WINGDIAPI WINBOOL WINAPI DeleteEnhMetaFile(HENHMETAFILE hmf); + WINGDIAPI WINBOOL WINAPI EnumEnhMetaFile(HDC hdc,HENHMETAFILE hmf,ENHMFENUMPROC proc,LPVOID param,CONST RECT *lpRect); + WINGDIAPI HENHMETAFILE WINAPI GetEnhMetaFileA(LPCSTR lpName); + WINGDIAPI HENHMETAFILE WINAPI GetEnhMetaFileW(LPCWSTR lpName); + WINGDIAPI UINT WINAPI GetEnhMetaFileBits(HENHMETAFILE hEMF,UINT nSize,LPBYTE lpData); + WINGDIAPI UINT WINAPI GetEnhMetaFileDescriptionA(HENHMETAFILE hemf,UINT cchBuffer,LPSTR lpDescription); + WINGDIAPI UINT WINAPI GetEnhMetaFileDescriptionW(HENHMETAFILE hemf,UINT cchBuffer,LPWSTR lpDescription); + WINGDIAPI UINT WINAPI GetEnhMetaFileHeader(HENHMETAFILE hemf,UINT nSize,LPENHMETAHEADER lpEnhMetaHeader); + WINGDIAPI UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE hemf,UINT nNumEntries,LPPALETTEENTRY lpPaletteEntries); + WINGDIAPI UINT WINAPI GetEnhMetaFilePixelFormat(HENHMETAFILE hemf,UINT cbBuffer,PIXELFORMATDESCRIPTOR *ppfd); + WINGDIAPI UINT WINAPI GetWinMetaFileBits(HENHMETAFILE hemf,UINT cbData16,LPBYTE pData16,INT iMapMode,HDC hdcRef); + WINGDIAPI WINBOOL WINAPI PlayEnhMetaFile(HDC hdc,HENHMETAFILE hmf,CONST RECT *lprect); + WINGDIAPI WINBOOL WINAPI PlayEnhMetaFileRecord(HDC hdc,LPHANDLETABLE pht,CONST ENHMETARECORD *pmr,UINT cht); + WINGDIAPI HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT nSize,CONST BYTE *pb); + WINGDIAPI HENHMETAFILE WINAPI SetWinMetaFileBits(UINT nSize,CONST BYTE *lpMeta16Data,HDC hdcRef,CONST METAFILEPICT *lpMFP); + WINGDIAPI WINBOOL WINAPI GdiComment(HDC hdc,UINT nSize,CONST BYTE *lpData); +#endif + +#ifndef NOTEXTMETRIC +#ifdef UNICODE +#define GetTextMetrics GetTextMetricsW +#else +#define GetTextMetrics GetTextMetricsA +#endif + + WINGDIAPI WINBOOL WINAPI GetTextMetricsA(HDC hdc,LPTEXTMETRICA lptm); + WINGDIAPI WINBOOL WINAPI GetTextMetricsW(HDC hdc,LPTEXTMETRICW lptm); +#endif + + typedef struct tagDIBSECTION { + BITMAP dsBm; + BITMAPINFOHEADER dsBmih; + DWORD dsBitfields[3]; + HANDLE dshSection; + DWORD dsOffset; + } DIBSECTION,*LPDIBSECTION,*PDIBSECTION; + + WINGDIAPI WINBOOL WINAPI AngleArc(HDC hdc,int x,int y,DWORD r,FLOAT StartAngle,FLOAT SweepAngle); + WINGDIAPI WINBOOL WINAPI PolyPolyline(HDC hdc,CONST POINT *apt,CONST DWORD *asz,DWORD csz); + WINGDIAPI WINBOOL WINAPI GetWorldTransform(HDC hdc,LPXFORM lpxf); + WINGDIAPI WINBOOL WINAPI SetWorldTransform(HDC hdc,CONST XFORM *lpxf); + WINGDIAPI WINBOOL WINAPI ModifyWorldTransform(HDC hdc,CONST XFORM *lpxf,DWORD mode); + WINGDIAPI WINBOOL WINAPI CombineTransform(LPXFORM lpxfOut,CONST XFORM *lpxf1,CONST XFORM *lpxf2); + WINGDIAPI HBITMAP WINAPI CreateDIBSection(HDC hdc,CONST BITMAPINFO *lpbmi,UINT usage,VOID **ppvBits,HANDLE hSection,DWORD offset); + WINGDIAPI UINT WINAPI GetDIBColorTable(HDC hdc,UINT iStart,UINT cEntries,RGBQUAD *prgbq); + WINGDIAPI UINT WINAPI SetDIBColorTable(HDC hdc,UINT iStart,UINT cEntries,CONST RGBQUAD *prgbq); + +#define CA_NEGATIVE 0x0001 +#define CA_LOG_FILTER 0x0002 + +#define ILLUMINANT_DEVICE_DEFAULT 0 +#define ILLUMINANT_A 1 +#define ILLUMINANT_B 2 +#define ILLUMINANT_C 3 +#define ILLUMINANT_D50 4 +#define ILLUMINANT_D55 5 +#define ILLUMINANT_D65 6 +#define ILLUMINANT_D75 7 +#define ILLUMINANT_F2 8 +#define ILLUMINANT_MAX_INDEX ILLUMINANT_F2 + +#define ILLUMINANT_TUNGSTEN ILLUMINANT_A +#define ILLUMINANT_DAYLIGHT ILLUMINANT_C +#define ILLUMINANT_FLUORESCENT ILLUMINANT_F2 +#define ILLUMINANT_NTSC ILLUMINANT_C + +#define RGB_GAMMA_MIN (WORD)02500 +#define RGB_GAMMA_MAX (WORD)65000 + +#define REFERENCE_WHITE_MIN (WORD)6000 +#define REFERENCE_WHITE_MAX (WORD)10000 +#define REFERENCE_BLACK_MIN (WORD)0 +#define REFERENCE_BLACK_MAX (WORD)4000 + +#define COLOR_ADJ_MIN (SHORT)-100 +#define COLOR_ADJ_MAX (SHORT)100 + + typedef struct tagCOLORADJUSTMENT { + WORD caSize; + WORD caFlags; + WORD caIlluminantIndex; + WORD caRedGamma; + WORD caGreenGamma; + WORD caBlueGamma; + WORD caReferenceBlack; + WORD caReferenceWhite; + SHORT caContrast; + SHORT caBrightness; + SHORT caColorfulness; + SHORT caRedGreenTint; + } COLORADJUSTMENT,*PCOLORADJUSTMENT,*LPCOLORADJUSTMENT; + + WINGDIAPI WINBOOL WINAPI SetColorAdjustment(HDC hdc,CONST COLORADJUSTMENT *lpca); + WINGDIAPI WINBOOL WINAPI GetColorAdjustment(HDC hdc,LPCOLORADJUSTMENT lpca); + WINGDIAPI HPALETTE WINAPI CreateHalftonePalette(HDC hdc); + + typedef WINBOOL (CALLBACK *ABORTPROC)(HDC,int); + + typedef struct _DOCINFOA { + int cbSize; + LPCSTR lpszDocName; + LPCSTR lpszOutput; + LPCSTR lpszDatatype; + DWORD fwType; + } DOCINFOA,*LPDOCINFOA; + + typedef struct _DOCINFOW { + int cbSize; + LPCWSTR lpszDocName; + LPCWSTR lpszOutput; + LPCWSTR lpszDatatype; + DWORD fwType; + } DOCINFOW,*LPDOCINFOW; + +#ifdef UNICODE + typedef DOCINFOW DOCINFO; + typedef LPDOCINFOW LPDOCINFO; +#else + typedef DOCINFOA DOCINFO; + typedef LPDOCINFOA LPDOCINFO; +#endif + +#define DI_APPBANDING 0x00000001 +#define DI_ROPS_READ_DESTINATION 0x00000002 + +#ifdef UNICODE +#define StartDoc StartDocW +#define GetObject GetObjectW +#define TextOut TextOutW +#define ExtTextOut ExtTextOutW +#define PolyTextOut PolyTextOutW +#define GetTextFace GetTextFaceW +#else #define StartDoc StartDocA +#define GetObject GetObjectA #define TextOut TextOutA +#define ExtTextOut ExtTextOutA +#define PolyTextOut PolyTextOutA +#define GetTextFace GetTextFaceA +#endif + + WINGDIAPI int WINAPI StartDocA(HDC hdc,CONST DOCINFOA *lpdi); + WINGDIAPI int WINAPI StartDocW(HDC hdc,CONST DOCINFOW *lpdi); + WINGDIAPI int WINAPI EndDoc(HDC hdc); + WINGDIAPI int WINAPI StartPage(HDC hdc); + WINGDIAPI int WINAPI EndPage(HDC hdc); + WINGDIAPI int WINAPI AbortDoc(HDC hdc); + WINGDIAPI int WINAPI SetAbortProc(HDC hdc,ABORTPROC proc); + WINGDIAPI WINBOOL WINAPI AbortPath(HDC hdc); + WINGDIAPI WINBOOL WINAPI ArcTo(HDC hdc,int left,int top,int right,int bottom,int xr1,int yr1,int xr2,int yr2); + WINGDIAPI WINBOOL WINAPI BeginPath(HDC hdc); + WINGDIAPI WINBOOL WINAPI CloseFigure(HDC hdc); + WINGDIAPI WINBOOL WINAPI EndPath(HDC hdc); + WINGDIAPI WINBOOL WINAPI FillPath(HDC hdc); + WINGDIAPI WINBOOL WINAPI FlattenPath(HDC hdc); + WINGDIAPI int WINAPI GetPath(HDC hdc,LPPOINT apt,LPBYTE aj,int cpt); + WINGDIAPI HRGN WINAPI PathToRegion(HDC hdc); + WINGDIAPI WINBOOL WINAPI PolyDraw(HDC hdc,CONST POINT *apt,CONST BYTE *aj,int cpt); + WINGDIAPI WINBOOL WINAPI SelectClipPath(HDC hdc,int mode); + WINGDIAPI int WINAPI SetArcDirection(HDC hdc,int dir); + WINGDIAPI WINBOOL WINAPI SetMiterLimit(HDC hdc,FLOAT limit,PFLOAT old); + WINGDIAPI WINBOOL WINAPI StrokeAndFillPath(HDC hdc); + WINGDIAPI WINBOOL WINAPI StrokePath(HDC hdc); + WINGDIAPI WINBOOL WINAPI WidenPath(HDC hdc); + WINGDIAPI HPEN WINAPI ExtCreatePen(DWORD iPenStyle,DWORD cWidth,CONST LOGBRUSH *plbrush,DWORD cStyle,CONST DWORD *pstyle); + WINGDIAPI WINBOOL WINAPI GetMiterLimit(HDC hdc,PFLOAT plimit); + WINGDIAPI int WINAPI GetArcDirection(HDC hdc); + WINGDIAPI int WINAPI GetObjectA(HANDLE h,int c,LPVOID pv); + WINGDIAPI int WINAPI GetObjectW(HANDLE h,int c,LPVOID pv); + WINGDIAPI WINBOOL WINAPI MoveToEx(HDC hdc,int x,int y,LPPOINT lppt); + WINGDIAPI WINBOOL WINAPI TextOutA(HDC hdc,int x,int y,LPCSTR lpString,int c); + WINGDIAPI WINBOOL WINAPI TextOutW(HDC hdc,int x,int y,LPCWSTR lpString,int c); + WINGDIAPI WINBOOL WINAPI ExtTextOutA(HDC hdc,int x,int y,UINT options,CONST RECT *lprect,LPCSTR lpString,UINT c,CONST INT *lpDx); + WINGDIAPI WINBOOL WINAPI ExtTextOutW(HDC hdc,int x,int y,UINT options,CONST RECT *lprect,LPCWSTR lpString,UINT c,CONST INT *lpDx); + WINGDIAPI WINBOOL WINAPI PolyTextOutA(HDC hdc,CONST POLYTEXTA *ppt,int nstrings); + WINGDIAPI WINBOOL WINAPI PolyTextOutW(HDC hdc,CONST POLYTEXTW *ppt,int nstrings); + WINGDIAPI HRGN WINAPI CreatePolygonRgn(CONST POINT *pptl,int cPoint,int iMode); + WINGDIAPI WINBOOL WINAPI DPtoLP(HDC hdc,LPPOINT lppt,int c); + WINGDIAPI WINBOOL WINAPI LPtoDP(HDC hdc,LPPOINT lppt,int c); + WINGDIAPI WINBOOL WINAPI Polygon(HDC hdc,CONST POINT *apt,int cpt); + WINGDIAPI WINBOOL WINAPI Polyline(HDC hdc,CONST POINT *apt,int cpt); + WINGDIAPI WINBOOL WINAPI PolyBezier(HDC hdc,CONST POINT *apt,DWORD cpt); + WINGDIAPI WINBOOL WINAPI PolyBezierTo(HDC hdc,CONST POINT *apt,DWORD cpt); + WINGDIAPI WINBOOL WINAPI PolylineTo(HDC hdc,CONST POINT *apt,DWORD cpt); + WINGDIAPI WINBOOL WINAPI SetViewportExtEx(HDC hdc,int x,int y,LPSIZE lpsz); + WINGDIAPI WINBOOL WINAPI SetViewportOrgEx(HDC hdc,int x,int y,LPPOINT lppt); + WINGDIAPI WINBOOL WINAPI SetWindowExtEx(HDC hdc,int x,int y,LPSIZE lpsz); + WINGDIAPI WINBOOL WINAPI SetWindowOrgEx(HDC hdc,int x,int y,LPPOINT lppt); + WINGDIAPI WINBOOL WINAPI OffsetViewportOrgEx(HDC hdc,int x,int y,LPPOINT lppt); + WINGDIAPI WINBOOL WINAPI OffsetWindowOrgEx(HDC hdc,int x,int y,LPPOINT lppt); + WINGDIAPI WINBOOL WINAPI ScaleViewportExtEx(HDC hdc,int xn,int dx,int yn,int yd,LPSIZE lpsz); + WINGDIAPI WINBOOL WINAPI ScaleWindowExtEx(HDC hdc,int xn,int xd,int yn,int yd,LPSIZE lpsz); + WINGDIAPI WINBOOL WINAPI SetBitmapDimensionEx(HBITMAP hbm,int w,int h,LPSIZE lpsz); + WINGDIAPI WINBOOL WINAPI SetBrushOrgEx(HDC hdc,int x,int y,LPPOINT lppt); + WINGDIAPI int WINAPI GetTextFaceA(HDC hdc,int c,LPSTR lpName); + WINGDIAPI int WINAPI GetTextFaceW(HDC hdc,int c,LPWSTR lpName); + +#define FONTMAPPER_MAX 10 + + typedef struct tagKERNINGPAIR { + WORD wFirst; + WORD wSecond; + int iKernAmount; + } KERNINGPAIR,*LPKERNINGPAIR; + +#ifdef UNICODE +#define GetKerningPairs GetKerningPairsW +#else +#define GetKerningPairs GetKerningPairsA +#endif + + WINGDIAPI DWORD WINAPI GetKerningPairsA(HDC hdc,DWORD nPairs,LPKERNINGPAIR lpKernPair); + WINGDIAPI DWORD WINAPI GetKerningPairsW(HDC hdc,DWORD nPairs,LPKERNINGPAIR lpKernPair); + WINGDIAPI WINBOOL WINAPI GetDCOrgEx(HDC hdc,LPPOINT lppt); + WINGDIAPI WINBOOL WINAPI FixBrushOrgEx(HDC hdc,int x,int y,LPPOINT ptl); + WINGDIAPI WINBOOL WINAPI UnrealizeObject(HGDIOBJ h); + WINGDIAPI WINBOOL WINAPI GdiFlush(); + WINGDIAPI DWORD WINAPI GdiSetBatchLimit(DWORD dw); + WINGDIAPI DWORD WINAPI GdiGetBatchLimit(); + +#define ICM_OFF 1 +#define ICM_ON 2 +#define ICM_QUERY 3 +#define ICM_DONE_OUTSIDEDC 4 + + typedef int (CALLBACK *ICMENUMPROCA)(LPSTR,LPARAM); + typedef int (CALLBACK *ICMENUMPROCW)(LPWSTR,LPARAM); + +#ifdef UNICODE +#define ICMENUMPROC ICMENUMPROCW +#define EnumICMProfiles EnumICMProfilesW +#define UpdateICMRegKey UpdateICMRegKeyW +#define GetLogColorSpace GetLogColorSpaceW +#define CreateColorSpace CreateColorSpaceW +#define GetICMProfile GetICMProfileW +#define SetICMProfile SetICMProfileW +#else +#define ICMENUMPROC ICMENUMPROCA +#define EnumICMProfiles EnumICMProfilesA #define UpdateICMRegKey UpdateICMRegKeyA +#define GetLogColorSpace GetLogColorSpaceA +#define CreateColorSpace CreateColorSpaceA +#define GetICMProfile GetICMProfileA +#define SetICMProfile SetICMProfileA +#endif + + WINGDIAPI int WINAPI SetICMMode(HDC hdc,int mode); + WINGDIAPI WINBOOL WINAPI CheckColorsInGamut(HDC hdc,LPVOID lpRGBTriple,LPVOID dlpBuffer,DWORD nCount); + WINGDIAPI HCOLORSPACE WINAPI GetColorSpace(HDC hdc); + WINGDIAPI WINBOOL WINAPI GetLogColorSpaceA(HCOLORSPACE hColorSpace,LPLOGCOLORSPACEA lpBuffer,DWORD nSize); + WINGDIAPI WINBOOL WINAPI GetLogColorSpaceW(HCOLORSPACE hColorSpace,LPLOGCOLORSPACEW lpBuffer,DWORD nSize); + WINGDIAPI HCOLORSPACE WINAPI CreateColorSpaceA(LPLOGCOLORSPACEA lplcs); + WINGDIAPI HCOLORSPACE WINAPI CreateColorSpaceW(LPLOGCOLORSPACEW lplcs); + WINGDIAPI HCOLORSPACE WINAPI SetColorSpace(HDC hdc,HCOLORSPACE hcs); + WINGDIAPI WINBOOL WINAPI DeleteColorSpace(HCOLORSPACE hcs); + WINGDIAPI WINBOOL WINAPI GetICMProfileA(HDC hdc,LPDWORD pBufSize,LPSTR pszFilename); + WINGDIAPI WINBOOL WINAPI GetICMProfileW(HDC hdc,LPDWORD pBufSize,LPWSTR pszFilename); + WINGDIAPI WINBOOL WINAPI SetICMProfileA(HDC hdc,LPSTR lpFileName); + WINGDIAPI WINBOOL WINAPI SetICMProfileW(HDC hdc,LPWSTR lpFileName); + WINGDIAPI WINBOOL WINAPI GetDeviceGammaRamp(HDC hdc,LPVOID lpRamp); + WINGDIAPI WINBOOL WINAPI SetDeviceGammaRamp(HDC hdc,LPVOID lpRamp); + WINGDIAPI WINBOOL WINAPI ColorMatchToTarget(HDC hdc,HDC hdcTarget,DWORD action); + WINGDIAPI int WINAPI EnumICMProfilesA(HDC hdc,ICMENUMPROCA proc,LPARAM param); + WINGDIAPI int WINAPI EnumICMProfilesW(HDC hdc,ICMENUMPROCW proc,LPARAM param); + WINGDIAPI WINBOOL WINAPI UpdateICMRegKeyA(DWORD reserved,LPSTR lpszCMID,LPSTR lpszFileName,UINT command); + WINGDIAPI WINBOOL WINAPI UpdateICMRegKeyW(DWORD reserved,LPWSTR lpszCMID,LPWSTR lpszFileName,UINT command); + WINGDIAPI WINBOOL WINAPI ColorCorrectPalette(HDC hdc,HPALETTE hPal,DWORD deFirst,DWORD num); + +#ifndef NOMETAFILE + +#define ENHMETA_SIGNATURE 0x464D4520 +#define ENHMETA_STOCK_OBJECT 0x80000000 + +#define EMR_HEADER 1 +#define EMR_POLYBEZIER 2 +#define EMR_POLYGON 3 +#define EMR_POLYLINE 4 +#define EMR_POLYBEZIERTO 5 +#define EMR_POLYLINETO 6 +#define EMR_POLYPOLYLINE 7 +#define EMR_POLYPOLYGON 8 +#define EMR_SETWINDOWEXTEX 9 +#define EMR_SETWINDOWORGEX 10 +#define EMR_SETVIEWPORTEXTEX 11 +#define EMR_SETVIEWPORTORGEX 12 +#define EMR_SETBRUSHORGEX 13 +#define EMR_EOF 14 +#define EMR_SETPIXELV 15 +#define EMR_SETMAPPERFLAGS 16 +#define EMR_SETMAPMODE 17 +#define EMR_SETBKMODE 18 +#define EMR_SETPOLYFILLMODE 19 +#define EMR_SETROP2 20 +#define EMR_SETSTRETCHBLTMODE 21 +#define EMR_SETTEXTALIGN 22 +#define EMR_SETCOLORADJUSTMENT 23 +#define EMR_SETTEXTCOLOR 24 +#define EMR_SETBKCOLOR 25 +#define EMR_OFFSETCLIPRGN 26 +#define EMR_MOVETOEX 27 +#define EMR_SETMETARGN 28 +#define EMR_EXCLUDECLIPRECT 29 +#define EMR_INTERSECTCLIPRECT 30 +#define EMR_SCALEVIEWPORTEXTEX 31 +#define EMR_SCALEWINDOWEXTEX 32 +#define EMR_SAVEDC 33 +#define EMR_RESTOREDC 34 +#define EMR_SETWORLDTRANSFORM 35 +#define EMR_MODIFYWORLDTRANSFORM 36 +#define EMR_SELECTOBJECT 37 +#define EMR_CREATEPEN 38 +#define EMR_CREATEBRUSHINDIRECT 39 +#define EMR_DELETEOBJECT 40 +#define EMR_ANGLEARC 41 +#define EMR_ELLIPSE 42 +#define EMR_RECTANGLE 43 +#define EMR_ROUNDRECT 44 +#define EMR_ARC 45 +#define EMR_CHORD 46 +#define EMR_PIE 47 +#define EMR_SELECTPALETTE 48 +#define EMR_CREATEPALETTE 49 +#define EMR_SETPALETTEENTRIES 50 +#define EMR_RESIZEPALETTE 51 +#define EMR_REALIZEPALETTE 52 +#define EMR_EXTFLOODFILL 53 +#define EMR_LINETO 54 +#define EMR_ARCTO 55 +#define EMR_POLYDRAW 56 +#define EMR_SETARCDIRECTION 57 +#define EMR_SETMITERLIMIT 58 +#define EMR_BEGINPATH 59 +#define EMR_ENDPATH 60 +#define EMR_CLOSEFIGURE 61 +#define EMR_FILLPATH 62 +#define EMR_STROKEANDFILLPATH 63 +#define EMR_STROKEPATH 64 +#define EMR_FLATTENPATH 65 +#define EMR_WIDENPATH 66 +#define EMR_SELECTCLIPPATH 67 +#define EMR_ABORTPATH 68 + +#define EMR_GDICOMMENT 70 +#define EMR_FILLRGN 71 +#define EMR_FRAMERGN 72 +#define EMR_INVERTRGN 73 +#define EMR_PAINTRGN 74 +#define EMR_EXTSELECTCLIPRGN 75 +#define EMR_BITBLT 76 +#define EMR_STRETCHBLT 77 +#define EMR_MASKBLT 78 +#define EMR_PLGBLT 79 +#define EMR_SETDIBITSTODEVICE 80 +#define EMR_STRETCHDIBITS 81 +#define EMR_EXTCREATEFONTINDIRECTW 82 +#define EMR_EXTTEXTOUTA 83 +#define EMR_EXTTEXTOUTW 84 +#define EMR_POLYBEZIER16 85 +#define EMR_POLYGON16 86 +#define EMR_POLYLINE16 87 +#define EMR_POLYBEZIERTO16 88 +#define EMR_POLYLINETO16 89 +#define EMR_POLYPOLYLINE16 90 +#define EMR_POLYPOLYGON16 91 +#define EMR_POLYDRAW16 92 +#define EMR_CREATEMONOBRUSH 93 +#define EMR_CREATEDIBPATTERNBRUSHPT 94 +#define EMR_EXTCREATEPEN 95 +#define EMR_POLYTEXTOUTA 96 +#define EMR_POLYTEXTOUTW 97 + +#define EMR_SETICMMODE 98 +#define EMR_CREATECOLORSPACE 99 +#define EMR_SETCOLORSPACE 100 +#define EMR_DELETECOLORSPACE 101 +#define EMR_GLSRECORD 102 +#define EMR_GLSBOUNDEDRECORD 103 +#define EMR_PIXELFORMAT 104 +#define EMR_RESERVED_105 105 +#define EMR_RESERVED_106 106 +#define EMR_RESERVED_107 107 +#define EMR_RESERVED_108 108 +#define EMR_RESERVED_109 109 +#define EMR_RESERVED_110 110 +#define EMR_COLORCORRECTPALETTE 111 +#define EMR_SETICMPROFILEA 112 +#define EMR_SETICMPROFILEW 113 +#define EMR_ALPHABLEND 114 +#define EMR_SETLAYOUT 115 +#define EMR_TRANSPARENTBLT 116 +#define EMR_RESERVED_117 117 +#define EMR_GRADIENTFILL 118 +#define EMR_RESERVED_119 119 +#define EMR_RESERVED_120 120 +#define EMR_COLORMATCHTOTARGETW 121 +#define EMR_CREATECOLORSPACEW 122 + +#define EMR_MIN 1 + +#define EMR_MAX 122 + + typedef struct tagEMR { + DWORD iType; + DWORD nSize; + } EMR,*PEMR; + + typedef struct tagEMRTEXT { + POINTL ptlReference; + DWORD nChars; + DWORD offString; + DWORD fOptions; + RECTL rcl; + DWORD offDx; + } EMRTEXT,*PEMRTEXT; + + typedef struct tagABORTPATH { + EMR emr; + } EMRABORTPATH,*PEMRABORTPATH,EMRBEGINPATH,*PEMRBEGINPATH,EMRENDPATH,*PEMRENDPATH,EMRCLOSEFIGURE,*PEMRCLOSEFIGURE,EMRFLATTENPATH,*PEMRFLATTENPATH,EMRWIDENPATH,*PEMRWIDENPATH,EMRSETMETARGN,*PEMRSETMETARGN,EMRSAVEDC,*PEMRSAVEDC,EMRREALIZEPALETTE,*PEMRREALIZEPALETTE; + + typedef struct tagEMRSELECTCLIPPATH { + EMR emr; + DWORD iMode; + } EMRSELECTCLIPPATH,*PEMRSELECTCLIPPATH,EMRSETBKMODE,*PEMRSETBKMODE,EMRSETMAPMODE,*PEMRSETMAPMODE,EMRSETLAYOUT,*PEMRSETLAYOUT, + EMRSETPOLYFILLMODE,*PEMRSETPOLYFILLMODE,EMRSETROP2,*PEMRSETROP2,EMRSETSTRETCHBLTMODE,*PEMRSETSTRETCHBLTMODE,EMRSETICMMODE, + *PEMRSETICMMODE,EMRSETTEXTALIGN,*PEMRSETTEXTALIGN; + + typedef struct tagEMRSETMITERLIMIT { + EMR emr; + FLOAT eMiterLimit; + } EMRSETMITERLIMIT,*PEMRSETMITERLIMIT; + + typedef struct tagEMRRESTOREDC { + EMR emr; + LONG iRelative; + } EMRRESTOREDC,*PEMRRESTOREDC; + + typedef struct tagEMRSETARCDIRECTION { + EMR emr; + DWORD iArcDirection; + + } EMRSETARCDIRECTION,*PEMRSETARCDIRECTION; + + typedef struct tagEMRSETMAPPERFLAGS { + EMR emr; + DWORD dwFlags; + } EMRSETMAPPERFLAGS,*PEMRSETMAPPERFLAGS; + + typedef struct tagEMRSETTEXTCOLOR { + EMR emr; + COLORREF crColor; + } EMRSETBKCOLOR,*PEMRSETBKCOLOR,EMRSETTEXTCOLOR,*PEMRSETTEXTCOLOR; + + typedef struct tagEMRSELECTOBJECT { + EMR emr; + DWORD ihObject; + } EMRSELECTOBJECT,*PEMRSELECTOBJECT,EMRDELETEOBJECT,*PEMRDELETEOBJECT; + + typedef struct tagEMRSELECTPALETTE { + EMR emr; + DWORD ihPal; + } EMRSELECTPALETTE,*PEMRSELECTPALETTE; + + typedef struct tagEMRRESIZEPALETTE { + EMR emr; + DWORD ihPal; + DWORD cEntries; + } EMRRESIZEPALETTE,*PEMRRESIZEPALETTE; + + typedef struct tagEMRSETPALETTEENTRIES { + EMR emr; + DWORD ihPal; + DWORD iStart; + DWORD cEntries; + PALETTEENTRY aPalEntries[1]; + } EMRSETPALETTEENTRIES,*PEMRSETPALETTEENTRIES; + + typedef struct tagEMRSETCOLORADJUSTMENT { + EMR emr; + COLORADJUSTMENT ColorAdjustment; + } EMRSETCOLORADJUSTMENT,*PEMRSETCOLORADJUSTMENT; + + typedef struct tagEMRGDICOMMENT { + EMR emr; + DWORD cbData; + BYTE Data[1]; + } EMRGDICOMMENT,*PEMRGDICOMMENT; + + typedef struct tagEMREOF { + EMR emr; + DWORD nPalEntries; + DWORD offPalEntries; + DWORD nSizeLast; + } EMREOF,*PEMREOF; + + typedef struct tagEMRLINETO { + EMR emr; + POINTL ptl; + } EMRLINETO,*PEMRLINETO,EMRMOVETOEX,*PEMRMOVETOEX; + + typedef struct tagEMROFFSETCLIPRGN { + EMR emr; + POINTL ptlOffset; + } EMROFFSETCLIPRGN,*PEMROFFSETCLIPRGN; + + typedef struct tagEMRFILLPATH { + EMR emr; + RECTL rclBounds; + } EMRFILLPATH,*PEMRFILLPATH,EMRSTROKEANDFILLPATH,*PEMRSTROKEANDFILLPATH,EMRSTROKEPATH,*PEMRSTROKEPATH; + + typedef struct tagEMREXCLUDECLIPRECT { + EMR emr; + RECTL rclClip; + } EMREXCLUDECLIPRECT,*PEMREXCLUDECLIPRECT,EMRINTERSECTCLIPRECT,*PEMRINTERSECTCLIPRECT; + + typedef struct tagEMRSETVIEWPORTORGEX { + EMR emr; + POINTL ptlOrigin; + } EMRSETVIEWPORTORGEX,*PEMRSETVIEWPORTORGEX,EMRSETWINDOWORGEX,*PEMRSETWINDOWORGEX,EMRSETBRUSHORGEX,*PEMRSETBRUSHORGEX; + + typedef struct tagEMRSETVIEWPORTEXTEX { + EMR emr; + SIZEL szlExtent; + } EMRSETVIEWPORTEXTEX,*PEMRSETVIEWPORTEXTEX,EMRSETWINDOWEXTEX,*PEMRSETWINDOWEXTEX; + + typedef struct tagEMRSCALEVIEWPORTEXTEX { + EMR emr; + LONG xNum; + LONG xDenom; + LONG yNum; + LONG yDenom; + } EMRSCALEVIEWPORTEXTEX,*PEMRSCALEVIEWPORTEXTEX,EMRSCALEWINDOWEXTEX,*PEMRSCALEWINDOWEXTEX; + + typedef struct tagEMRSETWORLDTRANSFORM { + EMR emr; + XFORM xform; + } EMRSETWORLDTRANSFORM,*PEMRSETWORLDTRANSFORM; + + typedef struct tagEMRMODIFYWORLDTRANSFORM { + EMR emr; + XFORM xform; + DWORD iMode; + } EMRMODIFYWORLDTRANSFORM,*PEMRMODIFYWORLDTRANSFORM; + + typedef struct tagEMRSETPIXELV { + EMR emr; + POINTL ptlPixel; + COLORREF crColor; + } EMRSETPIXELV,*PEMRSETPIXELV; + + typedef struct tagEMREXTFLOODFILL { + EMR emr; + POINTL ptlStart; + COLORREF crColor; + DWORD iMode; + } EMREXTFLOODFILL,*PEMREXTFLOODFILL; + + typedef struct tagEMRELLIPSE { + EMR emr; + RECTL rclBox; + } EMRELLIPSE,*PEMRELLIPSE,EMRRECTANGLE,*PEMRRECTANGLE; + + typedef struct tagEMRROUNDRECT { + EMR emr; + RECTL rclBox; + SIZEL szlCorner; + } EMRROUNDRECT,*PEMRROUNDRECT; + + typedef struct tagEMRARC { + EMR emr; + RECTL rclBox; + POINTL ptlStart; + POINTL ptlEnd; + } EMRARC,*PEMRARC,EMRARCTO,*PEMRARCTO,EMRCHORD,*PEMRCHORD,EMRPIE,*PEMRPIE; + + typedef struct tagEMRANGLEARC { + EMR emr; + POINTL ptlCenter; + DWORD nRadius; + FLOAT eStartAngle; + FLOAT eSweepAngle; + } EMRANGLEARC,*PEMRANGLEARC; + + typedef struct tagEMRPOLYLINE { + EMR emr; + RECTL rclBounds; + DWORD cptl; + POINTL aptl[1]; + } EMRPOLYLINE,*PEMRPOLYLINE,EMRPOLYBEZIER,*PEMRPOLYBEZIER,EMRPOLYGON,*PEMRPOLYGON,EMRPOLYBEZIERTO,*PEMRPOLYBEZIERTO,EMRPOLYLINETO,*PEMRPOLYLINETO; + + typedef struct tagEMRPOLYLINE16 { + EMR emr; + RECTL rclBounds; + DWORD cpts; + POINTS apts[1]; + } EMRPOLYLINE16,*PEMRPOLYLINE16,EMRPOLYBEZIER16,*PEMRPOLYBEZIER16,EMRPOLYGON16,*PEMRPOLYGON16,EMRPOLYBEZIERTO16,*PEMRPOLYBEZIERTO16,EMRPOLYLINETO16,*PEMRPOLYLINETO16; + + typedef struct tagEMRPOLYDRAW { + EMR emr; + RECTL rclBounds; + DWORD cptl; + POINTL aptl[1]; + BYTE abTypes[1]; + } EMRPOLYDRAW,*PEMRPOLYDRAW; + + typedef struct tagEMRPOLYDRAW16 { + EMR emr; + RECTL rclBounds; + DWORD cpts; + POINTS apts[1]; + BYTE abTypes[1]; + } EMRPOLYDRAW16,*PEMRPOLYDRAW16; + + typedef struct tagEMRPOLYPOLYLINE { + EMR emr; + RECTL rclBounds; + DWORD nPolys; + DWORD cptl; + DWORD aPolyCounts[1]; + POINTL aptl[1]; + } EMRPOLYPOLYLINE,*PEMRPOLYPOLYLINE,EMRPOLYPOLYGON,*PEMRPOLYPOLYGON; + + typedef struct tagEMRPOLYPOLYLINE16 { + EMR emr; + RECTL rclBounds; + DWORD nPolys; + DWORD cpts; + DWORD aPolyCounts[1]; + POINTS apts[1]; + } EMRPOLYPOLYLINE16,*PEMRPOLYPOLYLINE16,EMRPOLYPOLYGON16,*PEMRPOLYPOLYGON16; + + typedef struct tagEMRINVERTRGN { + EMR emr; + RECTL rclBounds; + DWORD cbRgnData; + BYTE RgnData[1]; + } EMRINVERTRGN,*PEMRINVERTRGN,EMRPAINTRGN,*PEMRPAINTRGN; + + typedef struct tagEMRFILLRGN { + EMR emr; + RECTL rclBounds; + DWORD cbRgnData; + DWORD ihBrush; + BYTE RgnData[1]; + } EMRFILLRGN,*PEMRFILLRGN; + + typedef struct tagEMRFRAMERGN { + EMR emr; + RECTL rclBounds; + DWORD cbRgnData; + DWORD ihBrush; + SIZEL szlStroke; + BYTE RgnData[1]; + } EMRFRAMERGN,*PEMRFRAMERGN; + + typedef struct tagEMREXTSELECTCLIPRGN { + EMR emr; + DWORD cbRgnData; + DWORD iMode; + BYTE RgnData[1]; + } EMREXTSELECTCLIPRGN,*PEMREXTSELECTCLIPRGN; + + typedef struct tagEMREXTTEXTOUTA { + EMR emr; + RECTL rclBounds; + DWORD iGraphicsMode; + FLOAT exScale; + FLOAT eyScale; + EMRTEXT emrtext; + } EMREXTTEXTOUTA,*PEMREXTTEXTOUTA,EMREXTTEXTOUTW,*PEMREXTTEXTOUTW; + + typedef struct tagEMRPOLYTEXTOUTA { + EMR emr; + RECTL rclBounds; + DWORD iGraphicsMode; + FLOAT exScale; + FLOAT eyScale; + LONG cStrings; + EMRTEXT aemrtext[1]; + } EMRPOLYTEXTOUTA,*PEMRPOLYTEXTOUTA,EMRPOLYTEXTOUTW,*PEMRPOLYTEXTOUTW; + + typedef struct tagEMRBITBLT { + EMR emr; + RECTL rclBounds; + LONG xDest; + LONG yDest; + LONG cxDest; + LONG cyDest; + DWORD dwRop; + LONG xSrc; + LONG ySrc; + XFORM xformSrc; + COLORREF crBkColorSrc; + DWORD iUsageSrc; + DWORD offBmiSrc; + DWORD cbBmiSrc; + DWORD offBitsSrc; + DWORD cbBitsSrc; + } EMRBITBLT,*PEMRBITBLT; + + typedef struct tagEMRSTRETCHBLT { + EMR emr; + RECTL rclBounds; + LONG xDest; + LONG yDest; + LONG cxDest; + LONG cyDest; + DWORD dwRop; + LONG xSrc; + LONG ySrc; + XFORM xformSrc; + COLORREF crBkColorSrc; + DWORD iUsageSrc; + DWORD offBmiSrc; + DWORD cbBmiSrc; + DWORD offBitsSrc; + DWORD cbBitsSrc; + LONG cxSrc; + LONG cySrc; + } EMRSTRETCHBLT,*PEMRSTRETCHBLT; + + typedef struct tagEMRMASKBLT { + EMR emr; + RECTL rclBounds; + LONG xDest; + LONG yDest; + LONG cxDest; + LONG cyDest; + DWORD dwRop; + LONG xSrc; + LONG ySrc; + XFORM xformSrc; + COLORREF crBkColorSrc; + DWORD iUsageSrc; + DWORD offBmiSrc; + DWORD cbBmiSrc; + DWORD offBitsSrc; + DWORD cbBitsSrc; + LONG xMask; + LONG yMask; + DWORD iUsageMask; + DWORD offBmiMask; + DWORD cbBmiMask; + DWORD offBitsMask; + DWORD cbBitsMask; + } EMRMASKBLT,*PEMRMASKBLT; + + typedef struct tagEMRPLGBLT { + EMR emr; + RECTL rclBounds; + POINTL aptlDest[3]; + LONG xSrc; + LONG ySrc; + LONG cxSrc; + LONG cySrc; + XFORM xformSrc; + COLORREF crBkColorSrc; + DWORD iUsageSrc; + DWORD offBmiSrc; + DWORD cbBmiSrc; + DWORD offBitsSrc; + DWORD cbBitsSrc; + LONG xMask; + LONG yMask; + DWORD iUsageMask; + DWORD offBmiMask; + DWORD cbBmiMask; + DWORD offBitsMask; + DWORD cbBitsMask; + } EMRPLGBLT,*PEMRPLGBLT; + + typedef struct tagEMRSETDIBITSTODEVICE { + EMR emr; + RECTL rclBounds; + LONG xDest; + LONG yDest; + LONG xSrc; + LONG ySrc; + LONG cxSrc; + LONG cySrc; + DWORD offBmiSrc; + DWORD cbBmiSrc; + DWORD offBitsSrc; + DWORD cbBitsSrc; + DWORD iUsageSrc; + DWORD iStartScan; + DWORD cScans; + } EMRSETDIBITSTODEVICE,*PEMRSETDIBITSTODEVICE; + + typedef struct tagEMRSTRETCHDIBITS { + EMR emr; + RECTL rclBounds; + LONG xDest; + LONG yDest; + LONG xSrc; + LONG ySrc; + LONG cxSrc; + LONG cySrc; + DWORD offBmiSrc; + DWORD cbBmiSrc; + DWORD offBitsSrc; + DWORD cbBitsSrc; + DWORD iUsageSrc; + DWORD dwRop; + LONG cxDest; + LONG cyDest; + } EMRSTRETCHDIBITS,*PEMRSTRETCHDIBITS; + + typedef struct tagEMREXTCREATEFONTINDIRECTW { + EMR emr; + DWORD ihFont; + EXTLOGFONTW elfw; + } EMREXTCREATEFONTINDIRECTW,*PEMREXTCREATEFONTINDIRECTW; + + typedef struct tagEMRCREATEPALETTE { + EMR emr; + DWORD ihPal; + LOGPALETTE lgpl; + } EMRCREATEPALETTE,*PEMRCREATEPALETTE; + + typedef struct tagEMRCREATEPEN { + EMR emr; + DWORD ihPen; + LOGPEN lopn; + } EMRCREATEPEN,*PEMRCREATEPEN; + + typedef struct tagEMREXTCREATEPEN { + EMR emr; + DWORD ihPen; + DWORD offBmi; + DWORD cbBmi; + DWORD offBits; + DWORD cbBits; + EXTLOGPEN elp; + } EMREXTCREATEPEN,*PEMREXTCREATEPEN; + + typedef struct tagEMRCREATEBRUSHINDIRECT { + EMR emr; + DWORD ihBrush; + LOGBRUSH32 lb; + } EMRCREATEBRUSHINDIRECT,*PEMRCREATEBRUSHINDIRECT; + + typedef struct tagEMRCREATEMONOBRUSH { + EMR emr; + DWORD ihBrush; + DWORD iUsage; + DWORD offBmi; + DWORD cbBmi; + DWORD offBits; + DWORD cbBits; + } EMRCREATEMONOBRUSH,*PEMRCREATEMONOBRUSH; + + typedef struct tagEMRCREATEDIBPATTERNBRUSHPT { + EMR emr; + DWORD ihBrush; + DWORD iUsage; + DWORD offBmi; + DWORD cbBmi; + DWORD offBits; + DWORD cbBits; + } EMRCREATEDIBPATTERNBRUSHPT,*PEMRCREATEDIBPATTERNBRUSHPT; + + typedef struct tagEMRFORMAT { + DWORD dSignature; + DWORD nVersion; + DWORD cbData; + DWORD offData; + } EMRFORMAT,*PEMRFORMAT; + + typedef struct tagEMRGLSRECORD { + EMR emr; + DWORD cbData; + BYTE Data[1]; + } EMRGLSRECORD,*PEMRGLSRECORD; + + typedef struct tagEMRGLSBOUNDEDRECORD { + EMR emr; + RECTL rclBounds; + DWORD cbData; + BYTE Data[1]; + } EMRGLSBOUNDEDRECORD,*PEMRGLSBOUNDEDRECORD; + + typedef struct tagEMRPIXELFORMAT { + EMR emr; + PIXELFORMATDESCRIPTOR pfd; + } EMRPIXELFORMAT,*PEMRPIXELFORMAT; + + typedef struct tagEMRCREATECOLORSPACE { + EMR emr; + DWORD ihCS; + LOGCOLORSPACEA lcs; + } EMRCREATECOLORSPACE,*PEMRCREATECOLORSPACE; + + typedef struct tagEMRSETCOLORSPACE { + EMR emr; + DWORD ihCS; + } EMRSETCOLORSPACE,*PEMRSETCOLORSPACE,EMRSELECTCOLORSPACE,*PEMRSELECTCOLORSPACE,EMRDELETECOLORSPACE,*PEMRDELETECOLORSPACE; + + typedef struct tagEMREXTESCAPE { + EMR emr; + INT iEscape; + INT cbEscData; + BYTE EscData[1]; + } EMREXTESCAPE,*PEMREXTESCAPE,EMRDRAWESCAPE,*PEMRDRAWESCAPE; + + typedef struct tagEMRNAMEDESCAPE { + EMR emr; + INT iEscape; + INT cbDriver; + INT cbEscData; + BYTE EscData[1]; + } EMRNAMEDESCAPE,*PEMRNAMEDESCAPE; + +#define SETICMPROFILE_EMBEDED 0x00000001 + + typedef struct tagEMRSETICMPROFILE { + EMR emr; + DWORD dwFlags; + DWORD cbName; + DWORD cbData; + BYTE Data[1]; + } EMRSETICMPROFILE,*PEMRSETICMPROFILE,EMRSETICMPROFILEA,*PEMRSETICMPROFILEA,EMRSETICMPROFILEW,*PEMRSETICMPROFILEW; + +#define CREATECOLORSPACE_EMBEDED 0x00000001 + + typedef struct tagEMRCREATECOLORSPACEW { + EMR emr; + DWORD ihCS; + LOGCOLORSPACEW lcs; + DWORD dwFlags; + DWORD cbData; + BYTE Data[1]; + } EMRCREATECOLORSPACEW,*PEMRCREATECOLORSPACEW; + +#define COLORMATCHTOTARGET_EMBEDED 0x00000001 + + typedef struct tagCOLORMATCHTOTARGET { + EMR emr; + DWORD dwAction; + DWORD dwFlags; + DWORD cbName; + DWORD cbData; + BYTE Data[1]; + } EMRCOLORMATCHTOTARGET,*PEMRCOLORMATCHTOTARGET; + + typedef struct tagCOLORCORRECTPALETTE { + EMR emr; + DWORD ihPalette; + DWORD nFirstEntry; + DWORD nPalEntries; + DWORD nReserved; + } EMRCOLORCORRECTPALETTE,*PEMRCOLORCORRECTPALETTE; + + typedef struct tagEMRALPHABLEND { + EMR emr; + RECTL rclBounds; + LONG xDest; + LONG yDest; + LONG cxDest; + LONG cyDest; + DWORD dwRop; + LONG xSrc; + LONG ySrc; + XFORM xformSrc; + COLORREF crBkColorSrc; + DWORD iUsageSrc; + DWORD offBmiSrc; + DWORD cbBmiSrc; + DWORD offBitsSrc; + DWORD cbBitsSrc; + LONG cxSrc; + LONG cySrc; + } EMRALPHABLEND,*PEMRALPHABLEND; + + typedef struct tagEMRGRADIENTFILL { + EMR emr; + RECTL rclBounds; + DWORD nVer; + DWORD nTri; + ULONG ulMode; + TRIVERTEX Ver[1]; + } EMRGRADIENTFILL,*PEMRGRADIENTFILL; + + typedef struct tagEMRTRANSPARENTBLT { + EMR emr; + RECTL rclBounds; + LONG xDest; + LONG yDest; + LONG cxDest; + LONG cyDest; + DWORD dwRop; + LONG xSrc; + LONG ySrc; + XFORM xformSrc; + COLORREF crBkColorSrc; + DWORD iUsageSrc; + DWORD offBmiSrc; + DWORD cbBmiSrc; + DWORD offBitsSrc; + DWORD cbBitsSrc; + LONG cxSrc; + LONG cySrc; + } EMRTRANSPARENTBLT,*PEMRTRANSPARENTBLT; + +#define GDICOMMENT_IDENTIFIER 0x43494447 +#define GDICOMMENT_WINDOWS_METAFILE 0x80000001 +#define GDICOMMENT_BEGINGROUP 0x00000002 +#define GDICOMMENT_ENDGROUP 0x00000003 +#define GDICOMMENT_MULTIFORMATS 0x40000004 +#define EPS_SIGNATURE 0x46535045 +#define GDICOMMENT_UNICODE_STRING 0x00000040 +#define GDICOMMENT_UNICODE_END 0x00000080 +#endif + +#ifdef UNICODE +#define wglUseFontBitmaps wglUseFontBitmapsW +#else #define wglUseFontBitmaps wglUseFontBitmapsA +#endif + + WINGDIAPI WINBOOL WINAPI wglCopyContext(HGLRC,HGLRC,UINT); + WINGDIAPI HGLRC WINAPI wglCreateContext(HDC); + WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC,int); + WINGDIAPI WINBOOL WINAPI wglDeleteContext(HGLRC); + WINGDIAPI HGLRC WINAPI wglGetCurrentContext(VOID); + WINGDIAPI HDC WINAPI wglGetCurrentDC(VOID); + WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR); + WINGDIAPI WINBOOL WINAPI wglMakeCurrent(HDC,HGLRC); + WINGDIAPI WINBOOL WINAPI wglShareLists(HGLRC,HGLRC); + WINGDIAPI WINBOOL WINAPI wglUseFontBitmapsA(HDC,DWORD,DWORD,DWORD); + WINGDIAPI WINBOOL WINAPI wglUseFontBitmapsW(HDC,DWORD,DWORD,DWORD); + WINGDIAPI WINBOOL WINAPI SwapBuffers(HDC); + + typedef struct _POINTFLOAT { + FLOAT x; + FLOAT y; + } POINTFLOAT,*PPOINTFLOAT; + + typedef struct _GLYPHMETRICSFLOAT { + FLOAT gmfBlackBoxX; + FLOAT gmfBlackBoxY; + POINTFLOAT gmfptGlyphOrigin; + FLOAT gmfCellIncX; + FLOAT gmfCellIncY; + } GLYPHMETRICSFLOAT,*PGLYPHMETRICSFLOAT,*LPGLYPHMETRICSFLOAT; + +#define WGL_FONT_LINES 0 +#define WGL_FONT_POLYGONS 1 + +#ifdef UNICODE +#define wglUseFontOutlines wglUseFontOutlinesW +#else #define wglUseFontOutlines wglUseFontOutlinesA #endif + + WINGDIAPI WINBOOL WINAPI wglUseFontOutlinesA(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT); + WINGDIAPI WINBOOL WINAPI wglUseFontOutlinesW(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT); + + typedef struct tagLAYERPLANEDESCRIPTOR { + WORD nSize; + WORD nVersion; + DWORD dwFlags; + BYTE iPixelType; + BYTE cColorBits; + BYTE cRedBits; + BYTE cRedShift; + BYTE cGreenBits; + BYTE cGreenShift; + BYTE cBlueBits; + BYTE cBlueShift; + BYTE cAlphaBits; + BYTE cAlphaShift; + BYTE cAccumBits; + BYTE cAccumRedBits; + BYTE cAccumGreenBits; + BYTE cAccumBlueBits; + BYTE cAccumAlphaBits; + BYTE cDepthBits; + BYTE cStencilBits; + BYTE cAuxBuffers; + BYTE iLayerPlane; + BYTE bReserved; + COLORREF crTransparent; + } LAYERPLANEDESCRIPTOR,*PLAYERPLANEDESCRIPTOR,*LPLAYERPLANEDESCRIPTOR; + +#define LPD_DOUBLEBUFFER 0x00000001 +#define LPD_STEREO 0x00000002 +#define LPD_SUPPORT_GDI 0x00000010 +#define LPD_SUPPORT_OPENGL 0x00000020 +#define LPD_SHARE_DEPTH 0x00000040 +#define LPD_SHARE_STENCIL 0x00000080 +#define LPD_SHARE_ACCUM 0x00000100 +#define LPD_SWAP_EXCHANGE 0x00000200 +#define LPD_SWAP_COPY 0x00000400 +#define LPD_TRANSPARENT 0x00001000 + +#define LPD_TYPE_RGBA 0 +#define LPD_TYPE_COLORINDEX 1 + +#define WGL_SWAP_MAIN_PLANE 0x00000001 +#define WGL_SWAP_OVERLAY1 0x00000002 +#define WGL_SWAP_OVERLAY2 0x00000004 +#define WGL_SWAP_OVERLAY3 0x00000008 +#define WGL_SWAP_OVERLAY4 0x00000010 +#define WGL_SWAP_OVERLAY5 0x00000020 +#define WGL_SWAP_OVERLAY6 0x00000040 +#define WGL_SWAP_OVERLAY7 0x00000080 +#define WGL_SWAP_OVERLAY8 0x00000100 +#define WGL_SWAP_OVERLAY9 0x00000200 +#define WGL_SWAP_OVERLAY10 0x00000400 +#define WGL_SWAP_OVERLAY11 0x00000800 +#define WGL_SWAP_OVERLAY12 0x00001000 +#define WGL_SWAP_OVERLAY13 0x00002000 +#define WGL_SWAP_OVERLAY14 0x00004000 +#define WGL_SWAP_OVERLAY15 0x00008000 +#define WGL_SWAP_UNDERLAY1 0x00010000 +#define WGL_SWAP_UNDERLAY2 0x00020000 +#define WGL_SWAP_UNDERLAY3 0x00040000 +#define WGL_SWAP_UNDERLAY4 0x00080000 +#define WGL_SWAP_UNDERLAY5 0x00100000 +#define WGL_SWAP_UNDERLAY6 0x00200000 +#define WGL_SWAP_UNDERLAY7 0x00400000 +#define WGL_SWAP_UNDERLAY8 0x00800000 +#define WGL_SWAP_UNDERLAY9 0x01000000 +#define WGL_SWAP_UNDERLAY10 0x02000000 +#define WGL_SWAP_UNDERLAY11 0x04000000 +#define WGL_SWAP_UNDERLAY12 0x08000000 +#define WGL_SWAP_UNDERLAY13 0x10000000 +#define WGL_SWAP_UNDERLAY14 0x20000000 +#define WGL_SWAP_UNDERLAY15 0x40000000 + + WINGDIAPI WINBOOL WINAPI wglDescribeLayerPlane(HDC,int,int,UINT,LPLAYERPLANEDESCRIPTOR); + WINGDIAPI int WINAPI wglSetLayerPaletteEntries(HDC,int,int,int,CONST COLORREF *); + WINGDIAPI int WINAPI wglGetLayerPaletteEntries(HDC,int,int,int,COLORREF *); + WINGDIAPI WINBOOL WINAPI wglRealizeLayerPalette(HDC,int,WINBOOL); + WINGDIAPI WINBOOL WINAPI wglSwapLayerBuffers(HDC,UINT); + + typedef struct _WGLSWAP { + HDC hdc; + UINT uiFlags; + } WGLSWAP,*PWGLSWAP,*LPWGLSWAP; + +#define WGL_SWAPMULTIPLE_MAX 16 + + WINGDIAPI DWORD WINAPI wglSwapMultipleBuffers(UINT,CONST WGLSWAP *); #endif + #ifdef __cplusplus } #endif diff --git a/tinyc/win32/include/winapi/winnetwk.h b/tinyc/win32/include/winapi/winnetwk.h deleted file mode 100644 index 662fba9f8..000000000 --- a/tinyc/win32/include/winapi/winnetwk.h +++ /dev/null @@ -1,346 +0,0 @@ -#ifndef _WINNETWK_H -#define _WINNETWK_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif -#define WNNC_NET_MSNET 0x00010000 -#define WNNC_NET_LANMAN 0x00020000 -#define WNNC_NET_NETWARE 0x00030000 -#define WNNC_NET_VINES 0x00040000 -#define WNNC_NET_10NET 0x00050000 -#define WNNC_NET_LOCUS 0x00060000 -#define WNNC_NET_SUN_PC_NFS 0x00070000 -#define WNNC_NET_LANSTEP 0x00080000 -#define WNNC_NET_9TILES 0x00090000 -#define WNNC_NET_LANTASTIC 0x000A0000 -#define WNNC_NET_AS400 0x000B0000 -#define WNNC_NET_FTP_NFS 0x000C0000 -#define WNNC_NET_PATHWORKS 0x000D0000 -#define WNNC_NET_LIFENET 0x000E0000 -#define WNNC_NET_POWERLAN 0x000F0000 -#define WNNC_NET_BWNFS 0x00100000 -#define WNNC_NET_COGENT 0x00110000 -#define WNNC_NET_FARALLON 0x00120000 -#define WNNC_NET_APPLETALK 0x00130000 -#define WNNC_NET_INTERGRAPH 0x00140000 -#define WNNC_NET_SYMFONET 0x00150000 -#define WNNC_NET_CLEARCASE 0x00160000 -#define WNNC_NET_FRONTIER 0x00170000 -#define WNNC_NET_BMC 0x00180000 -#define WNNC_NET_DCE 0x00190000 -#define WNNC_NET_AVID 0x001A0000 -#define WNNC_NET_DOCUSPACE 0x001B0000 -#define WNNC_NET_MANGOSOFT 0x001C0000 -#define WNNC_NET_SERNET 0x001D0000 -#define WNNC_NET_DECORB 0x00200000 -#define WNNC_NET_PROTSTOR 0x00210000 -#define WNNC_NET_FJ_REDIR 0x00220000 -#define WNNC_NET_DISTINCT 0x00230000 -#define WNNC_NET_TWINS 0x00240000 -#define WNNC_NET_RDR2SAMPLE 0x00250000 -#define WNNC_NET_CSC 0x00260000 -#define WNNC_NET_3IN1 0x00270000 -#define WNNC_NET_EXTENDNET 0x00290000 -#define WNNC_NET_OBJECT_DIRE 0x00300000 -#define WNNC_NET_MASFAX 0x00310000 -#define WNNC_NET_HOB_NFS 0x00320000 -#define WNNC_NET_SHIVA 0x00330000 -#define WNNC_NET_IBMAL 0x00340000 -#define WNNC_CRED_MANAGER 0xFFFF0000 - -#define RESOURCE_CONNECTED 1 -#define RESOURCE_GLOBALNET 2 -#define RESOURCE_REMEMBERED 3 -#define RESOURCE_RECENT 4 -#define RESOURCE_CONTEXT 5 -#define RESOURCETYPE_ANY 0 -#define RESOURCETYPE_DISK 1 -#define RESOURCETYPE_PRINT 2 -#define RESOURCETYPE_RESERVED 8 -#define RESOURCETYPE_UNKNOWN 0xFFFFFFFF -#define RESOURCEUSAGE_CONNECTABLE 0x00000001 -#define RESOURCEUSAGE_CONTAINER 0x00000002 -#define RESOURCEUSAGE_NOLOCALDEVICE 0x00000004 -#define RESOURCEUSAGE_SIBLING 0x00000008 -#define RESOURCEUSAGE_ATTACHED 0x00000010 -#define RESOURCEUSAGE_ALL (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED) -#define RESOURCEUSAGE_RESERVED 0x80000000 -#define RESOURCEDISPLAYTYPE_GENERIC 0 -#define RESOURCEDISPLAYTYPE_DOMAIN 1 -#define RESOURCEDISPLAYTYPE_SERVER 2 -#define RESOURCEDISPLAYTYPE_SHARE 3 -#define RESOURCEDISPLAYTYPE_FILE 4 -#define RESOURCEDISPLAYTYPE_GROUP 5 -#define RESOURCEDISPLAYTYPE_NETWORK 6 -#define RESOURCEDISPLAYTYPE_ROOT 7 -#define RESOURCEDISPLAYTYPE_SHAREADMIN 8 -#define RESOURCEDISPLAYTYPE_DIRECTORY 9 -#define RESOURCEDISPLAYTYPE_TREE 10 -#define NETPROPERTY_PERSISTENT 1 -#define CONNECT_UPDATE_PROFILE 1 -#define CONNECT_UPDATE_RECENT 2 -#define CONNECT_TEMPORARY 4 -#define CONNECT_INTERACTIVE 8 -#define CONNECT_PROMPT 16 -#define CONNECT_NEED_DRIVE 32 -#define CONNECT_REFCOUNT 64 -#define CONNECT_REDIRECT 128 -#define CONNECT_LOCALDRIVE 256 -#define CONNECT_CURRENT_MEDIA 512 -#define CONNDLG_RO_PATH 1 -#define CONNDLG_CONN_POINT 2 -#define CONNDLG_USE_MRU 4 -#define CONNDLG_HIDE_BOX 8 -#define CONNDLG_PERSIST 16 -#define CONNDLG_NOT_PERSIST 32 -#define DISC_UPDATE_PROFILE 1 -#define DISC_NO_FORCE 64 -#define WNFMT_MULTILINE 1 -#define WNFMT_ABBREVIATED 2 -#define WNFMT_INENUM 16 -#define WNFMT_CONNECTION 32 -#define WN_SUCCESS NO_ERROR -#define WN_NO_ERROR NO_ERROR -#define WN_NOT_SUPPORTED ERROR_NOT_SUPPORTED -#define WN_CANCEL ERROR_CANCELLED -#define WN_RETRY ERROR_RETRY -#define WN_NET_ERROR ERROR_UNEXP_NET_ERR -#define WN_MORE_DATA ERROR_MORE_DATA -#define WN_BAD_POINTER ERROR_INVALID_ADDRESS -#define WN_BAD_VALUE ERROR_INVALID_PARAMETER -#define WN_BAD_USER ERROR_BAD_USERNAME -#define WN_BAD_PASSWORD ERROR_INVALID_PASSWORD -#define WN_ACCESS_DENIED ERROR_ACCESS_DENIED -#define WN_FUNCTION_BUSY ERROR_BUSY -#define WN_WINDOWS_ERROR ERROR_UNEXP_NET_ERR -#define WN_OUT_OF_MEMORY ERROR_NOT_ENOUGH_MEMORY -#define WN_NO_NETWORK ERROR_NO_NETWORK -#define WN_EXTENDED_ERROR ERROR_EXTENDED_ERROR -#define WN_BAD_LEVEL ERROR_INVALID_LEVEL -#define WN_BAD_HANDLE ERROR_INVALID_HANDLE -#define WN_NOT_INITIALIZING ERROR_ALREADY_INITIALIZED -#define WN_NO_MORE_DEVICES ERROR_NO_MORE_DEVICES -#define WN_NOT_CONNECTED ERROR_NOT_CONNECTED -#define WN_OPEN_FILES ERROR_OPEN_FILES -#define WN_DEVICE_IN_USE ERROR_DEVICE_IN_USE -#define WN_BAD_NETNAME ERROR_BAD_NET_NAME -#define WN_BAD_LOCALNAME ERROR_BAD_DEVICE -#define WN_ALREADY_CONNECTED ERROR_ALREADY_ASSIGNED -#define WN_DEVICE_ERROR ERROR_GEN_FAILURE -#define WN_CONNECTION_CLOSED ERROR_CONNECTION_UNAVAIL -#define WN_NO_NET_OR_BAD_PATH ERROR_NO_NET_OR_BAD_PATH -#define WN_BAD_PROVIDER ERROR_BAD_PROVIDER -#define WN_CANNOT_OPEN_PROFILE ERROR_CANNOT_OPEN_PROFILE -#define WN_BAD_PROFILE ERROR_BAD_PROFILE -#define WN_BAD_DEV_TYPE ERROR_BAD_DEV_TYPE -#define WN_DEVICE_ALREADY_REMEMBERED ERROR_DEVICE_ALREADY_REMEMBERED -#define WN_NO_MORE_ENTRIES ERROR_NO_MORE_ITEMS -#define WN_NOT_CONTAINER ERROR_NOT_CONTAINER -#define WN_NOT_AUTHENTICATED ERROR_NOT_AUTHENTICATED -#define WN_NOT_LOGGED_ON ERROR_NOT_LOGGED_ON -#define WN_NOT_VALIDATED ERROR_NO_LOGON_SERVERS -#define UNIVERSAL_NAME_INFO_LEVEL 1 -#define REMOTE_NAME_INFO_LEVEL 2 -#define NETINFO_DLL16 1 -#define NETINFO_DISKRED 4 -#define NETINFO_PRINTERRED 8 -#define RP_LOGON 1 -#define RP_INIFILE 2 -#define PP_DISPLAYERRORS 1 -#define WNCON_FORNETCARD 1 -#define WNCON_NOTROUTED 2 -#define WNCON_SLOWLINK 4 -#define WNCON_DYNAMIC 8 - -#ifndef RC_INVOKED -typedef struct _NETRESOURCEA { - DWORD dwScope; - DWORD dwType; - DWORD dwDisplayType; - DWORD dwUsage; - LPSTR lpLocalName; - LPSTR lpRemoteName; - LPSTR lpComment ; - LPSTR lpProvider; -}NETRESOURCEA,*LPNETRESOURCEA; -typedef struct _NETRESOURCEW { - DWORD dwScope; - DWORD dwType; - DWORD dwDisplayType; - DWORD dwUsage; - LPWSTR lpLocalName; - LPWSTR lpRemoteName; - LPWSTR lpComment ; - LPWSTR lpProvider; -}NETRESOURCEW,*LPNETRESOURCEW; -typedef struct _CONNECTDLGSTRUCTA{ - DWORD cbStructure; - HWND hwndOwner; - LPNETRESOURCEA lpConnRes; - DWORD dwFlags; - DWORD dwDevNum; -} CONNECTDLGSTRUCTA,*LPCONNECTDLGSTRUCTA; -typedef struct _CONNECTDLGSTRUCTW{ - DWORD cbStructure; - HWND hwndOwner; - LPNETRESOURCEW lpConnRes; - DWORD dwFlags; - DWORD dwDevNum; -} CONNECTDLGSTRUCTW,*LPCONNECTDLGSTRUCTW; -typedef struct _DISCDLGSTRUCTA{ - DWORD cbStructure; - HWND hwndOwner; - LPSTR lpLocalName; - LPSTR lpRemoteName; - DWORD dwFlags; -} DISCDLGSTRUCTA,*LPDISCDLGSTRUCTA; -typedef struct _DISCDLGSTRUCTW{ - DWORD cbStructure; - HWND hwndOwner; - LPWSTR lpLocalName; - LPWSTR lpRemoteName; - DWORD dwFlags; -} DISCDLGSTRUCTW,*LPDISCDLGSTRUCTW; -typedef struct _UNIVERSAL_NAME_INFOA { LPSTR lpUniversalName; }UNIVERSAL_NAME_INFOA,*LPUNIVERSAL_NAME_INFOA; -typedef struct _UNIVERSAL_NAME_INFOW { LPWSTR lpUniversalName; }UNIVERSAL_NAME_INFOW,*LPUNIVERSAL_NAME_INFOW; -typedef struct _REMOTE_NAME_INFOA { - LPSTR lpUniversalName; - LPSTR lpConnectionName; - LPSTR lpRemainingPath; -}REMOTE_NAME_INFOA,*LPREMOTE_NAME_INFOA; -typedef struct _REMOTE_NAME_INFOW { - LPWSTR lpUniversalName; - LPWSTR lpConnectionName; - LPWSTR lpRemainingPath; -}REMOTE_NAME_INFOW,*LPREMOTE_NAME_INFOW; -typedef struct _NETINFOSTRUCT{ - DWORD cbStructure; - DWORD dwProviderVersion; - DWORD dwStatus; - DWORD dwCharacteristics; - DWORD dwHandle; - WORD wNetType; - DWORD dwPrinters; - DWORD dwDrives; -} NETINFOSTRUCT,*LPNETINFOSTRUCT; -typedef UINT(PASCAL *PFNGETPROFILEPATHA)(LPCSTR,LPSTR,UINT); -typedef UINT(PASCAL *PFNGETPROFILEPATHW)(LPCWSTR,LPWSTR,UINT); -typedef UINT(PASCAL *PFNRECONCILEPROFILEA)(LPCSTR,LPCSTR,DWORD); -typedef UINT(PASCAL *PFNRECONCILEPROFILEW)(LPCWSTR,LPCWSTR,DWORD); -typedef BOOL(PASCAL *PFNPROCESSPOLICIESA)(HWND,LPCSTR,LPCSTR,LPCSTR,DWORD); -typedef BOOL(PASCAL *PFNPROCESSPOLICIESW)(HWND,LPCWSTR,LPCWSTR,LPCWSTR,DWORD); -typedef struct _NETCONNECTINFOSTRUCT{ - DWORD cbStructure; - DWORD dwFlags; - DWORD dwSpeed; - DWORD dwDelay; - DWORD dwOptDataSize; -} NETCONNECTINFOSTRUCT,*LPNETCONNECTINFOSTRUCT; - -DWORD APIENTRY WNetAddConnectionA(LPCSTR,LPCSTR,LPCSTR); -DWORD APIENTRY WNetAddConnectionW(LPCWSTR,LPCWSTR,LPCWSTR); -DWORD APIENTRY WNetAddConnection2A(LPNETRESOURCEA,LPCSTR,LPCSTR,DWORD); -DWORD APIENTRY WNetAddConnection2W(LPNETRESOURCEW,LPCWSTR,LPCWSTR,DWORD); -DWORD APIENTRY WNetAddConnection3A(HWND,LPNETRESOURCEA,LPCSTR,LPCSTR,DWORD); -DWORD APIENTRY WNetAddConnection3W(HWND,LPNETRESOURCEW,LPCWSTR,LPCWSTR,DWORD); -DWORD APIENTRY WNetCancelConnectionA(LPCSTR,BOOL); -DWORD APIENTRY WNetCancelConnectionW(LPCWSTR,BOOL); -DWORD APIENTRY WNetCancelConnection2A(LPCSTR,DWORD,BOOL); -DWORD APIENTRY WNetCancelConnection2W(LPCWSTR,DWORD,BOOL); -DWORD APIENTRY WNetGetConnectionA(LPCSTR,LPSTR,PDWORD); -DWORD APIENTRY WNetGetConnectionW(LPCWSTR,LPWSTR,PDWORD); -DWORD APIENTRY WNetUseConnectionA(HWND,LPNETRESOURCEA,LPCSTR,LPCSTR,DWORD,LPSTR,PDWORD,PDWORD); -DWORD APIENTRY WNetUseConnectionW(HWND,LPNETRESOURCEW,LPCWSTR,LPCWSTR,DWORD,LPWSTR,PDWORD,PDWORD); -DWORD APIENTRY WNetSetConnectionA(LPCSTR,DWORD,PVOID); -DWORD APIENTRY WNetSetConnectionW(LPCWSTR,DWORD,PVOID); -DWORD APIENTRY WNetConnectionDialog(HWND,DWORD); -DWORD APIENTRY WNetDisconnectDialog(HWND,DWORD); -DWORD APIENTRY WNetConnectionDialog1A(LPCONNECTDLGSTRUCTA); -DWORD APIENTRY WNetConnectionDialog1W(LPCONNECTDLGSTRUCTW); -DWORD APIENTRY WNetDisconnectDialog1A(LPDISCDLGSTRUCTA); -DWORD APIENTRY WNetDisconnectDialog1W(LPDISCDLGSTRUCTW); -DWORD APIENTRY WNetOpenEnumA(DWORD,DWORD,DWORD,LPNETRESOURCEA,LPHANDLE); -DWORD APIENTRY WNetOpenEnumW(DWORD,DWORD,DWORD,LPNETRESOURCEW,LPHANDLE); -DWORD APIENTRY WNetEnumResourceA(HANDLE,PDWORD,PVOID,PDWORD); -DWORD APIENTRY WNetEnumResourceW(HANDLE,PDWORD,PVOID,PDWORD); -DWORD APIENTRY WNetCloseEnum(HANDLE); -DWORD APIENTRY WNetGetUniversalNameA(LPCSTR,DWORD,PVOID,PDWORD); -DWORD APIENTRY WNetGetUniversalNameW(LPCWSTR,DWORD,PVOID,PDWORD); -DWORD APIENTRY WNetGetUserA(LPCSTR,LPSTR,PDWORD); -DWORD APIENTRY WNetGetUserW(LPCWSTR,LPWSTR,PDWORD); -DWORD APIENTRY WNetGetProviderNameA(DWORD,LPSTR,PDWORD); -DWORD APIENTRY WNetGetProviderNameW(DWORD,LPWSTR,PDWORD); -DWORD APIENTRY WNetGetNetworkInformationA(LPCSTR,LPNETINFOSTRUCT); -DWORD APIENTRY WNetGetNetworkInformationW(LPCWSTR,LPNETINFOSTRUCT); -DWORD APIENTRY WNetGetResourceInformationA(LPNETRESOURCEA,LPVOID,LPDWORD,LPCSTR*); -DWORD APIENTRY WNetGetResourceInformationW(LPNETRESOURCEA,LPVOID,LPDWORD,LPCWSTR*); -DWORD APIENTRY WNetGetLastErrorA(PDWORD,LPSTR,DWORD,LPSTR,DWORD); -DWORD APIENTRY WNetGetLastErrorW(PDWORD,LPWSTR,DWORD,LPWSTR,DWORD); -DWORD APIENTRY MultinetGetConnectionPerformanceA(LPNETRESOURCEA,LPNETCONNECTINFOSTRUCT); -DWORD APIENTRY MultinetGetConnectionPerformanceW(LPNETRESOURCEW,LPNETCONNECTINFOSTRUCT); -#ifdef UNICODE -#define PFNPROCESSPOLICIES PFNPROCESSPOLICIESW -#define PFNRECONCILEPROFILE PFNRECONCILEPROFILEW -#define PFNGETPROFILEPATH PFNGETPROFILEPATHW -typedef NETRESOURCEW NETRESOURCE,*LPNETRESOURCE; -typedef CONNECTDLGSTRUCTW CONNECTDLGSTRUCT,*LPCONNECTDLGSTRUCT; -typedef DISCDLGSTRUCTW DISCDLGSTRUCT,*LPDISCDLGSTRUCT; -typedef REMOTE_NAME_INFOW REMOTE_NAME_INFO,*LPREMOTE_NAME_INFO; -typedef UNIVERSAL_NAME_INFOW UNIVERSAL_NAME_INFO,*LPUNIVERSAL_NAME_INFO; -#define WNetEnumResource WNetEnumResourceW -#define WNetOpenEnum WNetOpenEnumW -#define WNetGetResourceInformation WNetGetResourceInformationW -#define WNetGetUniversalName WNetGetUniversalNameW -#define WNetSetConnection WNetSetConnectionW -#define WNetUseConnection WNetUseConnectionW -#define WNetGetConnection WNetGetConnectionW -#define WNetCancelConnection2 WNetCancelConnection2W -#define WNetCancelConnection WNetCancelConnectionW -#define WNetAddConnection3 WNetAddConnection3W -#define WNetAddConnection2 WNetAddConnection2W -#define WNetAddConnection WNetAddConnectionW -#define WNetConnectionDialog1 WNetConnectionDialog1W -#define WNetDisconnectDialog1 WNetDisconnectDialog1W -#define WNetGetNetworkInformation WNetGetNetworkInformationW -#define WNetGetProviderName WNetGetProviderNameW -#define WNetGetUser WNetGetUserW -#define MultinetGetConnectionPerformance MultinetGetConnectionPerformanceW -#define WNetGetLastError WNetGetLastErrorW -#else -#define PFNGETPROFILEPATH PFNGETPROFILEPATHA -#define PFNRECONCILEPROFILE PFNRECONCILEPROFILEA -#define PFNPROCESSPOLICIES PFNPROCESSPOLICIESA -typedef NETRESOURCEA NETRESOURCE,*LPNETRESOURCE; -typedef CONNECTDLGSTRUCTA CONNECTDLGSTRUCT,*LPCONNECTDLGSTRUCT; -typedef DISCDLGSTRUCTA DISCDLGSTRUCT,*LPDISCDLGSTRUCT; -typedef UNIVERSAL_NAME_INFOA UNIVERSAL_NAME_INFO,*LPUNIVERSAL_NAME_INFO; -typedef REMOTE_NAME_INFOA REMOTE_NAME_INFO,*LPREMOTE_NAME_INFO; -#define WNetOpenEnum WNetOpenEnumA -#define WNetEnumResource WNetEnumResourceA -#define WNetGetResourceInformation WNetGetResourceInformationA -#define WNetGetUniversalName WNetGetUniversalNameA -#define WNetConnectionDialog1 WNetConnectionDialog1A -#define WNetDisconnectDialog1 WNetDisconnectDialog1A -#define WNetAddConnection2 WNetAddConnection2A -#define WNetAddConnection3 WNetAddConnection3A -#define WNetCancelConnection WNetCancelConnectionA -#define WNetCancelConnection2 WNetCancelConnection2A -#define WNetGetConnection WNetGetConnectionA -#define WNetUseConnection WNetUseConnectionA -#define WNetSetConnection WNetSetConnectionA -#define WNetAddConnection WNetAddConnectionA -#define WNetGetUser WNetGetUserA -#define WNetGetProviderName WNetGetProviderNameA -#define WNetGetNetworkInformation WNetGetNetworkInformationA -#define WNetGetLastError WNetGetLastErrorA -#define MultinetGetConnectionPerformance MultinetGetConnectionPerformanceA -#endif -#endif -#ifdef __cplusplus -} -#endif -#endif diff --git a/tinyc/win32/include/winapi/winnls.h b/tinyc/win32/include/winapi/winnls.h deleted file mode 100644 index 3933812b7..000000000 --- a/tinyc/win32/include/winapi/winnls.h +++ /dev/null @@ -1,651 +0,0 @@ -#ifndef _WINNLS_H -#define _WINNLS_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_LEADBYTES 12 -#define MAX_DEFAULTCHAR 2 -#define LOCALE_NOUSEROVERRIDE 0x80000000 -#define LOCALE_USE_CP_ACP 0x40000000 -#define LOCALE_ILANGUAGE 1 -#define LOCALE_SLANGUAGE 2 -#define LOCALE_SENGLANGUAGE 0x1001 -#define LOCALE_SABBREVLANGNAME 3 -#define LOCALE_SNATIVELANGNAME 4 -#define LOCALE_ICOUNTRY 5 -#define LOCALE_SCOUNTRY 6 -#define LOCALE_SENGCOUNTRY 0x1002 -#define LOCALE_SABBREVCTRYNAME 7 -#define LOCALE_SNATIVECTRYNAME 8 -#define LOCALE_IDEFAULTLANGUAGE 9 -#define LOCALE_IDEFAULTCOUNTRY 10 -#define LOCALE_IDEFAULTCODEPAGE 11 -#define LOCALE_IDEFAULTANSICODEPAGE 0x1004 -#define LOCALE_SLIST 12 -#define LOCALE_IMEASURE 13 -#define LOCALE_SDECIMAL 14 -#define LOCALE_STHOUSAND 15 -#define LOCALE_SGROUPING 16 -#define LOCALE_IDIGITS 17 -#define LOCALE_ILZERO 18 -#define LOCALE_INEGNUMBER 0x1010 -#define LOCALE_SNATIVEDIGITS 19 -#define LOCALE_SCURRENCY 20 -#define LOCALE_SINTLSYMBOL 21 -#define LOCALE_SMONDECIMALSEP 22 -#define LOCALE_SMONTHOUSANDSEP 23 -#define LOCALE_SMONGROUPING 24 -#define LOCALE_ICURRDIGITS 25 -#define LOCALE_IINTLCURRDIGITS 26 -#define LOCALE_ICURRENCY 27 -#define LOCALE_INEGCURR 28 -#define LOCALE_SDATE 29 -#define LOCALE_STIME 30 -#define LOCALE_SSHORTDATE 31 -#define LOCALE_SLONGDATE 32 -#define LOCALE_STIMEFORMAT 0x1003 -#define LOCALE_IDATE 33 -#define LOCALE_ILDATE 34 -#define LOCALE_ITIME 35 -#define LOCALE_ITIMEMARKPOSN 0x1005 -#define LOCALE_ICENTURY 36 -#define LOCALE_ITLZERO 37 -#define LOCALE_IDAYLZERO 38 -#define LOCALE_IMONLZERO 39 -#define LOCALE_S1159 40 -#define LOCALE_S2359 41 -#define LOCALE_ICALENDARTYPE 0x1009 -#define LOCALE_IOPTIONALCALENDAR 0x100B -#define LOCALE_IFIRSTDAYOFWEEK 0x100C -#define LOCALE_IFIRSTWEEKOFYEAR 0x100D -#define LOCALE_SDAYNAME1 42 -#define LOCALE_SDAYNAME2 43 -#define LOCALE_SDAYNAME3 44 -#define LOCALE_SDAYNAME4 45 -#define LOCALE_SDAYNAME5 46 -#define LOCALE_SDAYNAME6 47 -#define LOCALE_SDAYNAME7 48 -#define LOCALE_SABBREVDAYNAME1 49 -#define LOCALE_SABBREVDAYNAME2 50 -#define LOCALE_SABBREVDAYNAME3 51 -#define LOCALE_SABBREVDAYNAME4 52 -#define LOCALE_SABBREVDAYNAME5 53 -#define LOCALE_SABBREVDAYNAME6 54 -#define LOCALE_SABBREVDAYNAME7 55 -#define LOCALE_SMONTHNAME1 56 -#define LOCALE_SMONTHNAME2 57 -#define LOCALE_SMONTHNAME3 58 -#define LOCALE_SMONTHNAME4 59 -#define LOCALE_SMONTHNAME5 60 -#define LOCALE_SMONTHNAME6 61 -#define LOCALE_SMONTHNAME7 62 -#define LOCALE_SMONTHNAME8 63 -#define LOCALE_SMONTHNAME9 64 -#define LOCALE_SMONTHNAME10 65 -#define LOCALE_SMONTHNAME11 66 -#define LOCALE_SMONTHNAME12 67 -#define LOCALE_SMONTHNAME13 0x100E -#define LOCALE_SABBREVMONTHNAME1 68 -#define LOCALE_SABBREVMONTHNAME2 69 -#define LOCALE_SABBREVMONTHNAME3 70 -#define LOCALE_SABBREVMONTHNAME4 71 -#define LOCALE_SABBREVMONTHNAME5 72 -#define LOCALE_SABBREVMONTHNAME6 73 -#define LOCALE_SABBREVMONTHNAME7 74 -#define LOCALE_SABBREVMONTHNAME8 75 -#define LOCALE_SABBREVMONTHNAME9 76 -#define LOCALE_SABBREVMONTHNAME10 77 -#define LOCALE_SABBREVMONTHNAME11 78 -#define LOCALE_SABBREVMONTHNAME12 79 -#define LOCALE_SABBREVMONTHNAME13 0x100F -#define LOCALE_SPOSITIVESIGN 80 -#define LOCALE_SNEGATIVESIGN 81 -#define LOCALE_IPOSSIGNPOSN 82 -#define LOCALE_INEGSIGNPOSN 83 -#define LOCALE_IPOSSYMPRECEDES 84 -#define LOCALE_IPOSSEPBYSPACE 85 -#define LOCALE_INEGSYMPRECEDES 86 -#define LOCALE_INEGSEPBYSPACE 87 -#define LOCALE_FONTSIGNATURE 88 -#define LOCALE_SISO639LANGNAME 89 -#define LOCALE_SISO3166CTRYNAME 90 -#define LOCALE_SYSTEM_DEFAULT 0x800 -#define LOCALE_USER_DEFAULT 0x400 -#define NORM_IGNORECASE 1 -#define NORM_IGNOREKANATYPE 65536 -#define NORM_IGNORENONSPACE 2 -#define NORM_IGNORESYMBOLS 4 -#define NORM_IGNOREWIDTH 131072 -#define SORT_STRINGSORT 4096 -#define LCMAP_LOWERCASE 0x00000100 -#define LCMAP_UPPERCASE 0x00000200 -#define LCMAP_SORTKEY 0x00000400 -#define LCMAP_BYTEREV 0x00000800 -#define LCMAP_HIRAGANA 0x00100000 -#define LCMAP_KATAKANA 0x00200000 -#define LCMAP_HALFWIDTH 0x00400000 -#define LCMAP_FULLWIDTH 0x00800000 -#define LCMAP_LINGUISTIC_CASING 0x01000000 -#define LCMAP_SIMPLIFIED_CHINESE 0x02000000 -#define LCMAP_TRADITIONAL_CHINESE 0x04000000 -#define ENUM_ALL_CALENDARS (-1) -#define DATE_SHORTDATE 1 -#define DATE_LONGDATE 2 -#define DATE_USE_ALT_CALENDAR 4 -#define CP_INSTALLED 1 -#define CP_SUPPORTED 2 -#define LCID_INSTALLED 1 -#define LCID_SUPPORTED 2 -#define LCID_ALTERNATE_SORTS 4 -#define MAP_FOLDCZONE 16 -#define MAP_FOLDDIGITS 128 -#define MAP_PRECOMPOSED 32 -#define MAP_COMPOSITE 64 -#define CP_ACP 0 -#define CP_OEMCP 1 -#define CP_MACCP 2 -#define CP_THREAD_ACP 3 -#define CP_SYMBOL 42 -#define CP_UTF7 65000 -#define CP_UTF8 65001 -#define CT_CTYPE1 1 -#define CT_CTYPE2 2 -#define CT_CTYPE3 4 -#define C1_UPPER 1 -#define C1_LOWER 2 -#define C1_DIGIT 4 -#define C1_SPACE 8 -#define C1_PUNCT 16 -#define C1_CNTRL 32 -#define C1_BLANK 64 -#define C1_XDIGIT 128 -#define C1_ALPHA 256 -#define C2_LEFTTORIGHT 1 -#define C2_RIGHTTOLEFT 2 -#define C2_EUROPENUMBER 3 -#define C2_EUROPESEPARATOR 4 -#define C2_EUROPETERMINATOR 5 -#define C2_ARABICNUMBER 6 -#define C2_COMMONSEPARATOR 7 -#define C2_BLOCKSEPARATOR 8 -#define C2_SEGMENTSEPARATOR 9 -#define C2_WHITESPACE 10 -#define C2_OTHERNEUTRAL 11 -#define C2_NOTAPPLICABLE 0 -#define C3_NONSPACING 1 -#define C3_DIACRITIC 2 -#define C3_VOWELMARK 4 -#define C3_SYMBOL 8 -#define C3_KATAKANA 16 -#define C3_HIRAGANA 32 -#define C3_HALFWIDTH 64 -#define C3_FULLWIDTH 128 -#define C3_IDEOGRAPH 256 -#define C3_KASHIDA 512 -#define C3_LEXICAL 1024 -#define C3_ALPHA 32768 -#define C3_NOTAPPLICABLE 0 -#define TIME_NOMINUTESORSECONDS 1 -#define TIME_NOSECONDS 2 -#define TIME_NOTIMEMARKER 4 -#define TIME_FORCE24HOURFORMAT 8 -#define MB_PRECOMPOSED 1 -#define MB_COMPOSITE 2 -#define MB_ERR_INVALID_CHARS 8 -#define MB_USEGLYPHCHARS 4 -#define WC_COMPOSITECHECK 512 -#define WC_DISCARDNS 16 -#define WC_SEPCHARS 32 -#define WC_DEFAULTCHAR 64 -#define CTRY_DEFAULT 0 -#define CTRY_ALBANIA 355 -#define CTRY_ALGERIA 213 -#define CTRY_ARGENTINA 54 -#define CTRY_ARMENIA 374 -#define CTRY_AUSTRALIA 61 -#define CTRY_AUSTRIA 43 -#define CTRY_AZERBAIJAN 994 -#define CTRY_BAHRAIN 973 -#define CTRY_BELARUS 375 -#define CTRY_BELGIUM 32 -#define CTRY_BELIZE 501 -#define CTRY_BOLIVIA 591 -#define CTRY_BRAZIL 55 -#define CTRY_BRUNEI_DARUSSALAM 673 -#define CTRY_BULGARIA 359 -#define CTRY_CANADA 2 -#define CTRY_CARIBBEAN 1 -#define CTRY_CHILE 56 -#define CTRY_COLOMBIA 57 -#define CTRY_COSTA_RICA 506 -#define CTRY_CROATIA 385 -#define CTRY_CZECH 420 -#define CTRY_DENMARK 45 -#define CTRY_DOMINICAN_REPUBLIC 1 -#define CTRY_ECUADOR 593 -#define CTRY_EGYPT 20 -#define CTRY_EL_SALVADOR 503 -#define CTRY_ESTONIA 372 -#define CTRY_FAEROE_ISLANDS 298 -#define CTRY_FINLAND 358 -#define CTRY_FRANCE 33 -#define CTRY_GEORGIA 995 -#define CTRY_GERMANY 49 -#define CTRY_GREECE 30 -#define CTRY_GUATEMALA 502 -#define CTRY_HONDURAS 504 -#define CTRY_HONG_KONG 852 -#define CTRY_HUNGARY 36 -#define CTRY_ICELAND 354 -#define CTRY_INDIA 91 -#define CTRY_INDONESIA 62 -#define CTRY_IRAN 981 -#define CTRY_IRAQ 964 -#define CTRY_IRELAND 353 -#define CTRY_ISRAEL 972 -#define CTRY_ITALY 39 -#define CTRY_JAMAICA 1 -#define CTRY_JAPAN 81 -#define CTRY_JORDAN 962 -#define CTRY_KAZAKSTAN 7 -#define CTRY_KENYA 254 -#define CTRY_KUWAIT 965 -#define CTRY_LATVIA 371 -#define CTRY_LEBANON 961 -#define CTRY_LIBYA 218 -#define CTRY_LIECHTENSTEIN 41 -#define CTRY_LITHUANIA 370 -#define CTRY_LUXEMBOURG 352 -#define CTRY_MACAU 853 -#define CTRY_MACEDONIA 389 -#define CTRY_MALAYSIA 60 -#define CTRY_MEXICO 52 -#define CTRY_MONACO 33 -#define CTRY_MOROCCO 212 -#define CTRY_NETHERLANDS 31 -#define CTRY_NEW_ZEALAND 64 -#define CTRY_NICARAGUA 505 -#define CTRY_NORWAY 47 -#define CTRY_OMAN 968 -#define CTRY_PAKISTAN 92 -#define CTRY_PANAMA 507 -#define CTRY_PARAGUAY 595 -#define CTRY_PERU 51 -#define CTRY_PHILIPPINES 63 -#define CTRY_POLAND 48 -#define CTRY_PORTUGAL 351 -#define CTRY_PRCHINA 86 -#define CTRY_PUERTO_RICO 1 -#define CTRY_QATAR 974 -#define CTRY_ROMANIA 40 -#define CTRY_RUSSIA 7 -#define CTRY_SAUDI_ARABIA 966 -#define CTRY_SERBIA 381 -#define CTRY_SINGAPORE 65 -#define CTRY_SLOVAK 421 -#define CTRY_SLOVENIA 386 -#define CTRY_SOUTH_AFRICA 27 -#define CTRY_SOUTH_KOREA 82 -#define CTRY_SPAIN 34 -#define CTRY_SWEDEN 46 -#define CTRY_SWITZERLAND 41 -#define CTRY_SYRIA 963 -#define CTRY_TAIWAN 886 -#define CTRY_TATARSTAN 7 -#define CTRY_THAILAND 66 -#define CTRY_TRINIDAD_Y_TOBAGO 1 -#define CTRY_TUNISIA 216 -#define CTRY_TURKEY 90 -#define CTRY_UAE 971 -#define CTRY_UKRAINE 380 -#define CTRY_UNITED_KINGDOM 44 -#define CTRY_UNITED_STATES 1 -#define CTRY_URUGUAY 598 -#define CTRY_UZBEKISTAN 7 -#define CTRY_VENEZUELA 58 -#define CTRY_VIET_NAM 84 -#define CTRY_YEMEN 967 -#define CTRY_ZIMBABWE 263 -#define CAL_ICALINTVALUE 1 -#define CAL_SCALNAME 2 -#define CAL_IYEAROFFSETRANGE 3 -#define CAL_SERASTRING 4 -#define CAL_SSHORTDATE 5 -#define CAL_SLONGDATE 6 -#define CAL_SDAYNAME1 7 -#define CAL_SDAYNAME2 8 -#define CAL_SDAYNAME3 9 -#define CAL_SDAYNAME4 10 -#define CAL_SDAYNAME5 11 -#define CAL_SDAYNAME6 12 -#define CAL_SDAYNAME7 13 -#define CAL_SABBREVDAYNAME1 14 -#define CAL_SABBREVDAYNAME2 15 -#define CAL_SABBREVDAYNAME3 16 -#define CAL_SABBREVDAYNAME4 17 -#define CAL_SABBREVDAYNAME5 18 -#define CAL_SABBREVDAYNAME6 19 -#define CAL_SABBREVDAYNAME7 20 -#define CAL_SMONTHNAME1 21 -#define CAL_SMONTHNAME2 22 -#define CAL_SMONTHNAME3 23 -#define CAL_SMONTHNAME4 24 -#define CAL_SMONTHNAME5 25 -#define CAL_SMONTHNAME6 26 -#define CAL_SMONTHNAME7 27 -#define CAL_SMONTHNAME8 28 -#define CAL_SMONTHNAME9 29 -#define CAL_SMONTHNAME10 30 -#define CAL_SMONTHNAME11 31 -#define CAL_SMONTHNAME12 32 -#define CAL_SMONTHNAME13 33 -#define CAL_SABBREVMONTHNAME1 34 -#define CAL_SABBREVMONTHNAME2 35 -#define CAL_SABBREVMONTHNAME3 36 -#define CAL_SABBREVMONTHNAME4 37 -#define CAL_SABBREVMONTHNAME5 38 -#define CAL_SABBREVMONTHNAME6 39 -#define CAL_SABBREVMONTHNAME7 40 -#define CAL_SABBREVMONTHNAME8 41 -#define CAL_SABBREVMONTHNAME9 42 -#define CAL_SABBREVMONTHNAME10 43 -#define CAL_SABBREVMONTHNAME11 44 -#define CAL_SABBREVMONTHNAME12 45 -#define CAL_SABBREVMONTHNAME13 46 -#define CAL_GREGORIAN 1 -#define CAL_GREGORIAN_US 2 -#define CAL_JAPAN 3 -#define CAL_TAIWAN 4 -#define CAL_KOREA 5 -#define CAL_HIJRI 6 -#define CAL_THAI 7 -#define CAL_HEBREW 8 -#define CAL_GREGORIAN_ME_FRENCH 9 -#define CAL_GREGORIAN_ARABIC 10 -#define CAL_GREGORIAN_XLIT_ENGLISH 11 -#define CAL_GREGORIAN_XLIT_FRENCH 12 -#define CSTR_LESS_THAN 1 -#define CSTR_EQUAL 2 -#define CSTR_GREATER_THAN 3 -#define LGRPID_INSTALLED 1 -#define LGRPID_SUPPORTED 2 -#define LGRPID_WESTERN_EUROPE 1 -#define LGRPID_CENTRAL_EUROPE 2 -#define LGRPID_BALTIC 3 -#define LGRPID_GREEK 4 -#define LGRPID_CYRILLIC 5 -#define LGRPID_TURKISH 6 -#define LGRPID_JAPANESE 7 -#define LGRPID_KOREAN 8 -#define LGRPID_TRADITIONAL_CHINESE 9 -#define LGRPID_SIMPLIFIED_CHINESE 10 -#define LGRPID_THAI 11 -#define LGRPID_HEBREW 12 -#define LGRPID_ARABIC 13 -#define LGRPID_VIETNAMESE 14 -#define LGRPID_INDIC 15 -#define LGRPID_GEORGIAN 16 -#define LGRPID_ARMENIAN 17 - -#if(WINVER >= 0x0500) -#define LOCALE_SYEARMONTH 0x1006 -#define LOCALE_SENGCURRNAME 0x1007 -#define LOCALE_SNATIVECURRNAME 0x1008 -#define LOCALE_IDEFAULTEBCDICCODEPAGE 0x1012 -#define LOCALE_SSORTNAME 0x1013 -#define LOCALE_IDIGITSUBSTITUTION 0x1014 -#define LOCALE_IPAPERSIZE 0x100A -#define DATE_YEARMONTH 8 -#define DATE_LTRREADING 16 -#define DATE_RTLREADING 32 -#define MAP_EXPAND_LIGATURES 0x2000 -#define WC_NO_BEST_FIT_CHARS 1024 -#define CAL_SYEARMONTH 47 -#define CAL_ITWODIGITYEARMAX 48 -#define CAL_NOUSEROVERRIDE LOCALE_NOUSEROVERRIDE -#define CAL_RETURN_NUMBER LOCALE_RETURN_NUMBER -#define CAL_USE_CP_ACP LOCALE_USE_CP_ACP -#endif /* WINVER >= 0x0500 */ -#ifndef _BASETSD_H -typedef long LONG_PTR; -#endif - -#ifndef RC_INVOKED -typedef DWORD LCTYPE; -typedef DWORD CALTYPE; -typedef DWORD CALID; -typedef DWORD LGRPID; -typedef BOOL (CALLBACK *CALINFO_ENUMPROCA)(LPSTR); -typedef BOOL (CALLBACK *CALINFO_ENUMPROCW)(LPWSTR); -typedef BOOL (CALLBACK* CALINFO_ENUMPROCEXA)(LPSTR, CALID); -typedef BOOL (CALLBACK* CALINFO_ENUMPROCEXW)(LPWSTR, CALID); -typedef BOOL (CALLBACK* LANGUAGEGROUP_ENUMPROCA)(LGRPID, LPSTR, LPSTR, DWORD, LONG_PTR); -typedef BOOL (CALLBACK* LANGUAGEGROUP_ENUMPROCW)(LGRPID, LPWSTR, LPWSTR, DWORD, LONG_PTR); -typedef BOOL (CALLBACK* LANGGROUPLOCALE_ENUMPROCA)(LGRPID, LCID, LPSTR, LONG_PTR); -typedef BOOL (CALLBACK* LANGGROUPLOCALE_ENUMPROCW)(LGRPID, LCID, LPWSTR, LONG_PTR); -typedef BOOL (CALLBACK* UILANGUAGE_ENUMPROCW)(LPWSTR, LONG_PTR); -typedef BOOL (CALLBACK* UILANGUAGE_ENUMPROCA)(LPSTR, LONG_PTR); -typedef BOOL (CALLBACK *LOCALE_ENUMPROCA)(LPSTR); -typedef BOOL (CALLBACK *LOCALE_ENUMPROCW)(LPWSTR); -typedef BOOL (CALLBACK *CODEPAGE_ENUMPROCA)(LPSTR); -typedef BOOL (CALLBACK *CODEPAGE_ENUMPROCW)(LPWSTR); -typedef BOOL (CALLBACK *DATEFMT_ENUMPROCA)(LPSTR); -typedef BOOL (CALLBACK *DATEFMT_ENUMPROCW)(LPWSTR); -typedef BOOL (CALLBACK* DATEFMT_ENUMPROCEXA)(LPSTR, CALID); -typedef BOOL (CALLBACK* DATEFMT_ENUMPROCEXW)(LPWSTR, CALID); -typedef BOOL (CALLBACK *TIMEFMT_ENUMPROCA)(LPSTR); -typedef BOOL (CALLBACK *TIMEFMT_ENUMPROCW)(LPWSTR); - -typedef struct _cpinfo { - UINT MaxCharSize; - BYTE DefaultChar[MAX_DEFAULTCHAR]; - BYTE LeadByte[MAX_LEADBYTES]; -} CPINFO,*LPCPINFO; -typedef struct _cpinfoexA { - UINT MaxCharSize; - BYTE DefaultChar[MAX_DEFAULTCHAR]; - BYTE LeadByte[MAX_LEADBYTES]; - WCHAR UnicodeDefaultChar; - UINT CodePage; - CHAR CodePageName[MAX_PATH]; -} CPINFOEXA, *LPCPINFOEXA; -typedef struct _cpinfoexW { - UINT MaxCharSize; - BYTE DefaultChar[MAX_DEFAULTCHAR]; - BYTE LeadByte[MAX_LEADBYTES]; - WCHAR UnicodeDefaultChar; - UINT CodePage; - WCHAR CodePageName[MAX_PATH]; -} CPINFOEXW, *LPCPINFOEXW; -typedef struct _currencyfmtA { - UINT NumDigits; - UINT LeadingZero; - UINT Grouping; - LPSTR lpDecimalSep; - LPSTR lpThousandSep; - UINT NegativeOrder; - UINT PositiveOrder; - LPSTR lpCurrencySymbol; -} CURRENCYFMTA, *LPCURRENCYFMTA; -typedef struct _currencyfmtW { - UINT NumDigits; - UINT LeadingZero; - UINT Grouping; - LPWSTR lpDecimalSep; - LPWSTR lpThousandSep; - UINT NegativeOrder; - UINT PositiveOrder; - LPWSTR lpCurrencySymbol; -} CURRENCYFMTW, *LPCURRENCYFMTW; -typedef struct _numberfmtA { - UINT NumDigits; - UINT LeadingZero; - UINT Grouping; - LPSTR lpDecimalSep; - LPSTR lpThousandSep; - UINT NegativeOrder; -} NUMBERFMTA, *LPNUMBERFMTA; -typedef struct _numberfmtW { - UINT NumDigits; - UINT LeadingZero; - UINT Grouping; - LPWSTR lpDecimalSep; - LPWSTR lpThousandSep; - UINT NegativeOrder; -} NUMBERFMTW, *LPNUMBERFMTW; - -int WINAPI CompareStringA(LCID,DWORD,LPCSTR,int,LPCSTR,int); -int WINAPI CompareStringW(LCID,DWORD,LPCWSTR,int,LPCWSTR,int); -LCID WINAPI ConvertDefaultLocale(LCID); -BOOL WINAPI EnumCalendarInfoA(CALINFO_ENUMPROCA,LCID,CALID,CALTYPE); -BOOL WINAPI EnumCalendarInfoW(CALINFO_ENUMPROCW,LCID,CALID,CALTYPE); -BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA,LCID,DWORD); -BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW,LCID,DWORD); -BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA,DWORD); -BOOL WINAPI EnumSystemCodePagesW(CODEPAGE_ENUMPROCW,DWORD); -BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA,DWORD); -BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD); -BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA,LCID,DWORD); -BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW,LCID,DWORD); -int WINAPI FoldStringA(DWORD,LPCSTR,int,LPSTR,int); -int WINAPI FoldStringW(DWORD,LPCWSTR,int,LPWSTR,int); -UINT WINAPI GetACP(void); -BOOL WINAPI GetCPInfo(UINT,LPCPINFO); -BOOL WINAPI GetCPInfoExA(UINT,DWORD,LPCPINFOEXA); -BOOL WINAPI GetCPInfoExW(UINT,DWORD,LPCPINFOEXW); -int WINAPI GetCurrencyFormatA(LCID,DWORD,LPCSTR,const CURRENCYFMTA*,LPSTR,int); -int WINAPI GetCurrencyFormatW(LCID,DWORD,LPCWSTR,const CURRENCYFMTW*,LPWSTR,int); -int WINAPI GetDateFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,int); -int WINAPI GetDateFormatW(LCID,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,int); -int WINAPI GetLocaleInfoA(LCID,LCTYPE,LPSTR,int); -int WINAPI GetLocaleInfoW(LCID,LCTYPE,LPWSTR,int); -int WINAPI GetNumberFormatA(LCID,DWORD,LPCSTR,const NUMBERFMTA*,LPSTR,int); -int WINAPI GetNumberFormatW(LCID,DWORD,LPCWSTR,const NUMBERFMTW*,LPWSTR,int); -UINT WINAPI GetOEMCP(void); -BOOL WINAPI GetStringTypeA(LCID,DWORD,LPCSTR,int,LPWORD); -BOOL WINAPI GetStringTypeW(DWORD,LPCWSTR,int,LPWORD); -BOOL WINAPI GetStringTypeExA(LCID,DWORD,LPCSTR,int,LPWORD); -BOOL WINAPI GetStringTypeExW(LCID,DWORD,LPCWSTR,int,LPWORD); -LANGID WINAPI GetSystemDefaultLangID(void); -LCID WINAPI GetSystemDefaultLCID(void); -LCID WINAPI GetThreadLocale(void); -int WINAPI GetTimeFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,int); -int WINAPI GetTimeFormatW(LCID,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,int); -LANGID WINAPI GetUserDefaultLangID(void); -LCID WINAPI GetUserDefaultLCID(void); -BOOL WINAPI IsDBCSLeadByte(BYTE); -BOOL WINAPI IsDBCSLeadByteEx(UINT,BYTE); -BOOL WINAPI IsValidCodePage(UINT); -BOOL WINAPI IsValidLocale(LCID,DWORD); -int WINAPI LCMapStringA(LCID,DWORD,LPCSTR,int,LPSTR,int); -int WINAPI LCMapStringW(LCID,DWORD,LPCWSTR,int,LPWSTR,int); -int WINAPI MultiByteToWideChar(UINT,DWORD,LPCSTR,int,LPWSTR,int); -BOOL WINAPI SetLocaleInfoA(LCID,LCTYPE,LPCSTR); -BOOL WINAPI SetLocaleInfoW(LCID,LCTYPE,LPCWSTR); -BOOL WINAPI SetThreadLocale(LCID); -int WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL); -#if (WINVER >= 0x0500) -BOOL WINAPI EnumCalendarInfoExA(CALINFO_ENUMPROCEXA,LCID,CALID,CALTYPE); -BOOL WINAPI EnumCalendarInfoExW(CALINFO_ENUMPROCEXW,LCID,CALID,CALTYPE); -BOOL WINAPI EnumDateFormatsExA(DATEFMT_ENUMPROCEXA,LCID,DWORD); -BOOL WINAPI EnumDateFormatsExW(DATEFMT_ENUMPROCEXW,LCID,DWORD); -BOOL WINAPI EnumSystemLanguageGroupsA(LANGUAGEGROUP_ENUMPROCA,DWORD,LONG_PTR); -BOOL WINAPI EnumSystemLanguageGroupsW(LANGUAGEGROUP_ENUMPROCW,DWORD,LONG_PTR); -BOOL WINAPI EnumLanguageGroupLocalesA(LANGGROUPLOCALE_ENUMPROCA,LGRPID,DWORD,LONG_PTR); -BOOL WINAPI EnumLanguageGroupLocalesW(LANGGROUPLOCALE_ENUMPROCW,LGRPID,DWORD,LONG_PTR); -BOOL WINAPI EnumUILanguagesA(UILANGUAGE_ENUMPROCA,DWORD,LONG_PTR); -BOOL WINAPI EnumUILanguagesW(UILANGUAGE_ENUMPROCW,DWORD,LONG_PTR); -LANGID WINAPI GetSystemDefaultUILanguage(void); -LANGID WINAPI GetUserDefaultUILanguage(void); -BOOL WINAPI IsValidLanguageGroup(LGRPID,DWORD); -#endif /* (WINVER >= 0x0500) */ - -#ifdef UNICODE -#define CALINFO_ENUMPROC CALINFO_ENUMPROCW -#define CALINFO_ENUMPROCEX CALINFO_ENUMPROCEXW -#define LOCALE_ENUMPROC LOCALE_ENUMPROCW -#define CODEPAGE_ENUMPROC CODEPAGE_ENUMPROCW -#define DATEFMT_ENUMPROC DATEFMT_ENUMPROCW -#define DATEFMT_ENUMPROCEX DATEFMT_ENUMPROCEXW -#define TIMEFMT_ENUMPROC TIMEFMT_ENUMPROCW -#define LANGUAGEGROUP_ENUMPROC LANGUAGEGROUP_ENUMPROCW -#define LANGGROUPLOCALE_ENUMPROC LANGGROUPLOCALE_ENUMPROCW -#define UILANGUAGE_ENUMPROC UILANGUAGE_ENUMPROCW -typedef CPINFOEXW CPINFOEX; -typedef LPCPINFOEXW LPCPINFOEX; -typedef CURRENCYFMTW CURRENCYFMT; -typedef LPCURRENCYFMTW LPCURRENCYFMT; -typedef NUMBERFMTW NUMBERFMT; -typedef LPNUMBERFMTW LPNUMBERFMT; -#define CompareString CompareStringW -#define EnumCalendarInfo EnumCalendarInfoW -#define EnumSystemCodePages EnumSystemCodePagesW -#define EnumSystemLocales EnumSystemLocalesW -#define EnumTimeFormats EnumTimeFormatsW -#define FoldString FoldStringW -#define GetCPInfoEx GetCPInfoExW -#define GetCurrencyFormat GetCurrencyFormatW -#define GetDateFormat GetDateFormatW -#define GetLocaleInfo GetLocaleInfoW -#define GetNumberFormat GetNumberFormatW -#define GetStringTypeEx GetStringTypeExW -#define GetTimeFormat GetTimeFormatW -#define LCMapString LCMapStringW -#define SetLocaleInfo SetLocaleInfoW -#if (WINVER >= 0x0500) -#define EnumCalendarInfoEx EnumCalendarInfoExW; -#define EnumDateFormatsEx EnumDateFormatsExW; -#define EnumSystemLanguageGroups EnumSystemLanguageGroupsW; -#define EnumLanguageGroupLocales EnumLanguageGroupLocalesW; -#define EnumUILanguages EnumUILanguagesW; -#endif /* (WINVER >= 0x0500) */ -#else -#define CALINFO_ENUMPROC CALINFO_ENUMPROCA -#define CALINFO_ENUMPROCEX CALINFO_ENUMPROCEXA -#define LOCALE_ENUMPROC LOCALE_ENUMPROCA -#define CODEPAGE_ENUMPROC CODEPAGE_ENUMPROCA -#define DATEFMT_ENUMPROC DATEFMT_ENUMPROCA -#define DATEFMT_ENUMPROCEX DATEFMT_ENUMPROCEXA -#define TIMEFMT_ENUMPROC TIMEFMT_ENUMPROCA -#define LANGUAGEGROUP_ENUMPROC LANGUAGEGROUP_ENUMPROCA -#define LANGGROUPLOCALE_ENUMPROC LANGGROUPLOCALE_ENUMPROCA -#define UILANGUAGE_ENUMPROC UILANGUAGE_ENUMPROCA -typedef CPINFOEXA CPINFOEX; -typedef LPCPINFOEXA LPCPINFOEX; -typedef CURRENCYFMTA CURRENCYFMT; -typedef LPCURRENCYFMTA LPCURRENCYFMT; -typedef NUMBERFMTA NUMBERFMT; -typedef LPNUMBERFMTA LPNUMBERFMT; -#define CompareString CompareStringA -#define EnumCalendarInfo EnumCalendarInfoA -#define EnumSystemCodePages EnumSystemCodePagesA -#define EnumSystemLocales EnumSystemLocalesA -#define EnumTimeFormats EnumTimeFormatsA -#define FoldString FoldStringA -#define GetCPInfoEx GetCPInfoExA -#define GetCurrencyFormat GetCurrencyFormatA -#define GetDateFormat GetDateFormatA -#define GetLocaleInfo GetLocaleInfoA -#define GetNumberFormat GetNumberFormatA -#define GetStringTypeEx GetStringTypeExA -#define GetTimeFormat GetTimeFormatA -#define LCMapString LCMapStringA -#define SetLocaleInfo SetLocaleInfoA -#if (WINVER >= 0x0500) -#define EnumCalendarInfoEx EnumCalendarInfoExA; -#define EnumDateFormatsEx EnumDateFormatsExA; -#define EnumSystemLanguageGroups EnumSystemLanguageGroupsA; -#define EnumLanguageGroupLocales EnumLanguageGroupLocalesA; -#define EnumUILanguages EnumUILanguagesA; -#endif /* (WINVER >= 0x0500) */ -#endif /* UNICODE */ -#endif /* RC_INVOKED */ -#ifdef __cplusplus -} -#endif -#endif diff --git a/tinyc/win32/include/winapi/winnt.h b/tinyc/win32/include/winapi/winnt.h index 810d99158..4cf685d2a 100644 --- a/tinyc/win32/include/winapi/winnt.h +++ b/tinyc/win32/include/winapi/winnt.h @@ -1,568 +1,3121 @@ -#ifndef _WINNT_H -#define _WINNT_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -/* translate GCC target defines to MS equivalents. Keep this synchronized - with windows.h. */ -#if defined(__i686__) && !defined(_M_IX86) -#define _M_IX86 600 -#elif defined(__i586__) && !defined(_M_IX86) -#define _M_IX86 500 -#elif defined(__i486__) && !defined(_M_IX86) -#define _M_IX86 400 -#elif defined(__i386__) && !defined(_M_IX86) -#define _M_IX86 300 -#endif -#if defined(_M_IX86) && !defined(_X86_) -#define _X86_ -#elif defined(_M_ALPHA) && !defined(_ALPHA_) -#define _ALPHA_ -#elif defined(_M_PPC) && !defined(_PPC_) -#define _PPC_ -#elif defined(_M_MRX000) && !defined(_MIPS_) -#define _MIPS_ -#elif defined(_M_M68K) && !defined(_68K_) -#define _68K_ -#endif +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINNT_ +#define _WINNT_ #ifdef __cplusplus extern "C" { #endif -#include <winerror.h> +#include <ctype.h> +#define ANYSIZE_ARRAY 1 -#ifndef RC_INVOKED -#include <string.h> +//gr #include <specstrings.h> -/* FIXME: add more architectures. Is there a way to specify this in GCC? */ -#ifdef _X86_ -#define UNALIGNED +#define RESTRICTED_POINTER + +#ifndef __CRT_UNALIGNED +#define __CRT_UNALIGNED +#endif + +#if defined(__ia64__) || defined(__x86_64) +#define UNALIGNED __CRT_UNALIGNED +#ifdef _WIN64 +#define UNALIGNED64 __CRT_UNALIGNED +#else +#define UNALIGNED64 +#endif #else #define UNALIGNED +#define UNALIGNED64 #endif -#ifndef VOID -#define VOID void +#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && (defined(_X86_) && !defined(__x86_64)) +#define I_X86_ #endif -typedef char CHAR; -typedef short SHORT; -typedef long LONG; -typedef CHAR CCHAR; -typedef unsigned char UCHAR,*PUCHAR; -typedef unsigned short USHORT,*PUSHORT; -typedef unsigned long ULONG,*PULONG; -typedef char *PSZ; -#ifndef _WCHAR_T_DEFINED -#define _WCHAR_T_DEFINED -#ifndef _WCHAR_T_ -#define _WCHAR_T_ -#undef __need_wchar_t -#ifndef __cplusplus -typedef unsigned short wchar_t; +#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(__x86_64) +#define _AMD64_ #endif + +#if !defined(I_X86_) && !(defined(_X86_) && !defined(__x86_64)) && !defined(_AMD64_) && defined(__ia64__) +#if !defined(_IA64_) +#define _IA64_ #endif #endif -typedef wchar_t WCHAR; -typedef WCHAR *PWCHAR,*LPWCH,*PWCH,*NWPSTR,*LPWSTR,*PWSTR; -typedef CONST WCHAR *LPCWCH,*PCWCH,*LPCWSTR,*PCWSTR; -typedef CHAR *PCHAR,*LPCH,*PCH,*NPSTR,*LPSTR,*PSTR; -typedef CONST CHAR *LPCCH,*PCSTR,*LPCSTR; -#ifndef _TCHAR_DEFINED -#define _TCHAR_DEFINED -#ifdef UNICODE -/* - * NOTE: This tests UNICODE, which is different from the _UNICODE define - * used to differentiate standard C runtime calls. - */ -typedef WCHAR TCHAR; -typedef WCHAR _TCHAR; + +#ifdef _WIN64 +#define MAX_NATURAL_ALIGNMENT sizeof(ULONGLONG) +#define MEMORY_ALLOCATION_ALIGNMENT 16 +#else +#define MAX_NATURAL_ALIGNMENT sizeof(DWORD) +#define MEMORY_ALLOCATION_ALIGNMENT 8 +#endif + +#ifdef __cplusplus +#define TYPE_ALIGNMENT(t) __alignof__ (t) +#else +#define TYPE_ALIGNMENT(t) FIELD_OFFSET(struct { char x; t test; },test) +#endif + +#ifdef _WIN64 +#ifdef _AMD64_ +#define PROBE_ALIGNMENT(_s) TYPE_ALIGNMENT(DWORD) +#elif defined(_IA64_) +#define PROBE_ALIGNMENT(_s) (TYPE_ALIGNMENT(_s) > TYPE_ALIGNMENT(DWORD) ? TYPE_ALIGNMENT(_s) : TYPE_ALIGNMENT(DWORD)) #else -typedef CHAR TCHAR; -typedef CHAR _TCHAR; +#error No Target Architecture #endif +#define PROBE_ALIGNMENT32(_s) TYPE_ALIGNMENT(DWORD) +#else +#define PROBE_ALIGNMENT(_s) TYPE_ALIGNMENT(DWORD) +#endif + +#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] + +#include <basetsd.h> + +#if defined(_X86_) || defined(__ia64__) || defined(__x86_64) +#define DECLSPEC_IMPORT __declspec(dllimport) +#else +#define DECLSPEC_IMPORT #endif -typedef TCHAR TBYTE,*PTCH,*PTBYTE; -typedef TCHAR *LPTCH,*PTSTR,*LPTSTR,*LP,*PTCHAR; -typedef const TCHAR *LPCTSTR; + +#ifndef DECLSPEC_NORETURN +#define DECLSPEC_NORETURN __declspec(noreturn) +#endif + +#ifndef DECLSPEC_ALIGN +#define DECLSPEC_ALIGN(x) __attribute__ ((aligned(x))) +#endif + +#ifndef SYSTEM_CACHE_ALIGNMENT_SIZE +#if defined(_AMD64_) || defined(I_X86_) +#define SYSTEM_CACHE_ALIGNMENT_SIZE 64 +#else +#define SYSTEM_CACHE_ALIGNMENT_SIZE 128 +#endif +#endif + +#ifndef DECLSPEC_CACHEALIGN +#define DECLSPEC_CACHEALIGN DECLSPEC_ALIGN(SYSTEM_CACHE_ALIGNMENT_SIZE) +#endif + +#ifndef DECLSPEC_UUID +#define DECLSPEC_UUID(x) +#endif + +#ifndef DECLSPEC_NOVTABLE +#define DECLSPEC_NOVTABLE +#endif + +#ifndef DECLSPEC_SELECTANY +#define DECLSPEC_SELECTANY __declspec(selectany) +#endif + +#ifndef NOP_FUNCTION +#define NOP_FUNCTION (void)0 +#endif + +#ifndef DECLSPEC_NOINLINE +#define DECLSPEC_NOINLINE +#endif + +#ifndef FORCEINLINE +#define FORCEINLINE static __inline__ +#endif + +#ifndef DECLSPEC_DEPRECATED +#define DECLSPEC_DEPRECATED __declspec(deprecated) +#define DEPRECATE_SUPPORTED +#endif + +#define DECLSPEC_DEPRECATED_DDK +#define PRAGMA_DEPRECATED_DDK 0 + + typedef void *PVOID; + typedef void *PVOID64; + +#define NTAPI __stdcall +#define NTSYSAPI DECLSPEC_IMPORT +#define NTSYSCALLAPI DECLSPEC_IMPORT + +#ifndef VOID +#define VOID void + typedef char CHAR; + typedef short SHORT; + typedef long LONG; +#endif + + typedef wchar_t WCHAR; + typedef WCHAR *PWCHAR,*LPWCH,*PWCH; + typedef CONST WCHAR *LPCWCH,*PCWCH; + typedef WCHAR *NWPSTR,*LPWSTR,*PWSTR; + typedef PWSTR *PZPWSTR; + typedef CONST PWSTR *PCZPWSTR; + typedef WCHAR UNALIGNED *LPUWSTR,*PUWSTR; + typedef CONST WCHAR *LPCWSTR,*PCWSTR; + typedef PCWSTR *PZPCWSTR; + typedef CONST WCHAR UNALIGNED *LPCUWSTR,*PCUWSTR; + typedef CHAR *PCHAR,*LPCH,*PCH; + typedef CONST CHAR *LPCCH,*PCCH; + typedef CHAR *NPSTR,*LPSTR,*PSTR; + typedef PSTR *PZPSTR; + typedef CONST PSTR *PCZPSTR; + typedef CONST CHAR *LPCSTR,*PCSTR; + typedef PCSTR *PZPCSTR; + #ifdef UNICODE -/* - * __TEXT is a private macro whose specific use is to force the expansion of a - * macro passed as an argument to the macro TEXT. DO NOT use this - * macro within your programs. It's name and function could change without - * notice. - */ -#define __TEXT(q) L##q +#ifndef _TCHAR_DEFINED +#define _TCHAR_DEFINED + typedef WCHAR TCHAR,*PTCHAR; + typedef WCHAR TBYTE ,*PTBYTE; +#endif + + typedef LPWSTR LPTCH,PTCH; + typedef LPWSTR PTSTR,LPTSTR; + typedef LPCWSTR PCTSTR,LPCTSTR; + typedef LPUWSTR PUTSTR,LPUTSTR; + typedef LPCUWSTR PCUTSTR,LPCUTSTR; + typedef LPWSTR LP; +#define __TEXT(quote) L##quote #else -#define __TEXT(q) q +#ifndef _TCHAR_DEFINED +#define _TCHAR_DEFINED + typedef char TCHAR,*PTCHAR; + typedef unsigned char TBYTE ,*PTBYTE; #endif -/* - * UNICODE a constant string when UNICODE is defined, else returns the string - * unmodified. - * The corresponding macros _TEXT() and _T() for mapping _UNICODE strings - * passed to C runtime functions are defined in mingw/tchar.h - */ -#define TEXT(q) __TEXT(q) -typedef SHORT *PSHORT; -typedef LONG *PLONG; -typedef void *HANDLE; -typedef HANDLE *PHANDLE,*LPHANDLE; -#ifdef STRICT -#define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n + + typedef LPSTR LPTCH,PTCH; + typedef LPSTR PTSTR,LPTSTR,PUTSTR,LPUTSTR; + typedef LPCSTR PCTSTR,LPCTSTR,PCUTSTR,LPCUTSTR; +#define __TEXT(quote) quote +#endif + +#define TEXT(quote) __TEXT(quote) + + typedef SHORT *PSHORT; + typedef LONG *PLONG; + + typedef void *HANDLE; +#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name + typedef HANDLE *PHANDLE; + + typedef BYTE FCHAR; + typedef WORD FSHORT; + typedef DWORD FLONG; + +#ifndef _HRESULT_DEFINED +#define _HRESULT_DEFINED + typedef LONG HRESULT; +#endif + +#ifdef __cplusplus +#define EXTERN_C extern "C" #else -#define DECLARE_HANDLE(n) typedef HANDLE n +#define EXTERN_C extern #endif + +#define STDMETHODCALLTYPE WINAPI +#define STDMETHODVCALLTYPE __cdecl +#define STDAPICALLTYPE WINAPI +#define STDAPIVCALLTYPE __cdecl +#define STDAPI EXTERN_C HRESULT WINAPI +#define STDAPI_(type) EXTERN_C type WINAPI +#define STDMETHODIMP HRESULT WINAPI +#define STDMETHODIMP_(type) type WINAPI +#define STDAPIV EXTERN_C HRESULT STDAPIVCALLTYPE +#define STDAPIV_(type) EXTERN_C type STDAPIVCALLTYPE +#define STDMETHODIMPV HRESULT STDMETHODVCALLTYPE +#define STDMETHODIMPV_(type) type STDMETHODVCALLTYPE + + typedef char CCHAR; +#ifndef _LCID_DEFINED +#define _LCID_DEFINED typedef DWORD LCID; -typedef PDWORD PLCID; -typedef WORD LANGID; -#ifdef __GNUC__ -#define _HAVE_INT64 -#define _INTEGRAL_MAX_BITS 64 -#undef __int64 -#define __int64 long long -#elif defined(__WATCOMC__) && (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64 ) -#define _HAVE_INT64 -#endif /* __GNUC__/__WATCOMC */ -#if defined(_HAVE_INT64) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64) -typedef __int64 LONGLONG; -typedef unsigned __int64 DWORDLONG; +#endif + typedef PDWORD PLCID; +#ifndef _LANGID_DEFINED +#define _LANGID_DEFINED + typedef WORD LANGID; +#endif +#define APPLICATION_ERROR_MASK 0x20000000 +#define ERROR_SEVERITY_SUCCESS 0x00000000 +#define ERROR_SEVERITY_INFORMATIONAL 0x40000000 +#define ERROR_SEVERITY_WARNING 0x80000000 +#define ERROR_SEVERITY_ERROR 0xC0000000 + +#ifdef __ia64__ + __declspec(align(16)) +#endif + typedef struct _FLOAT128 { + __int64 LowPart; + __int64 HighPart; + } FLOAT128; + + typedef FLOAT128 *PFLOAT128; + +#define _ULONGLONG_ +#if((!(defined(_X86_) && !defined(__x86_64)) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64))) + typedef __int64 LONGLONG; + typedef unsigned __int64 ULONGLONG; + +#define MAXLONGLONG (0x7fffffffffffffff) #else -typedef double LONGLONG,DWORDLONG; -#endif -typedef LONGLONG *PLONGLONG; -typedef DWORDLONG *PDWORDLONG; -typedef DWORDLONG ULONGLONG,*PULONGLONG; -typedef LONGLONG USN; -#ifdef _HAVE_INT64 -#define Int32x32To64(a,b) ((LONGLONG)(a)*(LONGLONG)(b)) -#define UInt32x32To64(a,b) ((DWORDLONG)(a)*(DWORDLONG)(b)) -#define Int64ShllMod32(a,b) ((DWORDLONG)(a)<<(b)) -#define Int64ShraMod32(a,b) ((LONGLONG)(a)>>(b)) + + typedef double LONGLONG; + typedef double ULONGLONG; +#endif + + typedef LONGLONG *PLONGLONG; + typedef ULONGLONG *PULONGLONG; + + typedef LONGLONG USN; + + typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + }; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; + } LARGE_INTEGER; + + typedef LARGE_INTEGER *PLARGE_INTEGER; + + typedef union _ULARGE_INTEGER { + struct { + DWORD LowPart; + DWORD HighPart; + }; + struct { + DWORD LowPart; + DWORD HighPart; + } u; + ULONGLONG QuadPart; + } ULARGE_INTEGER; + + typedef ULARGE_INTEGER *PULARGE_INTEGER; + + typedef struct _LUID { + DWORD LowPart; + LONG HighPart; + } LUID,*PLUID; + +#define _DWORDLONG_ + typedef ULONGLONG DWORDLONG; + typedef DWORDLONG *PDWORDLONG; + +#ifdef RC_INVOKED +#define Int32x32To64(a,b) ((LONGLONG)((LONG)(a)) *(LONGLONG)((LONG)(b))) +#define UInt32x32To64(a,b) ((ULONGLONG)((DWORD)(a)) *(ULONGLONG)((DWORD)(b))) +#define Int64ShrlMod32(a,b) ((ULONGLONG)(a) >> (b)) +#elif (defined(_X86_) && !defined(__x86_64)) +#define Int32x32To64(a,b) (LONGLONG)((LONGLONG)(LONG)(a) *(LONG)(b)) +#define UInt32x32To64(a,b) (ULONGLONG)((ULONGLONG)(DWORD)(a) *(DWORD)(b)) #define Int64ShrlMod32(a,b) ((DWORDLONG)(a)>>(b)) +#elif defined(__ia64__) || defined(__x86_64) +#define Int32x32To64(a,b) ((LONGLONG)((LONG)(a)) *(LONGLONG)((LONG)(b))) +#define UInt32x32To64(a,b) ((ULONGLONG)((DWORD)(a)) *(ULONGLONG)((DWORD)(b))) +#define Int64ShrlMod32(a,b) ((ULONGLONG)(a) >> (b)) +#else +#error Must define a target architecture. #endif -#define ANSI_NULL '\0' -#define UNICODE_NULL L'\0' -typedef BYTE BOOLEAN,*PBOOLEAN; + +#define Int64ShraMod32(a,b) ((LONGLONG)(a) >> (b)) +#define Int64ShllMod32(a,b) ((ULONGLONG)(a) << (b)) + +#ifdef __cplusplus + extern "C" { #endif -#define NTAPI __stdcall -#include <basetsd.h> -#define APPLICATION_ERROR_MASK 0x20000000 -#define ERROR_SEVERITY_SUCCESS 0x00000000 -#define ERROR_SEVERITY_INFORMATIONAL 0x40000000 -#define ERROR_SEVERITY_WARNING 0x80000000 -#define ERROR_SEVERITY_ERROR 0xC0000000 -#define COMPRESSION_FORMAT_NONE 0 -#define COMPRESSION_FORMAT_DEFAULT 1 -#define COMPRESSION_FORMAT_LZNT1 2 -#define COMPRESSION_ENGINE_STANDARD 0 -#define COMPRESSION_ENGINE_MAXIMUM 256 -#define ACCESS_ALLOWED_ACE_TYPE 0 -#define ACCESS_DENIED_ACE_TYPE 1 -#define ANYSIZE_ARRAY 1 -#define SYSTEM_AUDIT_ACE_TYPE 2 -#define SYSTEM_ALARM_ACE_TYPE 3 -#define OBJECT_INHERIT_ACE 1 -#define CONTAINER_INHERIT_ACE 2 -#define NO_PROPAGATE_INHERIT_ACE 4 -#define INHERIT_ONLY_ACE 8 -#define VALID_INHERIT_FLAGS 16 -#define SUCCESSFUL_ACCESS_ACE_FLAG 64 -#define FAILED_ACCESS_ACE_FLAG 128 -#define DELETE 0x00010000L -#define READ_CONTROL 0x20000L -#define WRITE_DAC 0x40000L -#define WRITE_OWNER 0x80000L -#define SYNCHRONIZE 0x100000L -#define STANDARD_RIGHTS_REQUIRED 0xF0000 -#define STANDARD_RIGHTS_READ 0x20000 -#define STANDARD_RIGHTS_WRITE 0x20000 -#define STANDARD_RIGHTS_EXECUTE 0x20000 -#define STANDARD_RIGHTS_ALL 0x1F0000 -#define SPECIFIC_RIGHTS_ALL 0xFFFF -#define ACCESS_SYSTEM_SECURITY 0x1000000 -#define MAXIMUM_ALLOWED 0x2000000 -#define GENERIC_READ 0x80000000 -#define GENERIC_WRITE 0x40000000 -#define GENERIC_EXECUTE 0x20000000 -#define GENERIC_ALL 0x10000000 -#define FILE_READ_DATA 1 -#define FILE_LIST_DIRECTORY 1 -#define FILE_WRITE_DATA 2 -#define FILE_ADD_FILE 2 -#define FILE_APPEND_DATA 4 -#define FILE_ADD_SUBDIRECTORY 4 -#define FILE_CREATE_PIPE_INSTANCE 4 -#define FILE_READ_EA 8 -#define FILE_READ_PROPERTIES 8 -#define FILE_WRITE_EA 16 -#define FILE_WRITE_PROPERTIES 16 -#define FILE_EXECUTE 32 -#define FILE_TRAVERSE 32 -#define FILE_DELETE_CHILD 64 -#define FILE_READ_ATTRIBUTES 128 -#define FILE_WRITE_ATTRIBUTES 256 -#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1FF) -#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ|FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA|SYNCHRONIZE) -#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONIZE) -#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|FILE_READ_ATTRIBUTES|FILE_EXECUTE|SYNCHRONIZE) -#define FILE_SHARE_READ 1 -#define FILE_SHARE_WRITE 2 -#define FILE_SHARE_DELETE 4 -#define FILE_ATTRIBUTE_READONLY 1 -#define FILE_ATTRIBUTE_HIDDEN 2 -#define FILE_ATTRIBUTE_SYSTEM 4 -#define FILE_ATTRIBUTE_DIRECTORY 16 -#define FILE_ATTRIBUTE_ARCHIVE 32 -#define FILE_ATTRIBUTE_DEVICE 64 -#define FILE_ATTRIBUTE_NORMAL 128 -#define FILE_ATTRIBUTE_TEMPORARY 256 -#define FILE_ATTRIBUTE_SPARSE_FILE 512 -#define FILE_ATTRIBUTE_REPARSE_POINT 1024 -#define FILE_ATTRIBUTE_COMPRESSED 2048 -#define FILE_ATTRIBUTE_OFFLINE 0x1000 -#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000 -#define FILE_ATTRIBUTE_ENCRYPTED 0x4000 -#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) -#define FILE_NOTIFY_CHANGE_FILE_NAME 1 -#define FILE_NOTIFY_CHANGE_DIR_NAME 2 -#define FILE_NOTIFY_CHANGE_ATTRIBUTES 4 -#define FILE_NOTIFY_CHANGE_SIZE 8 -#define FILE_NOTIFY_CHANGE_LAST_WRITE 16 -#define FILE_NOTIFY_CHANGE_LAST_ACCESS 32 -#define FILE_NOTIFY_CHANGE_CREATION 64 -#define FILE_NOTIFY_CHANGE_SECURITY 256 -#define MAILSLOT_NO_MESSAGE ((DWORD)-1) -#define MAILSLOT_WAIT_FOREVER ((DWORD)-1) -#define FILE_CASE_SENSITIVE_SEARCH 1 -#define FILE_CASE_PRESERVED_NAMES 2 -#define FILE_UNICODE_ON_DISK 4 -#define FILE_PERSISTENT_ACLS 8 -#define FILE_FILE_COMPRESSION 16 -#define FILE_VOLUME_QUOTAS 32 -#define FILE_SUPPORTS_SPARSE_FILES 64 -#define FILE_SUPPORTS_REPARSE_POINTS 128 -#define FILE_SUPPORTS_REMOTE_STORAGE 256 -#define FILE_VOLUME_IS_COMPRESSED 0x8000 -#define FILE_SUPPORTS_OBJECT_IDS 0x10000 -#define FILE_SUPPORTS_ENCRYPTION 0x20000 -#define FILE_NAMED_STREAMS 0x40000 -#define IO_COMPLETION_MODIFY_STATE 2 -#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|3) -#define DUPLICATE_CLOSE_SOURCE 1 -#define DUPLICATE_SAME_ACCESS 2 -#define PROCESS_TERMINATE 1 -#define PROCESS_CREATE_THREAD 2 -#define PROCESS_VM_OPERATION 8 -#define PROCESS_VM_READ 16 -#define PROCESS_VM_WRITE 32 -#define PROCESS_DUP_HANDLE 64 -#define PROCESS_CREATE_PROCESS 128 -#define PROCESS_SET_QUOTA 256 -#define PROCESS_SET_INFORMATION 512 -#define PROCESS_QUERY_INFORMATION 1024 -#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xFFF) -#define THREAD_TERMINATE 1 -#define THREAD_SUSPEND_RESUME 2 -#define THREAD_GET_CONTEXT 8 -#define THREAD_SET_CONTEXT 16 -#define THREAD_SET_INFORMATION 32 -#define THREAD_QUERY_INFORMATION 64 -#define THREAD_SET_THREAD_TOKEN 128 -#define THREAD_IMPERSONATE 256 -#define THREAD_DIRECT_IMPERSONATION 0x200 -#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3FF) -#define EXCEPTION_NONCONTINUABLE 1 +#ifdef __x86_64 + +#define RotateLeft8 _rotl8 +#define RotateLeft16 _rotl16 +#define RotateRight8 _rotr8 +#define RotateRight16 _rotr16 + + unsigned char __cdecl _rotl8(unsigned char Value,unsigned char Shift); + unsigned short __cdecl _rotl16(unsigned short Value,unsigned char Shift); + unsigned char __cdecl _rotr8(unsigned char Value,unsigned char Shift); + unsigned short __cdecl _rotr16(unsigned short Value,unsigned char Shift); +#endif + +#define RotateLeft32 _rotl +#define RotateLeft64 _rotl64 +#define RotateRight32 _rotr +#define RotateRight64 _rotr64 + + unsigned int __cdecl _rotl(unsigned int Value,int Shift); + unsigned __int64 __cdecl _rotl64(unsigned __int64 Value,int Shift); + unsigned int __cdecl _rotr(unsigned int Value,int Shift); + unsigned __int64 __cdecl _rotr64(unsigned __int64 Value,int Shift); +#ifdef __cplusplus + } +#endif + +#define ANSI_NULL ((CHAR)0) +#define UNICODE_NULL ((WCHAR)0) +#define UNICODE_STRING_MAX_BYTES ((WORD) 65534) +#define UNICODE_STRING_MAX_CHARS (32767) + +#ifndef _BOOLEAN_ +#define _BOOLEAN_ + typedef BYTE BOOLEAN; +#endif + typedef BOOLEAN *PBOOLEAN; + + typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; + } LIST_ENTRY,*PLIST_ENTRY,*RESTRICTED_POINTER PRLIST_ENTRY; + + typedef struct _SINGLE_LIST_ENTRY { + struct _SINGLE_LIST_ENTRY *Next; + } SINGLE_LIST_ENTRY,*PSINGLE_LIST_ENTRY; + + typedef struct LIST_ENTRY32 { + DWORD Flink; + DWORD Blink; + } LIST_ENTRY32; + typedef LIST_ENTRY32 *PLIST_ENTRY32; + + typedef struct LIST_ENTRY64 { + ULONGLONG Flink; + ULONGLONG Blink; + } LIST_ENTRY64; + typedef LIST_ENTRY64 *PLIST_ENTRY64; + +#include <guiddef.h> + +#ifndef __OBJECTID_DEFINED +#define __OBJECTID_DEFINED + typedef struct _OBJECTID { + GUID Lineage; + DWORD Uniquifier; + } OBJECTID; +#endif + +#define MINCHAR 0x80 +#define MAXCHAR 0x7f +#define MINSHORT 0x8000 +#define MAXSHORT 0x7fff +#define MINLONG 0x80000000 +#define MAXLONG 0x7fffffff +#define MAXBYTE 0xff +#define MAXWORD 0xffff +#define MAXDWORD 0xffffffff + +#define FIELD_OFFSET(type,field) ((LONG)(LONG_PTR)&(((type *)0)->field)) +#define RTL_FIELD_SIZE(type,field) (sizeof(((type *)0)->field)) +#define RTL_SIZEOF_THROUGH_FIELD(type,field) (FIELD_OFFSET(type,field) + RTL_FIELD_SIZE(type,field)) +#define RTL_CONTAINS_FIELD(Struct,Size,Field) ((((PCHAR)(&(Struct)->Field)) + sizeof((Struct)->Field)) <= (((PCHAR)(Struct))+(Size))) +#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0])) +#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A) + +#ifdef ENABLE_RTL_NUMBER_OF_V2 +#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V2(A) +#else +#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A) +#endif + +#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A) +#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A) + +#define RTL_FIELD_TYPE(type,field) (((type*)0)->field) +#define RTL_NUMBER_OF_FIELD(type,field) (RTL_NUMBER_OF(RTL_FIELD_TYPE(type,field))) +#define RTL_PADDING_BETWEEN_FIELDS(T,F1,F2) ((FIELD_OFFSET(T,F2) > FIELD_OFFSET(T,F1)) ? (FIELD_OFFSET(T,F2) - FIELD_OFFSET(T,F1) - RTL_FIELD_SIZE(T,F1)) : (FIELD_OFFSET(T,F1) - FIELD_OFFSET(T,F2) - RTL_FIELD_SIZE(T,F2))) + +#ifdef __cplusplus +#define RTL_CONST_CAST(type) const_cast<type> +#else +#define RTL_CONST_CAST(type) (type) +#endif + +#define RTL_BITS_OF(sizeOfArg) (sizeof(sizeOfArg) *8) +#define RTL_BITS_OF_FIELD(type,field) (RTL_BITS_OF(RTL_FIELD_TYPE(type,field))) +#define CONTAINING_RECORD(address,type,field) ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field))) + +#define VER_SERVER_NT 0x80000000 +#define VER_WORKSTATION_NT 0x40000000 +#define VER_SUITE_SMALLBUSINESS 0x00000001 +#define VER_SUITE_ENTERPRISE 0x00000002 +#define VER_SUITE_BACKOFFICE 0x00000004 +#define VER_SUITE_COMMUNICATIONS 0x00000008 +#define VER_SUITE_TERMINAL 0x00000010 +#define VER_SUITE_SMALLBUSINESS_RESTRICTED 0x00000020 +#define VER_SUITE_EMBEDDEDNT 0x00000040 +#define VER_SUITE_DATACENTER 0x00000080 +#define VER_SUITE_SINGLEUSERTS 0x00000100 +#define VER_SUITE_PERSONAL 0x00000200 +#define VER_SUITE_BLADE 0x00000400 +#define VER_SUITE_EMBEDDED_RESTRICTED 0x00000800 +#define VER_SUITE_SECURITY_APPLIANCE 0x00001000 +#define VER_SUITE_STORAGE_SERVER 0x00002000 +#define VER_SUITE_COMPUTE_SERVER 0x00004000 + +#define PRODUCT_UNDEFINED 0x0 + +#define PRODUCT_ULTIMATE 0x1 +#define PRODUCT_HOME_BASIC 0x2 +#define PRODUCT_HOME_PREMIUM 0x3 +#define PRODUCT_ENTERPRISE 0x4 +#define PRODUCT_HOME_BASIC_N 0x5 +#define PRODUCT_BUSINESS 0x6 +#define PRODUCT_STANDARD_SERVER 0x7 +#define PRODUCT_DATACENTER_SERVER 0x8 +#define PRODUCT_SMALLBUSINESS_SERVER 0x9 +#define PRODUCT_ENTERPRISE_SERVER 0xa +#define PRODUCT_STARTER 0xb +#define PRODUCT_DATACENTER_SERVER_CORE 0xc +#define PRODUCT_STANDARD_SERVER_CORE 0xd +#define PRODUCT_ENTERPRISE_SERVER_CORE 0xe +#define PRODUCT_ENTERPRISE_SERVER_IA64 0xf +#define PRODUCT_BUSINESS_N 0x10 +#define PRODUCT_WEB_SERVER 0x11 +#define PRODUCT_CLUSTER_SERVER 0x12 +#define PRODUCT_HOME_SERVER 0x13 +#define PRODUCT_STORAGE_EXPRESS_SERVER 0x14 +#define PRODUCT_STORAGE_STANDARD_SERVER 0x15 +#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x16 +#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x17 +#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x18 +#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x19 + +#define PRODUCT_UNLICENSED 0xabcdabcd + +#define LANG_NEUTRAL 0x00 +#define LANG_INVARIANT 0x7f + +#define LANG_AFRIKAANS 0x36 +#define LANG_ALBANIAN 0x1c +#define LANG_ALSATIAN 0x84 +#define LANG_AMHARIC 0x5e +#define LANG_ARABIC 0x01 +#define LANG_ARMENIAN 0x2b +#define LANG_ASSAMESE 0x4d +#define LANG_AZERI 0x2c +#define LANG_BASHKIR 0x6d +#define LANG_BASQUE 0x2d +#define LANG_BELARUSIAN 0x23 +#define LANG_BENGALI 0x45 +#define LANG_BRETON 0x7e +#define LANG_BOSNIAN 0x1a +#define LANG_BOSNIAN_NEUTRAL 0x781a +#define LANG_BULGARIAN 0x02 +#define LANG_CATALAN 0x03 +#define LANG_CHINESE 0x04 +#define LANG_CHINESE_SIMPLIFIED 0x04 +#define LANG_CHINESE_TRADITIONAL 0x7c04 +#define LANG_CORSICAN 0x83 +#define LANG_CROATIAN 0x1a +#define LANG_CZECH 0x05 +#define LANG_DANISH 0x06 +#define LANG_DARI 0x8c +#define LANG_DIVEHI 0x65 +#define LANG_DUTCH 0x13 +#define LANG_ENGLISH 0x09 +#define LANG_ESTONIAN 0x25 +#define LANG_FAEROESE 0x38 +#define LANG_FARSI 0x29 +#define LANG_FILIPINO 0x64 +#define LANG_FINNISH 0x0b +#define LANG_FRENCH 0x0c +#define LANG_FRISIAN 0x62 +#define LANG_GALICIAN 0x56 +#define LANG_GEORGIAN 0x37 +#define LANG_GERMAN 0x07 +#define LANG_GREEK 0x08 +#define LANG_GREENLANDIC 0x6f +#define LANG_GUJARATI 0x47 +#define LANG_HAUSA 0x68 +#define LANG_HEBREW 0x0d +#define LANG_HINDI 0x39 +#define LANG_HUNGARIAN 0x0e +#define LANG_ICELANDIC 0x0f +#define LANG_IGBO 0x70 +#define LANG_INDONESIAN 0x21 +#define LANG_INUKTITUT 0x5d +#define LANG_IRISH 0x3c +#define LANG_ITALIAN 0x10 +#define LANG_JAPANESE 0x11 +#define LANG_KANNADA 0x4b +#define LANG_KASHMIRI 0x60 +#define LANG_KAZAK 0x3f +#define LANG_KHMER 0x53 +#define LANG_KICHE 0x86 +#define LANG_KINYARWANDA 0x87 +#define LANG_KONKANI 0x57 +#define LANG_KOREAN 0x12 +#define LANG_KYRGYZ 0x40 +#define LANG_LAO 0x54 +#define LANG_LATVIAN 0x26 +#define LANG_LITHUANIAN 0x27 +#define LANG_LOWER_SORBIAN 0x2e +#define LANG_LUXEMBOURGISH 0x6e +#define LANG_MACEDONIAN 0x2f +#define LANG_MALAY 0x3e +#define LANG_MALAYALAM 0x4c +#define LANG_MALTESE 0x3a +#define LANG_MANIPURI 0x58 +#define LANG_MAORI 0x81 +#define LANG_MAPUDUNGUN 0x7a +#define LANG_MARATHI 0x4e +#define LANG_MOHAWK 0x7c +#define LANG_MONGOLIAN 0x50 +#define LANG_NEPALI 0x61 +#define LANG_NORWEGIAN 0x14 +#define LANG_OCCITAN 0x82 +#define LANG_ORIYA 0x48 +#define LANG_PASHTO 0x63 +#define LANG_PERSIAN 0x29 +#define LANG_POLISH 0x15 +#define LANG_PORTUGUESE 0x16 +#define LANG_PUNJABI 0x46 +#define LANG_QUECHUA 0x6b +#define LANG_ROMANIAN 0x18 +#define LANG_RUSSIAN 0x19 +#define LANG_SAMI 0x3b +#define LANG_ROMANSH 0x17 +#define LANG_SANSKRIT 0x4f +#define LANG_SERBIAN 0x1a +#define LANG_SERBIAN_NEUTRAL 0x7c1a +#define LANG_SINDHI 0x59 +#define LANG_SINHALESE 0x5b +#define LANG_SLOVAK 0x1b +#define LANG_SLOVENIAN 0x24 +#define LANG_SOTHO 0x6c +#define LANG_SPANISH 0x0a +#define LANG_SWAHILI 0x41 +#define LANG_SWEDISH 0x1d +#define LANG_SYRIAC 0x5a +#define LANG_TAJIK 0x28 +#define LANG_TAMAZIGHT 0x5f +#define LANG_TAMIL 0x49 +#define LANG_TATAR 0x44 +#define LANG_TELUGU 0x4a +#define LANG_THAI 0x1e +#define LANG_TIBETAN 0x51 +#define LANG_TIGRIGNA 0x73 +#define LANG_TSWANA 0x32 +#define LANG_TURKISH 0x1f +#define LANG_TURKMEN 0x42 +#define LANG_UIGHUR 0x80 +#define LANG_UKRAINIAN 0x22 +#define LANG_UPPER_SORBIAN 0x2e +#define LANG_URDU 0x20 +#define LANG_UZBEK 0x43 +#define LANG_VIETNAMESE 0x2a +#define LANG_WELSH 0x52 +#define LANG_WOLOF 0x88 +#define LANG_XHOSA 0x34 +#define LANG_YAKUT 0x85 +#define LANG_YI 0x78 +#define LANG_YORUBA 0x6a +#define LANG_ZULU 0x35 + +#define SUBLANG_NEUTRAL 0x0 +#define SUBLANG_DEFAULT 0x1 +#define SUBLANG_SYS_DEFAULT 0x2 +#define SUBLANG_CUSTOM_DEFAULT 0x3 +#define SUBLANG_CUSTOM_UNSPECIFIED 0x4 +#define SUBLANG_UI_CUSTOM_DEFAULT 0x5 + +#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01 +#define SUBLANG_ARABIC_IRAQ 0x02 +#define SUBLANG_ARABIC_EGYPT 0x03 +#define SUBLANG_ARABIC_LIBYA 0x04 +#define SUBLANG_ARABIC_ALGERIA 0x05 +#define SUBLANG_ARABIC_MOROCCO 0x06 +#define SUBLANG_ARABIC_TUNISIA 0x07 +#define SUBLANG_ARABIC_OMAN 0x08 +#define SUBLANG_ARABIC_YEMEN 0x09 +#define SUBLANG_ARABIC_SYRIA 0x0a +#define SUBLANG_ARABIC_JORDAN 0x0b +#define SUBLANG_ARABIC_LEBANON 0x0c +#define SUBLANG_ARABIC_KUWAIT 0x0d +#define SUBLANG_ARABIC_UAE 0x0e +#define SUBLANG_ARABIC_BAHRAIN 0x0f +#define SUBLANG_ARABIC_QATAR 0x10 +#define SUBLANG_AZERI_LATIN 0x01 +#define SUBLANG_AZERI_CYRILLIC 0x02 +#define SUBLANG_CHINESE_TRADITIONAL 0x01 +#define SUBLANG_CHINESE_SIMPLIFIED 0x02 +#define SUBLANG_CHINESE_HONGKONG 0x03 +#define SUBLANG_CHINESE_SINGAPORE 0x04 +#define SUBLANG_CHINESE_MACAU 0x05 +#define SUBLANG_DUTCH 0x01 +#define SUBLANG_DUTCH_BELGIAN 0x02 +#define SUBLANG_ENGLISH_US 0x01 +#define SUBLANG_ENGLISH_UK 0x02 +#define SUBLANG_ENGLISH_AUS 0x03 +#define SUBLANG_ENGLISH_CAN 0x04 +#define SUBLANG_ENGLISH_NZ 0x05 +#define SUBLANG_ENGLISH_EIRE 0x06 +#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07 +#define SUBLANG_ENGLISH_JAMAICA 0x08 +#define SUBLANG_ENGLISH_CARIBBEAN 0x09 +#define SUBLANG_ENGLISH_BELIZE 0x0a +#define SUBLANG_ENGLISH_TRINIDAD 0x0b +#define SUBLANG_ENGLISH_ZIMBABWE 0x0c +#define SUBLANG_ENGLISH_PHILIPPINES 0x0d +#define SUBLANG_FRENCH 0x01 +#define SUBLANG_FRENCH_BELGIAN 0x02 +#define SUBLANG_FRENCH_CANADIAN 0x03 +#define SUBLANG_FRENCH_SWISS 0x04 +#define SUBLANG_FRENCH_LUXEMBOURG 0x05 +#define SUBLANG_FRENCH_MONACO 0x06 +#define SUBLANG_GERMAN 0x01 +#define SUBLANG_GERMAN_SWISS 0x02 +#define SUBLANG_GERMAN_AUSTRIAN 0x03 +#define SUBLANG_GERMAN_LUXEMBOURG 0x04 +#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05 +#define SUBLANG_ITALIAN 0x01 +#define SUBLANG_ITALIAN_SWISS 0x02 +#define SUBLANG_KASHMIRI_SASIA 0x02 +#define SUBLANG_KASHMIRI_INDIA 0x02 +#define SUBLANG_KOREAN 0x01 +#define SUBLANG_LITHUANIAN 0x01 +#define SUBLANG_MALAY_MALAYSIA 0x01 +#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 +#define SUBLANG_NEPALI_INDIA 0x02 +#define SUBLANG_NORWEGIAN_BOKMAL 0x01 +#define SUBLANG_NORWEGIAN_NYNORSK 0x02 +#define SUBLANG_PORTUGUESE 0x02 +#define SUBLANG_PORTUGUESE_BRAZILIAN 0x01 +#define SUBLANG_SERBIAN_LATIN 0x02 +#define SUBLANG_SERBIAN_CYRILLIC 0x03 +#define SUBLANG_SPANISH 0x01 +#define SUBLANG_SPANISH_MEXICAN 0x02 +#define SUBLANG_SPANISH_MODERN 0x03 +#define SUBLANG_SPANISH_GUATEMALA 0x04 +#define SUBLANG_SPANISH_COSTA_RICA 0x05 +#define SUBLANG_SPANISH_PANAMA 0x06 +#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07 +#define SUBLANG_SPANISH_VENEZUELA 0x08 +#define SUBLANG_SPANISH_COLOMBIA 0x09 +#define SUBLANG_SPANISH_PERU 0x0a +#define SUBLANG_SPANISH_ARGENTINA 0x0b +#define SUBLANG_SPANISH_ECUADOR 0x0c +#define SUBLANG_SPANISH_CHILE 0x0d +#define SUBLANG_SPANISH_URUGUAY 0x0e +#define SUBLANG_SPANISH_PARAGUAY 0x0f +#define SUBLANG_SPANISH_BOLIVIA 0x10 +#define SUBLANG_SPANISH_EL_SALVADOR 0x11 +#define SUBLANG_SPANISH_HONDURAS 0x12 +#define SUBLANG_SPANISH_NICARAGUA 0x13 +#define SUBLANG_SPANISH_PUERTO_RICO 0x14 +#define SUBLANG_SWEDISH 0x01 +#define SUBLANG_SWEDISH_FINLAND 0x02 +#define SUBLANG_URDU_PAKISTAN 0x01 +#define SUBLANG_URDU_INDIA 0x02 +#define SUBLANG_UZBEK_LATIN 0x01 +#define SUBLANG_UZBEK_CYRILLIC 0x02 + +#define SORT_DEFAULT 0x0 +#define SORT_INVARIANT_MATH 0x1 + +#define SORT_JAPANESE_XJIS 0x0 +#define SORT_JAPANESE_UNICODE 0x1 +#define SORT_JAPANESE_RADICALSTROKE 0x4 + +#define SORT_CHINESE_BIG5 0x0 +#define SORT_CHINESE_PRCP 0x0 +#define SORT_CHINESE_UNICODE 0x1 +#define SORT_CHINESE_PRC 0x2 +#define SORT_CHINESE_BOPOMOFO 0x3 + +#define SORT_KOREAN_KSC 0x0 +#define SORT_KOREAN_UNICODE 0x1 + +#define SORT_GERMAN_PHONE_BOOK 0x1 + +#define SORT_HUNGARIAN_DEFAULT 0x0 +#define SORT_HUNGARIAN_TECHNICAL 0x1 + +#define SORT_GEORGIAN_TRADITIONAL 0x0 +#define SORT_GEORGIAN_MODERN 0x1 + +#define MAKELANGID(p,s) ((((WORD)(s)) << 10) | (WORD)(p)) +#define PRIMARYLANGID(lgid) ((WORD)(lgid) & 0x3ff) +#define SUBLANGID(lgid) ((WORD)(lgid) >> 10) + +#define NLS_VALID_LOCALE_MASK 0x000fffff + +#define MAKELCID(lgid,srtid) ((DWORD)((((DWORD)((WORD)(srtid))) << 16) | ((DWORD)((WORD)(lgid))))) +#define MAKESORTLCID(lgid,srtid,ver) ((DWORD)((MAKELCID(lgid,srtid)) | (((DWORD)((WORD)(ver))) << 20))) +#define LANGIDFROMLCID(lcid) ((WORD)(lcid)) +#define SORTIDFROMLCID(lcid) ((WORD)((((DWORD)(lcid)) >> 16) & 0xf)) +#define SORTVERSIONFROMLCID(lcid) ((WORD)((((DWORD)(lcid)) >> 20) & 0xf)) + +#define LOCALE_NAME_MAX_LENGTH 85 +#define LANG_SYSTEM_DEFAULT (MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT)) +#define LANG_USER_DEFAULT (MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT)) + +#define LOCALE_SYSTEM_DEFAULT (MAKELCID(LANG_SYSTEM_DEFAULT,SORT_DEFAULT)) +#define LOCALE_USER_DEFAULT (MAKELCID(LANG_USER_DEFAULT,SORT_DEFAULT)) + +#define LOCALE_NEUTRAL (MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT)) + +#define LOCALE_CUSTOM_DEFAULT (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_CUSTOM_DEFAULT), SORT_DEFAULT)) +#define LOCALE_CUSTOM_UNSPECIFIED (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_CUSTOM_UNSPECIFIED), SORT_DEFAULT)) +#define LOCALE_CUSTOM_UI_DEFAULT (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_UI_CUSTOM_DEFAULT), SORT_DEFAULT)) + +#define LOCALE_INVARIANT (MAKELCID(MAKELANGID(LANG_INVARIANT,SUBLANG_NEUTRAL),SORT_DEFAULT)) + +#define UNREFERENCED_PARAMETER(P) (P) +#define DBG_UNREFERENCED_PARAMETER(P) (P) +#define DBG_UNREFERENCED_LOCAL_VARIABLE(V) (V) + +#define DEFAULT_UNREACHABLE + +#ifndef WIN32_NO_STATUS +#define STATUS_WAIT_0 ((DWORD)0x00000000L) +#define STATUS_ABANDONED_WAIT_0 ((DWORD)0x00000080L) +#define STATUS_USER_APC ((DWORD)0x000000C0L) +#define STATUS_TIMEOUT ((DWORD)0x00000102L) +#define STATUS_PENDING ((DWORD)0x00000103L) +#define DBG_EXCEPTION_HANDLED ((DWORD)0x00010001L) +#define DBG_CONTINUE ((DWORD)0x00010002L) +#define STATUS_SEGMENT_NOTIFICATION ((DWORD)0x40000005L) +#define DBG_TERMINATE_THREAD ((DWORD)0x40010003L) +#define DBG_TERMINATE_PROCESS ((DWORD)0x40010004L) +#define DBG_CONTROL_C ((DWORD)0x40010005L) +#define DBG_CONTROL_BREAK ((DWORD)0x40010008L) +#define DBG_COMMAND_EXCEPTION ((DWORD)0x40010009L) +#define STATUS_GUARD_PAGE_VIOLATION ((DWORD)0x80000001L) +#define STATUS_DATATYPE_MISALIGNMENT ((DWORD)0x80000002L) +#define STATUS_BREAKPOINT ((DWORD)0x80000003L) +#define STATUS_SINGLE_STEP ((DWORD)0x80000004L) +#define DBG_EXCEPTION_NOT_HANDLED ((DWORD)0x80010001L) +#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L) +#define STATUS_IN_PAGE_ERROR ((DWORD)0xC0000006L) +#define STATUS_INVALID_HANDLE ((DWORD)0xC0000008L) +#define STATUS_NO_MEMORY ((DWORD)0xC0000017L) +#define STATUS_ILLEGAL_INSTRUCTION ((DWORD)0xC000001DL) +#define STATUS_NONCONTINUABLE_EXCEPTION ((DWORD)0xC0000025L) +#define STATUS_INVALID_DISPOSITION ((DWORD)0xC0000026L) +#define STATUS_ARRAY_BOUNDS_EXCEEDED ((DWORD)0xC000008CL) +#define STATUS_FLOAT_DENORMAL_OPERAND ((DWORD)0xC000008DL) +#define STATUS_FLOAT_DIVIDE_BY_ZERO ((DWORD)0xC000008EL) +#define STATUS_FLOAT_INEXACT_RESULT ((DWORD)0xC000008FL) +#define STATUS_FLOAT_INVALID_OPERATION ((DWORD)0xC0000090L) +#define STATUS_FLOAT_OVERFLOW ((DWORD)0xC0000091L) +#define STATUS_FLOAT_STACK_CHECK ((DWORD)0xC0000092L) +#define STATUS_FLOAT_UNDERFLOW ((DWORD)0xC0000093L) +#define STATUS_INTEGER_DIVIDE_BY_ZERO ((DWORD)0xC0000094L) +#define STATUS_INTEGER_OVERFLOW ((DWORD)0xC0000095L) +#define STATUS_PRIVILEGED_INSTRUCTION ((DWORD)0xC0000096L) +#define STATUS_STACK_OVERFLOW ((DWORD)0xC00000FDL) +#define STATUS_CONTROL_C_EXIT ((DWORD)0xC000013AL) +#define STATUS_FLOAT_MULTIPLE_FAULTS ((DWORD)0xC00002B4L) +#define STATUS_FLOAT_MULTIPLE_TRAPS ((DWORD)0xC00002B5L) +#define STATUS_REG_NAT_CONSUMPTION ((DWORD)0xC00002C9L) +#define STATUS_SXS_EARLY_DEACTIVATION ((DWORD)0xC015000FL) +#define STATUS_SXS_INVALID_DEACTIVATION ((DWORD)0xC0150010L) +#endif + +#define MAXIMUM_WAIT_OBJECTS 64 +#define MAXIMUM_SUSPEND_COUNT MAXCHAR + + typedef ULONG_PTR KSPIN_LOCK; + typedef KSPIN_LOCK *PKSPIN_LOCK; + +#ifdef _AMD64_ + +#if defined(__x86_64) && !defined(RC_INVOKED) + +#ifdef __cplusplus + extern "C" { +#endif + +#define BitTest _bittest +#define BitTestAndComplement _bittestandcomplement +#define BitTestAndSet _bittestandset +#define BitTestAndReset _bittestandreset +#define InterlockedBitTestAndSet _interlockedbittestandset +#define InterlockedBitTestAndReset _interlockedbittestandreset +#define BitTest64 _bittest64 +#define BitTestAndComplement64 _bittestandcomplement64 +#define BitTestAndSet64 _bittestandset64 +#define BitTestAndReset64 _bittestandreset64 +#define InterlockedBitTestAndSet64 _interlockedbittestandset64 +#define InterlockedBitTestAndReset64 _interlockedbittestandreset64 + + __CRT_INLINE BOOLEAN _bittest(LONG const *Base,LONG Offset) { + int old = 0; + __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _bittestandcomplement(LONG *Base,LONG Offset) { + int old = 0; + __asm__ __volatile__("btcl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN InterlockedBitTestAndComplement(LONG *Base,LONG Bit) { + int old = 0; + __asm__ __volatile__("lock ; btcl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Bit)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _bittestandset(LONG *Base,LONG Offset) { + int old = 0; + __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _bittestandreset(LONG *Base,LONG Offset) { + int old = 0; + __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _interlockedbittestandset(LONG *Base,LONG Offset) { + int old = 0; + __asm__ __volatile__("lock ; btsl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _interlockedbittestandreset(LONG *Base,LONG Offset) { + int old = 0; + __asm__ __volatile__("lock ; btrl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _bittest64(LONG64 const *Base,LONG64 Offset) { + int old = 0; + __asm__ __volatile__("btq %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _bittestandcomplement64(LONG64 *Base,LONG64 Offset) { + int old = 0; + __asm__ __volatile__("btcq %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _bittestandset64(LONG64 *Base,LONG64 Offset) { + int old = 0; + __asm__ __volatile__("btsq %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _bittestandreset64(LONG64 *Base,LONG64 Offset) { + int old = 0; + __asm__ __volatile__("btrq %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _interlockedbittestandset64(LONG64 *Base,LONG64 Offset) { + int old = 0; + __asm__ __volatile__("lock ; btsq %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } + __CRT_INLINE BOOLEAN _interlockedbittestandreset64(LONG64 *Base,LONG64 Offset) { + int old = 0; + __asm__ __volatile__("lock ; btrq %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long long *) Base)) + :"Ir" (Offset)); + return (BOOLEAN) (old!=0); + } +#define BitScanForward _BitScanForward +#define BitScanReverse _BitScanReverse +#define BitScanForward64 _BitScanForward64 +#define BitScanReverse64 _BitScanReverse64 + + __CRT_INLINE BOOLEAN _BitScanForward(DWORD *Index,DWORD Mask) { + __asm__ __volatile__("bsfl %1,%0" : "=r" (Mask),"=m" ((*(volatile long *)Index))); + return Mask!=0; + } + __CRT_INLINE BOOLEAN _BitScanReverse(DWORD *Index,DWORD Mask) { + __asm__ __volatile__("bsrl %1,%0" : "=r" (Mask),"=m" ((*(volatile long *)Index))); + return Mask!=0; + } + __CRT_INLINE BOOLEAN _BitScanForward64(DWORD *Index,DWORD64 Mask) { + __asm__ __volatile__("bsfq %1,%0" : "=r" (Mask),"=m" ((*(volatile long long *)Index))); + return Mask!=0; + } + __CRT_INLINE BOOLEAN _BitScanReverse64(DWORD *Index,DWORD64 Mask) { + __asm__ __volatile__("bsrq %1,%0" : "=r" (Mask),"=m" ((*(volatile long long *)Index))); + return Mask!=0; + } + +#define InterlockedIncrement16 _InterlockedIncrement16 +#define InterlockedDecrement16 _InterlockedDecrement16 +#define InterlockedCompareExchange16 _InterlockedCompareExchange16 + +#define InterlockedAnd _InterlockedAnd +#define InterlockedOr _InterlockedOr +#define InterlockedXor _InterlockedXor +#define InterlockedIncrement _InterlockedIncrement +#define InterlockedIncrementAcquire InterlockedIncrement +#define InterlockedIncrementRelease InterlockedIncrement +#define InterlockedDecrement _InterlockedDecrement +#define InterlockedDecrementAcquire InterlockedDecrement +#define InterlockedDecrementRelease InterlockedDecrement +#define InterlockedAdd _InterlockedAdd +#define InterlockedExchange _InterlockedExchange +#define InterlockedExchangeAdd _InterlockedExchangeAdd +#define InterlockedCompareExchange _InterlockedCompareExchange +#define InterlockedCompareExchangeAcquire InterlockedCompareExchange +#define InterlockedCompareExchangeRelease InterlockedCompareExchange + +#define InterlockedAnd64 _InterlockedAnd64 +#define InterlockedAndAffinity InterlockedAnd64 +#define InterlockedOr64 _InterlockedOr64 +#define InterlockedOrAffinity InterlockedOr64 +#define InterlockedXor64 _InterlockedXor64 +#define InterlockedIncrement64 _InterlockedIncrement64 +#define InterlockedDecrement64 _InterlockedDecrement64 +#define InterlockedAdd64 _InterlockedAdd64 +#define InterlockedExchange64 _InterlockedExchange64 +#define InterlockedExchangeAcquire64 InterlockedExchange64 +#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64 +#define InterlockedCompareExchange64 _InterlockedCompareExchange64 +#define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64 +#define InterlockedCompareExchangeRelease64 InterlockedCompareExchange64 + +#define InterlockedExchangePointer _InterlockedExchangePointer +#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer +#define InterlockedCompareExchangePointerAcquire _InterlockedCompareExchangePointer +#define InterlockedCompareExchangePointerRelease _InterlockedCompareExchangePointer + +#define InterlockedExchangeAddSizeT(a,b) InterlockedExchangeAdd64((LONG64 *)a,b) +#define InterlockedIncrementSizeT(a) InterlockedIncrement64((LONG64 *)a) +#define InterlockedDecrementSizeT(a) InterlockedDecrement64((LONG64 *)a) + + __CRT_INLINE SHORT InterlockedIncrement16(SHORT volatile *Addend) { + unsigned char c; + unsigned char s; + __asm__ __volatile__( + "lock ; addw $1,%0; sete %1 ; sets %2" + :"=m" (*Addend), "=qm" (c), "=qm" (s) + :"m" (*Addend) : "memory"); + return (c != 0 ? 0 : (s != 0 ? -1 : 1)); + } + __CRT_INLINE SHORT InterlockedDecrement16(SHORT volatile *Addend) { + unsigned char c; + unsigned char s; + __asm__ __volatile__( + "lock ; subw $1,%0; sete %1 ; sets %2" + :"=m" (*Addend), "=qm" (c), "=qm" (s) + :"m" (*Addend) : "memory"); + return (c != 0 ? 0 : (s != 0 ? -1 : 1)); + } + __CRT_INLINE SHORT InterlockedCompareExchange16(SHORT volatile *Destination,SHORT ExChange,SHORT Comperand) { + SHORT prev; + __asm__ __volatile__("lock ; cmpxchgw %w1,%2" + :"=a"(prev) + :"q"(ExChange), "m"(*Destination), "0"(Comperand) + : "memory"); + return prev; + } + __CRT_INLINE LONG InterlockedAnd(LONG volatile *Destination,LONG Value) { + __asm__ __volatile__("lock ; andl %0,%1" + : :"r"(Value),"m"(*Destination) + : "memory"); + return *Destination; + } + __CRT_INLINE LONG InterlockedOr(LONG volatile *Destination,LONG Value) { + __asm__ __volatile__("lock ; orl %0,%1" + : : "r"(Value),"m"(*Destination) : "memory"); + return *Destination; + } + __CRT_INLINE LONG InterlockedXor(LONG volatile *Destination,LONG Value) { + __asm__ __volatile__("lock ; xorl %0,%1" + : : "r"(Value),"m"(*Destination) : "memory"); + return *Destination; + } + // $$$$ + __CRT_INLINE LONG64 InterlockedAnd64(LONG64 volatile *Destination,LONG64 Value) { + __asm__ __volatile__("lock ; andq %0,%1" + : : "r"(Value),"m"(*Destination) : "memory"); + return *Destination; + } + __CRT_INLINE LONG64 InterlockedOr64(LONG64 volatile *Destination,LONG64 Value) { + __asm__ __volatile__("lock ; orq %0,%1" + : : "r"(Value),"m"(*Destination) : "memory"); + return *Destination; + } + __CRT_INLINE LONG64 InterlockedXor64(LONG64 volatile *Destination,LONG64 Value) { + __asm__ __volatile__("lock ; xorq %0,%1" + : : "r"(Value),"m"(*Destination) : "memory"); + return *Destination; + } + __CRT_INLINE LONG InterlockedIncrement(LONG volatile *Addend) { + unsigned char c; + unsigned char s; + __asm__ __volatile__( + "lock ; addl $1,%0; sete %1 ; sets %2" + :"=m" (*Addend), "=qm" (c), "=qm" (s) + :"m" (*Addend) : "memory"); + return (c != 0 ? 0 : (s != 0 ? -1 : 1)); + } + __CRT_INLINE LONG InterlockedDecrement(LONG volatile *Addend) { + unsigned char c; + unsigned char s; + __asm__ __volatile__( + "lock ; subl $1,%0; sete %1 ; sets %2" + :"=m" (*Addend), "=qm" (c), "=qm" (s) + :"m" (*Addend) : "memory"); + return (c != 0 ? 0 : (s != 0 ? -1 : 1)); + } + __CRT_INLINE LONG InterlockedExchange(LONG volatile *Target,LONG Value) { + __asm__ __volatile("lock ; xchgl %0,%1" + : "=r"(Value) + : "m"(*Target),"0"(Value) + : "memory"); + return Value; + } + LONG InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); + +#ifndef _X86AMD64_ + __CRT_INLINE LONG InterlockedAdd(LONG volatile *Addend,LONG Value) { return InterlockedExchangeAdd(Addend,Value) + Value; } +#endif + __CRT_INLINE LONG InterlockedCompareExchange(LONG volatile *Destination,LONG ExChange,LONG Comperand) { + LONG prev; + __asm__ __volatile__("lock ; cmpxchgl %1,%2" : "=a" (prev) : "q" (ExChange),"m" (*Destination), "0" (Comperand) : "memory"); + return prev; + } + __CRT_INLINE LONG64 InterlockedIncrement64(LONG64 volatile *Addend) { + unsigned char c; + unsigned char s; + __asm__ __volatile__( + "lock ; addq $1,%0; sete %1 ; sets %2" + :"=m" (*Addend), "=qm" (c), "=qm" (s) + :"m" (*Addend) : "memory"); + return (c != 0 ? 0 : (s != 0 ? -1 : 1)); + } + __CRT_INLINE LONG64 InterlockedDecrement64(LONG64 volatile *Addend) { + unsigned char c; + unsigned char s; + __asm__ __volatile__( + "lock ; subq $1,%0; sete %1 ; sets %2" + :"=m" (*Addend), "=qm" (c), "=qm" (s) + :"m" (*Addend) : "memory"); + return (c != 0 ? 0 : (s != 0 ? -1 : 1)); + } + __CRT_INLINE LONG64 InterlockedExchange64(LONG64 volatile *Target,LONG64 Value) { + __asm__ __volatile("lock ; xchgq %0,%1" + : "=r"(Value) + : "m"(*Target),"0"(Value) + : "memory"); + return Value; + } + LONG64 InterlockedExchangeAdd64(LONG64 volatile *Addend,LONG64 Value); + +#ifndef _X86AMD64_ + __CRT_INLINE LONG64 InterlockedAdd64(LONG64 volatile *Addend,LONG64 Value) { return InterlockedExchangeAdd64(Addend,Value) + Value; } +#endif + + __CRT_INLINE LONG64 InterlockedCompareExchange64(LONG64 volatile *Destination,LONG64 ExChange,LONG64 Comperand) { + LONG64 prev; + __asm__ __volatile__("lock ; cmpxchgq %1,%2" : "=a" (prev) : "q" (ExChange),"m" (*Destination), "0" (Comperand) : "memory"); + return prev; + } + __CRT_INLINE PVOID InterlockedCompareExchangePointer(PVOID volatile *Destination,PVOID ExChange,PVOID Comperand) { + PVOID prev; + __asm__ __volatile__("lock ; cmpxchgq %1,%2" : "=a" (prev) : "q" (ExChange),"m" (*Destination), "0" (Comperand) : "memory"); + return prev; + } + __CRT_INLINE PVOID InterlockedExchangePointer(PVOID volatile *Target,PVOID Value) { + __asm__ __volatile("lock ; xchgq %0,%1" + : "=r"(Value) + : "m"(*Target),"0"(Value) + : "memory"); + return Value; + } + +#define CacheLineFlush(Address) _mm_clflush(Address) + + VOID _ReadWriteBarrier(VOID); + +#define FastFence __faststorefence +#define LoadFence _mm_lfence +#define MemoryFence _mm_mfence +#define StoreFence _mm_sfence + + VOID __faststorefence(VOID); + VOID _m_prefetchw(volatile CONST VOID *Source); + +//!__TINYC__: #include <intrin.h> + +#define YieldProcessor _mm_pause +#define MemoryBarrier __faststorefence +#define PreFetchCacheLine(l,a) _mm_prefetch((CHAR CONST *) a,l) +#define PrefetchForWrite(p) _m_prefetchw(p) +#define ReadForWriteAccess(p) (_m_prefetchw(p),*(p)) + +#define PF_TEMPORAL_LEVEL_1 _MM_HINT_T0 +#define PF_TEMPORAL_LEVEL_2 _MM_HINT_T1 +#define PF_TEMPORAL_LEVEL_3 _MM_HINT_T2 +#define PF_NON_TEMPORAL_LEVEL_ALL _MM_HINT_NTA + +#define ReadMxCsr _mm_getcsr +#define WriteMxCsr _mm_setcsr + + VOID __int2c(VOID); + +#define DbgRaiseAssertionFailure() __int2c() +#define GetCallersEflags() __getcallerseflags() + + unsigned __int32 __getcallerseflags(VOID); + +#define GetSegmentLimit __segmentlimit + + DWORD __segmentlimit(DWORD Selector); + +#define ReadTimeStampCounter() __rdtsc() + + DWORD64 __rdtsc(VOID); + VOID __movsb(PBYTE Destination,BYTE const *Source,SIZE_T Count); + VOID __movsw(PWORD Destination,WORD const *Source,SIZE_T Count); + VOID __movsd(PDWORD Destination,DWORD const *Source,SIZE_T Count); + VOID __movsq(PDWORD64 Destination,DWORD64 const *Source,SIZE_T Count); + VOID __stosb(PBYTE Destination,BYTE Value,SIZE_T Count); + VOID __stosw(PWORD Destination,WORD Value,SIZE_T Count); + VOID __stosd(PDWORD Destination,DWORD Value,SIZE_T Count); + VOID __stosq(PDWORD64 Destination,DWORD64 Value,SIZE_T Count); + +#define MultiplyHigh __mulh +#define UnsignedMultiplyHigh __umulh + + LONGLONG MultiplyHigh(LONGLONG Multiplier,LONGLONG Multiplicand); + ULONGLONG UnsignedMultiplyHigh(ULONGLONG Multiplier,ULONGLONG Multiplicand); + +#define ShiftLeft128 __shiftleft128 +#define ShiftRight128 __shiftright128 + + DWORD64 ShiftLeft128(DWORD64 LowPart,DWORD64 HighPart,BYTE Shift); + DWORD64 ShiftRight128(DWORD64 LowPart,DWORD64 HighPart,BYTE Shift); + +#define Multiply128 _mul128 + + LONG64 Multiply128(LONG64 Multiplier,LONG64 Multiplicand,LONG64 *HighProduct); + +#define UnsignedMultiply128 _umul128 + + DWORD64 UnsignedMultiply128(DWORD64 Multiplier,DWORD64 Multiplicand,DWORD64 *HighProduct); + + __CRT_INLINE LONG64 MultiplyExtract128(LONG64 Multiplier,LONG64 Multiplicand,BYTE Shift) { + LONG64 extractedProduct; + LONG64 highProduct; + LONG64 lowProduct; + lowProduct = Multiply128(Multiplier,Multiplicand,&highProduct); + extractedProduct = (LONG64)ShiftRight128((LONG64)lowProduct,(LONG64)highProduct,Shift); + return extractedProduct; + } + + __CRT_INLINE DWORD64 UnsignedMultiplyExtract128(DWORD64 Multiplier,DWORD64 Multiplicand,BYTE Shift) { + DWORD64 extractedProduct; + DWORD64 highProduct; + DWORD64 lowProduct; + lowProduct = UnsignedMultiply128(Multiplier,Multiplicand,&highProduct); + extractedProduct = ShiftRight128(lowProduct,highProduct,Shift); + return extractedProduct; + } + + __CRT_INLINE BYTE __readgsbyte(DWORD Offset) { + BYTE ret; + __asm__ volatile ("movb %%gs:%1,%0" + : "=r" (ret) ,"=m" ((*(volatile long *) (DWORD64) Offset))); + return ret; + } + __CRT_INLINE WORD __readgsword(DWORD Offset) { + WORD ret; + __asm__ volatile ("movw %%gs:%1,%0" + : "=r" (ret) ,"=m" ((*(volatile long *) (DWORD64) Offset))); + return ret; + } + __CRT_INLINE DWORD __readgsdword(DWORD Offset) { + DWORD ret; + __asm__ volatile ("movl %%gs:%1,%0" + : "=r" (ret) ,"=m" ((*(volatile long *) (DWORD64) Offset))); + return ret; + } + __CRT_INLINE DWORD64 __readgsqword(DWORD Offset) { + void *ret; + __asm__ volatile ("movq %%gs:%1,%0" + : "=r" (ret) ,"=m" ((*(volatile long *) (DWORD64) Offset))); + return (DWORD64) ret; + } + __CRT_INLINE VOID __writegsbyte(DWORD Offset,BYTE Data) { + __asm__ volatile ("movb %0,%%gs:%1" + : "=r" (Data) ,"=m" ((*(volatile long *) (DWORD64) Offset))); + } + __CRT_INLINE VOID __writegsword(DWORD Offset,WORD Data) { + __asm__ volatile ("movw %0,%%gs:%1" + : "=r" (Data) ,"=m" ((*(volatile long *) (DWORD64) Offset))); + } + __CRT_INLINE VOID __writegsdword(DWORD Offset,DWORD Data) { + __asm__ volatile ("movl %0,%%gs:%1" + : "=r" (Data) ,"=m" ((*(volatile long *) (DWORD64) Offset))); + } + __CRT_INLINE VOID __writegsqword(DWORD Offset,DWORD64 Data) { + __asm__ volatile ("movq %0,%%gs:%1" + : "=r" (Data) ,"=m" ((*(volatile long *) (DWORD64) Offset))); + } + +#ifdef __cplusplus + } +#endif +#endif + +#define EXCEPTION_READ_FAULT 0 +#define EXCEPTION_WRITE_FAULT 1 +#define EXCEPTION_EXECUTE_FAULT 8 + +#if !defined(RC_INVOKED) + +#define CONTEXT_AMD64 0x100000 + +#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L) +#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L) +#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L) +#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) + +#define CONTEXT_EXCEPTION_ACTIVE 0x8000000 +#define CONTEXT_SERVICE_ACTIVE 0x10000000 +#define CONTEXT_EXCEPTION_REQUEST 0x40000000 +#define CONTEXT_EXCEPTION_REPORTING 0x80000000 +#endif + +#define INITIAL_MXCSR 0x1f80 +#define INITIAL_FPCSR 0x027f + + typedef DECLSPEC_ALIGN(16) struct _M128A { + ULONGLONG Low; + LONGLONG High; + } M128A,*PM128A; + + typedef struct _XMM_SAVE_AREA32 { + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + M128A FloatRegisters[8]; + M128A XmmRegisters[16]; + BYTE Reserved4[96]; + } XMM_SAVE_AREA32,*PXMM_SAVE_AREA32; + +#define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32) + + typedef DECLSPEC_ALIGN(16) struct _CONTEXT { + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; + union { + XMM_SAVE_AREA32 FltSave; + XMM_SAVE_AREA32 FloatSave; + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + }; + }; + M128A VectorRegister[26]; + DWORD64 VectorControl; + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; + } CONTEXT,*PCONTEXT; + +#define RUNTIME_FUNCTION_INDIRECT 0x1 + + typedef struct _RUNTIME_FUNCTION { + DWORD BeginAddress; + DWORD EndAddress; + DWORD UnwindData; + } RUNTIME_FUNCTION,*PRUNTIME_FUNCTION; + + typedef PRUNTIME_FUNCTION (*PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64 ControlPc,PVOID Context); + typedef DWORD (*POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK)(HANDLE Process,PVOID TableAddress,PDWORD Entries,PRUNTIME_FUNCTION *Functions); + +#define OUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK_EXPORT_NAME "OutOfProcessFunctionTableCallback" + + NTSYSAPI VOID __cdecl RtlRestoreContext (PCONTEXT ContextRecord,struct _EXCEPTION_RECORD *ExceptionRecord); + NTSYSAPI BOOLEAN __cdecl RtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable,DWORD EntryCount,DWORD64 BaseAddress); + NTSYSAPI BOOLEAN __cdecl RtlInstallFunctionTableCallback(DWORD64 TableIdentifier,DWORD64 BaseAddress,DWORD Length,PGET_RUNTIME_FUNCTION_CALLBACK Callback,PVOID Context,PCWSTR OutOfProcessCallbackDll); + NTSYSAPI BOOLEAN __cdecl RtlDeleteFunctionTable(PRUNTIME_FUNCTION FunctionTable); +#endif + +#ifdef I_X86_ +#if(defined(_X86_) && !defined(__x86_64)) && !defined(RC_INVOKED) +#ifdef __cplusplus + extern "C" { +#endif + + __CRT_INLINE BOOLEAN InterlockedBitTestAndSet(LONG *Base,LONG Bit) { + int old = 0; + __asm__ __volatile__("lock ; btsl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Bit)); + return (BOOLEAN) (old!=0); + } + + __CRT_INLINE BOOLEAN InterlockedBitTestAndReset(LONG *Base,LONG Bit) { + int old = 0; + __asm__ __volatile__("lock ; btrl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Bit)); + return (BOOLEAN) (old!=0); + } + + __CRT_INLINE BOOLEAN InterlockedBitTestAndComplement(LONG *Base,LONG Bit) { + int old = 0; + __asm__ __volatile__("lock ; btcl %2,%1\n\tsbbl %0,%0 " + :"=r" (old),"=m" ((*(volatile long *) Base)) + :"Ir" (Bit)); + return (BOOLEAN) (old!=0); + } + +#ifdef _PREFIX_ + BYTE __readfsbyte(DWORD Offset); + WORD __readfsword(DWORD Offset); + DWORD __readfsdword(DWORD Offset); + VOID __writefsbyte(DWORD Offset,BYTE Data); + VOID __writefsword(DWORD Offset,WORD Data); + VOID __writefsdword(DWORD Offset,DWORD Data); +#endif + +#ifdef __cplusplus + } +#endif +#endif + +#if(defined(_X86_) && !defined(__x86_64)) + __CRT_INLINE VOID MemoryBarrier(VOID) { + LONG Barrier; + __asm__ __volatile__("xchgl %eax,%0 " + :"=r" (Barrier)); + } +#define YieldProcessor() __asm__ __volatile__("rep nop "); + +#define PreFetchCacheLine(l,a) +#define ReadForWriteAccess(p) (*(p)) + +#define PF_TEMPORAL_LEVEL_1 +#define PF_NON_TEMPORAL_LEVEL_ALL + + __CRT_INLINE VOID DbgRaiseAssertionFailure(void) { + __asm__ __volatile__("int 0x2c "); + } + PVOID GetCurrentFiber(void); + __CRT_INLINE PVOID GetCurrentFiber(void) + { + void *ret; + __asm__ volatile ("movl %%fs:0x10,%0" + : "=r" (ret)); + return ret; + } + PVOID GetFiberData(void); + __CRT_INLINE PVOID GetFiberData(void) + { + void *ret; + __asm__ volatile ("movl %%fs:0x10,%0\n" + "movl (%0),%0" + : "=r" (ret)); + return ret; + } +#endif + +#define EXCEPTION_READ_FAULT 0 +#define EXCEPTION_WRITE_FAULT 1 +#define EXCEPTION_EXECUTE_FAULT 8 + +#define SIZE_OF_80387_REGISTERS 80 + +#if !defined(RC_INVOKED) + +#define CONTEXT_i386 0x00010000 +#define CONTEXT_i486 0x00010000 + +#define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) +#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) +#define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L) +#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) +#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386 | 0x00000020L) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) + +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS) +#endif + +#define MAXIMUM_SUPPORTED_EXTENSION 512 + + typedef struct _FLOATING_SAVE_AREA { + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; + DWORD Cr0NpxState; + } FLOATING_SAVE_AREA; + + typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA; + + typedef struct _CONTEXT { + DWORD ContextFlags; + DWORD Dr0; + DWORD Dr1; + DWORD Dr2; + DWORD Dr3; + DWORD Dr6; + DWORD Dr7; + FLOATING_SAVE_AREA FloatSave; + DWORD SegGs; + DWORD SegFs; + DWORD SegEs; + DWORD SegDs; + + DWORD Edi; + DWORD Esi; + DWORD Ebx; + DWORD Edx; + DWORD Ecx; + DWORD Eax; + DWORD Ebp; + DWORD Eip; + DWORD SegCs; + DWORD EFlags; + DWORD Esp; + DWORD SegSs; + BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; + } CONTEXT; + + typedef CONTEXT *PCONTEXT; +#endif + +#ifndef _LDT_ENTRY_DEFINED +#define _LDT_ENTRY_DEFINED + + typedef struct _LDT_ENTRY { + WORD LimitLow; + WORD BaseLow; + union { + struct { + BYTE BaseMid; + BYTE Flags1; + BYTE Flags2; + BYTE BaseHi; + } Bytes; + struct { + DWORD BaseMid : 8; + DWORD Type : 5; + DWORD Dpl : 2; + DWORD Pres : 1; + DWORD LimitHi : 4; + DWORD Sys : 1; + DWORD Reserved_0 : 1; + DWORD Default_Big : 1; + DWORD Granularity : 1; + DWORD BaseHi : 8; + } Bits; + } HighWord; + } LDT_ENTRY,*PLDT_ENTRY; +#endif + +#if defined(__ia64__) && !defined(RC_INVOKED) + +#ifdef __cplusplus + extern "C" { +#endif + + BOOLEAN BitScanForward64(DWORD *Index,DWORD64 Mask); + BOOLEAN BitScanReverse64(DWORD *Index,DWORD64 Mask); + +#ifdef __cplusplus + } +#endif +#endif + +#if !defined(GENUTIL) && !defined(_GENIA64_) && defined(_IA64_) + + void *_cdecl _rdteb(void); +#ifdef __ia64__ + +#define NtCurrentTeb() ((struct _TEB *)_rdteb()) +#define GetCurrentFiber() (((PNT_TIB)NtCurrentTeb())->FiberData) +#define GetFiberData() (*(PVOID *)(GetCurrentFiber())) + +#ifdef __cplusplus + extern "C" { +#endif + + void __break(int); + void __yield(void); + void __mf(void); + void __lfetch(int Level,VOID CONST *Address); + void __lfetchfault(int Level,VOID CONST *Address); + void __lfetch_excl(int Level,VOID CONST *Address); + void __lfetchfault_excl(int Level,VOID CONST *Address); + +#define MD_LFHINT_NONE 0x00 +#define MD_LFHINT_NT1 0x01 +#define MD_LFHINT_NT2 0x02 +#define MD_LFHINT_NTA 0x03 + +#ifdef __cplusplus + } +#endif + +#define YieldProcessor __yield +#define MemoryBarrier __mf +#define PreFetchCacheLine __lfetch +#define ReadForWriteAccess(p) (*(p)) +#define DbgRaiseAssertionFailure() __break(ASSERT_BREAKPOINT) + +#define PF_TEMPORAL_LEVEL_1 MD_LFHINT_NONE +#define PF_NON_TEMPORAL_LEVEL_ALL MD_LFHINT_NTA + +#define UnsignedMultiplyHigh __UMULH + + ULONGLONG UnsignedMultiplyHigh(ULONGLONG Multiplier,ULONGLONG Multiplicand); +#else + struct _TEB *NtCurrentTeb(void); +#endif +#endif + +#ifdef _IA64_ + +#define EXCEPTION_READ_FAULT 0 +#define EXCEPTION_WRITE_FAULT 1 +#define EXCEPTION_EXECUTE_FAULT 2 + +#if !defined(RC_INVOKED) + +#define CONTEXT_IA64 0x00080000 + +#define CONTEXT_CONTROL (CONTEXT_IA64 | 0x00000001L) +#define CONTEXT_LOWER_FLOATING_POINT (CONTEXT_IA64 | 0x00000002L) +#define CONTEXT_HIGHER_FLOATING_POINT (CONTEXT_IA64 | 0x00000004L) +#define CONTEXT_INTEGER (CONTEXT_IA64 | 0x00000008L) +#define CONTEXT_DEBUG (CONTEXT_IA64 | 0x00000010L) +#define CONTEXT_IA32_CONTROL (CONTEXT_IA64 | 0x00000020L) + +#define CONTEXT_FLOATING_POINT (CONTEXT_LOWER_FLOATING_POINT | CONTEXT_HIGHER_FLOATING_POINT) +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER | CONTEXT_IA32_CONTROL) +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER | CONTEXT_DEBUG | CONTEXT_IA32_CONTROL) + +#define CONTEXT_EXCEPTION_ACTIVE 0x8000000 +#define CONTEXT_SERVICE_ACTIVE 0x10000000 +#define CONTEXT_EXCEPTION_REQUEST 0x40000000 +#define CONTEXT_EXCEPTION_REPORTING 0x80000000 +#endif + + typedef struct _CONTEXT { + DWORD ContextFlags; + DWORD Fill1[3]; + ULONGLONG DbI0; + ULONGLONG DbI1; + ULONGLONG DbI2; + ULONGLONG DbI3; + ULONGLONG DbI4; + ULONGLONG DbI5; + ULONGLONG DbI6; + ULONGLONG DbI7; + ULONGLONG DbD0; + ULONGLONG DbD1; + ULONGLONG DbD2; + ULONGLONG DbD3; + ULONGLONG DbD4; + ULONGLONG DbD5; + ULONGLONG DbD6; + ULONGLONG DbD7; + FLOAT128 FltS0; + FLOAT128 FltS1; + FLOAT128 FltS2; + FLOAT128 FltS3; + FLOAT128 FltT0; + FLOAT128 FltT1; + FLOAT128 FltT2; + FLOAT128 FltT3; + FLOAT128 FltT4; + FLOAT128 FltT5; + FLOAT128 FltT6; + FLOAT128 FltT7; + FLOAT128 FltT8; + FLOAT128 FltT9; + FLOAT128 FltS4; + FLOAT128 FltS5; + FLOAT128 FltS6; + FLOAT128 FltS7; + FLOAT128 FltS8; + FLOAT128 FltS9; + FLOAT128 FltS10; + FLOAT128 FltS11; + FLOAT128 FltS12; + FLOAT128 FltS13; + FLOAT128 FltS14; + FLOAT128 FltS15; + FLOAT128 FltS16; + FLOAT128 FltS17; + FLOAT128 FltS18; + FLOAT128 FltS19; + FLOAT128 FltF32; + FLOAT128 FltF33; + FLOAT128 FltF34; + FLOAT128 FltF35; + FLOAT128 FltF36; + FLOAT128 FltF37; + FLOAT128 FltF38; + FLOAT128 FltF39; + FLOAT128 FltF40; + FLOAT128 FltF41; + FLOAT128 FltF42; + FLOAT128 FltF43; + FLOAT128 FltF44; + FLOAT128 FltF45; + FLOAT128 FltF46; + FLOAT128 FltF47; + FLOAT128 FltF48; + FLOAT128 FltF49; + FLOAT128 FltF50; + FLOAT128 FltF51; + FLOAT128 FltF52; + FLOAT128 FltF53; + FLOAT128 FltF54; + FLOAT128 FltF55; + FLOAT128 FltF56; + FLOAT128 FltF57; + FLOAT128 FltF58; + FLOAT128 FltF59; + FLOAT128 FltF60; + FLOAT128 FltF61; + FLOAT128 FltF62; + FLOAT128 FltF63; + FLOAT128 FltF64; + FLOAT128 FltF65; + FLOAT128 FltF66; + FLOAT128 FltF67; + FLOAT128 FltF68; + FLOAT128 FltF69; + FLOAT128 FltF70; + FLOAT128 FltF71; + FLOAT128 FltF72; + FLOAT128 FltF73; + FLOAT128 FltF74; + FLOAT128 FltF75; + FLOAT128 FltF76; + FLOAT128 FltF77; + FLOAT128 FltF78; + FLOAT128 FltF79; + FLOAT128 FltF80; + FLOAT128 FltF81; + FLOAT128 FltF82; + FLOAT128 FltF83; + FLOAT128 FltF84; + FLOAT128 FltF85; + FLOAT128 FltF86; + FLOAT128 FltF87; + FLOAT128 FltF88; + FLOAT128 FltF89; + FLOAT128 FltF90; + FLOAT128 FltF91; + FLOAT128 FltF92; + FLOAT128 FltF93; + FLOAT128 FltF94; + FLOAT128 FltF95; + FLOAT128 FltF96; + FLOAT128 FltF97; + FLOAT128 FltF98; + FLOAT128 FltF99; + FLOAT128 FltF100; + FLOAT128 FltF101; + FLOAT128 FltF102; + FLOAT128 FltF103; + FLOAT128 FltF104; + FLOAT128 FltF105; + FLOAT128 FltF106; + FLOAT128 FltF107; + FLOAT128 FltF108; + FLOAT128 FltF109; + FLOAT128 FltF110; + FLOAT128 FltF111; + FLOAT128 FltF112; + FLOAT128 FltF113; + FLOAT128 FltF114; + FLOAT128 FltF115; + FLOAT128 FltF116; + FLOAT128 FltF117; + FLOAT128 FltF118; + FLOAT128 FltF119; + FLOAT128 FltF120; + FLOAT128 FltF121; + FLOAT128 FltF122; + FLOAT128 FltF123; + FLOAT128 FltF124; + FLOAT128 FltF125; + FLOAT128 FltF126; + FLOAT128 FltF127; + ULONGLONG StFPSR; + ULONGLONG IntGp; + ULONGLONG IntT0; + ULONGLONG IntT1; + ULONGLONG IntS0; + ULONGLONG IntS1; + ULONGLONG IntS2; + ULONGLONG IntS3; + ULONGLONG IntV0; + ULONGLONG IntT2; + ULONGLONG IntT3; + ULONGLONG IntT4; + ULONGLONG IntSp; + ULONGLONG IntTeb; + ULONGLONG IntT5; + ULONGLONG IntT6; + ULONGLONG IntT7; + ULONGLONG IntT8; + ULONGLONG IntT9; + ULONGLONG IntT10; + ULONGLONG IntT11; + ULONGLONG IntT12; + ULONGLONG IntT13; + ULONGLONG IntT14; + ULONGLONG IntT15; + ULONGLONG IntT16; + ULONGLONG IntT17; + ULONGLONG IntT18; + ULONGLONG IntT19; + ULONGLONG IntT20; + ULONGLONG IntT21; + ULONGLONG IntT22; + ULONGLONG IntNats; + ULONGLONG Preds; + ULONGLONG BrRp; + ULONGLONG BrS0; + ULONGLONG BrS1; + ULONGLONG BrS2; + ULONGLONG BrS3; + ULONGLONG BrS4; + ULONGLONG BrT0; + ULONGLONG BrT1; + ULONGLONG ApUNAT; + ULONGLONG ApLC; + ULONGLONG ApEC; + ULONGLONG ApCCV; + ULONGLONG ApDCR; + ULONGLONG RsPFS; + ULONGLONG RsBSP; + ULONGLONG RsBSPSTORE; + ULONGLONG RsRSC; + ULONGLONG RsRNAT; + ULONGLONG StIPSR; + ULONGLONG StIIP; + ULONGLONG StIFS; + ULONGLONG StFCR; + ULONGLONG Eflag; + ULONGLONG SegCSD; + ULONGLONG SegSSD; + ULONGLONG Cflag; + ULONGLONG StFSR; + ULONGLONG StFIR; + ULONGLONG StFDR; + ULONGLONG UNUSEDPACK; + } CONTEXT,*PCONTEXT; + + typedef struct _PLABEL_DESCRIPTOR { + ULONGLONG EntryPoint; + ULONGLONG GlobalPointer; + } PLABEL_DESCRIPTOR,*PPLABEL_DESCRIPTOR; + + typedef struct _RUNTIME_FUNCTION { + DWORD BeginAddress; + DWORD EndAddress; + DWORD UnwindInfoAddress; + } RUNTIME_FUNCTION,*PRUNTIME_FUNCTION; + + typedef PRUNTIME_FUNCTION (*PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64 ControlPc,PVOID Context); + typedef DWORD (*POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK)(HANDLE Process,PVOID TableAddress,PDWORD Entries,PRUNTIME_FUNCTION *Functions); + +#define OUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK_EXPORT_NAME "OutOfProcessFunctionTableCallback" + + BOOLEAN RtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable,DWORD EntryCount,ULONGLONG BaseAddress,ULONGLONG TargetGp); + BOOLEAN RtlInstallFunctionTableCallback(DWORD64 TableIdentifier,DWORD64 BaseAddress,DWORD Length,DWORD64 TargetGp,PGET_RUNTIME_FUNCTION_CALLBACK Callback,PVOID Context,PCWSTR OutOfProcessCallbackDll); + BOOLEAN RtlDeleteFunctionTable(PRUNTIME_FUNCTION FunctionTable); + VOID RtlRestoreContext (PCONTEXT ContextRecord,struct _EXCEPTION_RECORD *ExceptionRecord); + VOID __jump_unwind(ULONGLONG TargetMsFrame,ULONGLONG TargetBsFrame,ULONGLONG TargetPc); +#endif + +#define EXCEPTION_NONCONTINUABLE 0x1 #define EXCEPTION_MAXIMUM_PARAMETERS 15 -/* - * To prevent gcc compiler warnings, bracket these defines when initialising - * a SID_IDENTIFIER_AUTHORITY, eg. - * SID_IDENTIFIER_AUTHORITY aNullSidAuthority = {SECURITY_NULL_SID_AUTHORITY}; - */ -#define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0} -#define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1} -#define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2} -#define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3} -#define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4} -#define SECURITY_NT_AUTHORITY {0,0,0,0,0,5} -#define SECURITY_NULL_RID 0 -#define SECURITY_WORLD_RID 0 -#define SECURITY_LOCAL_RID 0 -#define SECURITY_CREATOR_OWNER_RID 0 -#define SECURITY_CREATOR_GROUP_RID 1 -#define SECURITY_DIALUP_RID 1 -#define SECURITY_NETWORK_RID 2 -#define SECURITY_BATCH_RID 3 -#define SECURITY_INTERACTIVE_RID 4 -#define SECURITY_LOGON_IDS_RID 5 -#define SECURITY_SERVICE_RID 6 -#define SECURITY_LOCAL_SYSTEM_RID 18 -#define SECURITY_BUILTIN_DOMAIN_RID 32 -#define SECURITY_PRINCIPAL_SELF_RID 10 -#define SID_REVISION 1 -#define DOMAIN_USER_RID_ADMIN 0x1F4L -#define DOMAIN_USER_RID_GUEST 0x1F5L -#define DOMAIN_GROUP_RID_ADMINS 0x200L -#define DOMAIN_GROUP_RID_USERS 0x201L -#define DOMAIN_ALIAS_RID_ADMINS 0x220L -#define DOMAIN_ALIAS_RID_USERS 0x221L -#define DOMAIN_ALIAS_RID_GUESTS 0x222L -#define DOMAIN_ALIAS_RID_POWER_USERS 0x223L -#define DOMAIN_ALIAS_RID_ACCOUNT_OPS 0x224L -#define DOMAIN_ALIAS_RID_SYSTEM_OPS 0x225L -#define DOMAIN_ALIAS_RID_PRINT_OPS 0x226L -#define DOMAIN_ALIAS_RID_BACKUP_OPS 0x227L -#define DOMAIN_ALIAS_RID_REPLICATOR 0x228L -#define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege") -#define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege") -#define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege") -#define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege") -#define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege") + + typedef struct _EXCEPTION_RECORD { + DWORD ExceptionCode; + DWORD ExceptionFlags; + struct _EXCEPTION_RECORD *ExceptionRecord; + PVOID ExceptionAddress; + DWORD NumberParameters; + ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; + } EXCEPTION_RECORD; + + typedef EXCEPTION_RECORD *PEXCEPTION_RECORD; + + typedef struct _EXCEPTION_RECORD32 { + DWORD ExceptionCode; + DWORD ExceptionFlags; + DWORD ExceptionRecord; + DWORD ExceptionAddress; + DWORD NumberParameters; + DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; + } EXCEPTION_RECORD32,*PEXCEPTION_RECORD32; + + typedef struct _EXCEPTION_RECORD64 { + DWORD ExceptionCode; + DWORD ExceptionFlags; + DWORD64 ExceptionRecord; + DWORD64 ExceptionAddress; + DWORD NumberParameters; + DWORD __unusedAlignment; + DWORD64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; + } EXCEPTION_RECORD64,*PEXCEPTION_RECORD64; + + typedef struct _EXCEPTION_POINTERS { + PEXCEPTION_RECORD ExceptionRecord; + PCONTEXT ContextRecord; + } EXCEPTION_POINTERS,*PEXCEPTION_POINTERS; + +#ifdef __x86_64 + + typedef EXCEPTION_DISPOSITION NTAPI EXCEPTION_ROUTINE (struct _EXCEPTION_RECORD *ExceptionRecord, PVOID EstablisherFrame, struct _CONTEXT *ContextRecord, PVOID DispatcherContext); +#ifndef __PEXCEPTION_ROUTINE_DEFINED +#define __PEXCEPTION_ROUTINE_DEFINED + typedef EXCEPTION_ROUTINE *PEXCEPTION_ROUTINE; +#endif + + /* http://msdn.microsoft.com/en-us/library/ms680597(VS.85).aspx */ + +#define UNWIND_HISTORY_TABLE_SIZE 12 + + typedef struct _UNWIND_HISTORY_TABLE_ENTRY { + ULONG64 ImageBase; + PRUNTIME_FUNCTION FunctionEntry; + } UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY; + +#define UNWIND_HISTORY_TABLE_NONE 0 +#define UNWIND_HISTORY_TABLE_GLOBAL 1 +#define UNWIND_HISTORY_TABLE_LOCAL 2 + + typedef struct _UNWIND_HISTORY_TABLE { + ULONG Count; + UCHAR Search; + ULONG64 LowAddress; + ULONG64 HighAddress; + UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE]; + } UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE; + + /* http://msdn.microsoft.com/en-us/library/b6sf5kbd(VS.80).aspx */ + + struct _DISPATCHER_CONTEXT; + typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; + typedef struct _DISPATCHER_CONTEXT *PDISPATCHER_CONTEXT; + + struct _DISPATCHER_CONTEXT { + ULONG64 ControlPc; + ULONG64 ImageBase; + PRUNTIME_FUNCTION FunctionEntry; + ULONG64 EstablisherFrame; + ULONG64 TargetIp; + PCONTEXT ContextRecord; + PEXCEPTION_ROUTINE LanguageHandler; + PVOID HandlerData; + /* http://www.nynaeve.net/?p=99 */ + PUNWIND_HISTORY_TABLE HistoryTable; + ULONG ScopeIndex; + ULONG Fill0; + }; + + /* http://msdn.microsoft.com/en-us/library/ms680617(VS.85).aspx */ + + typedef struct _KNONVOLATILE_CONTEXT_POINTERS + { + PM128A FloatingContext[16]; + PULONG64 IntegerContext[16]; + } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; +#endif /* defined(__x86_64) */ + + typedef PVOID PACCESS_TOKEN; + typedef PVOID PSECURITY_DESCRIPTOR; + typedef PVOID PSID; + + typedef DWORD ACCESS_MASK; + typedef ACCESS_MASK *PACCESS_MASK; + +#define DELETE (0x00010000L) +#define READ_CONTROL (0x00020000L) +#define WRITE_DAC (0x00040000L) +#define WRITE_OWNER (0x00080000L) +#define SYNCHRONIZE (0x00100000L) + +#define STANDARD_RIGHTS_REQUIRED (0x000F0000L) +#define STANDARD_RIGHTS_READ (READ_CONTROL) +#define STANDARD_RIGHTS_WRITE (READ_CONTROL) +#define STANDARD_RIGHTS_EXECUTE (READ_CONTROL) +#define STANDARD_RIGHTS_ALL (0x001F0000L) + +#define SPECIFIC_RIGHTS_ALL (0x0000FFFFL) + +#define ACCESS_SYSTEM_SECURITY (0x01000000L) + +#define MAXIMUM_ALLOWED (0x02000000L) + +#define GENERIC_READ (0x80000000L) +#define GENERIC_WRITE (0x40000000L) +#define GENERIC_EXECUTE (0x20000000L) +#define GENERIC_ALL (0x10000000L) + + typedef struct _GENERIC_MAPPING { + ACCESS_MASK GenericRead; + ACCESS_MASK GenericWrite; + ACCESS_MASK GenericExecute; + ACCESS_MASK GenericAll; + } GENERIC_MAPPING; + typedef GENERIC_MAPPING *PGENERIC_MAPPING; + +#include <pshpack4.h> + + typedef struct _LUID_AND_ATTRIBUTES { + LUID Luid; + DWORD Attributes; + } LUID_AND_ATTRIBUTES,*PLUID_AND_ATTRIBUTES; + typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY]; + typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY; + +#include <poppack.h> + +#ifndef SID_IDENTIFIER_AUTHORITY_DEFINED +#define SID_IDENTIFIER_AUTHORITY_DEFINED + typedef struct _SID_IDENTIFIER_AUTHORITY { + BYTE Value[6]; + } SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY; +#endif + +#ifndef SID_DEFINED +#define SID_DEFINED + typedef struct _SID { + BYTE Revision; + BYTE SubAuthorityCount; + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + DWORD SubAuthority[ANYSIZE_ARRAY]; + } SID,*PISID; +#endif + +#define SID_REVISION (1) +#define SID_MAX_SUB_AUTHORITIES (15) +#define SID_RECOMMENDED_SUB_AUTHORITIES (1) + +#define SECURITY_MAX_SID_SIZE (sizeof(SID) - sizeof(DWORD) + (SID_MAX_SUB_AUTHORITIES *sizeof(DWORD))) + + typedef enum _SID_NAME_USE { + SidTypeUser = 1,SidTypeGroup,SidTypeDomain,SidTypeAlias,SidTypeWellKnownGroup,SidTypeDeletedAccount,SidTypeInvalid,SidTypeUnknown,SidTypeComputer + } SID_NAME_USE,*PSID_NAME_USE; + + typedef struct _SID_AND_ATTRIBUTES { + PSID Sid; + DWORD Attributes; + } SID_AND_ATTRIBUTES,*PSID_AND_ATTRIBUTES; + + typedef SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY]; + typedef SID_AND_ATTRIBUTES_ARRAY *PSID_AND_ATTRIBUTES_ARRAY; + +#define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0} +#define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1} +#define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2} +#define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3} +#define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4} +#define SECURITY_RESOURCE_MANAGER_AUTHORITY {0,0,0,0,0,9} + +#define SECURITY_NULL_RID (0x00000000L) +#define SECURITY_WORLD_RID (0x00000000L) +#define SECURITY_LOCAL_RID (0x00000000L) + +#define SECURITY_CREATOR_OWNER_RID (0x00000000L) +#define SECURITY_CREATOR_GROUP_RID (0x00000001L) + +#define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L) +#define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L) + +#define SECURITY_NT_AUTHORITY {0,0,0,0,0,5} + +#define SECURITY_DIALUP_RID (0x00000001L) +#define SECURITY_NETWORK_RID (0x00000002L) +#define SECURITY_BATCH_RID (0x00000003L) +#define SECURITY_INTERACTIVE_RID (0x00000004L) +#define SECURITY_LOGON_IDS_RID (0x00000005L) +#define SECURITY_LOGON_IDS_RID_COUNT (3L) +#define SECURITY_SERVICE_RID (0x00000006L) +#define SECURITY_ANONYMOUS_LOGON_RID (0x00000007L) +#define SECURITY_PROXY_RID (0x00000008L) +#define SECURITY_ENTERPRISE_CONTROLLERS_RID (0x00000009L) +#define SECURITY_SERVER_LOGON_RID SECURITY_ENTERPRISE_CONTROLLERS_RID +#define SECURITY_PRINCIPAL_SELF_RID (0x0000000AL) +#define SECURITY_AUTHENTICATED_USER_RID (0x0000000BL) +#define SECURITY_RESTRICTED_CODE_RID (0x0000000CL) +#define SECURITY_TERMINAL_SERVER_RID (0x0000000DL) +#define SECURITY_REMOTE_LOGON_RID (0x0000000EL) +#define SECURITY_THIS_ORGANIZATION_RID (0x0000000FL) +#define SECURITY_IUSER_RID (0x00000011L) + +#define SECURITY_LOCAL_SYSTEM_RID (0x00000012L) +#define SECURITY_LOCAL_SERVICE_RID (0x00000013L) +#define SECURITY_NETWORK_SERVICE_RID (0x00000014L) + +#define SECURITY_NT_NON_UNIQUE (0x00000015L) +#define SECURITY_NT_NON_UNIQUE_SUB_AUTH_COUNT (3L) + +#define SECURITY_ENTERPRISE_READONLY_CONTROLLERS_RID (0x00000016L) + +#define SECURITY_BUILTIN_DOMAIN_RID (0x00000020L) +#define SECURITY_WRITE_RESTRICTED_CODE_RID (0x00000021L) + +#define SECURITY_PACKAGE_BASE_RID (0x00000040L) +#define SECURITY_PACKAGE_RID_COUNT (2L) +#define SECURITY_PACKAGE_NTLM_RID (0x0000000AL) +#define SECURITY_PACKAGE_SCHANNEL_RID (0x0000000EL) +#define SECURITY_PACKAGE_DIGEST_RID (0x00000015L) + +#define SECURITY_SERVICE_ID_BASE_RID (0x00000050L) +#define SECURITY_SERVICE_ID_RID_COUNT (6L) + +#define SECURITY_RESERVED_ID_BASE_RID (0x00000051L) + +#define SECURITY_MAX_ALWAYS_FILTERED (0x000003E7L) +#define SECURITY_MIN_NEVER_FILTERED (0x000003E8L) + +#define SECURITY_OTHER_ORGANIZATION_RID (0x000003E8L) + +#define FOREST_USER_RID_MAX (0x000001F3L) + +#define DOMAIN_USER_RID_ADMIN (0x000001F4L) +#define DOMAIN_USER_RID_GUEST (0x000001F5L) +#define DOMAIN_USER_RID_KRBTGT (0x000001F6L) + +#define DOMAIN_USER_RID_MAX (0x000003E7L) + +#define DOMAIN_GROUP_RID_ADMINS (0x00000200L) +#define DOMAIN_GROUP_RID_USERS (0x00000201L) +#define DOMAIN_GROUP_RID_GUESTS (0x00000202L) +#define DOMAIN_GROUP_RID_COMPUTERS (0x00000203L) +#define DOMAIN_GROUP_RID_CONTROLLERS (0x00000204L) +#define DOMAIN_GROUP_RID_CERT_ADMINS (0x00000205L) +#define DOMAIN_GROUP_RID_SCHEMA_ADMINS (0x00000206L) +#define DOMAIN_GROUP_RID_ENTERPRISE_ADMINS (0x00000207L) +#define DOMAIN_GROUP_RID_POLICY_ADMINS (0x00000208L) +#define DOMAIN_GROUP_RID_READONLY_CONTROLLERS (0x00000209L) + +#define DOMAIN_ALIAS_RID_ADMINS (0x00000220L) +#define DOMAIN_ALIAS_RID_USERS (0x00000221L) +#define DOMAIN_ALIAS_RID_GUESTS (0x00000222L) +#define DOMAIN_ALIAS_RID_POWER_USERS (0x00000223L) + +#define DOMAIN_ALIAS_RID_ACCOUNT_OPS (0x00000224L) +#define DOMAIN_ALIAS_RID_SYSTEM_OPS (0x00000225L) +#define DOMAIN_ALIAS_RID_PRINT_OPS (0x00000226L) +#define DOMAIN_ALIAS_RID_BACKUP_OPS (0x00000227L) + +#define DOMAIN_ALIAS_RID_REPLICATOR (0x00000228L) +#define DOMAIN_ALIAS_RID_RAS_SERVERS (0x00000229L) +#define DOMAIN_ALIAS_RID_PREW2KCOMPACCESS (0x0000022AL) +#define DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS (0x0000022BL) +#define DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS (0x0000022CL) +#define DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS (0x0000022DL) + +#define DOMAIN_ALIAS_RID_MONITORING_USERS (0x0000022EL) +#define DOMAIN_ALIAS_RID_LOGGING_USERS (0x0000022FL) +#define DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS (0x00000230L) +#define DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS (0x00000231L) +#define DOMAIN_ALIAS_RID_DCOM_USERS (0x00000232L) + +#define DOMAIN_ALIAS_RID_IUSERS (0x00000238L) +#define DOMAIN_ALIAS_RID_CRYPTO_OPERATORS (0x00000239L) +#define DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP (0x0000023BL) +#define DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP (0x0000023CL) +#define DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP (0x0000023DL) + +#define SECURITY_MANDATORY_LABEL_AUTHORITY {0,0,0,0,0,16} +#define SECURITY_MANDATORY_UNTRUSTED_RID (0x00000000L) +#define SECURITY_MANDATORY_LOW_RID (0x00001000L) +#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L) +#define SECURITY_MANDATORY_HIGH_RID (0x00003000L) +#define SECURITY_MANDATORY_SYSTEM_RID (0x00004000L) +#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID (0x00005000L) + +#define SECURITY_MANDATORY_MAXIMUM_USER_RID SECURITY_MANDATORY_SYSTEM_RID + +#define MANDATORY_LEVEL_TO_MANDATORY_RID(IL) (IL * 0x1000) + + typedef enum { + WinNullSid = 0,WinWorldSid = 1,WinLocalSid = 2,WinCreatorOwnerSid = 3,WinCreatorGroupSid = 4,WinCreatorOwnerServerSid = 5,WinCreatorGroupServerSid = 6,WinNtAuthoritySid = 7,WinDialupSid = 8,WinNetworkSid = 9,WinBatchSid = 10,WinInteractiveSid = 11,WinServiceSid = 12,WinAnonymousSid = 13,WinProxySid = 14,WinEnterpriseControllersSid = 15,WinSelfSid = 16,WinAuthenticatedUserSid = 17,WinRestrictedCodeSid = 18,WinTerminalServerSid = 19,WinRemoteLogonIdSid = 20,WinLogonIdsSid = 21,WinLocalSystemSid = 22,WinLocalServiceSid = 23,WinNetworkServiceSid = 24,WinBuiltinDomainSid = 25,WinBuiltinAdministratorsSid = 26,WinBuiltinUsersSid = 27,WinBuiltinGuestsSid = 28,WinBuiltinPowerUsersSid = 29,WinBuiltinAccountOperatorsSid = 30,WinBuiltinSystemOperatorsSid = 31,WinBuiltinPrintOperatorsSid = 32,WinBuiltinBackupOperatorsSid = 33,WinBuiltinReplicatorSid = 34,WinBuiltinPreWindows2000CompatibleAccessSid = 35,WinBuiltinRemoteDesktopUsersSid = 36,WinBuiltinNetworkConfigurationOperatorsSid = 37,WinAccountAdministratorSid = 38,WinAccountGuestSid = 39,WinAccountKrbtgtSid = 40,WinAccountDomainAdminsSid = 41,WinAccountDomainUsersSid = 42,WinAccountDomainGuestsSid = 43,WinAccountComputersSid = 44,WinAccountControllersSid = 45,WinAccountCertAdminsSid = 46,WinAccountSchemaAdminsSid = 47,WinAccountEnterpriseAdminsSid = 48,WinAccountPolicyAdminsSid = 49,WinAccountRasAndIasServersSid = 50,WinNTLMAuthenticationSid = 51,WinDigestAuthenticationSid = 52,WinSChannelAuthenticationSid = 53,WinThisOrganizationSid = 54,WinOtherOrganizationSid = 55,WinBuiltinIncomingForestTrustBuildersSid = 56,WinBuiltinPerfMonitoringUsersSid = 57,WinBuiltinPerfLoggingUsersSid = 58,WinBuiltinAuthorizationAccessSid = 59,WinBuiltinTerminalServerLicenseServersSid = 60,WinBuiltinDCOMUsersSid = 61 + } WELL_KNOWN_SID_TYPE; + +#define SYSTEM_LUID { 0x3E7,0x0 } +#define ANONYMOUS_LOGON_LUID { 0x3e6,0x0 } +#define LOCALSERVICE_LUID { 0x3e5,0x0 } +#define NETWORKSERVICE_LUID { 0x3e4,0x0 } +#define IUSER_LUID { 0x3e3, 0x0 } + +#define SE_GROUP_MANDATORY (0x00000001L) +#define SE_GROUP_ENABLED_BY_DEFAULT (0x00000002L) +#define SE_GROUP_ENABLED (0x00000004L) +#define SE_GROUP_OWNER (0x00000008L) +#define SE_GROUP_USE_FOR_DENY_ONLY (0x00000010L) +#define SE_GROUP_INTEGRITY (0x00000020L) +#define SE_GROUP_INTEGRITY_ENABLED (0x00000040L) +#define SE_GROUP_LOGON_ID (0xC0000000L) +#define SE_GROUP_RESOURCE (0x20000000L) + +#define ACL_REVISION (2) +#define ACL_REVISION_DS (4) + +#define ACL_REVISION1 (1) +#define MIN_ACL_REVISION ACL_REVISION2 +#define ACL_REVISION2 (2) +#define ACL_REVISION3 (3) +#define ACL_REVISION4 (4) +#define MAX_ACL_REVISION ACL_REVISION4 + + typedef struct _ACL { + BYTE AclRevision; + BYTE Sbz1; + WORD AclSize; + WORD AceCount; + WORD Sbz2; + } ACL; + typedef ACL *PACL; + + typedef struct _ACE_HEADER { + BYTE AceType; + BYTE AceFlags; + WORD AceSize; + } ACE_HEADER; + typedef ACE_HEADER *PACE_HEADER; + +#define ACCESS_MIN_MS_ACE_TYPE (0x0) +#define ACCESS_ALLOWED_ACE_TYPE (0x0) +#define ACCESS_DENIED_ACE_TYPE (0x1) +#define SYSTEM_AUDIT_ACE_TYPE (0x2) +#define SYSTEM_ALARM_ACE_TYPE (0x3) +#define ACCESS_MAX_MS_V2_ACE_TYPE (0x3) + +#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE (0x4) +#define ACCESS_MAX_MS_V3_ACE_TYPE (0x4) + +#define ACCESS_MIN_MS_OBJECT_ACE_TYPE (0x5) +#define ACCESS_ALLOWED_OBJECT_ACE_TYPE (0x5) +#define ACCESS_DENIED_OBJECT_ACE_TYPE (0x6) +#define SYSTEM_AUDIT_OBJECT_ACE_TYPE (0x7) +#define SYSTEM_ALARM_OBJECT_ACE_TYPE (0x8) +#define ACCESS_MAX_MS_OBJECT_ACE_TYPE (0x8) + +#define ACCESS_MAX_MS_V4_ACE_TYPE (0x8) +#define ACCESS_MAX_MS_ACE_TYPE (0x8) + +#define ACCESS_ALLOWED_CALLBACK_ACE_TYPE (0x9) +#define ACCESS_DENIED_CALLBACK_ACE_TYPE (0xA) +#define ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE (0xB) +#define ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE (0xC) +#define SYSTEM_AUDIT_CALLBACK_ACE_TYPE (0xD) +#define SYSTEM_ALARM_CALLBACK_ACE_TYPE (0xE) +#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE (0xF) +#define SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE (0x10) + +#define SYSTEM_MANDATORY_LABEL_ACE_TYPE (0x11) +#define ACCESS_MAX_MS_V5_ACE_TYPE (0x11) + +#define OBJECT_INHERIT_ACE (0x1) +#define CONTAINER_INHERIT_ACE (0x2) +#define NO_PROPAGATE_INHERIT_ACE (0x4) +#define INHERIT_ONLY_ACE (0x8) +#define INHERITED_ACE (0x10) +#define VALID_INHERIT_FLAGS (0x1F) + +#define SUCCESSFUL_ACCESS_ACE_FLAG (0x40) +#define FAILED_ACCESS_ACE_FLAG (0x80) + + typedef struct _ACCESS_ALLOWED_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; + } ACCESS_ALLOWED_ACE; + + typedef ACCESS_ALLOWED_ACE *PACCESS_ALLOWED_ACE; + + typedef struct _ACCESS_DENIED_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; + } ACCESS_DENIED_ACE; + typedef ACCESS_DENIED_ACE *PACCESS_DENIED_ACE; + + typedef struct _SYSTEM_AUDIT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; + } SYSTEM_AUDIT_ACE; + typedef SYSTEM_AUDIT_ACE *PSYSTEM_AUDIT_ACE; + + typedef struct _SYSTEM_ALARM_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; + } SYSTEM_ALARM_ACE; + typedef SYSTEM_ALARM_ACE *PSYSTEM_ALARM_ACE; + + typedef struct _ACCESS_ALLOWED_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; + } ACCESS_ALLOWED_OBJECT_ACE,*PACCESS_ALLOWED_OBJECT_ACE; + + typedef struct _ACCESS_DENIED_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; + } ACCESS_DENIED_OBJECT_ACE,*PACCESS_DENIED_OBJECT_ACE; + + typedef struct _SYSTEM_AUDIT_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; + } SYSTEM_AUDIT_OBJECT_ACE,*PSYSTEM_AUDIT_OBJECT_ACE; + + typedef struct _SYSTEM_ALARM_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; + } SYSTEM_ALARM_OBJECT_ACE,*PSYSTEM_ALARM_OBJECT_ACE; + + typedef struct _ACCESS_ALLOWED_CALLBACK_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; + + } ACCESS_ALLOWED_CALLBACK_ACE,*PACCESS_ALLOWED_CALLBACK_ACE; + + typedef struct _ACCESS_DENIED_CALLBACK_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; + + } ACCESS_DENIED_CALLBACK_ACE,*PACCESS_DENIED_CALLBACK_ACE; + + typedef struct _SYSTEM_AUDIT_CALLBACK_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; + + } SYSTEM_AUDIT_CALLBACK_ACE,*PSYSTEM_AUDIT_CALLBACK_ACE; + + typedef struct _SYSTEM_ALARM_CALLBACK_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; + + } SYSTEM_ALARM_CALLBACK_ACE,*PSYSTEM_ALARM_CALLBACK_ACE; + + typedef struct _ACCESS_ALLOWED_CALLBACK_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; + + } ACCESS_ALLOWED_CALLBACK_OBJECT_ACE,*PACCESS_ALLOWED_CALLBACK_OBJECT_ACE; + + typedef struct _ACCESS_DENIED_CALLBACK_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; + + } ACCESS_DENIED_CALLBACK_OBJECT_ACE,*PACCESS_DENIED_CALLBACK_OBJECT_ACE; + + typedef struct _SYSTEM_AUDIT_CALLBACK_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; + + } SYSTEM_AUDIT_CALLBACK_OBJECT_ACE,*PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE; + + typedef struct _SYSTEM_ALARM_CALLBACK_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; + + } SYSTEM_ALARM_CALLBACK_OBJECT_ACE,*PSYSTEM_ALARM_CALLBACK_OBJECT_ACE; + +#define ACE_OBJECT_TYPE_PRESENT 0x1 +#define ACE_INHERITED_OBJECT_TYPE_PRESENT 0x2 + + typedef enum _ACL_INFORMATION_CLASS { + AclRevisionInformation = 1,AclSizeInformation + } ACL_INFORMATION_CLASS; + + typedef struct _ACL_REVISION_INFORMATION { + DWORD AclRevision; + } ACL_REVISION_INFORMATION; + typedef ACL_REVISION_INFORMATION *PACL_REVISION_INFORMATION; + + typedef struct _ACL_SIZE_INFORMATION { + DWORD AceCount; + DWORD AclBytesInUse; + DWORD AclBytesFree; + } ACL_SIZE_INFORMATION; + typedef ACL_SIZE_INFORMATION *PACL_SIZE_INFORMATION; + +#define SECURITY_DESCRIPTOR_REVISION (1) +#define SECURITY_DESCRIPTOR_REVISION1 (1) + +#define SECURITY_DESCRIPTOR_MIN_LENGTH (sizeof(SECURITY_DESCRIPTOR)) + + typedef WORD SECURITY_DESCRIPTOR_CONTROL,*PSECURITY_DESCRIPTOR_CONTROL; + +#define SE_OWNER_DEFAULTED (0x0001) +#define SE_GROUP_DEFAULTED (0x0002) +#define SE_DACL_PRESENT (0x0004) +#define SE_DACL_DEFAULTED (0x0008) +#define SE_SACL_PRESENT (0x0010) +#define SE_SACL_DEFAULTED (0x0020) +#define SE_DACL_AUTO_INHERIT_REQ (0x0100) +#define SE_SACL_AUTO_INHERIT_REQ (0x0200) +#define SE_DACL_AUTO_INHERITED (0x0400) +#define SE_SACL_AUTO_INHERITED (0x0800) +#define SE_DACL_PROTECTED (0x1000) +#define SE_SACL_PROTECTED (0x2000) +#define SE_RM_CONTROL_VALID (0x4000) +#define SE_SELF_RELATIVE (0x8000) + + typedef struct _SECURITY_DESCRIPTOR_RELATIVE { + BYTE Revision; + BYTE Sbz1; + SECURITY_DESCRIPTOR_CONTROL Control; + DWORD Owner; + DWORD Group; + DWORD Sacl; + DWORD Dacl; + } SECURITY_DESCRIPTOR_RELATIVE,*PISECURITY_DESCRIPTOR_RELATIVE; + + typedef struct _SECURITY_DESCRIPTOR { + BYTE Revision; + BYTE Sbz1; + SECURITY_DESCRIPTOR_CONTROL Control; + PSID Owner; + PSID Group; + PACL Sacl; + PACL Dacl; + + } SECURITY_DESCRIPTOR,*PISECURITY_DESCRIPTOR; + + typedef struct _OBJECT_TYPE_LIST { + WORD Level; + WORD Sbz; + GUID *ObjectType; + } OBJECT_TYPE_LIST,*POBJECT_TYPE_LIST; + +#define ACCESS_OBJECT_GUID 0 +#define ACCESS_PROPERTY_SET_GUID 1 +#define ACCESS_PROPERTY_GUID 2 + +#define ACCESS_MAX_LEVEL 4 + + typedef enum _AUDIT_EVENT_TYPE { + AuditEventObjectAccess,AuditEventDirectoryServiceAccess + } AUDIT_EVENT_TYPE,*PAUDIT_EVENT_TYPE; + +#define AUDIT_ALLOW_NO_PRIVILEGE 0x1 + +#define ACCESS_DS_SOURCE_A "DS" +#define ACCESS_DS_SOURCE_W L"DS" +#define ACCESS_DS_OBJECT_TYPE_NAME_A "Directory Service Object" +#define ACCESS_DS_OBJECT_TYPE_NAME_W L"Directory Service Object" + +#define SE_PRIVILEGE_ENABLED_BY_DEFAULT (0x00000001L) +#define SE_PRIVILEGE_ENABLED (0x00000002L) +#define SE_PRIVILEGE_REMOVED (0X00000004L) +#define SE_PRIVILEGE_USED_FOR_ACCESS (0x80000000L) + +#define PRIVILEGE_SET_ALL_NECESSARY (1) + + typedef struct _PRIVILEGE_SET { + DWORD PrivilegeCount; + DWORD Control; + LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]; + } PRIVILEGE_SET,*PPRIVILEGE_SET; + +#define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege") +#define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege") +#define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege") +#define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege") +#define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege") #define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege") -#define SE_TCB_NAME TEXT("SeTcbPrivilege") -#define SE_SECURITY_NAME TEXT("SeSecurityPrivilege") -#define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege") -#define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege") -#define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege") -#define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege") -#define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege") -#define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege") +#define SE_TCB_NAME TEXT("SeTcbPrivilege") +#define SE_SECURITY_NAME TEXT("SeSecurityPrivilege") +#define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege") +#define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege") +#define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege") +#define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege") +#define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege") +#define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege") #define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege") -#define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege") +#define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege") #define SE_BACKUP_NAME TEXT("SeBackupPrivilege") -#define SE_RESTORE_NAME TEXT("SeRestorePrivilege") -#define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege") -#define SE_DEBUG_NAME TEXT("SeDebugPrivilege") -#define SE_AUDIT_NAME TEXT("SeAuditPrivilege") -#define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege") -#define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege") -#define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege") -#define SE_GROUP_MANDATORY 1 -#define SE_GROUP_ENABLED_BY_DEFAULT 2 -#define SE_GROUP_ENABLED 4 -#define SE_GROUP_OWNER 8 -#define SE_GROUP_USE_FOR_DENY_ONLY 16 -#define SE_GROUP_LOGON_ID 3221225472U -#define SE_GROUP_RESOURCE 536870912 -#define LANG_NEUTRAL 0x00 -#define LANG_ARABIC 0x01 -#define LANG_BULGARIAN 0x02 -#define LANG_CATALAN 0x03 -#define LANG_CHINESE 0x04 -#define LANG_CZECH 0x05 -#define LANG_DANISH 0x06 -#define LANG_GERMAN 0x07 -#define LANG_GREEK 0x08 -#define LANG_ENGLISH 0x09 -#define LANG_SPANISH 0x0a -#define LANG_FINNISH 0x0b -#define LANG_FRENCH 0x0c -#define LANG_HEBREW 0x0d -#define LANG_HUNGARIAN 0x0e -#define LANG_ICELANDIC 0x0f -#define LANG_ITALIAN 0x10 -#define LANG_JAPANESE 0x11 -#define LANG_KOREAN 0x12 -#define LANG_DUTCH 0x13 -#define LANG_NORWEGIAN 0x14 -#define LANG_POLISH 0x15 -#define LANG_PORTUGUESE 0x16 -#define LANG_ROMANIAN 0x18 -#define LANG_RUSSIAN 0x19 -#define LANG_CROATIAN 0x1a -#define LANG_SERBIAN 0x1a -#define LANG_SLOVAK 0x1b -#define LANG_ALBANIAN 0x1c -#define LANG_SWEDISH 0x1d -#define LANG_THAI 0x1e -#define LANG_TURKISH 0x1f -#define LANG_URDU 0x20 -#define LANG_INDONESIAN 0x21 -#define LANG_UKRAINIAN 0x22 -#define LANG_BELARUSIAN 0x23 -#define LANG_SLOVENIAN 0x24 -#define LANG_ESTONIAN 0x25 -#define LANG_LATVIAN 0x26 -#define LANG_LITHUANIAN 0x27 -#define LANG_FARSI 0x29 -#define LANG_VIETNAMESE 0x2a -#define LANG_ARMENIAN 0x2b -#define LANG_AZERI 0x2c -#define LANG_BASQUE 0x2d -#define LANG_MACEDONIAN 0x2f -#define LANG_AFRIKAANS 0x36 -#define LANG_GEORGIAN 0x37 -#define LANG_FAEROESE 0x38 -#define LANG_HINDI 0x39 -#define LANG_MALAY 0x3e -#define LANG_KAZAK 0x3f -#define LANG_SWAHILI 0x41 -#define LANG_UZBEK 0x43 -#define LANG_TATAR 0x44 -#define LANG_BENGALI 0x45 -#define LANG_PUNJABI 0x46 -#define LANG_GUJARATI 0x47 -#define LANG_ORIYA 0x48 -#define LANG_TAMIL 0x49 -#define LANG_TELUGU 0x4a -#define LANG_KANNADA 0x4b -#define LANG_MALAYALAM 0x4c -#define LANG_ASSAMESE 0x4d -#define LANG_MARATHI 0x4e -#define LANG_SANSKRIT 0x4f -#define LANG_KONKANI 0x57 -#define LANG_MANIPURI 0x58 -#define LANG_SINDHI 0x59 -#define LANG_KASHMIRI 0x60 -#define LANG_NEPALI 0x61 -#define SUBLANG_NEUTRAL 0x00 -#define SUBLANG_DEFAULT 0x01 -#define SUBLANG_SYS_DEFAULT 0x02 -#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01 -#define SUBLANG_ARABIC_IRAQ 0x02 -#define SUBLANG_ARABIC_EGYPT 0x03 -#define SUBLANG_ARABIC_LIBYA 0x04 -#define SUBLANG_ARABIC_ALGERIA 0x05 -#define SUBLANG_ARABIC_MOROCCO 0x06 -#define SUBLANG_ARABIC_TUNISIA 0x07 -#define SUBLANG_ARABIC_OMAN 0x08 -#define SUBLANG_ARABIC_YEMEN 0x09 -#define SUBLANG_ARABIC_SYRIA 0x0a -#define SUBLANG_ARABIC_JORDAN 0x0b -#define SUBLANG_ARABIC_LEBANON 0x0c -#define SUBLANG_ARABIC_KUWAIT 0x0d -#define SUBLANG_ARABIC_UAE 0x0e -#define SUBLANG_ARABIC_BAHRAIN 0x0f -#define SUBLANG_ARABIC_QATAR 0x10 -#define SUBLANG_AZERI_CYRILLIC 0x01 -#define SUBLANG_AZERI_LATIN 0x02 -#define SUBLANG_CHINESE_TRADITIONAL 0x01 -#define SUBLANG_CHINESE_SIMPLIFIED 0x02 -#define SUBLANG_CHINESE_HONGKONG 0x03 -#define SUBLANG_CHINESE_SINGAPORE 0x04 -#define SUBLANG_CHINESE_MACAU 0x05 -#define SUBLANG_DUTCH 0x01 -#define SUBLANG_DUTCH_BELGIAN 0x02 -#define SUBLANG_ENGLISH_US 0x01 -#define SUBLANG_ENGLISH_UK 0x02 -#define SUBLANG_ENGLISH_AUS 0x03 -#define SUBLANG_ENGLISH_CAN 0x04 -#define SUBLANG_ENGLISH_NZ 0x05 -#define SUBLANG_ENGLISH_EIRE 0x06 -#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07 -#define SUBLANG_ENGLISH_JAMAICA 0x08 -#define SUBLANG_ENGLISH_CARIBBEAN 0x09 -#define SUBLANG_ENGLISH_BELIZE 0x0a -#define SUBLANG_ENGLISH_TRINIDAD 0x0b -#define SUBLANG_ENGLISH_PHILIPPINES 0x0c -#define SUBLANG_ENGLISH_ZIMBABWE 0x0d -#define SUBLANG_FRENCH 0x01 -#define SUBLANG_FRENCH_BELGIAN 0x02 -#define SUBLANG_FRENCH_CANADIAN 0x03 -#define SUBLANG_FRENCH_SWISS 0x04 -#define SUBLANG_FRENCH_LUXEMBOURG 0x05 -#define SUBLANG_FRENCH_MONACO 0x06 -#define SUBLANG_GERMAN 0x01 -#define SUBLANG_GERMAN_SWISS 0x02 -#define SUBLANG_GERMAN_AUSTRIAN 0x03 -#define SUBLANG_GERMAN_LUXEMBOURG 0x04 -#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05 -#define SUBLANG_ITALIAN 0x01 -#define SUBLANG_ITALIAN_SWISS 0x02 -#define SUBLANG_KASHMIRI_INDIA 0x02 -#define SUBLANG_KOREAN 0x01 -#define SUBLANG_LITHUANIAN 0x01 -#define SUBLANG_MALAY_MALAYSIA 0x01 -#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 -#define SUBLANG_NEPALI_INDIA 0x02 -#define SUBLANG_NORWEGIAN_BOKMAL 0x01 -#define SUBLANG_NORWEGIAN_NYNORSK 0x02 -#define SUBLANG_PORTUGUESE 0x01 -#define SUBLANG_PORTUGUESE_BRAZILIAN 0x02 -#define SUBLANG_SERBIAN_LATIN 0x02 -#define SUBLANG_SERBIAN_CYRILLIC 0x03 -#define SUBLANG_SPANISH 0x01 -#define SUBLANG_SPANISH_MEXICAN 0x02 -#define SUBLANG_SPANISH_MODERN 0x03 -#define SUBLANG_SPANISH_GUATEMALA 0x04 -#define SUBLANG_SPANISH_COSTA_RICA 0x05 -#define SUBLANG_SPANISH_PANAMA 0x06 -#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07 -#define SUBLANG_SPANISH_VENEZUELA 0x08 -#define SUBLANG_SPANISH_COLOMBIA 0x09 -#define SUBLANG_SPANISH_PERU 0x0a -#define SUBLANG_SPANISH_ARGENTINA 0x0b -#define SUBLANG_SPANISH_ECUADOR 0x0c -#define SUBLANG_SPANISH_CHILE 0x0d -#define SUBLANG_SPANISH_URUGUAY 0x0e -#define SUBLANG_SPANISH_PARAGUAY 0x0f -#define SUBLANG_SPANISH_BOLIVIA 0x10 -#define SUBLANG_SPANISH_EL_SALVADOR 0x11 -#define SUBLANG_SPANISH_HONDURAS 0x12 -#define SUBLANG_SPANISH_NICARAGUA 0x13 -#define SUBLANG_SPANISH_PUERTO_RICO 0x14 -#define SUBLANG_SWEDISH 0x01 -#define SUBLANG_SWEDISH_FINLAND 0x02 -#define SUBLANG_URDU_PAKISTAN 0x01 -#define SUBLANG_URDU_INDIA 0x02 -#define SUBLANG_UZBEK_LATIN 0x01 -#define SUBLANG_UZBEK_CYRILLIC 0x02 -#define NLS_VALID_LOCALE_MASK 1048575 -#define SORT_DEFAULT 0 -#define SORT_JAPANESE_XJIS 0 -#define SORT_JAPANESE_UNICODE 1 -#define SORT_CHINESE_BIG5 0 -#define SORT_CHINESE_PRCP 0 -#define SORT_CHINESE_UNICODE 1 -#define SORT_CHINESE_PRC 2 -#define SORT_CHINESE_BOPOMOFO 3 -#define SORT_KOREAN_KSC 0 -#define SORT_KOREAN_UNICODE 1 -#define SORT_GERMAN_PHONE_BOOK 1 -#define SORT_HUNGARIAN_DEFAULT 0 -#define SORT_HUNGARIAN_TECHNICAL 1 -#define SORT_GEORGIAN_TRADITIONAL 0 -#define SORT_GEORGIAN_MODERN 1 -#define MAKELANGID(p,s) ((((WORD)(s))<<10)|(WORD)(p)) -#define MAKELCID(l,s) ((DWORD)((((DWORD)((WORD)(s)))<<16)|((DWORD)((WORD)(l))))) -#define PRIMARYLANGID(l) ((WORD)(l)&0x3ff) -#define SORTIDFROMLCID(l) ((WORD)((((DWORD)(l))&NLS_VALID_LOCALE_MASK)>>16)) -#define SORTVERSIONFROMLCID(l) ((WORD)((((DWORD)(l))>>20)&0xf)) -#define SUBLANGID(l) ((WORD)(l)>>10) -#define LANGIDFROMLCID(l) ((WORD)(l)) -#define LANG_SYSTEM_DEFAULT MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT) -#define LANG_USER_DEFAULT MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT) -#define LOCALE_NEUTRAL MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT) -#define ACL_REVISION 2 -#define ACL_REVISION_DS 4 -#define ACL_REVISION1 1 -#define ACL_REVISION2 2 -#define ACL_REVISION3 3 -#define ACL_REVISION4 4 -#define MIN_ACL_REVISION 2 -#define MAX_ACL_REVISION 4 -#define MINCHAR 0x80 -#define MAXCHAR 0x7f -#define MINSHORT 0x8000 -#define MAXSHORT 0x7fff -#define MINLONG 0x80000000 -#define MAXLONG 0x7fffffff -#define MAXBYTE 0xff -#define MAXWORD 0xffff -#define MAXDWORD 0xffffffff +#define SE_RESTORE_NAME TEXT("SeRestorePrivilege") +#define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege") +#define SE_DEBUG_NAME TEXT("SeDebugPrivilege") +#define SE_AUDIT_NAME TEXT("SeAuditPrivilege") +#define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege") +#define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege") +#define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege") +#define SE_UNDOCK_NAME TEXT("SeUndockPrivilege") +#define SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege") +#define SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege") +#define SE_MANAGE_VOLUME_NAME TEXT("SeManageVolumePrivilege") +#define SE_IMPERSONATE_NAME TEXT("SeImpersonatePrivilege") +#define SE_CREATE_GLOBAL_NAME TEXT("SeCreateGlobalPrivilege") + + typedef enum _SECURITY_IMPERSONATION_LEVEL { + SecurityAnonymous,SecurityIdentification,SecurityImpersonation,SecurityDelegation + } SECURITY_IMPERSONATION_LEVEL,*PSECURITY_IMPERSONATION_LEVEL; + +#define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation +#define SECURITY_MIN_IMPERSONATION_LEVEL SecurityAnonymous +#define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation +#define VALID_IMPERSONATION_LEVEL(L) (((L) >= SECURITY_MIN_IMPERSONATION_LEVEL) && ((L) <= SECURITY_MAX_IMPERSONATION_LEVEL)) + +#define TOKEN_ASSIGN_PRIMARY (0x0001) +#define TOKEN_DUPLICATE (0x0002) +#define TOKEN_IMPERSONATE (0x0004) +#define TOKEN_QUERY (0x0008) +#define TOKEN_QUERY_SOURCE (0x0010) +#define TOKEN_ADJUST_PRIVILEGES (0x0020) +#define TOKEN_ADJUST_GROUPS (0x0040) +#define TOKEN_ADJUST_DEFAULT (0x0080) +#define TOKEN_ADJUST_SESSIONID (0x0100) + +#define TOKEN_ALL_ACCESS_P (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT) +#define TOKEN_ALL_ACCESS (TOKEN_ALL_ACCESS_P | TOKEN_ADJUST_SESSIONID) +#define TOKEN_READ (STANDARD_RIGHTS_READ | TOKEN_QUERY) + +#define TOKEN_WRITE (STANDARD_RIGHTS_WRITE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT) + +#define TOKEN_EXECUTE (STANDARD_RIGHTS_EXECUTE) + + typedef enum _TOKEN_TYPE { + TokenPrimary = 1,TokenImpersonation + } TOKEN_TYPE; + typedef TOKEN_TYPE *PTOKEN_TYPE; + + typedef enum _TOKEN_INFORMATION_CLASS { + TokenUser = 1,TokenGroups,TokenPrivileges,TokenOwner,TokenPrimaryGroup,TokenDefaultDacl,TokenSource,TokenType,TokenImpersonationLevel, + TokenStatistics,TokenRestrictedSids,TokenSessionId,TokenGroupsAndPrivileges,TokenSessionReference,TokenSandBoxInert,TokenAuditPolicy, + TokenOrigin,MaxTokenInfoClass + } TOKEN_INFORMATION_CLASS,*PTOKEN_INFORMATION_CLASS; + + typedef struct _TOKEN_USER { + SID_AND_ATTRIBUTES User; + } TOKEN_USER,*PTOKEN_USER; + + typedef struct _TOKEN_GROUPS { + DWORD GroupCount; + SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; + } TOKEN_GROUPS,*PTOKEN_GROUPS; + + typedef struct _TOKEN_PRIVILEGES { + DWORD PrivilegeCount; + LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; + } TOKEN_PRIVILEGES,*PTOKEN_PRIVILEGES; + + typedef struct _TOKEN_OWNER { + PSID Owner; + } TOKEN_OWNER,*PTOKEN_OWNER; + + typedef struct _TOKEN_PRIMARY_GROUP { + PSID PrimaryGroup; + } TOKEN_PRIMARY_GROUP,*PTOKEN_PRIMARY_GROUP; + + typedef struct _TOKEN_DEFAULT_DACL { + PACL DefaultDacl; + } TOKEN_DEFAULT_DACL,*PTOKEN_DEFAULT_DACL; + + typedef struct _TOKEN_GROUPS_AND_PRIVILEGES { + DWORD SidCount; + DWORD SidLength; + PSID_AND_ATTRIBUTES Sids; + DWORD RestrictedSidCount; + DWORD RestrictedSidLength; + PSID_AND_ATTRIBUTES RestrictedSids; + DWORD PrivilegeCount; + DWORD PrivilegeLength; + PLUID_AND_ATTRIBUTES Privileges; + LUID AuthenticationId; + } TOKEN_GROUPS_AND_PRIVILEGES,*PTOKEN_GROUPS_AND_PRIVILEGES; + +#define TOKEN_AUDIT_SUCCESS_INCLUDE 0x1 +#define TOKEN_AUDIT_SUCCESS_EXCLUDE 0x2 +#define TOKEN_AUDIT_FAILURE_INCLUDE 0x4 +#define TOKEN_AUDIT_FAILURE_EXCLUDE 0x8 + +#define VALID_AUDIT_POLICY_BITS (TOKEN_AUDIT_SUCCESS_INCLUDE | TOKEN_AUDIT_SUCCESS_EXCLUDE | TOKEN_AUDIT_FAILURE_INCLUDE | TOKEN_AUDIT_FAILURE_EXCLUDE) +#define VALID_TOKEN_AUDIT_POLICY_ELEMENT(P) ((((P).PolicyMask & ~VALID_AUDIT_POLICY_BITS)==0) && ((P).Category <= AuditEventMaxType)) + + typedef struct _TOKEN_AUDIT_POLICY_ELEMENT { + DWORD Category; + DWORD PolicyMask; + } TOKEN_AUDIT_POLICY_ELEMENT,*PTOKEN_AUDIT_POLICY_ELEMENT; + + typedef struct _TOKEN_AUDIT_POLICY { + DWORD PolicyCount; + TOKEN_AUDIT_POLICY_ELEMENT Policy[ANYSIZE_ARRAY]; + } TOKEN_AUDIT_POLICY,*PTOKEN_AUDIT_POLICY; + +#define PER_USER_AUDITING_POLICY_SIZE(p) (sizeof(TOKEN_AUDIT_POLICY) + (((p)->PolicyCount > ANYSIZE_ARRAY) ? (sizeof(TOKEN_AUDIT_POLICY_ELEMENT) *((p)->PolicyCount - ANYSIZE_ARRAY)) : 0)) +#define PER_USER_AUDITING_POLICY_SIZE_BY_COUNT(C) (sizeof(TOKEN_AUDIT_POLICY) + (((C) > ANYSIZE_ARRAY) ? (sizeof(TOKEN_AUDIT_POLICY_ELEMENT) *((C) - ANYSIZE_ARRAY)) : 0)) + +#define TOKEN_SOURCE_LENGTH 8 + + typedef struct _TOKEN_SOURCE { + CHAR SourceName[TOKEN_SOURCE_LENGTH]; + LUID SourceIdentifier; + } TOKEN_SOURCE,*PTOKEN_SOURCE; + + typedef struct _TOKEN_STATISTICS { + LUID TokenId; + LUID AuthenticationId; + LARGE_INTEGER ExpirationTime; + TOKEN_TYPE TokenType; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + DWORD DynamicCharged; + DWORD DynamicAvailable; + DWORD GroupCount; + DWORD PrivilegeCount; + LUID ModifiedId; + } TOKEN_STATISTICS,*PTOKEN_STATISTICS; + + typedef struct _TOKEN_CONTROL { + LUID TokenId; + LUID AuthenticationId; + LUID ModifiedId; + TOKEN_SOURCE TokenSource; + } TOKEN_CONTROL,*PTOKEN_CONTROL; + + typedef struct _TOKEN_ORIGIN { + LUID OriginatingLogonSession; + } TOKEN_ORIGIN,*PTOKEN_ORIGIN; + +#define SECURITY_DYNAMIC_TRACKING (TRUE) +#define SECURITY_STATIC_TRACKING (FALSE) + + typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,*PSECURITY_CONTEXT_TRACKING_MODE; + + typedef struct _SECURITY_QUALITY_OF_SERVICE { + DWORD Length; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode; + BOOLEAN EffectiveOnly; + } SECURITY_QUALITY_OF_SERVICE,*PSECURITY_QUALITY_OF_SERVICE; + + typedef struct _SE_IMPERSONATION_STATE { + PACCESS_TOKEN Token; + BOOLEAN CopyOnOpen; + BOOLEAN EffectiveOnly; + SECURITY_IMPERSONATION_LEVEL Level; + } SE_IMPERSONATION_STATE,*PSE_IMPERSONATION_STATE; + +#define DISABLE_MAX_PRIVILEGE 0x1 +#define SANDBOX_INERT 0x2 + + typedef DWORD SECURITY_INFORMATION,*PSECURITY_INFORMATION; + +#define OWNER_SECURITY_INFORMATION (0x00000001L) +#define GROUP_SECURITY_INFORMATION (0x00000002L) +#define DACL_SECURITY_INFORMATION (0x00000004L) +#define SACL_SECURITY_INFORMATION (0x00000008L) + +#define PROTECTED_DACL_SECURITY_INFORMATION (0x80000000L) +#define PROTECTED_SACL_SECURITY_INFORMATION (0x40000000L) +#define UNPROTECTED_DACL_SECURITY_INFORMATION (0x20000000L) +#define UNPROTECTED_SACL_SECURITY_INFORMATION (0x10000000L) + +#define PROCESS_TERMINATE (0x0001) +#define PROCESS_CREATE_THREAD (0x0002) +#define PROCESS_SET_SESSIONID (0x0004) +#define PROCESS_VM_OPERATION (0x0008) +#define PROCESS_VM_READ (0x0010) +#define PROCESS_VM_WRITE (0x0020) +#define PROCESS_DUP_HANDLE (0x0040) +#define PROCESS_CREATE_PROCESS (0x0080) +#define PROCESS_SET_QUOTA (0x0100) +#define PROCESS_SET_INFORMATION (0x0200) +#define PROCESS_QUERY_INFORMATION (0x0400) +#define PROCESS_SUSPEND_RESUME (0x0800) +#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF) + +#ifdef _WIN64 +#define MAXIMUM_PROCESSORS 64 +#else +#define MAXIMUM_PROCESSORS 32 +#endif + +#define THREAD_TERMINATE (0x0001) +#define THREAD_SUSPEND_RESUME (0x0002) +#define THREAD_GET_CONTEXT (0x0008) +#define THREAD_SET_CONTEXT (0x0010) +#define THREAD_SET_INFORMATION (0x0020) +#define THREAD_QUERY_INFORMATION (0x0040) +#define THREAD_SET_THREAD_TOKEN (0x0080) +#define THREAD_IMPERSONATE (0x0100) +#define THREAD_DIRECT_IMPERSONATION (0x0200) + +#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3FF) + +#define JOB_OBJECT_ASSIGN_PROCESS (0x0001) +#define JOB_OBJECT_SET_ATTRIBUTES (0x0002) +#define JOB_OBJECT_QUERY (0x0004) +#define JOB_OBJECT_TERMINATE (0x0008) +#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES (0x0010) +#define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1F) + + typedef struct _JOB_SET_ARRAY { + HANDLE JobHandle; + DWORD MemberLevel; + DWORD Flags; + } JOB_SET_ARRAY,*PJOB_SET_ARRAY; + +#define FLS_MAXIMUM_AVAILABLE 128 +#define TLS_MINIMUM_AVAILABLE 64 + +#ifndef _NT_TIB_DEFINED +#define _NT_TIB_DEFINED + typedef struct _NT_TIB { + struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; + PVOID StackBase; + PVOID StackLimit; + PVOID SubSystemTib; + union { + PVOID FiberData; + DWORD Version; + }; + PVOID ArbitraryUserPointer; + struct _NT_TIB *Self; + } NT_TIB; + typedef NT_TIB *PNT_TIB; +#endif + + typedef struct _NT_TIB32 { + DWORD ExceptionList; + DWORD StackBase; + DWORD StackLimit; + DWORD SubSystemTib; + union { + DWORD FiberData; + DWORD Version; + }; + DWORD ArbitraryUserPointer; + DWORD Self; + } NT_TIB32,*PNT_TIB32; + + typedef struct _NT_TIB64 { + DWORD64 ExceptionList; + DWORD64 StackBase; + DWORD64 StackLimit; + DWORD64 SubSystemTib; + union { + DWORD64 FiberData; + DWORD Version; + }; + DWORD64 ArbitraryUserPointer; + DWORD64 Self; + } NT_TIB64,*PNT_TIB64; + +#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) +#define WX86 +#endif + +#define THREAD_BASE_PRIORITY_LOWRT 15 +#define THREAD_BASE_PRIORITY_MAX 2 +#define THREAD_BASE_PRIORITY_MIN (-2) +#define THREAD_BASE_PRIORITY_IDLE (-15) + + typedef struct _QUOTA_LIMITS { + SIZE_T PagedPoolLimit; + SIZE_T NonPagedPoolLimit; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + SIZE_T PagefileLimit; + LARGE_INTEGER TimeLimit; + } QUOTA_LIMITS,*PQUOTA_LIMITS; + +#define QUOTA_LIMITS_HARDWS_MIN_ENABLE 0x00000001 +#define QUOTA_LIMITS_HARDWS_MIN_DISABLE 0x00000002 +#define QUOTA_LIMITS_HARDWS_MAX_ENABLE 0x00000004 +#define QUOTA_LIMITS_HARDWS_MAX_DISABLE 0x00000008 + + typedef struct _QUOTA_LIMITS_EX { + SIZE_T PagedPoolLimit; + SIZE_T NonPagedPoolLimit; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + SIZE_T PagefileLimit; + LARGE_INTEGER TimeLimit; + SIZE_T Reserved1; + SIZE_T Reserved2; + SIZE_T Reserved3; + SIZE_T Reserved4; + DWORD Flags; + DWORD Reserved5; + } QUOTA_LIMITS_EX,*PQUOTA_LIMITS_EX; + + typedef struct _IO_COUNTERS { + ULONGLONG ReadOperationCount; + ULONGLONG WriteOperationCount; + ULONGLONG OtherOperationCount; + ULONGLONG ReadTransferCount; + ULONGLONG WriteTransferCount; + ULONGLONG OtherTransferCount; + } IO_COUNTERS; + typedef IO_COUNTERS *PIO_COUNTERS; + + typedef struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION { + LARGE_INTEGER TotalUserTime; + LARGE_INTEGER TotalKernelTime; + LARGE_INTEGER ThisPeriodTotalUserTime; + LARGE_INTEGER ThisPeriodTotalKernelTime; + DWORD TotalPageFaultCount; + DWORD TotalProcesses; + DWORD ActiveProcesses; + DWORD TotalTerminatedProcesses; + } JOBOBJECT_BASIC_ACCOUNTING_INFORMATION,*PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION; + + typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION { + LARGE_INTEGER PerProcessUserTimeLimit; + LARGE_INTEGER PerJobUserTimeLimit; + DWORD LimitFlags; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + DWORD ActiveProcessLimit; + ULONG_PTR Affinity; + DWORD PriorityClass; + DWORD SchedulingClass; + } JOBOBJECT_BASIC_LIMIT_INFORMATION,*PJOBOBJECT_BASIC_LIMIT_INFORMATION; + + typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION { + JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; + IO_COUNTERS IoInfo; + SIZE_T ProcessMemoryLimit; + SIZE_T JobMemoryLimit; + SIZE_T PeakProcessMemoryUsed; + SIZE_T PeakJobMemoryUsed; + } JOBOBJECT_EXTENDED_LIMIT_INFORMATION,*PJOBOBJECT_EXTENDED_LIMIT_INFORMATION; + + typedef struct _JOBOBJECT_BASIC_PROCESS_ID_LIST { + DWORD NumberOfAssignedProcesses; + DWORD NumberOfProcessIdsInList; + ULONG_PTR ProcessIdList[1]; + } JOBOBJECT_BASIC_PROCESS_ID_LIST,*PJOBOBJECT_BASIC_PROCESS_ID_LIST; + + typedef struct _JOBOBJECT_BASIC_UI_RESTRICTIONS { + DWORD UIRestrictionsClass; + } JOBOBJECT_BASIC_UI_RESTRICTIONS,*PJOBOBJECT_BASIC_UI_RESTRICTIONS; + + typedef struct _JOBOBJECT_SECURITY_LIMIT_INFORMATION { + DWORD SecurityLimitFlags; + HANDLE JobToken; + PTOKEN_GROUPS SidsToDisable; + PTOKEN_PRIVILEGES PrivilegesToDelete; + PTOKEN_GROUPS RestrictedSids; + } JOBOBJECT_SECURITY_LIMIT_INFORMATION,*PJOBOBJECT_SECURITY_LIMIT_INFORMATION; + + typedef struct _JOBOBJECT_END_OF_JOB_TIME_INFORMATION { + DWORD EndOfJobTimeAction; + } JOBOBJECT_END_OF_JOB_TIME_INFORMATION,*PJOBOBJECT_END_OF_JOB_TIME_INFORMATION; + + typedef struct _JOBOBJECT_ASSOCIATE_COMPLETION_PORT { + PVOID CompletionKey; + HANDLE CompletionPort; + } JOBOBJECT_ASSOCIATE_COMPLETION_PORT,*PJOBOBJECT_ASSOCIATE_COMPLETION_PORT; + + typedef struct _JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION { + JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo; + IO_COUNTERS IoInfo; + } JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION,*PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION; + + typedef struct _JOBOBJECT_JOBSET_INFORMATION { + DWORD MemberLevel; + } JOBOBJECT_JOBSET_INFORMATION,*PJOBOBJECT_JOBSET_INFORMATION; + +#define JOB_OBJECT_TERMINATE_AT_END_OF_JOB 0 +#define JOB_OBJECT_POST_AT_END_OF_JOB 1 + +#define JOB_OBJECT_MSG_END_OF_JOB_TIME 1 +#define JOB_OBJECT_MSG_END_OF_PROCESS_TIME 2 +#define JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT 3 +#define JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO 4 +#define JOB_OBJECT_MSG_NEW_PROCESS 6 +#define JOB_OBJECT_MSG_EXIT_PROCESS 7 +#define JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS 8 +#define JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT 9 +#define JOB_OBJECT_MSG_JOB_MEMORY_LIMIT 10 + +#define JOB_OBJECT_LIMIT_WORKINGSET 0x00000001 +#define JOB_OBJECT_LIMIT_PROCESS_TIME 0x00000002 +#define JOB_OBJECT_LIMIT_JOB_TIME 0x00000004 +#define JOB_OBJECT_LIMIT_ACTIVE_PROCESS 0x00000008 +#define JOB_OBJECT_LIMIT_AFFINITY 0x00000010 +#define JOB_OBJECT_LIMIT_PRIORITY_CLASS 0x00000020 +#define JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME 0x00000040 +#define JOB_OBJECT_LIMIT_SCHEDULING_CLASS 0x00000080 + +#define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100 +#define JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200 +#define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400 +#define JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800 +#define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000 +#define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000 + +#define JOB_OBJECT_LIMIT_RESERVED2 0x00004000 +#define JOB_OBJECT_LIMIT_RESERVED3 0x00008000 +#define JOB_OBJECT_LIMIT_RESERVED4 0x00010000 +#define JOB_OBJECT_LIMIT_RESERVED5 0x00020000 +#define JOB_OBJECT_LIMIT_RESERVED6 0x00040000 + +#define JOB_OBJECT_LIMIT_VALID_FLAGS 0x0007ffff + +#define JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS 0x000000ff +#define JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS 0x00003fff +#define JOB_OBJECT_RESERVED_LIMIT_VALID_FLAGS 0x0007ffff + +#define JOB_OBJECT_UILIMIT_NONE 0x00000000 + +#define JOB_OBJECT_UILIMIT_HANDLES 0x00000001 +#define JOB_OBJECT_UILIMIT_READCLIPBOARD 0x00000002 +#define JOB_OBJECT_UILIMIT_WRITECLIPBOARD 0x00000004 +#define JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS 0x00000008 +#define JOB_OBJECT_UILIMIT_DISPLAYSETTINGS 0x00000010 +#define JOB_OBJECT_UILIMIT_GLOBALATOMS 0x00000020 +#define JOB_OBJECT_UILIMIT_DESKTOP 0x00000040 +#define JOB_OBJECT_UILIMIT_EXITWINDOWS 0x00000080 + +#define JOB_OBJECT_UILIMIT_ALL 0x000000FF + +#define JOB_OBJECT_UI_VALID_FLAGS 0x000000FF + +#define JOB_OBJECT_SECURITY_NO_ADMIN 0x00000001 +#define JOB_OBJECT_SECURITY_RESTRICTED_TOKEN 0x00000002 +#define JOB_OBJECT_SECURITY_ONLY_TOKEN 0x00000004 +#define JOB_OBJECT_SECURITY_FILTER_TOKENS 0x00000008 + +#define JOB_OBJECT_SECURITY_VALID_FLAGS 0x0000000f + + typedef enum _JOBOBJECTINFOCLASS { + JobObjectBasicAccountingInformation = 1,JobObjectBasicLimitInformation,JobObjectBasicProcessIdList,JobObjectBasicUIRestrictions, + JobObjectSecurityLimitInformation,JobObjectEndOfJobTimeInformation,JobObjectAssociateCompletionPortInformation, + JobObjectBasicAndIoAccountingInformation,JobObjectExtendedLimitInformation,JobObjectJobSetInformation,MaxJobObjectInfoClass + } JOBOBJECTINFOCLASS; + +#define EVENT_MODIFY_STATE 0x0002 +#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) + +#define MUTANT_QUERY_STATE 0x0001 + +#define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE| MUTANT_QUERY_STATE) +#define SEMAPHORE_MODIFY_STATE 0x0002 +#define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) + +#define TIMER_QUERY_STATE 0x0001 +#define TIMER_MODIFY_STATE 0x0002 + +#define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE| TIMER_QUERY_STATE|TIMER_MODIFY_STATE) + +#define TIME_ZONE_ID_UNKNOWN 0 +#define TIME_ZONE_ID_STANDARD 1 +#define TIME_ZONE_ID_DAYLIGHT 2 + + typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP { + RelationProcessorCore,RelationNumaNode,RelationCache + } LOGICAL_PROCESSOR_RELATIONSHIP; + +#define LTP_PC_SMT 0x1 + + typedef enum _PROCESSOR_CACHE_TYPE { + CacheUnified,CacheInstruction,CacheData,CacheTrace + } PROCESSOR_CACHE_TYPE; + +#define CACHE_FULLY_ASSOCIATIVE 0xFF + + typedef struct _CACHE_DESCRIPTOR { + BYTE Level; + BYTE Associativity; + WORD LineSize; + DWORD Size; + PROCESSOR_CACHE_TYPE Type; + } CACHE_DESCRIPTOR,*PCACHE_DESCRIPTOR; + + typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION { + ULONG_PTR ProcessorMask; + LOGICAL_PROCESSOR_RELATIONSHIP Relationship; + union { + struct { + BYTE Flags; + } ProcessorCore; + struct { + DWORD NodeNumber; + } NumaNode; + CACHE_DESCRIPTOR Cache; + ULONGLONG Reserved[2]; + }; + } SYSTEM_LOGICAL_PROCESSOR_INFORMATION,*PSYSTEM_LOGICAL_PROCESSOR_INFORMATION; + #define PROCESSOR_INTEL_386 386 #define PROCESSOR_INTEL_486 486 #define PROCESSOR_INTEL_PENTIUM 586 +#define PROCESSOR_INTEL_IA64 2200 +#define PROCESSOR_AMD_X8664 8664 #define PROCESSOR_MIPS_R4000 4000 #define PROCESSOR_ALPHA_21064 21064 +#define PROCESSOR_PPC_601 601 +#define PROCESSOR_PPC_603 603 +#define PROCESSOR_PPC_604 604 +#define PROCESSOR_PPC_620 620 +#define PROCESSOR_HITACHI_SH3 10003 +#define PROCESSOR_HITACHI_SH3E 10004 +#define PROCESSOR_HITACHI_SH4 10005 +#define PROCESSOR_MOTOROLA_821 821 +#define PROCESSOR_SHx_SH3 103 +#define PROCESSOR_SHx_SH4 104 +#define PROCESSOR_STRONGARM 2577 +#define PROCESSOR_ARM720 1824 +#define PROCESSOR_ARM820 2080 +#define PROCESSOR_ARM920 2336 +#define PROCESSOR_ARM_7TDMI 70001 +#define PROCESSOR_OPTIL 0x494f + #define PROCESSOR_ARCHITECTURE_INTEL 0 #define PROCESSOR_ARCHITECTURE_MIPS 1 #define PROCESSOR_ARCHITECTURE_ALPHA 2 #define PROCESSOR_ARCHITECTURE_PPC 3 +#define PROCESSOR_ARCHITECTURE_SHX 4 +#define PROCESSOR_ARCHITECTURE_ARM 5 +#define PROCESSOR_ARCHITECTURE_IA64 6 +#define PROCESSOR_ARCHITECTURE_ALPHA64 7 +#define PROCESSOR_ARCHITECTURE_MSIL 8 +#define PROCESSOR_ARCHITECTURE_AMD64 9 +#define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10 + #define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF + #define PF_FLOATING_POINT_PRECISION_ERRATA 0 #define PF_FLOATING_POINT_EMULATED 1 #define PF_COMPARE_EXCHANGE_DOUBLE 2 @@ -573,229 +3126,997 @@ typedef BYTE BOOLEAN,*PBOOLEAN; #define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7 #define PF_RDTSC_INSTRUCTION_AVAILABLE 8 #define PF_PAE_ENABLED 9 -#define PAGE_READONLY 2 -#define PAGE_READWRITE 4 -#define PAGE_WRITECOPY 8 -#define FILE_ACTION_ADDED 1 -#define FILE_ACTION_REMOVED 2 -#define FILE_ACTION_MODIFIED 3 -#define FILE_ACTION_RENAMED_OLD_NAME 4 -#define FILE_ACTION_RENAMED_NEW_NAME 5 -#define HEAP_NO_SERIALIZE 1 -#define HEAP_GROWABLE 2 -#define HEAP_GENERATE_EXCEPTIONS 4 -#define HEAP_ZERO_MEMORY 8 -#define HEAP_REALLOC_IN_PLACE_ONLY 16 -#define HEAP_TAIL_CHECKING_ENABLED 32 -#define HEAP_FREE_CHECKING_ENABLED 64 -#define HEAP_DISABLE_COALESCE_ON_FREE 128 -#define HEAP_CREATE_ALIGN_16 0x0000 -#define HEAP_CREATE_ENABLE_TRACING 0x20000 -#define HEAP_MAXIMUM_TAG 0xFFF -#define HEAP_PSEUDO_TAG_FLAG 0x8000 -#define HEAP_TAG_SHIFT 16 -#define HEAP_MAKE_TAG_FLAGS(b,o) ((DWORD)((b)+(o)<<16))) -#define KEY_QUERY_VALUE 1 -#define KEY_SET_VALUE 2 -#define KEY_CREATE_SUB_KEY 4 -#define KEY_ENUMERATE_SUB_KEYS 8 -#define KEY_NOTIFY 16 -#define KEY_CREATE_LINK 32 -#define KEY_WRITE 0x20006 -#define KEY_EXECUTE 0x20019 -#define KEY_READ 0x20019 -#define KEY_ALL_ACCESS 0xf003f -#define REG_WHOLE_HIVE_VOLATILE 1 -#define REG_REFRESH_HIVE 2 -#define REG_NO_LAZY_FLUSH 4 -#define REG_OPTION_RESERVED 0 -#define REG_OPTION_NON_VOLATILE 0 -#define REG_OPTION_VOLATILE 1 -#define REG_OPTION_CREATE_LINK 2 -#define REG_OPTION_BACKUP_RESTORE 4 -#define REG_OPTION_OPEN_LINK 8 -#define REG_LEGAL_OPTION 15 -#define OWNER_SECURITY_INFORMATION 1 -#define GROUP_SECURITY_INFORMATION 2 -#define DACL_SECURITY_INFORMATION 4 -#define SACL_SECURITY_INFORMATION 8 -#define MAXIMUM_PROCESSORS 32 -#define PAGE_EXECUTE 16 -#define PAGE_EXECUTE_READ 32 -#define PAGE_EXECUTE_READWRITE 64 -#define PAGE_GUARD 256 -#define PAGE_NOACCESS 1 -#define PAGE_NOCACHE 512 -#define MEM_COMMIT 0x1000 -#define MEM_RESERVE 0x2000 -#define MEM_DECOMMIT 0x4000 -#define MEM_RELEASE 0x8000 -#define MEM_FREE 0x10000 -#define MEM_PRIVATE 0x20000 -#define MEM_MAPPED 0x40000 -#define MEM_RESET 0x80000 -#define MEM_TOP_DOWN 0x100000 -#define MEM_WRITE_WATCH 0x200000 /* 98/Me */ -#define MEM_PHYSICAL 0x400000 -#define MEM_4MB_PAGES 0x80000000 -#define MEM_IMAGE 16777216 +#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10 +#define PF_SSE_DAZ_MODE_AVAILABLE 11 +#define PF_NX_ENABLED 12 + + typedef struct _MEMORY_BASIC_INFORMATION { + PVOID BaseAddress; + PVOID AllocationBase; + DWORD AllocationProtect; + SIZE_T RegionSize; + DWORD State; + DWORD Protect; + DWORD Type; + } MEMORY_BASIC_INFORMATION,*PMEMORY_BASIC_INFORMATION; + + typedef struct _MEMORY_BASIC_INFORMATION32 { + DWORD BaseAddress; + DWORD AllocationBase; + DWORD AllocationProtect; + DWORD RegionSize; + DWORD State; + DWORD Protect; + DWORD Type; + } MEMORY_BASIC_INFORMATION32,*PMEMORY_BASIC_INFORMATION32; + + typedef DECLSPEC_ALIGN(16) struct _MEMORY_BASIC_INFORMATION64 { + ULONGLONG BaseAddress; + ULONGLONG AllocationBase; + DWORD AllocationProtect; + DWORD __alignment1; + ULONGLONG RegionSize; + DWORD State; + DWORD Protect; + DWORD Type; + DWORD __alignment2; + } MEMORY_BASIC_INFORMATION64,*PMEMORY_BASIC_INFORMATION64; + +#define SECTION_QUERY 0x0001 +#define SECTION_MAP_WRITE 0x0002 +#define SECTION_MAP_READ 0x0004 +#define SECTION_MAP_EXECUTE 0x0008 +#define SECTION_EXTEND_SIZE 0x0010 +#define SECTION_MAP_EXECUTE_EXPLICIT 0x0020 + +#define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY| SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE) +#define PAGE_NOACCESS 0x01 +#define PAGE_READONLY 0x02 +#define PAGE_READWRITE 0x04 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 +#define PAGE_WRITECOMBINE 0x400 +#define MEM_COMMIT 0x1000 +#define MEM_RESERVE 0x2000 +#define MEM_DECOMMIT 0x4000 +#define MEM_RELEASE 0x8000 +#define MEM_FREE 0x10000 +#define MEM_PRIVATE 0x20000 +#define MEM_MAPPED 0x40000 +#define MEM_RESET 0x80000 +#define MEM_TOP_DOWN 0x100000 +#define MEM_WRITE_WATCH 0x200000 +#define MEM_PHYSICAL 0x400000 +#define MEM_LARGE_PAGES 0x20000000 +#define MEM_4MB_PAGES 0x80000000 #define SEC_FILE 0x800000 #define SEC_IMAGE 0x1000000 -#define SEC_VLM 0x2000000 #define SEC_RESERVE 0x4000000 #define SEC_COMMIT 0x8000000 #define SEC_NOCACHE 0x10000000 -#define PAGE_EXECUTE_WRITECOPY 128 -#define SECTION_EXTEND_SIZE 16 -#define SECTION_MAP_READ 4 -#define SECTION_MAP_WRITE 2 -#define SECTION_QUERY 1 -#define SECTION_ALL_ACCESS 0xf001f -#define MESSAGE_RESOURCE_UNICODE 1 -#define RTL_CRITSECT_TYPE 0 -#define RTL_RESOURCE_TYPE 1 -#define FIELD_OFFSET(t,f) ((LONG)&(((t*)0)->f)) -#define IMAGE_SIZEOF_FILE_HEADER 20 -#define IMAGE_FILE_RELOCS_STRIPPED 1 -#define IMAGE_FILE_EXECUTABLE_IMAGE 2 -#define IMAGE_FILE_LINE_NUMS_STRIPPED 4 -#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8 -#define IMAGE_FILE_BYTES_REVERSED_LO 128 -#define IMAGE_FILE_32BIT_MACHINE 256 -#define IMAGE_FILE_DEBUG_STRIPPED 512 -#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 1024 -#define IMAGE_FILE_NET_RUN_FROM_SWAP 2048 -#define IMAGE_FILE_SYSTEM 4096 -#define IMAGE_FILE_DLL 8192 -#define IMAGE_FILE_UP_SYSTEM_ONLY 16384 -#define IMAGE_FILE_BYTES_REVERSED_HI 32768 -#define IMAGE_FILE_MACHINE_UNKNOWN 0 -#define IMAGE_FILE_MACHINE_I386 332 -#define IMAGE_FILE_MACHINE_R3000 354 -#define IMAGE_FILE_MACHINE_R4000 358 -#define IMAGE_FILE_MACHINE_R10000 360 -#define IMAGE_FILE_MACHINE_ALPHA 388 -#define IMAGE_FILE_MACHINE_POWERPC 496 +#define SEC_LARGE_PAGES 0x80000000 +#define MEM_IMAGE SEC_IMAGE +#define WRITE_WATCH_FLAG_RESET 0x01 + +#define FILE_READ_DATA (0x0001) +#define FILE_LIST_DIRECTORY (0x0001) + +#define FILE_WRITE_DATA (0x0002) +#define FILE_ADD_FILE (0x0002) + +#define FILE_APPEND_DATA (0x0004) +#define FILE_ADD_SUBDIRECTORY (0x0004) +#define FILE_CREATE_PIPE_INSTANCE (0x0004) + +#define FILE_READ_EA (0x0008) + +#define FILE_WRITE_EA (0x0010) + +#define FILE_EXECUTE (0x0020) +#define FILE_TRAVERSE (0x0020) + +#define FILE_DELETE_CHILD (0x0040) + +#define FILE_READ_ATTRIBUTES (0x0080) + +#define FILE_WRITE_ATTRIBUTES (0x0100) + +#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) +#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE) +#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE) +#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE) + +#define FILE_SHARE_READ 0x00000001 +#define FILE_SHARE_WRITE 0x00000002 +#define FILE_SHARE_DELETE 0x00000004 +#define FILE_ATTRIBUTE_READONLY 0x00000001 +#define FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define FILE_ATTRIBUTE_DEVICE 0x00000040 +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 +#define FILE_ATTRIBUTE_OFFLINE 0x00001000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 +#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 +#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 +#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004 +#define FILE_NOTIFY_CHANGE_SIZE 0x00000008 +#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010 +#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020 +#define FILE_NOTIFY_CHANGE_CREATION 0x00000040 +#define FILE_NOTIFY_CHANGE_SECURITY 0x00000100 +#define FILE_ACTION_ADDED 0x00000001 +#define FILE_ACTION_REMOVED 0x00000002 +#define FILE_ACTION_MODIFIED 0x00000003 +#define FILE_ACTION_RENAMED_OLD_NAME 0x00000004 +#define FILE_ACTION_RENAMED_NEW_NAME 0x00000005 +#define MAILSLOT_NO_MESSAGE ((DWORD)-1) +#define MAILSLOT_WAIT_FOREVER ((DWORD)-1) +#define FILE_CASE_SENSITIVE_SEARCH 0x00000001 +#define FILE_CASE_PRESERVED_NAMES 0x00000002 +#define FILE_UNICODE_ON_DISK 0x00000004 +#define FILE_PERSISTENT_ACLS 0x00000008 +#define FILE_FILE_COMPRESSION 0x00000010 +#define FILE_VOLUME_QUOTAS 0x00000020 +#define FILE_SUPPORTS_SPARSE_FILES 0x00000040 +#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080 +#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100 +#define FILE_VOLUME_IS_COMPRESSED 0x00008000 +#define FILE_SUPPORTS_OBJECT_IDS 0x00010000 +#define FILE_SUPPORTS_ENCRYPTION 0x00020000 +#define FILE_NAMED_STREAMS 0x00040000 +#define FILE_READ_ONLY_VOLUME 0x00080000 + + typedef struct _FILE_NOTIFY_INFORMATION { + DWORD NextEntryOffset; + DWORD Action; + DWORD FileNameLength; + WCHAR FileName[1]; + } FILE_NOTIFY_INFORMATION,*PFILE_NOTIFY_INFORMATION; + + typedef union _FILE_SEGMENT_ELEMENT { + PVOID64 Buffer; + ULONGLONG Alignment; + }FILE_SEGMENT_ELEMENT,*PFILE_SEGMENT_ELEMENT; + + typedef struct _REPARSE_GUID_DATA_BUFFER { + DWORD ReparseTag; + WORD ReparseDataLength; + WORD Reserved; + GUID ReparseGuid; + struct { + BYTE DataBuffer[1]; + } GenericReparseBuffer; + } REPARSE_GUID_DATA_BUFFER,*PREPARSE_GUID_DATA_BUFFER; + +#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER,GenericReparseBuffer) + +#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 *1024) + +#define IO_REPARSE_TAG_RESERVED_ZERO (0) +#define IO_REPARSE_TAG_RESERVED_ONE (1) + +#define IO_REPARSE_TAG_RESERVED_RANGE IO_REPARSE_TAG_RESERVED_ONE + +#define IsReparseTagMicrosoft(_tag) (((_tag) & 0x80000000)) +#define IsReparseTagNameSurrogate(_tag) (((_tag) & 0x20000000)) + +#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) +#define IO_REPARSE_TAG_HSM (0xC0000004L) +#define IO_REPARSE_TAG_SIS (0x80000007L) +#define IO_REPARSE_TAG_DFS (0x8000000AL) +#define IO_REPARSE_TAG_FILTER_MANAGER (0x8000000BL) +#define IO_COMPLETION_MODIFY_STATE 0x0002 +#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) +#define DUPLICATE_CLOSE_SOURCE 0x00000001 +#define DUPLICATE_SAME_ACCESS 0x00000002 + + typedef enum _SYSTEM_POWER_STATE { + PowerSystemUnspecified = 0,PowerSystemWorking = 1,PowerSystemSleeping1 = 2,PowerSystemSleeping2 = 3,PowerSystemSleeping3 = 4,PowerSystemHibernate = 5,PowerSystemShutdown = 6,PowerSystemMaximum = 7 + } SYSTEM_POWER_STATE,*PSYSTEM_POWER_STATE; + +#define POWER_SYSTEM_MAXIMUM 7 + + typedef enum { + PowerActionNone = 0,PowerActionReserved,PowerActionSleep,PowerActionHibernate,PowerActionShutdown,PowerActionShutdownReset,PowerActionShutdownOff,PowerActionWarmEject + } POWER_ACTION,*PPOWER_ACTION; + + typedef enum _DEVICE_POWER_STATE { + PowerDeviceUnspecified = 0,PowerDeviceD0,PowerDeviceD1,PowerDeviceD2,PowerDeviceD3,PowerDeviceMaximum + } DEVICE_POWER_STATE,*PDEVICE_POWER_STATE; + +#define ES_SYSTEM_REQUIRED ((DWORD)0x00000001) +#define ES_DISPLAY_REQUIRED ((DWORD)0x00000002) +#define ES_USER_PRESENT ((DWORD)0x00000004) +#define ES_CONTINUOUS ((DWORD)0x80000000) + + typedef DWORD EXECUTION_STATE; + + typedef enum { + LT_DONT_CARE,LT_LOWEST_LATENCY + } LATENCY_TIME; + +#define PDCAP_D0_SUPPORTED 0x00000001 +#define PDCAP_D1_SUPPORTED 0x00000002 +#define PDCAP_D2_SUPPORTED 0x00000004 +#define PDCAP_D3_SUPPORTED 0x00000008 +#define PDCAP_WAKE_FROM_D0_SUPPORTED 0x00000010 +#define PDCAP_WAKE_FROM_D1_SUPPORTED 0x00000020 +#define PDCAP_WAKE_FROM_D2_SUPPORTED 0x00000040 +#define PDCAP_WAKE_FROM_D3_SUPPORTED 0x00000080 +#define PDCAP_WARM_EJECT_SUPPORTED 0x00000100 + + typedef struct CM_Power_Data_s { + DWORD PD_Size; + DEVICE_POWER_STATE PD_MostRecentPowerState; + DWORD PD_Capabilities; + DWORD PD_D1Latency; + DWORD PD_D2Latency; + DWORD PD_D3Latency; + DEVICE_POWER_STATE PD_PowerStateMapping[POWER_SYSTEM_MAXIMUM]; + SYSTEM_POWER_STATE PD_DeepestSystemWake; + } CM_POWER_DATA,*PCM_POWER_DATA; + + typedef enum { + SystemPowerPolicyAc,SystemPowerPolicyDc,VerifySystemPolicyAc,VerifySystemPolicyDc,SystemPowerCapabilities,SystemBatteryState,SystemPowerStateHandler,ProcessorStateHandler,SystemPowerPolicyCurrent,AdministratorPowerPolicy,SystemReserveHiberFile,ProcessorInformation,SystemPowerInformation,ProcessorStateHandler2,LastWakeTime,LastSleepTime,SystemExecutionState,SystemPowerStateNotifyHandler,ProcessorPowerPolicyAc,ProcessorPowerPolicyDc,VerifyProcessorPowerPolicyAc,VerifyProcessorPowerPolicyDc,ProcessorPowerPolicyCurrent,SystemPowerStateLogging,SystemPowerLoggingEntry + } POWER_INFORMATION_LEVEL; + + typedef struct { + DWORD Granularity; + DWORD Capacity; + } BATTERY_REPORTING_SCALE,*PBATTERY_REPORTING_SCALE; + + typedef struct { + POWER_ACTION Action; + DWORD Flags; + DWORD EventCode; + } POWER_ACTION_POLICY,*PPOWER_ACTION_POLICY; + +#define POWER_ACTION_QUERY_ALLOWED 0x00000001 +#define POWER_ACTION_UI_ALLOWED 0x00000002 +#define POWER_ACTION_OVERRIDE_APPS 0x00000004 +#define POWER_ACTION_LIGHTEST_FIRST 0x10000000 +#define POWER_ACTION_LOCK_CONSOLE 0x20000000 +#define POWER_ACTION_DISABLE_WAKES 0x40000000 +#define POWER_ACTION_CRITICAL 0x80000000 + +#define POWER_LEVEL_USER_NOTIFY_TEXT 0x00000001 +#define POWER_LEVEL_USER_NOTIFY_SOUND 0x00000002 +#define POWER_LEVEL_USER_NOTIFY_EXEC 0x00000004 +#define POWER_USER_NOTIFY_BUTTON 0x00000008 +#define POWER_USER_NOTIFY_SHUTDOWN 0x00000010 +#define POWER_FORCE_TRIGGER_RESET 0x80000000 + + typedef struct { + BOOLEAN Enable; + BYTE Spare[3]; + DWORD BatteryLevel; + POWER_ACTION_POLICY PowerPolicy; + SYSTEM_POWER_STATE MinSystemState; + } SYSTEM_POWER_LEVEL,*PSYSTEM_POWER_LEVEL; + +#define NUM_DISCHARGE_POLICIES 4 +#define DISCHARGE_POLICY_CRITICAL 0 +#define DISCHARGE_POLICY_LOW 1 + +#define PO_THROTTLE_NONE 0 +#define PO_THROTTLE_CONSTANT 1 +#define PO_THROTTLE_DEGRADE 2 +#define PO_THROTTLE_ADAPTIVE 3 +#define PO_THROTTLE_MAXIMUM 4 + + typedef struct _SYSTEM_POWER_POLICY { + DWORD Revision; + POWER_ACTION_POLICY PowerButton; + POWER_ACTION_POLICY SleepButton; + POWER_ACTION_POLICY LidClose; + SYSTEM_POWER_STATE LidOpenWake; + DWORD Reserved; + POWER_ACTION_POLICY Idle; + DWORD IdleTimeout; + BYTE IdleSensitivity; + BYTE DynamicThrottle; + BYTE Spare2[2]; + SYSTEM_POWER_STATE MinSleep; + SYSTEM_POWER_STATE MaxSleep; + SYSTEM_POWER_STATE ReducedLatencySleep; + DWORD WinLogonFlags; + DWORD Spare3; + DWORD DozeS4Timeout; + DWORD BroadcastCapacityResolution; + SYSTEM_POWER_LEVEL DischargePolicy[NUM_DISCHARGE_POLICIES]; + DWORD VideoTimeout; + BOOLEAN VideoDimDisplay; + DWORD VideoReserved[3]; + DWORD SpindownTimeout; + BOOLEAN OptimizeForPower; + BYTE FanThrottleTolerance; + BYTE ForcedThrottle; + BYTE MinThrottle; + POWER_ACTION_POLICY OverThrottled; + } SYSTEM_POWER_POLICY,*PSYSTEM_POWER_POLICY; + + typedef struct _PROCESSOR_POWER_POLICY_INFO { + DWORD TimeCheck; + DWORD DemoteLimit; + DWORD PromoteLimit; + BYTE DemotePercent; + BYTE PromotePercent; + BYTE Spare[2]; + DWORD AllowDemotion:1; + DWORD AllowPromotion:1; + DWORD Reserved:30; + } PROCESSOR_POWER_POLICY_INFO,*PPROCESSOR_POWER_POLICY_INFO; + + typedef struct _PROCESSOR_POWER_POLICY { + DWORD Revision; + BYTE DynamicThrottle; + BYTE Spare[3]; + DWORD DisableCStates:1; + DWORD Reserved:31; + DWORD PolicyCount; + PROCESSOR_POWER_POLICY_INFO Policy[3]; + } PROCESSOR_POWER_POLICY,*PPROCESSOR_POWER_POLICY; + + typedef struct _ADMINISTRATOR_POWER_POLICY { + SYSTEM_POWER_STATE MinSleep; + SYSTEM_POWER_STATE MaxSleep; + DWORD MinVideoTimeout; + DWORD MaxVideoTimeout; + DWORD MinSpindownTimeout; + DWORD MaxSpindownTimeout; + } ADMINISTRATOR_POWER_POLICY,*PADMINISTRATOR_POWER_POLICY; + + typedef struct { + BOOLEAN PowerButtonPresent; + BOOLEAN SleepButtonPresent; + BOOLEAN LidPresent; + BOOLEAN SystemS1; + BOOLEAN SystemS2; + BOOLEAN SystemS3; + BOOLEAN SystemS4; + BOOLEAN SystemS5; + BOOLEAN HiberFilePresent; + BOOLEAN FullWake; + BOOLEAN VideoDimPresent; + BOOLEAN ApmPresent; + BOOLEAN UpsPresent; + BOOLEAN ThermalControl; + BOOLEAN ProcessorThrottle; + BYTE ProcessorMinThrottle; + BYTE ProcessorMaxThrottle; + BYTE spare2[4]; + BOOLEAN DiskSpinDown; + BYTE spare3[8]; + BOOLEAN SystemBatteriesPresent; + BOOLEAN BatteriesAreShortTerm; + BATTERY_REPORTING_SCALE BatteryScale[3]; + SYSTEM_POWER_STATE AcOnLineWake; + SYSTEM_POWER_STATE SoftLidWake; + SYSTEM_POWER_STATE RtcWake; + SYSTEM_POWER_STATE MinDeviceWakeState; + SYSTEM_POWER_STATE DefaultLowLatencyWake; + } SYSTEM_POWER_CAPABILITIES,*PSYSTEM_POWER_CAPABILITIES; + + typedef struct { + BOOLEAN AcOnLine; + BOOLEAN BatteryPresent; + BOOLEAN Charging; + BOOLEAN Discharging; + BOOLEAN Spare1[4]; + DWORD MaxCapacity; + DWORD RemainingCapacity; + DWORD Rate; + DWORD EstimatedTime; + DWORD DefaultAlert1; + DWORD DefaultAlert2; + } SYSTEM_BATTERY_STATE,*PSYSTEM_BATTERY_STATE; + +#include "pshpack4.h" + #define IMAGE_DOS_SIGNATURE 0x5A4D #define IMAGE_OS2_SIGNATURE 0x454E #define IMAGE_OS2_SIGNATURE_LE 0x454C #define IMAGE_VXD_SIGNATURE 0x454C #define IMAGE_NT_SIGNATURE 0x00004550 -#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b -#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 -#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944 + +#include "pshpack2.h" + + typedef struct _IMAGE_DOS_HEADER { + WORD e_magic; + WORD e_cblp; + WORD e_cp; + WORD e_crlc; + WORD e_cparhdr; + WORD e_minalloc; + WORD e_maxalloc; + WORD e_ss; + WORD e_sp; + WORD e_csum; + WORD e_ip; + WORD e_cs; + WORD e_lfarlc; + WORD e_ovno; + WORD e_res[4]; + WORD e_oemid; + WORD e_oeminfo; + WORD e_res2[10]; + LONG e_lfanew; + } IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; + + typedef struct _IMAGE_OS2_HEADER { + WORD ne_magic; + CHAR ne_ver; + CHAR ne_rev; + WORD ne_enttab; + WORD ne_cbenttab; + LONG ne_crc; + WORD ne_flags; + WORD ne_autodata; + WORD ne_heap; + WORD ne_stack; + LONG ne_csip; + LONG ne_sssp; + WORD ne_cseg; + WORD ne_cmod; + WORD ne_cbnrestab; + WORD ne_segtab; + WORD ne_rsrctab; + WORD ne_restab; + WORD ne_modtab; + WORD ne_imptab; + LONG ne_nrestab; + WORD ne_cmovent; + WORD ne_align; + WORD ne_cres; + BYTE ne_exetyp; + BYTE ne_flagsothers; + WORD ne_pretthunks; + WORD ne_psegrefbytes; + WORD ne_swaparea; + WORD ne_expver; + } IMAGE_OS2_HEADER,*PIMAGE_OS2_HEADER; + + typedef struct _IMAGE_VXD_HEADER { + WORD e32_magic; + BYTE e32_border; + BYTE e32_worder; + DWORD e32_level; + WORD e32_cpu; + WORD e32_os; + DWORD e32_ver; + DWORD e32_mflags; + DWORD e32_mpages; + DWORD e32_startobj; + DWORD e32_eip; + DWORD e32_stackobj; + DWORD e32_esp; + DWORD e32_pagesize; + DWORD e32_lastpagesize; + DWORD e32_fixupsize; + DWORD e32_fixupsum; + DWORD e32_ldrsize; + DWORD e32_ldrsum; + DWORD e32_objtab; + DWORD e32_objcnt; + DWORD e32_objmap; + DWORD e32_itermap; + DWORD e32_rsrctab; + DWORD e32_rsrccnt; + DWORD e32_restab; + DWORD e32_enttab; + DWORD e32_dirtab; + DWORD e32_dircnt; + DWORD e32_fpagetab; + DWORD e32_frectab; + DWORD e32_impmod; + DWORD e32_impmodcnt; + DWORD e32_impproc; + DWORD e32_pagesum; + DWORD e32_datapage; + DWORD e32_preload; + DWORD e32_nrestab; + DWORD e32_cbnrestab; + DWORD e32_nressum; + DWORD e32_autodata; + DWORD e32_debuginfo; + DWORD e32_debuglen; + DWORD e32_instpreload; + DWORD e32_instdemand; + DWORD e32_heapsize; + BYTE e32_res3[12]; + DWORD e32_winresoff; + DWORD e32_winreslen; + WORD e32_devid; + WORD e32_ddkver; + } IMAGE_VXD_HEADER,*PIMAGE_VXD_HEADER; + +#include "poppack.h" + + typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; + } IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +#define IMAGE_FILE_32BIT_MACHINE 0x0100 +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 +#define IMAGE_FILE_SYSTEM 0x1000 +#define IMAGE_FILE_DLL 0x2000 +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_R3000 0x0162 +#define IMAGE_FILE_MACHINE_R4000 0x0166 +#define IMAGE_FILE_MACHINE_R10000 0x0168 +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 +#define IMAGE_FILE_MACHINE_ALPHA 0x0184 +#define IMAGE_FILE_MACHINE_SH3 0x01a2 +#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 +#define IMAGE_FILE_MACHINE_SH3E 0x01a4 +#define IMAGE_FILE_MACHINE_SH4 0x01a6 +#define IMAGE_FILE_MACHINE_SH5 0x01a8 +#define IMAGE_FILE_MACHINE_ARM 0x01c0 +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 +#define IMAGE_FILE_MACHINE_AM33 0x01d3 +#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 +#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 +#define IMAGE_FILE_MACHINE_IA64 0x0200 +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 +#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 +#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 +#define IMAGE_FILE_MACHINE_TRICORE 0x0520 +#define IMAGE_FILE_MACHINE_CEF 0x0CEF +#define IMAGE_FILE_MACHINE_EBC 0x0EBC +#define IMAGE_FILE_MACHINE_AMD64 0x8664 +#define IMAGE_FILE_MACHINE_M32R 0x9041 +#define IMAGE_FILE_MACHINE_CEE 0xC0EE + + typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; + } IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; + #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + + typedef struct _IMAGE_OPTIONAL_HEADER { + + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; + } IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32; + + typedef struct _IMAGE_ROM_OPTIONAL_HEADER { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD BaseOfBss; + DWORD GprMask; + DWORD CprMask[4]; + DWORD GpValue; + } IMAGE_ROM_OPTIONAL_HEADER,*PIMAGE_ROM_OPTIONAL_HEADER; + + typedef struct _IMAGE_OPTIONAL_HEADER64 { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; + } IMAGE_OPTIONAL_HEADER64,*PIMAGE_OPTIONAL_HEADER64; + #define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 #define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 -#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 +#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224 +#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240 + +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +#ifdef _WIN64 + typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; + typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL64_HEADER +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC +#else + typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; + typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL32_HEADER +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC +#endif + + typedef struct _IMAGE_NT_HEADERS64 { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; + } IMAGE_NT_HEADERS64,*PIMAGE_NT_HEADERS64; + + typedef struct _IMAGE_NT_HEADERS { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER32 OptionalHeader; + } IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32; + + typedef struct _IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; + } IMAGE_ROM_HEADERS,*PIMAGE_ROM_HEADERS; + +#ifdef _WIN64 + typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; + typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; +#else + typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; + typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; +#endif + +#define IMAGE_FIRST_SECTION(ntheader) ((PIMAGE_SECTION_HEADER) ((ULONG_PTR)ntheader + FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader) + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader)) + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 +#define IMAGE_SUBSYSTEM_NATIVE 1 +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 +#define IMAGE_SUBSYSTEM_OS2_CUI 5 +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 +#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 +#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define IMAGE_SUBSYSTEM_EFI_ROM 13 +#define IMAGE_SUBSYSTEM_XBOX 14 + +#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 +#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 +#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 +#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 +#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 + +#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 +#define IMAGE_DIRECTORY_ENTRY_TLS 9 +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 +#define IMAGE_DIRECTORY_ENTRY_IAT 12 +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 + + typedef struct ANON_OBJECT_HEADER { + WORD Sig1; + WORD Sig2; + WORD Version; + WORD Machine; + DWORD TimeDateStamp; + CLSID ClassID; + DWORD SizeOfData; + } ANON_OBJECT_HEADER; + #define IMAGE_SIZEOF_SHORT_NAME 8 + + typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; + } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; + #define IMAGE_SIZEOF_SECTION_HEADER 40 -#define IMAGE_SIZEOF_SYMBOL 18 -#define IMAGE_SIZEOF_AUX_SYMBOL 18 -#define IMAGE_SIZEOF_RELOCATION 10 -#define IMAGE_SIZEOF_BASE_RELOCATION 8 -#define IMAGE_SIZEOF_LINENUMBER 6 -#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 -#define SIZEOF_RFPO_DATA 16 -#define IMAGE_SUBSYSTEM_UNKNOWN 0 -#define IMAGE_SUBSYSTEM_NATIVE 1 -#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 -#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 -#define IMAGE_SUBSYSTEM_OS2_CUI 5 -#define IMAGE_SUBSYSTEM_POSIX_CUI 7 -#define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader)) -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 -#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 -#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 -#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 -#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 -#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 -#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 -#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 -#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 -#define IMAGE_DIRECTORY_ENTRY_TLS 9 -#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 -#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 -#define IMAGE_DIRECTORY_ENTRY_IAT 12 -#define IMAGE_SCN_TYPE_NO_PAD 8 -#define IMAGE_SCN_CNT_CODE 32 -#define IMAGE_SCN_CNT_INITIALIZED_DATA 64 -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 128 -#define IMAGE_SCN_LNK_OTHER 256 -#define IMAGE_SCN_LNK_INFO 512 -#define IMAGE_SCN_LNK_REMOVE 2048 -#define IMAGE_SCN_LNK_COMDAT 4096 -#define IMAGE_SCN_MEM_FARDATA 0x8000 -#define IMAGE_SCN_MEM_PURGEABLE 0x20000 -#define IMAGE_SCN_MEM_16BIT 0x20000 -#define IMAGE_SCN_MEM_LOCKED 0x40000 -#define IMAGE_SCN_MEM_PRELOAD 0x80000 -#define IMAGE_SCN_ALIGN_1BYTES 0x100000 -#define IMAGE_SCN_ALIGN_2BYTES 0x200000 -#define IMAGE_SCN_ALIGN_4BYTES 0x300000 -#define IMAGE_SCN_ALIGN_8BYTES 0x400000 -#define IMAGE_SCN_ALIGN_16BYTES 0x500000 -#define IMAGE_SCN_ALIGN_32BYTES 0x600000 -#define IMAGE_SCN_ALIGN_64BYTES 0x700000 -#define IMAGE_SCN_LNK_NRELOC_OVFL 0x1000000 -#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000 -#define IMAGE_SCN_MEM_NOT_CACHED 0x4000000 -#define IMAGE_SCN_MEM_NOT_PAGED 0x8000000 + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 + +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 +#define IMAGE_SCN_LNK_OTHER 0x00000100 +#define IMAGE_SCN_LNK_INFO 0x00000200 +#define IMAGE_SCN_LNK_REMOVE 0x00000800 +#define IMAGE_SCN_LNK_COMDAT 0x00001000 +#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 +#define IMAGE_SCN_GPREL 0x00008000 +#define IMAGE_SCN_MEM_FARDATA 0x00008000 +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 + +#define IMAGE_SCN_ALIGN_MASK 0x00F00000 + +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 #define IMAGE_SCN_MEM_SHARED 0x10000000 #define IMAGE_SCN_MEM_EXECUTE 0x20000000 #define IMAGE_SCN_MEM_READ 0x40000000 #define IMAGE_SCN_MEM_WRITE 0x80000000 -#define IMAGE_SYM_UNDEFINED 0 -#define IMAGE_SYM_ABSOLUTE (-1) -#define IMAGE_SYM_DEBUG (-2) -#define IMAGE_SYM_TYPE_NULL 0 -#define IMAGE_SYM_TYPE_VOID 1 -#define IMAGE_SYM_TYPE_CHAR 2 -#define IMAGE_SYM_TYPE_SHORT 3 -#define IMAGE_SYM_TYPE_INT 4 -#define IMAGE_SYM_TYPE_LONG 5 -#define IMAGE_SYM_TYPE_FLOAT 6 -#define IMAGE_SYM_TYPE_DOUBLE 7 -#define IMAGE_SYM_TYPE_STRUCT 8 -#define IMAGE_SYM_TYPE_UNION 9 -#define IMAGE_SYM_TYPE_ENUM 10 -#define IMAGE_SYM_TYPE_MOE 11 -#define IMAGE_SYM_TYPE_BYTE 12 -#define IMAGE_SYM_TYPE_WORD 13 -#define IMAGE_SYM_TYPE_UINT 14 -#define IMAGE_SYM_TYPE_DWORD 15 -#define IMAGE_SYM_TYPE_PCODE 32768 + +#define IMAGE_SCN_SCALE_INDEX 0x00000001 + +#include "pshpack2.h" + + typedef struct _IMAGE_SYMBOL { + union { + BYTE ShortName[8]; + struct { + DWORD Short; + DWORD Long; + } Name; + DWORD LongName[2]; + } N; + DWORD Value; + SHORT SectionNumber; + WORD Type; + BYTE StorageClass; + BYTE NumberOfAuxSymbols; + } IMAGE_SYMBOL; + typedef IMAGE_SYMBOL UNALIGNED *PIMAGE_SYMBOL; + +#define IMAGE_SIZEOF_SYMBOL 18 + +#define IMAGE_SYM_UNDEFINED (SHORT)0 +#define IMAGE_SYM_ABSOLUTE (SHORT)-1 +#define IMAGE_SYM_DEBUG (SHORT)-2 +#define IMAGE_SYM_SECTION_MAX 0xFEFF + +#define IMAGE_SYM_TYPE_NULL 0x0000 +#define IMAGE_SYM_TYPE_VOID 0x0001 +#define IMAGE_SYM_TYPE_CHAR 0x0002 +#define IMAGE_SYM_TYPE_SHORT 0x0003 +#define IMAGE_SYM_TYPE_INT 0x0004 +#define IMAGE_SYM_TYPE_LONG 0x0005 +#define IMAGE_SYM_TYPE_FLOAT 0x0006 +#define IMAGE_SYM_TYPE_DOUBLE 0x0007 +#define IMAGE_SYM_TYPE_STRUCT 0x0008 +#define IMAGE_SYM_TYPE_UNION 0x0009 +#define IMAGE_SYM_TYPE_ENUM 0x000A +#define IMAGE_SYM_TYPE_MOE 0x000B +#define IMAGE_SYM_TYPE_BYTE 0x000C +#define IMAGE_SYM_TYPE_WORD 0x000D +#define IMAGE_SYM_TYPE_UINT 0x000E +#define IMAGE_SYM_TYPE_DWORD 0x000F +#define IMAGE_SYM_TYPE_PCODE 0x8000 + #define IMAGE_SYM_DTYPE_NULL 0 #define IMAGE_SYM_DTYPE_POINTER 1 #define IMAGE_SYM_DTYPE_FUNCTION 2 #define IMAGE_SYM_DTYPE_ARRAY 3 -#define IMAGE_SYM_CLASS_END_OF_FUNCTION (-1) -#define IMAGE_SYM_CLASS_NULL 0 -#define IMAGE_SYM_CLASS_AUTOMATIC 1 -#define IMAGE_SYM_CLASS_EXTERNAL 2 -#define IMAGE_SYM_CLASS_STATIC 3 -#define IMAGE_SYM_CLASS_REGISTER 4 -#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 -#define IMAGE_SYM_CLASS_LABEL 6 -#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 -#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 -#define IMAGE_SYM_CLASS_ARGUMENT 9 -#define IMAGE_SYM_CLASS_STRUCT_TAG 10 -#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 -#define IMAGE_SYM_CLASS_UNION_TAG 12 -#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 -#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 -#define IMAGE_SYM_CLASS_ENUM_TAG 15 -#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 -#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 -#define IMAGE_SYM_CLASS_BIT_FIELD 18 -#define IMAGE_SYM_CLASS_FAR_EXTERNAL 68 -#define IMAGE_SYM_CLASS_BLOCK 100 -#define IMAGE_SYM_CLASS_FUNCTION 101 -#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 -#define IMAGE_SYM_CLASS_FILE 103 -#define IMAGE_SYM_CLASS_SECTION 104 -#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE)-1 +#define IMAGE_SYM_CLASS_NULL 0x0000 +#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 +#define IMAGE_SYM_CLASS_EXTERNAL 0x0002 +#define IMAGE_SYM_CLASS_STATIC 0x0003 +#define IMAGE_SYM_CLASS_REGISTER 0x0004 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005 +#define IMAGE_SYM_CLASS_LABEL 0x0006 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008 +#define IMAGE_SYM_CLASS_ARGUMENT 0x0009 +#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B +#define IMAGE_SYM_CLASS_UNION_TAG 0x000C +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E +#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011 +#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012 +#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044 +#define IMAGE_SYM_CLASS_BLOCK 0x0064 +#define IMAGE_SYM_CLASS_FUNCTION 0x0065 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066 +#define IMAGE_SYM_CLASS_FILE 0x0067 +#define IMAGE_SYM_CLASS_SECTION 0x0068 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069 +#define IMAGE_SYM_CLASS_CLR_TOKEN 0x006B + +#define N_BTMASK 0x000F +#define N_TMASK 0x0030 +#define N_TMASK1 0x00C0 +#define N_TMASK2 0x00F0 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +#define BTYPE(x) ((x) & N_BTMASK) + +#ifndef ISPTR +#define ISPTR(x) (((x) & N_TMASK)==(IMAGE_SYM_DTYPE_POINTER << N_BTSHFT)) +#endif + +#ifndef ISFCN +#define ISFCN(x) (((x) & N_TMASK)==(IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT)) +#endif + +#ifndef ISARY +#define ISARY(x) (((x) & N_TMASK)==(IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT)) +#endif + +#ifndef ISTAG +#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG) +#endif + +#ifndef INCREF +#define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK)) +#endif +#ifndef DECREF +#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) +#endif + + typedef union _IMAGE_AUX_SYMBOL { + struct { + DWORD TagIndex; + union { + struct { + WORD Linenumber; + WORD Size; + } LnSz; + DWORD TotalSize; + } Misc; + union { + struct { + DWORD PointerToLinenumber; + DWORD PointerToNextFunction; + } Function; + struct { + WORD Dimension[4]; + } Array; + } FcnAry; + WORD TvIndex; + } Sym; + struct { + BYTE Name[IMAGE_SIZEOF_SYMBOL]; + } File; + struct { + DWORD Length; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD CheckSum; + SHORT Number; + BYTE Selection; + } Section; + } IMAGE_AUX_SYMBOL; + typedef IMAGE_AUX_SYMBOL UNALIGNED *PIMAGE_AUX_SYMBOL; + +#define IMAGE_SIZEOF_AUX_SYMBOL 18 + + typedef enum IMAGE_AUX_SYMBOL_TYPE { + IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1 + } IMAGE_AUX_SYMBOL_TYPE; + +#include <pshpack2.h> + + typedef struct IMAGE_AUX_SYMBOL_TOKEN_DEF { + BYTE bAuxType; + BYTE bReserved; + DWORD SymbolTableIndex; + BYTE rgbReserved[12]; + } IMAGE_AUX_SYMBOL_TOKEN_DEF; + + typedef IMAGE_AUX_SYMBOL_TOKEN_DEF UNALIGNED *PIMAGE_AUX_SYMBOL_TOKEN_DEF; + +#include <poppack.h> + #define IMAGE_COMDAT_SELECT_NODUPLICATES 1 #define IMAGE_COMDAT_SELECT_ANY 2 #define IMAGE_COMDAT_SELECT_SAME_SIZE 3 @@ -803,92 +4124,648 @@ typedef BYTE BOOLEAN,*PBOOLEAN; #define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 #define IMAGE_COMDAT_SELECT_LARGEST 6 #define IMAGE_COMDAT_SELECT_NEWEST 7 + #define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 #define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 #define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 -#define IMAGE_REL_I386_ABSOLUTE 0 -#define IMAGE_REL_I386_DIR16 1 -#define IMAGE_REL_I386_REL16 2 -#define IMAGE_REL_I386_DIR32 6 -#define IMAGE_REL_I386_DIR32NB 7 -#define IMAGE_REL_I386_SEG12 9 -#define IMAGE_REL_I386_SECTION 10 -#define IMAGE_REL_I386_SECREL 11 -#define IMAGE_REL_I386_REL32 20 -#define IMAGE_REL_MIPS_ABSOLUTE 0 -#define IMAGE_REL_MIPS_REFHALF 1 -#define IMAGE_REL_MIPS_REFWORD 2 -#define IMAGE_REL_MIPS_JMPADDR 3 -#define IMAGE_REL_MIPS_REFHI 4 -#define IMAGE_REL_MIPS_REFLO 5 -#define IMAGE_REL_MIPS_GPREL 6 -#define IMAGE_REL_MIPS_LITERAL 7 -#define IMAGE_REL_MIPS_SECTION 10 -#define IMAGE_REL_MIPS_SECREL 11 -#define IMAGE_REL_MIPS_SECRELLO 12 -#define IMAGE_REL_MIPS_SECRELHI 13 -#define IMAGE_REL_MIPS_REFWORDNB 34 -#define IMAGE_REL_MIPS_PAIR 35 -#define IMAGE_REL_ALPHA_ABSOLUTE 0 -#define IMAGE_REL_ALPHA_REFLONG 1 -#define IMAGE_REL_ALPHA_REFQUAD 2 -#define IMAGE_REL_ALPHA_GPREL32 3 -#define IMAGE_REL_ALPHA_LITERAL 4 -#define IMAGE_REL_ALPHA_LITUSE 5 -#define IMAGE_REL_ALPHA_GPDISP 6 -#define IMAGE_REL_ALPHA_BRADDR 7 -#define IMAGE_REL_ALPHA_HINT 8 -#define IMAGE_REL_ALPHA_INLINE_REFLONG 9 -#define IMAGE_REL_ALPHA_REFHI 10 -#define IMAGE_REL_ALPHA_REFLO 11 -#define IMAGE_REL_ALPHA_PAIR 12 -#define IMAGE_REL_ALPHA_MATCH 13 -#define IMAGE_REL_ALPHA_SECTION 14 -#define IMAGE_REL_ALPHA_SECREL 15 -#define IMAGE_REL_ALPHA_REFLONGNB 16 -#define IMAGE_REL_ALPHA_SECRELLO 17 -#define IMAGE_REL_ALPHA_SECRELHI 18 -#define IMAGE_REL_PPC_ABSOLUTE 0 -#define IMAGE_REL_PPC_ADDR64 1 -#define IMAGE_REL_PPC_ADDR32 2 -#define IMAGE_REL_PPC_ADDR24 3 -#define IMAGE_REL_PPC_ADDR16 4 -#define IMAGE_REL_PPC_ADDR14 5 -#define IMAGE_REL_PPC_REL24 6 -#define IMAGE_REL_PPC_REL14 7 -#define IMAGE_REL_PPC_TOCREL16 8 -#define IMAGE_REL_PPC_TOCREL14 9 -#define IMAGE_REL_PPC_ADDR32NB 10 -#define IMAGE_REL_PPC_SECREL 11 -#define IMAGE_REL_PPC_SECTION 12 -#define IMAGE_REL_PPC_IFGLUE 13 -#define IMAGE_REL_PPC_IMGLUE 14 -#define IMAGE_REL_PPC_SECREL16 15 -#define IMAGE_REL_PPC_REFHI 16 -#define IMAGE_REL_PPC_REFLO 17 -#define IMAGE_REL_PPC_PAIR 18 -#define IMAGE_REL_PPC_TYPEMASK 255 -#define IMAGE_REL_PPC_NEG 256 -#define IMAGE_REL_PPC_BRTAKEN 512 -#define IMAGE_REL_PPC_BRNTAKEN 1024 -#define IMAGE_REL_PPC_TOCDEFN 2048 + + typedef struct _IMAGE_RELOCATION { + union { + DWORD VirtualAddress; + DWORD RelocCount; + }; + DWORD SymbolTableIndex; + WORD Type; + } IMAGE_RELOCATION; + typedef IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +#define IMAGE_REL_I386_ABSOLUTE 0x0000 +#define IMAGE_REL_I386_DIR16 0x0001 +#define IMAGE_REL_I386_REL16 0x0002 +#define IMAGE_REL_I386_DIR32 0x0006 +#define IMAGE_REL_I386_DIR32NB 0x0007 +#define IMAGE_REL_I386_SEG12 0x0009 +#define IMAGE_REL_I386_SECTION 0x000A +#define IMAGE_REL_I386_SECREL 0x000B +#define IMAGE_REL_I386_TOKEN 0x000C +#define IMAGE_REL_I386_SECREL7 0x000D +#define IMAGE_REL_I386_REL32 0x0014 + +#define IMAGE_REL_MIPS_ABSOLUTE 0x0000 +#define IMAGE_REL_MIPS_REFHALF 0x0001 +#define IMAGE_REL_MIPS_REFWORD 0x0002 +#define IMAGE_REL_MIPS_JMPADDR 0x0003 +#define IMAGE_REL_MIPS_REFHI 0x0004 +#define IMAGE_REL_MIPS_REFLO 0x0005 +#define IMAGE_REL_MIPS_GPREL 0x0006 +#define IMAGE_REL_MIPS_LITERAL 0x0007 +#define IMAGE_REL_MIPS_SECTION 0x000A +#define IMAGE_REL_MIPS_SECREL 0x000B +#define IMAGE_REL_MIPS_SECRELLO 0x000C +#define IMAGE_REL_MIPS_SECRELHI 0x000D +#define IMAGE_REL_MIPS_TOKEN 0x000E +#define IMAGE_REL_MIPS_JMPADDR16 0x0010 +#define IMAGE_REL_MIPS_REFWORDNB 0x0022 +#define IMAGE_REL_MIPS_PAIR 0x0025 + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0000 +#define IMAGE_REL_ALPHA_REFLONG 0x0001 +#define IMAGE_REL_ALPHA_REFQUAD 0x0002 +#define IMAGE_REL_ALPHA_GPREL32 0x0003 +#define IMAGE_REL_ALPHA_LITERAL 0x0004 +#define IMAGE_REL_ALPHA_LITUSE 0x0005 +#define IMAGE_REL_ALPHA_GPDISP 0x0006 +#define IMAGE_REL_ALPHA_BRADDR 0x0007 +#define IMAGE_REL_ALPHA_HINT 0x0008 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009 +#define IMAGE_REL_ALPHA_REFHI 0x000A +#define IMAGE_REL_ALPHA_REFLO 0x000B +#define IMAGE_REL_ALPHA_PAIR 0x000C +#define IMAGE_REL_ALPHA_MATCH 0x000D +#define IMAGE_REL_ALPHA_SECTION 0x000E +#define IMAGE_REL_ALPHA_SECREL 0x000F +#define IMAGE_REL_ALPHA_REFLONGNB 0x0010 +#define IMAGE_REL_ALPHA_SECRELLO 0x0011 +#define IMAGE_REL_ALPHA_SECRELHI 0x0012 +#define IMAGE_REL_ALPHA_REFQ3 0x0013 +#define IMAGE_REL_ALPHA_REFQ2 0x0014 +#define IMAGE_REL_ALPHA_REFQ1 0x0015 +#define IMAGE_REL_ALPHA_GPRELLO 0x0016 +#define IMAGE_REL_ALPHA_GPRELHI 0x0017 + +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 +#define IMAGE_REL_PPC_ADDR64 0x0001 +#define IMAGE_REL_PPC_ADDR32 0x0002 +#define IMAGE_REL_PPC_ADDR24 0x0003 +#define IMAGE_REL_PPC_ADDR16 0x0004 +#define IMAGE_REL_PPC_ADDR14 0x0005 +#define IMAGE_REL_PPC_REL24 0x0006 +#define IMAGE_REL_PPC_REL14 0x0007 +#define IMAGE_REL_PPC_TOCREL16 0x0008 +#define IMAGE_REL_PPC_TOCREL14 0x0009 +#define IMAGE_REL_PPC_ADDR32NB 0x000A +#define IMAGE_REL_PPC_SECREL 0x000B +#define IMAGE_REL_PPC_SECTION 0x000C +#define IMAGE_REL_PPC_IFGLUE 0x000D +#define IMAGE_REL_PPC_IMGLUE 0x000E +#define IMAGE_REL_PPC_SECREL16 0x000F +#define IMAGE_REL_PPC_REFHI 0x0010 +#define IMAGE_REL_PPC_REFLO 0x0011 +#define IMAGE_REL_PPC_PAIR 0x0012 +#define IMAGE_REL_PPC_SECRELLO 0x0013 +#define IMAGE_REL_PPC_SECRELHI 0x0014 +#define IMAGE_REL_PPC_GPREL 0x0015 +#define IMAGE_REL_PPC_TOKEN 0x0016 +#define IMAGE_REL_PPC_TYPEMASK 0x00FF +#define IMAGE_REL_PPC_NEG 0x0100 +#define IMAGE_REL_PPC_BRTAKEN 0x0200 +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 +#define IMAGE_REL_PPC_TOCDEFN 0x0800 + +#define IMAGE_REL_SH3_ABSOLUTE 0x0000 +#define IMAGE_REL_SH3_DIRECT16 0x0001 +#define IMAGE_REL_SH3_DIRECT32 0x0002 +#define IMAGE_REL_SH3_DIRECT8 0x0003 +#define IMAGE_REL_SH3_DIRECT8_WORD 0x0004 +#define IMAGE_REL_SH3_DIRECT8_LONG 0x0005 +#define IMAGE_REL_SH3_DIRECT4 0x0006 +#define IMAGE_REL_SH3_DIRECT4_WORD 0x0007 +#define IMAGE_REL_SH3_DIRECT4_LONG 0x0008 +#define IMAGE_REL_SH3_PCREL8_WORD 0x0009 +#define IMAGE_REL_SH3_PCREL8_LONG 0x000A +#define IMAGE_REL_SH3_PCREL12_WORD 0x000B +#define IMAGE_REL_SH3_STARTOF_SECTION 0x000C +#define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D +#define IMAGE_REL_SH3_SECTION 0x000E +#define IMAGE_REL_SH3_SECREL 0x000F +#define IMAGE_REL_SH3_DIRECT32_NB 0x0010 +#define IMAGE_REL_SH3_GPREL4_LONG 0x0011 +#define IMAGE_REL_SH3_TOKEN 0x0012 + +#define IMAGE_REL_SHM_PCRELPT 0x0013 +#define IMAGE_REL_SHM_REFLO 0x0014 +#define IMAGE_REL_SHM_REFHALF 0x0015 +#define IMAGE_REL_SHM_RELLO 0x0016 +#define IMAGE_REL_SHM_RELHALF 0x0017 +#define IMAGE_REL_SHM_PAIR 0x0018 + +#define IMAGE_REL_SH_NOMODE 0x8000 + +#define IMAGE_REL_ARM_ABSOLUTE 0x0000 +#define IMAGE_REL_ARM_ADDR32 0x0001 +#define IMAGE_REL_ARM_ADDR32NB 0x0002 +#define IMAGE_REL_ARM_BRANCH24 0x0003 +#define IMAGE_REL_ARM_BRANCH11 0x0004 +#define IMAGE_REL_ARM_TOKEN 0x0005 +#define IMAGE_REL_ARM_GPREL12 0x0006 +#define IMAGE_REL_ARM_GPREL7 0x0007 +#define IMAGE_REL_ARM_BLX24 0x0008 +#define IMAGE_REL_ARM_BLX11 0x0009 +#define IMAGE_REL_ARM_SECTION 0x000E +#define IMAGE_REL_ARM_SECREL 0x000F + +#define IMAGE_REL_AM_ABSOLUTE 0x0000 +#define IMAGE_REL_AM_ADDR32 0x0001 +#define IMAGE_REL_AM_ADDR32NB 0x0002 +#define IMAGE_REL_AM_CALL32 0x0003 +#define IMAGE_REL_AM_FUNCINFO 0x0004 +#define IMAGE_REL_AM_REL32_1 0x0005 +#define IMAGE_REL_AM_REL32_2 0x0006 +#define IMAGE_REL_AM_SECREL 0x0007 +#define IMAGE_REL_AM_SECTION 0x0008 +#define IMAGE_REL_AM_TOKEN 0x0009 + +#define IMAGE_REL_AMD64_ABSOLUTE 0x0000 +#define IMAGE_REL_AMD64_ADDR64 0x0001 +#define IMAGE_REL_AMD64_ADDR32 0x0002 +#define IMAGE_REL_AMD64_ADDR32NB 0x0003 +#define IMAGE_REL_AMD64_REL32 0x0004 +#define IMAGE_REL_AMD64_REL32_1 0x0005 +#define IMAGE_REL_AMD64_REL32_2 0x0006 +#define IMAGE_REL_AMD64_REL32_3 0x0007 +#define IMAGE_REL_AMD64_REL32_4 0x0008 +#define IMAGE_REL_AMD64_REL32_5 0x0009 +#define IMAGE_REL_AMD64_SECTION 0x000A +#define IMAGE_REL_AMD64_SECREL 0x000B +#define IMAGE_REL_AMD64_SECREL7 0x000C +#define IMAGE_REL_AMD64_TOKEN 0x000D +#define IMAGE_REL_AMD64_SREL32 0x000E +#define IMAGE_REL_AMD64_PAIR 0x000F +#define IMAGE_REL_AMD64_SSPAN32 0x0010 + +#define IMAGE_REL_IA64_ABSOLUTE 0x0000 +#define IMAGE_REL_IA64_IMM14 0x0001 +#define IMAGE_REL_IA64_IMM22 0x0002 +#define IMAGE_REL_IA64_IMM64 0x0003 +#define IMAGE_REL_IA64_DIR32 0x0004 +#define IMAGE_REL_IA64_DIR64 0x0005 +#define IMAGE_REL_IA64_PCREL21B 0x0006 +#define IMAGE_REL_IA64_PCREL21M 0x0007 +#define IMAGE_REL_IA64_PCREL21F 0x0008 +#define IMAGE_REL_IA64_GPREL22 0x0009 +#define IMAGE_REL_IA64_LTOFF22 0x000A +#define IMAGE_REL_IA64_SECTION 0x000B +#define IMAGE_REL_IA64_SECREL22 0x000C +#define IMAGE_REL_IA64_SECREL64I 0x000D +#define IMAGE_REL_IA64_SECREL32 0x000E + +#define IMAGE_REL_IA64_DIR32NB 0x0010 +#define IMAGE_REL_IA64_SREL14 0x0011 +#define IMAGE_REL_IA64_SREL22 0x0012 +#define IMAGE_REL_IA64_SREL32 0x0013 +#define IMAGE_REL_IA64_UREL32 0x0014 +#define IMAGE_REL_IA64_PCREL60X 0x0015 +#define IMAGE_REL_IA64_PCREL60B 0x0016 +#define IMAGE_REL_IA64_PCREL60F 0x0017 +#define IMAGE_REL_IA64_PCREL60I 0x0018 +#define IMAGE_REL_IA64_PCREL60M 0x0019 +#define IMAGE_REL_IA64_IMMGPREL64 0x001A +#define IMAGE_REL_IA64_TOKEN 0x001B +#define IMAGE_REL_IA64_GPREL32 0x001C +#define IMAGE_REL_IA64_ADDEND 0x001F + +#define IMAGE_REL_CEF_ABSOLUTE 0x0000 +#define IMAGE_REL_CEF_ADDR32 0x0001 +#define IMAGE_REL_CEF_ADDR64 0x0002 +#define IMAGE_REL_CEF_ADDR32NB 0x0003 +#define IMAGE_REL_CEF_SECTION 0x0004 +#define IMAGE_REL_CEF_SECREL 0x0005 +#define IMAGE_REL_CEF_TOKEN 0x0006 + +#define IMAGE_REL_CEE_ABSOLUTE 0x0000 +#define IMAGE_REL_CEE_ADDR32 0x0001 +#define IMAGE_REL_CEE_ADDR64 0x0002 +#define IMAGE_REL_CEE_ADDR32NB 0x0003 +#define IMAGE_REL_CEE_SECTION 0x0004 +#define IMAGE_REL_CEE_SECREL 0x0005 +#define IMAGE_REL_CEE_TOKEN 0x0006 + +#define IMAGE_REL_M32R_ABSOLUTE 0x0000 +#define IMAGE_REL_M32R_ADDR32 0x0001 +#define IMAGE_REL_M32R_ADDR32NB 0x0002 +#define IMAGE_REL_M32R_ADDR24 0x0003 +#define IMAGE_REL_M32R_GPREL16 0x0004 +#define IMAGE_REL_M32R_PCREL24 0x0005 +#define IMAGE_REL_M32R_PCREL16 0x0006 +#define IMAGE_REL_M32R_PCREL8 0x0007 +#define IMAGE_REL_M32R_REFHALF 0x0008 +#define IMAGE_REL_M32R_REFHI 0x0009 +#define IMAGE_REL_M32R_REFLO 0x000A +#define IMAGE_REL_M32R_PAIR 0x000B +#define IMAGE_REL_M32R_SECTION 0x000C +#define IMAGE_REL_M32R_SECREL32 0x000D +#define IMAGE_REL_M32R_TOKEN 0x000E + +#define EXT_IMM64(Value,Address,Size,InstPos,ValPos) Value |= (((ULONGLONG)((*(Address) >> InstPos) & (((ULONGLONG)1 << Size) - 1))) << ValPos) +#define INS_IMM64(Value,Address,Size,InstPos,ValPos) *(PDWORD)Address = (*(PDWORD)Address & ~(((1 << Size) - 1) << InstPos)) | ((DWORD)((((ULONGLONG)Value >> ValPos) & (((ULONGLONG)1 << Size) - 1))) << InstPos) + +#define EMARCH_ENC_I17_IMM7B_INST_WORD_X 3 +#define EMARCH_ENC_I17_IMM7B_SIZE_X 7 +#define EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X 4 +#define EMARCH_ENC_I17_IMM7B_VAL_POS_X 0 + +#define EMARCH_ENC_I17_IMM9D_INST_WORD_X 3 +#define EMARCH_ENC_I17_IMM9D_SIZE_X 9 +#define EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X 18 +#define EMARCH_ENC_I17_IMM9D_VAL_POS_X 7 + +#define EMARCH_ENC_I17_IMM5C_INST_WORD_X 3 +#define EMARCH_ENC_I17_IMM5C_SIZE_X 5 +#define EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X 13 +#define EMARCH_ENC_I17_IMM5C_VAL_POS_X 16 + +#define EMARCH_ENC_I17_IC_INST_WORD_X 3 +#define EMARCH_ENC_I17_IC_SIZE_X 1 +#define EMARCH_ENC_I17_IC_INST_WORD_POS_X 12 +#define EMARCH_ENC_I17_IC_VAL_POS_X 21 + +#define EMARCH_ENC_I17_IMM41a_INST_WORD_X 1 +#define EMARCH_ENC_I17_IMM41a_SIZE_X 10 +#define EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X 14 +#define EMARCH_ENC_I17_IMM41a_VAL_POS_X 22 + +#define EMARCH_ENC_I17_IMM41b_INST_WORD_X 1 +#define EMARCH_ENC_I17_IMM41b_SIZE_X 8 +#define EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X 24 +#define EMARCH_ENC_I17_IMM41b_VAL_POS_X 32 + +#define EMARCH_ENC_I17_IMM41c_INST_WORD_X 2 +#define EMARCH_ENC_I17_IMM41c_SIZE_X 23 +#define EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X 0 +#define EMARCH_ENC_I17_IMM41c_VAL_POS_X 40 + +#define EMARCH_ENC_I17_SIGN_INST_WORD_X 3 +#define EMARCH_ENC_I17_SIGN_SIZE_X 1 +#define EMARCH_ENC_I17_SIGN_INST_WORD_POS_X 27 +#define EMARCH_ENC_I17_SIGN_VAL_POS_X 63 + +#define X3_OPCODE_INST_WORD_X 3 +#define X3_OPCODE_SIZE_X 4 +#define X3_OPCODE_INST_WORD_POS_X 28 +#define X3_OPCODE_SIGN_VAL_POS_X 0 + +#define X3_I_INST_WORD_X 3 +#define X3_I_SIZE_X 1 +#define X3_I_INST_WORD_POS_X 27 +#define X3_I_SIGN_VAL_POS_X 59 + +#define X3_D_WH_INST_WORD_X 3 +#define X3_D_WH_SIZE_X 3 +#define X3_D_WH_INST_WORD_POS_X 24 +#define X3_D_WH_SIGN_VAL_POS_X 0 + +#define X3_IMM20_INST_WORD_X 3 +#define X3_IMM20_SIZE_X 20 +#define X3_IMM20_INST_WORD_POS_X 4 +#define X3_IMM20_SIGN_VAL_POS_X 0 + +#define X3_IMM39_1_INST_WORD_X 2 +#define X3_IMM39_1_SIZE_X 23 +#define X3_IMM39_1_INST_WORD_POS_X 0 +#define X3_IMM39_1_SIGN_VAL_POS_X 36 + +#define X3_IMM39_2_INST_WORD_X 1 +#define X3_IMM39_2_SIZE_X 16 +#define X3_IMM39_2_INST_WORD_POS_X 16 +#define X3_IMM39_2_SIGN_VAL_POS_X 20 + +#define X3_P_INST_WORD_X 3 +#define X3_P_SIZE_X 4 +#define X3_P_INST_WORD_POS_X 0 +#define X3_P_SIGN_VAL_POS_X 0 + +#define X3_TMPLT_INST_WORD_X 0 +#define X3_TMPLT_SIZE_X 4 +#define X3_TMPLT_INST_WORD_POS_X 0 +#define X3_TMPLT_SIGN_VAL_POS_X 0 + +#define X3_BTYPE_QP_INST_WORD_X 2 +#define X3_BTYPE_QP_SIZE_X 9 +#define X3_BTYPE_QP_INST_WORD_POS_X 23 +#define X3_BTYPE_QP_INST_VAL_POS_X 0 + +#define X3_EMPTY_INST_WORD_X 1 +#define X3_EMPTY_SIZE_X 2 +#define X3_EMPTY_INST_WORD_POS_X 14 +#define X3_EMPTY_INST_VAL_POS_X 0 + + typedef struct _IMAGE_LINENUMBER { + union { + DWORD SymbolTableIndex; + DWORD VirtualAddress; + } Type; + WORD Linenumber; + } IMAGE_LINENUMBER; + typedef IMAGE_LINENUMBER UNALIGNED *PIMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +#include "poppack.h" + + typedef struct _IMAGE_BASE_RELOCATION { + DWORD VirtualAddress; + DWORD SizeOfBlock; + + } IMAGE_BASE_RELOCATION; + typedef IMAGE_BASE_RELOCATION UNALIGNED *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + #define IMAGE_REL_BASED_ABSOLUTE 0 #define IMAGE_REL_BASED_HIGH 1 #define IMAGE_REL_BASED_LOW 2 #define IMAGE_REL_BASED_HIGHLOW 3 #define IMAGE_REL_BASED_HIGHADJ 4 #define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + #define IMAGE_ARCHIVE_START_SIZE 8 #define IMAGE_ARCHIVE_START "!<arch>\n" #define IMAGE_ARCHIVE_END "`\n" #define IMAGE_ARCHIVE_PAD "\n" #define IMAGE_ARCHIVE_LINKER_MEMBER "/ " #define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " -#define IMAGE_ORDINAL_FLAG 0x80000000 -#define IMAGE_SNAP_BY_ORDINAL(o) ((o&IMAGE_ORDINAL_FLAG)!=0) -#define IMAGE_ORDINAL(o) (o&0xffff) + + typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + BYTE Name[16]; + BYTE Date[12]; + BYTE UserID[6]; + BYTE GroupID[6]; + BYTE Mode[8]; + BYTE Size[10]; + BYTE EndHeader[2]; + } IMAGE_ARCHIVE_MEMBER_HEADER,*PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + + typedef struct _IMAGE_EXPORT_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + DWORD AddressOfFunctions; + DWORD AddressOfNames; + DWORD AddressOfNameOrdinals; + } IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; + + typedef struct _IMAGE_IMPORT_BY_NAME { + WORD Hint; + BYTE Name[1]; + } IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; + +#include "pshpack8.h" + + typedef struct _IMAGE_THUNK_DATA64 { + union { + ULONGLONG ForwarderString; + ULONGLONG Function; + ULONGLONG Ordinal; + ULONGLONG AddressOfData; + } u1; + } IMAGE_THUNK_DATA64; + typedef IMAGE_THUNK_DATA64 *PIMAGE_THUNK_DATA64; + +#include "poppack.h" + + typedef struct _IMAGE_THUNK_DATA32 { + union { + DWORD ForwarderString; + DWORD Function; + DWORD Ordinal; + DWORD AddressOfData; + } u1; + } IMAGE_THUNK_DATA32; + typedef IMAGE_THUNK_DATA32 *PIMAGE_THUNK_DATA32; + +#define IMAGE_ORDINAL_FLAG64 0x8000000000000000ull +#define IMAGE_ORDINAL_FLAG32 0x80000000 +#define IMAGE_ORDINAL64(Ordinal) (Ordinal & 0xffffull) +#define IMAGE_ORDINAL32(Ordinal) (Ordinal & 0xffff) +#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64)!=0) +#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32)!=0) + + typedef VOID + (NTAPI *PIMAGE_TLS_CALLBACK)(PVOID DllHandle,DWORD Reason,PVOID Reserved); + + typedef struct _IMAGE_TLS_DIRECTORY64 { + ULONGLONG StartAddressOfRawData; + ULONGLONG EndAddressOfRawData; + ULONGLONG AddressOfIndex; + ULONGLONG AddressOfCallBacks; + DWORD SizeOfZeroFill; + DWORD Characteristics; + } IMAGE_TLS_DIRECTORY64; + typedef IMAGE_TLS_DIRECTORY64 *PIMAGE_TLS_DIRECTORY64; + + typedef struct _IMAGE_TLS_DIRECTORY32 { + DWORD StartAddressOfRawData; + DWORD EndAddressOfRawData; + DWORD AddressOfIndex; + DWORD AddressOfCallBacks; + DWORD SizeOfZeroFill; + DWORD Characteristics; + } IMAGE_TLS_DIRECTORY32; + typedef IMAGE_TLS_DIRECTORY32 *PIMAGE_TLS_DIRECTORY32; + +#ifdef _WIN64 +#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG64 +#define IMAGE_ORDINAL(Ordinal) IMAGE_ORDINAL64(Ordinal) + typedef IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA; + typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA; +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) IMAGE_SNAP_BY_ORDINAL64(Ordinal) + typedef IMAGE_TLS_DIRECTORY64 IMAGE_TLS_DIRECTORY; + typedef PIMAGE_TLS_DIRECTORY64 PIMAGE_TLS_DIRECTORY; +#else +#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG32 +#define IMAGE_ORDINAL(Ordinal) IMAGE_ORDINAL32(Ordinal) + typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA; + typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA; +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) IMAGE_SNAP_BY_ORDINAL32(Ordinal) + typedef IMAGE_TLS_DIRECTORY32 IMAGE_TLS_DIRECTORY; + typedef PIMAGE_TLS_DIRECTORY32 PIMAGE_TLS_DIRECTORY; +#endif + + typedef struct _IMAGE_IMPORT_DESCRIPTOR { + union { + DWORD Characteristics; + DWORD OriginalFirstThunk; + }; + DWORD TimeDateStamp; + + DWORD ForwarderChain; + DWORD Name; + DWORD FirstThunk; + } IMAGE_IMPORT_DESCRIPTOR; + typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR; + + typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR { + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD NumberOfModuleForwarderRefs; + } IMAGE_BOUND_IMPORT_DESCRIPTOR,*PIMAGE_BOUND_IMPORT_DESCRIPTOR; + + typedef struct _IMAGE_BOUND_FORWARDER_REF { + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD Reserved; + } IMAGE_BOUND_FORWARDER_REF,*PIMAGE_BOUND_FORWARDER_REF; + + typedef struct _IMAGE_RESOURCE_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + WORD NumberOfNamedEntries; + WORD NumberOfIdEntries; + } IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; + #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 + + typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { + union { + struct { + DWORD NameOffset:31; + DWORD NameIsString:1; + }; + DWORD Name; + WORD Id; + }; + union { + DWORD OffsetToData; + struct { + DWORD OffsetToDirectory:31; + DWORD DataIsDirectory:1; + }; + }; + } IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; + + typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { + WORD Length; + CHAR NameString[1]; + } IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING; + + typedef struct _IMAGE_RESOURCE_DIR_STRING_U { + WORD Length; + WCHAR NameString[1]; + } IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U; + + typedef struct _IMAGE_RESOURCE_DATA_ENTRY { + DWORD OffsetToData; + DWORD Size; + DWORD CodePage; + DWORD Reserved; + } IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY; + + typedef struct { + DWORD Size; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD GlobalFlagsClear; + DWORD GlobalFlagsSet; + DWORD CriticalSectionDefaultTimeout; + DWORD DeCommitFreeBlockThreshold; + DWORD DeCommitTotalFreeThreshold; + DWORD LockPrefixTable; + DWORD MaximumAllocationSize; + DWORD VirtualMemoryThreshold; + DWORD ProcessHeapFlags; + DWORD ProcessAffinityMask; + WORD CSDVersion; + WORD Reserved1; + DWORD EditList; + DWORD SecurityCookie; + DWORD SEHandlerTable; + DWORD SEHandlerCount; + } IMAGE_LOAD_CONFIG_DIRECTORY32,*PIMAGE_LOAD_CONFIG_DIRECTORY32; + + typedef struct { + DWORD Size; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD GlobalFlagsClear; + DWORD GlobalFlagsSet; + DWORD CriticalSectionDefaultTimeout; + ULONGLONG DeCommitFreeBlockThreshold; + ULONGLONG DeCommitTotalFreeThreshold; + ULONGLONG LockPrefixTable; + ULONGLONG MaximumAllocationSize; + ULONGLONG VirtualMemoryThreshold; + ULONGLONG ProcessAffinityMask; + DWORD ProcessHeapFlags; + WORD CSDVersion; + WORD Reserved1; + ULONGLONG EditList; + ULONGLONG SecurityCookie; + ULONGLONG SEHandlerTable; + ULONGLONG SEHandlerCount; + } IMAGE_LOAD_CONFIG_DIRECTORY64,*PIMAGE_LOAD_CONFIG_DIRECTORY64; + +#ifdef _WIN64 + typedef IMAGE_LOAD_CONFIG_DIRECTORY64 IMAGE_LOAD_CONFIG_DIRECTORY; + typedef PIMAGE_LOAD_CONFIG_DIRECTORY64 PIMAGE_LOAD_CONFIG_DIRECTORY; +#else + typedef IMAGE_LOAD_CONFIG_DIRECTORY32 IMAGE_LOAD_CONFIG_DIRECTORY; + typedef PIMAGE_LOAD_CONFIG_DIRECTORY32 PIMAGE_LOAD_CONFIG_DIRECTORY; +#endif + + typedef struct _IMAGE_CE_RUNTIME_FUNCTION_ENTRY { + DWORD FuncStart; + DWORD PrologLen : 8; + DWORD FuncLen : 22; + DWORD ThirtyTwoBit : 1; + DWORD ExceptionFlag : 1; + } IMAGE_CE_RUNTIME_FUNCTION_ENTRY,*PIMAGE_CE_RUNTIME_FUNCTION_ENTRY; + + typedef struct _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY { + ULONGLONG BeginAddress; + ULONGLONG EndAddress; + ULONGLONG ExceptionHandler; + ULONGLONG HandlerData; + ULONGLONG PrologEndAddress; + } IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY,*PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY; + + typedef struct _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY { + DWORD BeginAddress; + DWORD EndAddress; + DWORD ExceptionHandler; + DWORD HandlerData; + DWORD PrologEndAddress; + } IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY,*PIMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY; + + typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY { + DWORD BeginAddress; + DWORD EndAddress; + DWORD UnwindInfoAddress; + } _IMAGE_RUNTIME_FUNCTION_ENTRY,*_PIMAGE_RUNTIME_FUNCTION_ENTRY; + + typedef _IMAGE_RUNTIME_FUNCTION_ENTRY IMAGE_IA64_RUNTIME_FUNCTION_ENTRY; + typedef _PIMAGE_RUNTIME_FUNCTION_ENTRY PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY; + + typedef _IMAGE_RUNTIME_FUNCTION_ENTRY IMAGE_RUNTIME_FUNCTION_ENTRY; + typedef _PIMAGE_RUNTIME_FUNCTION_ENTRY PIMAGE_RUNTIME_FUNCTION_ENTRY; + + typedef struct _IMAGE_DEBUG_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Type; + DWORD SizeOfData; + DWORD AddressOfRawData; + DWORD PointerToRawData; + } IMAGE_DEBUG_DIRECTORY,*PIMAGE_DEBUG_DIRECTORY; + #define IMAGE_DEBUG_TYPE_UNKNOWN 0 #define IMAGE_DEBUG_TYPE_COFF 1 #define IMAGE_DEBUG_TYPE_CODEVIEW 2 @@ -898,1770 +4775,1061 @@ typedef BYTE BOOLEAN,*PBOOLEAN; #define IMAGE_DEBUG_TYPE_FIXUP 6 #define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7 #define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8 +#define IMAGE_DEBUG_TYPE_BORLAND 9 +#define IMAGE_DEBUG_TYPE_RESERVED10 10 +#define IMAGE_DEBUG_TYPE_CLSID 11 + + typedef struct _IMAGE_COFF_SYMBOLS_HEADER { + DWORD NumberOfSymbols; + DWORD LvaToFirstSymbol; + DWORD NumberOfLinenumbers; + DWORD LvaToFirstLinenumber; + DWORD RvaToFirstByteOfCode; + DWORD RvaToLastByteOfCode; + DWORD RvaToFirstByteOfData; + DWORD RvaToLastByteOfData; + } IMAGE_COFF_SYMBOLS_HEADER,*PIMAGE_COFF_SYMBOLS_HEADER; + #define FRAME_FPO 0 #define FRAME_TRAP 1 #define FRAME_TSS 2 #define FRAME_NONFPO 3 + + typedef struct _FPO_DATA { + DWORD ulOffStart; + DWORD cbProcSize; + DWORD cdwLocals; + WORD cdwParams; + WORD cbProlog : 8; + WORD cbRegs : 3; + WORD fHasSEH : 1; + WORD fUseBP : 1; + WORD reserved : 1; + WORD cbFrame : 2; + } FPO_DATA,*PFPO_DATA; +#define SIZEOF_RFPO_DATA 16 + #define IMAGE_DEBUG_MISC_EXENAME 1 -#define N_BTMASK 0x000F -#define N_TMASK 0x0030 -#define N_TMASK1 0x00C0 -#define N_TMASK2 0x00F0 -#define N_BTSHFT 4 -#define N_TSHIFT 2 -#define IS_TEXT_UNICODE_ASCII16 1 -#define IS_TEXT_UNICODE_REVERSE_ASCII16 16 -#define IS_TEXT_UNICODE_STATISTICS 2 -#define IS_TEXT_UNICODE_REVERSE_STATISTICS 32 -#define IS_TEXT_UNICODE_CONTROLS 4 -#define IS_TEXT_UNICODE_REVERSE_CONTROLS 64 -#define IS_TEXT_UNICODE_SIGNATURE 8 -#define IS_TEXT_UNICODE_REVERSE_SIGNATURE 128 -#define IS_TEXT_UNICODE_ILLEGAL_CHARS 256 -#define IS_TEXT_UNICODE_ODD_LENGTH 512 -#define IS_TEXT_UNICODE_NULL_BYTES 4096 -#define IS_TEXT_UNICODE_UNICODE_MASK 15 -#define IS_TEXT_UNICODE_REVERSE_MASK 240 -#define IS_TEXT_UNICODE_NOT_UNICODE_MASK 3840 -#define IS_TEXT_UNICODE_NOT_ASCII_MASK 61440 -#define SERVICE_KERNEL_DRIVER 1 -#define SERVICE_FILE_SYSTEM_DRIVER 2 -#define SERVICE_ADAPTER 4 -#define SERVICE_RECOGNIZER_DRIVER 8 -#define SERVICE_DRIVER (SERVICE_KERNEL_DRIVER|SERVICE_FILE_SYSTEM_DRIVER|SERVICE_RECOGNIZER_DRIVER) -#define SERVICE_WIN32_OWN_PROCESS 16 -#define SERVICE_WIN32_SHARE_PROCESS 32 -#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS|SERVICE_WIN32_SHARE_PROCESS) -#define SERVICE_INTERACTIVE_PROCESS 256 -#define SERVICE_TYPE_ALL (SERVICE_WIN32|SERVICE_ADAPTER|SERVICE_DRIVER|SERVICE_INTERACTIVE_PROCESS) -#define SERVICE_BOOT_START 0 -#define SERVICE_SYSTEM_START 1 -#define SERVICE_AUTO_START 2 -#define SERVICE_DEMAND_START 3 -#define SERVICE_DISABLED 4 -#define SERVICE_ERROR_IGNORE 0 -#define SERVICE_ERROR_NORMAL 1 -#define SERVICE_ERROR_SEVERE 2 -#define SERVICE_ERROR_CRITICAL 3 -#define SE_OWNER_DEFAULTED 1 -#define SE_GROUP_DEFAULTED 2 -#define SE_DACL_PRESENT 4 -#define SE_DACL_DEFAULTED 8 -#define SE_SACL_PRESENT 16 -#define SE_SACL_DEFAULTED 32 -#define SE_DACL_AUTO_INHERIT_REQ 256 -#define SE_SACL_AUTO_INHERIT_REQ 512 -#define SE_DACL_AUTO_INHERITED 1024 -#define SE_SACL_AUTO_INHERITED 2048 -#define SE_DACL_PROTECTED 4096 -#define SE_SACL_PROTECTED 8192 -#define SE_SELF_RELATIVE 0x8000 -#define SECURITY_DESCRIPTOR_MIN_LENGTH 20 -#define SECURITY_DESCRIPTOR_REVISION 1 -#define SECURITY_DESCRIPTOR_REVISION1 1 -#define SE_PRIVILEGE_ENABLED_BY_DEFAULT 1 -#define SE_PRIVILEGE_ENABLED 2 -#define SE_PRIVILEGE_USED_FOR_ACCESS 0x80000000 -#define PRIVILEGE_SET_ALL_NECESSARY 1 -#define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation -#define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation -#define SECURITY_DYNAMIC_TRACKING TRUE -#define SECURITY_STATIC_TRACKING FALSE -#define TOKEN_SOURCE_LENGTH 8 -#define TOKEN_ADJUST_DEFAULT 128 -#define TOKEN_ADJUST_GROUPS 64 -#define TOKEN_ADJUST_PRIVILEGES 32 -#define TOKEN_ALL_ACCESS 0xf00ff -#define TOKEN_ASSIGN_PRIMARY 1 -#define TOKEN_DUPLICATE 2 -#define TOKEN_EXECUTE 0x20000 -#define TOKEN_IMPERSONATE 4 -#define TOKEN_QUERY 8 -#define TOKEN_QUERY_SOURCE 16 -#define TOKEN_READ 0x20008 -#define TOKEN_WRITE 0x200e0 -#define DLL_PROCESS_DETACH 0 -#define DLL_PROCESS_ATTACH 1 -#define DLL_THREAD_ATTACH 2 -#define DLL_THREAD_DETACH 3 -#define DBG_CONTINUE 0x10002 -#define DBG_TERMINATE_THREAD 0x40010003 -#define DBG_TERMINATE_PROCESS 0x40010004 -#define DBG_CONTROL_C 0x40010005 -#define DBG_CONTROL_BREAK 0x40010008 -#define DBG_EXCEPTION_NOT_HANDLED 0x80010001 -#define TAPE_ABSOLUTE_POSITION 0 -#define TAPE_LOGICAL_POSITION 1 -#define TAPE_PSEUDO_LOGICAL_POSITION 2 -#define TAPE_REWIND 0 -#define TAPE_ABSOLUTE_BLOCK 1 -#define TAPE_LOGICAL_BLOCK 2 -#define TAPE_PSEUDO_LOGICAL_BLOCK 3 -#define TAPE_SPACE_END_OF_DATA 4 -#define TAPE_SPACE_RELATIVE_BLOCKS 5 -#define TAPE_SPACE_FILEMARKS 6 -#define TAPE_SPACE_SEQUENTIAL_FMKS 7 -#define TAPE_SPACE_SETMARKS 8 -#define TAPE_SPACE_SEQUENTIAL_SMKS 9 -#define TAPE_DRIVE_FIXED 1 -#define TAPE_DRIVE_SELECT 2 -#define TAPE_DRIVE_INITIATOR 4 -#define TAPE_DRIVE_ERASE_SHORT 16 -#define TAPE_DRIVE_ERASE_LONG 32 -#define TAPE_DRIVE_ERASE_BOP_ONLY 64 -#define TAPE_DRIVE_ERASE_IMMEDIATE 128 -#define TAPE_DRIVE_TAPE_CAPACITY 256 -#define TAPE_DRIVE_TAPE_REMAINING 512 -#define TAPE_DRIVE_FIXED_BLOCK 1024 -#define TAPE_DRIVE_VARIABLE_BLOCK 2048 -#define TAPE_DRIVE_WRITE_PROTECT 4096 -#define TAPE_DRIVE_EOT_WZ_SIZE 8192 -#define TAPE_DRIVE_ECC 0x10000 -#define TAPE_DRIVE_COMPRESSION 0x20000 -#define TAPE_DRIVE_PADDING 0x40000 -#define TAPE_DRIVE_REPORT_SMKS 0x80000 -#define TAPE_DRIVE_GET_ABSOLUTE_BLK 0x100000 -#define TAPE_DRIVE_GET_LOGICAL_BLK 0x200000 -#define TAPE_DRIVE_SET_EOT_WZ_SIZE 0x400000 -#define TAPE_DRIVE_EJECT_MEDIA 0x1000000 -#define TAPE_DRIVE_CLEAN_REQUESTS 0x2000000 -#define TAPE_DRIVE_SET_CMP_BOP_ONLY 0x4000000 + + typedef struct _IMAGE_DEBUG_MISC { + DWORD DataType; + DWORD Length; + BOOLEAN Unicode; + BYTE Reserved[3]; + BYTE Data[1]; + } IMAGE_DEBUG_MISC,*PIMAGE_DEBUG_MISC; + + typedef struct _IMAGE_FUNCTION_ENTRY { + DWORD StartingAddress; + DWORD EndingAddress; + DWORD EndOfPrologue; + } IMAGE_FUNCTION_ENTRY,*PIMAGE_FUNCTION_ENTRY; + + typedef struct _IMAGE_FUNCTION_ENTRY64 { + ULONGLONG StartingAddress; + ULONGLONG EndingAddress; + union { + ULONGLONG EndOfPrologue; + ULONGLONG UnwindInfoAddress; + }; + } IMAGE_FUNCTION_ENTRY64,*PIMAGE_FUNCTION_ENTRY64; + + typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { + WORD Signature; + WORD Flags; + WORD Machine; + WORD Characteristics; + DWORD TimeDateStamp; + DWORD CheckSum; + DWORD ImageBase; + DWORD SizeOfImage; + DWORD NumberOfSections; + DWORD ExportedNamesSize; + DWORD DebugDirectorySize; + DWORD SectionAlignment; + DWORD Reserved[2]; + } IMAGE_SEPARATE_DEBUG_HEADER,*PIMAGE_SEPARATE_DEBUG_HEADER; + + typedef struct _NON_PAGED_DEBUG_INFO { + WORD Signature; + WORD Flags; + DWORD Size; + WORD Machine; + WORD Characteristics; + DWORD TimeDateStamp; + DWORD CheckSum; + DWORD SizeOfImage; + ULONGLONG ImageBase; + + } NON_PAGED_DEBUG_INFO,*PNON_PAGED_DEBUG_INFO; + +#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944 +#define NON_PAGED_DEBUG_SIGNATURE 0x494E + +#define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000 +#define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000 + + typedef struct _ImageArchitectureHeader { + unsigned int AmaskValue: 1; + int Adummy1 :7; + unsigned int AmaskShift: 8; + int Adummy2 :16; + DWORD FirstEntryRVA; + } IMAGE_ARCHITECTURE_HEADER,*PIMAGE_ARCHITECTURE_HEADER; + + typedef struct _ImageArchitectureEntry { + DWORD FixupInstRVA; + DWORD NewInst; + } IMAGE_ARCHITECTURE_ENTRY,*PIMAGE_ARCHITECTURE_ENTRY; + +#include "poppack.h" + +#define IMPORT_OBJECT_HDR_SIG2 0xffff + + typedef struct IMPORT_OBJECT_HEADER { + WORD Sig1; + WORD Sig2; + WORD Version; + WORD Machine; + DWORD TimeDateStamp; + DWORD SizeOfData; + union { + WORD Ordinal; + WORD Hint; + }; + WORD Type : 2; + WORD NameType : 3; + WORD Reserved : 11; + } IMPORT_OBJECT_HEADER; + + typedef enum IMPORT_OBJECT_TYPE { + IMPORT_OBJECT_CODE = 0,IMPORT_OBJECT_DATA = 1,IMPORT_OBJECT_CONST = 2 + } IMPORT_OBJECT_TYPE; + + typedef enum IMPORT_OBJECT_NAME_TYPE { + IMPORT_OBJECT_ORDINAL = 0,IMPORT_OBJECT_NAME = 1,IMPORT_OBJECT_NAME_NO_PREFIX = 2,IMPORT_OBJECT_NAME_UNDECORATE = 3 + } IMPORT_OBJECT_NAME_TYPE; + +#ifndef __IMAGE_COR20_HEADER_DEFINED__ +#define __IMAGE_COR20_HEADER_DEFINED__ + typedef enum ReplacesCorHdrNumericDefines { + COMIMAGE_FLAGS_ILONLY =0x00000001,COMIMAGE_FLAGS_32BITREQUIRED =0x00000002,COMIMAGE_FLAGS_IL_LIBRARY =0x00000004, + COMIMAGE_FLAGS_STRONGNAMESIGNED =0x00000008,COMIMAGE_FLAGS_TRACKDEBUGDATA =0x00010000,COR_VERSION_MAJOR_V2 =2, + COR_VERSION_MAJOR =COR_VERSION_MAJOR_V2,COR_VERSION_MINOR =0,COR_DELETED_NAME_LENGTH =8,COR_VTABLEGAP_NAME_LENGTH =8, + NATIVE_TYPE_MAX_CB =1,COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE=0xFF,IMAGE_COR_MIH_METHODRVA =0x01,IMAGE_COR_MIH_EHRVA =0x02, + IMAGE_COR_MIH_BASICBLOCK =0x08,COR_VTABLE_32BIT =0x01,COR_VTABLE_64BIT =0x02,COR_VTABLE_FROM_UNMANAGED =0x04, + COR_VTABLE_CALL_MOST_DERIVED =0x10,IMAGE_COR_EATJ_THUNK_SIZE =32,MAX_CLASS_NAME =1024,MAX_PACKAGE_NAME =1024 + } ReplacesCorHdrNumericDefines; + + typedef struct IMAGE_COR20_HEADER { + DWORD cb; + WORD MajorRuntimeVersion; + WORD MinorRuntimeVersion; + IMAGE_DATA_DIRECTORY MetaData; + DWORD Flags; + DWORD EntryPointToken; + IMAGE_DATA_DIRECTORY Resources; + IMAGE_DATA_DIRECTORY StrongNameSignature; + IMAGE_DATA_DIRECTORY CodeManagerTable; + IMAGE_DATA_DIRECTORY VTableFixups; + IMAGE_DATA_DIRECTORY ExportAddressTableJumps; + IMAGE_DATA_DIRECTORY ManagedNativeHeader; + } IMAGE_COR20_HEADER,*PIMAGE_COR20_HEADER; +#endif + +#if defined (__x86_64) + NTSYSAPI PRUNTIME_FUNCTION NTAPI RtlLookupFunctionEntry (DWORD64 ControlPc, PDWORD64 ImageBase, PUNWIND_HISTORY_TABLE HistoryTable); + NTSYSAPI VOID NTAPI RtlUnwindEx (PVOID TargetFrame, PVOID TargetIp, PEXCEPTION_RECORD ExceptionRecord, PVOID ReturnValue, PCONTEXT ContextRecord, PUNWIND_HISTORY_TABLE HistoryTable); +#endif + +#include <string.h> + +#ifndef _SLIST_HEADER_ +#define _SLIST_HEADER_ + +#ifdef _WIN64 + typedef struct _SLIST_ENTRY *PSLIST_ENTRY; + typedef DECLSPEC_ALIGN(16) struct _SLIST_ENTRY { + PSLIST_ENTRY Next; + } SLIST_ENTRY; +#else + +#define SLIST_ENTRY SINGLE_LIST_ENTRY +#define _SLIST_ENTRY _SINGLE_LIST_ENTRY +#define PSLIST_ENTRY PSINGLE_LIST_ENTRY +#endif + +#if defined(_WIN64) + + typedef DECLSPEC_ALIGN(16) struct _SLIST_HEADER { + ULONGLONG Alignment; + ULONGLONG Region; + } SLIST_HEADER; + + typedef struct _SLIST_HEADER *PSLIST_HEADER; +#else + + typedef union _SLIST_HEADER { + ULONGLONG Alignment; + struct { + SLIST_ENTRY Next; + WORD Depth; + WORD Sequence; + }; + } SLIST_HEADER,*PSLIST_HEADER; +#endif +#endif + + NTSYSAPI VOID NTAPI RtlInitializeSListHead(PSLIST_HEADER ListHead); + NTSYSAPI PSLIST_ENTRY NTAPI RtlFirstEntrySList(const SLIST_HEADER *ListHead); + NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedPopEntrySList(PSLIST_HEADER ListHead); + NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedPushEntrySList(PSLIST_HEADER ListHead,PSLIST_ENTRY ListEntry); + NTSYSAPI PSLIST_ENTRY NTAPI RtlInterlockedFlushSList(PSLIST_HEADER ListHead); + NTSYSAPI WORD NTAPI RtlQueryDepthSList(PSLIST_HEADER ListHead); + +#define HEAP_NO_SERIALIZE 0x00000001 +#define HEAP_GROWABLE 0x00000002 +#define HEAP_GENERATE_EXCEPTIONS 0x00000004 +#define HEAP_ZERO_MEMORY 0x00000008 +#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 +#define HEAP_TAIL_CHECKING_ENABLED 0x00000020 +#define HEAP_FREE_CHECKING_ENABLED 0x00000040 +#define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 +#define HEAP_CREATE_ALIGN_16 0x00010000 +#define HEAP_CREATE_ENABLE_TRACING 0x00020000 +#define HEAP_CREATE_ENABLE_EXECUTE 0x00040000 +#define HEAP_MAXIMUM_TAG 0x0FFF +#define HEAP_PSEUDO_TAG_FLAG 0x8000 +#define HEAP_TAG_SHIFT 18 +#define HEAP_MAKE_TAG_FLAGS(b,o) ((DWORD)((b) + ((o) << 18))) + + NTSYSAPI VOID NTAPI RtlCaptureContext(PCONTEXT ContextRecord); + +#define IS_TEXT_UNICODE_ASCII16 0x0001 +#define IS_TEXT_UNICODE_REVERSE_ASCII16 0x0010 + +#define IS_TEXT_UNICODE_STATISTICS 0x0002 +#define IS_TEXT_UNICODE_REVERSE_STATISTICS 0x0020 + +#define IS_TEXT_UNICODE_CONTROLS 0x0004 +#define IS_TEXT_UNICODE_REVERSE_CONTROLS 0x0040 + +#define IS_TEXT_UNICODE_SIGNATURE 0x0008 +#define IS_TEXT_UNICODE_REVERSE_SIGNATURE 0x0080 + +#define IS_TEXT_UNICODE_ILLEGAL_CHARS 0x0100 +#define IS_TEXT_UNICODE_ODD_LENGTH 0x0200 +#define IS_TEXT_UNICODE_DBCS_LEADBYTE 0x0400 +#define IS_TEXT_UNICODE_NULL_BYTES 0x1000 + +#define IS_TEXT_UNICODE_UNICODE_MASK 0x000F +#define IS_TEXT_UNICODE_REVERSE_MASK 0x00F0 +#define IS_TEXT_UNICODE_NOT_UNICODE_MASK 0x0F00 +#define IS_TEXT_UNICODE_NOT_ASCII_MASK 0xF000 + +#define COMPRESSION_FORMAT_NONE (0x0000) +#define COMPRESSION_FORMAT_DEFAULT (0x0001) +#define COMPRESSION_FORMAT_LZNT1 (0x0002) +#define COMPRESSION_ENGINE_STANDARD (0x0000) +#define COMPRESSION_ENGINE_MAXIMUM (0x0100) +#define COMPRESSION_ENGINE_HIBER (0x0200) + +#if _DBG_MEMCPY_INLINE_ && !defined(_MEMCPY_INLINE_) && !defined(_CRTBLD) +#define _MEMCPY_INLINE_ + __CRT_INLINE PVOID __cdecl memcpy_inline(void *dst,const void *src,size_t size) { + if(((char *)dst > (char *)src) && ((char *)dst < ((char *)src + size))) { + __debugbreak(); + } + return memcpy(dst,src,size); + } +#define memcpy memcpy_inline +#endif + + NTSYSAPI SIZE_T NTAPI RtlCompareMemory(const VOID *Source1,const VOID *Source2,SIZE_T Length); + +#define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination),(Source),(Length))) +#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length)) +#define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length)) +#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length)) +#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length)) + + __CRT_INLINE PVOID RtlSecureZeroMemory(PVOID ptr,SIZE_T cnt) { + volatile char *vptr =(volatile char *)ptr; +#ifdef __x86_64 + __stosb((PBYTE)((DWORD64)vptr),0,cnt); +#else + while(cnt) { + *vptr = 0; + vptr++; + cnt--; + } +#endif + return ptr; + } + + typedef struct _MESSAGE_RESOURCE_ENTRY { + WORD Length; + WORD Flags; + BYTE Text[1]; + } MESSAGE_RESOURCE_ENTRY,*PMESSAGE_RESOURCE_ENTRY; + +#define MESSAGE_RESOURCE_UNICODE 0x0001 + + typedef struct _MESSAGE_RESOURCE_BLOCK { + DWORD LowId; + DWORD HighId; + DWORD OffsetToEntries; + } MESSAGE_RESOURCE_BLOCK,*PMESSAGE_RESOURCE_BLOCK; + + typedef struct _MESSAGE_RESOURCE_DATA { + DWORD NumberOfBlocks; + MESSAGE_RESOURCE_BLOCK Blocks[1]; + } MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA; + + typedef struct _OSVERSIONINFOA { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[128]; + } OSVERSIONINFOA,*POSVERSIONINFOA,*LPOSVERSIONINFOA; + + typedef struct _OSVERSIONINFOW { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR szCSDVersion[128]; + } OSVERSIONINFOW,*POSVERSIONINFOW,*LPOSVERSIONINFOW,RTL_OSVERSIONINFOW,*PRTL_OSVERSIONINFOW; + +#ifdef UNICODE + typedef OSVERSIONINFOW OSVERSIONINFO; + typedef POSVERSIONINFOW POSVERSIONINFO; + typedef LPOSVERSIONINFOW LPOSVERSIONINFO; +#else + typedef OSVERSIONINFOA OSVERSIONINFO; + typedef POSVERSIONINFOA POSVERSIONINFO; + typedef LPOSVERSIONINFOA LPOSVERSIONINFO; +#endif + + typedef struct _OSVERSIONINFOEXA { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR szCSDVersion[128]; + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; + } OSVERSIONINFOEXA,*POSVERSIONINFOEXA,*LPOSVERSIONINFOEXA; + + typedef struct _OSVERSIONINFOEXW { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR szCSDVersion[128]; + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; + } OSVERSIONINFOEXW,*POSVERSIONINFOEXW,*LPOSVERSIONINFOEXW,RTL_OSVERSIONINFOEXW,*PRTL_OSVERSIONINFOEXW; +#ifdef UNICODE + typedef OSVERSIONINFOEXW OSVERSIONINFOEX; + typedef POSVERSIONINFOEXW POSVERSIONINFOEX; + typedef LPOSVERSIONINFOEXW LPOSVERSIONINFOEX; +#else + typedef OSVERSIONINFOEXA OSVERSIONINFOEX; + typedef POSVERSIONINFOEXA POSVERSIONINFOEX; + typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX; +#endif + +#define VER_EQUAL 1 +#define VER_GREATER 2 +#define VER_GREATER_EQUAL 3 +#define VER_LESS 4 +#define VER_LESS_EQUAL 5 +#define VER_AND 6 +#define VER_OR 7 + +#define VER_CONDITION_MASK 7 +#define VER_NUM_BITS_PER_CONDITION_MASK 3 + +#define VER_MINORVERSION 0x0000001 +#define VER_MAJORVERSION 0x0000002 +#define VER_BUILDNUMBER 0x0000004 +#define VER_PLATFORMID 0x0000008 +#define VER_SERVICEPACKMINOR 0x0000010 +#define VER_SERVICEPACKMAJOR 0x0000020 +#define VER_SUITENAME 0x0000040 +#define VER_PRODUCT_TYPE 0x0000080 + +#define VER_NT_WORKSTATION 0x0000001 +#define VER_NT_DOMAIN_CONTROLLER 0x0000002 +#define VER_NT_SERVER 0x0000003 + +#define VER_PLATFORM_WIN32s 0 +#define VER_PLATFORM_WIN32_WINDOWS 1 +#define VER_PLATFORM_WIN32_NT 2 + +#define VER_SET_CONDITION(_m_,_t_,_c_) ((_m_)=VerSetConditionMask((_m_),(_t_),(_c_))) + + NTSYSAPI ULONGLONG NTAPI VerSetConditionMask(ULONGLONG ConditionMask,DWORD TypeMask,BYTE Condition); + + typedef struct _RTL_CRITICAL_SECTION_DEBUG { + WORD Type; + WORD CreatorBackTraceIndex; + struct _RTL_CRITICAL_SECTION *CriticalSection; + LIST_ENTRY ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD Spare[2]; + } RTL_CRITICAL_SECTION_DEBUG,*PRTL_CRITICAL_SECTION_DEBUG,RTL_RESOURCE_DEBUG,*PRTL_RESOURCE_DEBUG; + +#define RTL_CRITSECT_TYPE 0 +#define RTL_RESOURCE_TYPE 1 + + typedef struct _RTL_CRITICAL_SECTION { + PRTL_CRITICAL_SECTION_DEBUG DebugInfo; + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; + HANDLE LockSemaphore; + ULONG_PTR SpinCount; + } RTL_CRITICAL_SECTION,*PRTL_CRITICAL_SECTION; + + typedef VOID (NTAPI *RTL_VERIFIER_DLL_LOAD_CALLBACK) (PWSTR DllName,PVOID DllBase,SIZE_T DllSize,PVOID Reserved); + typedef VOID (NTAPI *RTL_VERIFIER_DLL_UNLOAD_CALLBACK) (PWSTR DllName,PVOID DllBase,SIZE_T DllSize,PVOID Reserved); + typedef VOID (NTAPI *RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK)(PVOID AllocationBase,SIZE_T AllocationSize); + + typedef struct _RTL_VERIFIER_THUNK_DESCRIPTOR { + PCHAR ThunkName; + PVOID ThunkOldAddress; + PVOID ThunkNewAddress; + } RTL_VERIFIER_THUNK_DESCRIPTOR,*PRTL_VERIFIER_THUNK_DESCRIPTOR; + + typedef struct _RTL_VERIFIER_DLL_DESCRIPTOR { + PWCHAR DllName; + DWORD DllFlags; + PVOID DllAddress; + PRTL_VERIFIER_THUNK_DESCRIPTOR DllThunks; + } RTL_VERIFIER_DLL_DESCRIPTOR,*PRTL_VERIFIER_DLL_DESCRIPTOR; + + typedef struct _RTL_VERIFIER_PROVIDER_DESCRIPTOR { + DWORD Length; + PRTL_VERIFIER_DLL_DESCRIPTOR ProviderDlls; + RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback; + RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback; + PWSTR VerifierImage; + DWORD VerifierFlags; + DWORD VerifierDebug; + PVOID RtlpGetStackTraceAddress; + PVOID RtlpDebugPageHeapCreate; + PVOID RtlpDebugPageHeapDestroy; + RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback; + } RTL_VERIFIER_PROVIDER_DESCRIPTOR,*PRTL_VERIFIER_PROVIDER_DESCRIPTOR; + +#define RTL_VRF_FLG_FULL_PAGE_HEAP 0x00000001 +#define RTL_VRF_FLG_RESERVED_DONOTUSE 0x00000002 +#define RTL_VRF_FLG_HANDLE_CHECKS 0x00000004 +#define RTL_VRF_FLG_STACK_CHECKS 0x00000008 +#define RTL_VRF_FLG_APPCOMPAT_CHECKS 0x00000010 +#define RTL_VRF_FLG_TLS_CHECKS 0x00000020 +#define RTL_VRF_FLG_DIRTY_STACKS 0x00000040 +#define RTL_VRF_FLG_RPC_CHECKS 0x00000080 +#define RTL_VRF_FLG_COM_CHECKS 0x00000100 +#define RTL_VRF_FLG_DANGEROUS_APIS 0x00000200 +#define RTL_VRF_FLG_RACE_CHECKS 0x00000400 +#define RTL_VRF_FLG_DEADLOCK_CHECKS 0x00000800 +#define RTL_VRF_FLG_FIRST_CHANCE_EXCEPTION_CHECKS 0x00001000 +#define RTL_VRF_FLG_VIRTUAL_MEM_CHECKS 0x00002000 +#define RTL_VRF_FLG_ENABLE_LOGGING 0x00004000 +#define RTL_VRF_FLG_FAST_FILL_HEAP 0x00008000 +#define RTL_VRF_FLG_VIRTUAL_SPACE_TRACKING 0x00010000 +#define RTL_VRF_FLG_ENABLED_SYSTEM_WIDE 0x00020000 +#define RTL_VRF_FLG_MISCELLANEOUS_CHECKS 0x00020000 +#define RTL_VRF_FLG_LOCK_CHECKS 0x00040000 + +#define APPLICATION_VERIFIER_INTERNAL_ERROR 0x80000000 +#define APPLICATION_VERIFIER_INTERNAL_WARNING 0x40000000 +#define APPLICATION_VERIFIER_NO_BREAK 0x20000000 +#define APPLICATION_VERIFIER_CONTINUABLE_BREAK 0x10000000 + +#define APPLICATION_VERIFIER_UNKNOWN_ERROR 0x0001 +#define APPLICATION_VERIFIER_ACCESS_VIOLATION 0x0002 +#define APPLICATION_VERIFIER_UNSYNCHRONIZED_ACCESS 0x0003 +#define APPLICATION_VERIFIER_EXTREME_SIZE_REQUEST 0x0004 +#define APPLICATION_VERIFIER_BAD_HEAP_HANDLE 0x0005 +#define APPLICATION_VERIFIER_SWITCHED_HEAP_HANDLE 0x0006 +#define APPLICATION_VERIFIER_DOUBLE_FREE 0x0007 +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK 0x0008 +#define APPLICATION_VERIFIER_DESTROY_PROCESS_HEAP 0x0009 +#define APPLICATION_VERIFIER_UNEXPECTED_EXCEPTION 0x000A +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_EXCEPTION_RAISED_FOR_HEADER 0x000B +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_EXCEPTION_RAISED_FOR_PROBING 0x000C +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_HEADER 0x000D +#define APPLICATION_VERIFIER_CORRUPTED_FREED_HEAP_BLOCK 0x000E +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_SUFFIX 0x000F +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_START_STAMP 0x0010 +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_END_STAMP 0x0011 +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK_PREFIX 0x0012 +#define APPLICATION_VERIFIER_FIRST_CHANCE_ACCESS_VIOLATION 0x0013 +#define APPLICATION_VERIFIER_CORRUPTED_HEAP_LIST 0x0014 + +#define APPLICATION_VERIFIER_TERMINATE_THREAD_CALL 0x0100 +#define APPLICATION_VERIFIER_STACK_OVERFLOW 0x0101 +#define APPLICATION_VERIFIER_INVALID_EXIT_PROCESS_CALL 0x0102 + +#define APPLICATION_VERIFIER_EXIT_THREAD_OWNS_LOCK 0x0200 +#define APPLICATION_VERIFIER_LOCK_IN_UNLOADED_DLL 0x0201 +#define APPLICATION_VERIFIER_LOCK_IN_FREED_HEAP 0x0202 +#define APPLICATION_VERIFIER_LOCK_DOUBLE_INITIALIZE 0x0203 +#define APPLICATION_VERIFIER_LOCK_IN_FREED_MEMORY 0x0204 +#define APPLICATION_VERIFIER_LOCK_CORRUPTED 0x0205 +#define APPLICATION_VERIFIER_LOCK_INVALID_OWNER 0x0206 +#define APPLICATION_VERIFIER_LOCK_INVALID_RECURSION_COUNT 0x0207 +#define APPLICATION_VERIFIER_LOCK_INVALID_LOCK_COUNT 0x0208 +#define APPLICATION_VERIFIER_LOCK_OVER_RELEASED 0x0209 +#define APPLICATION_VERIFIER_LOCK_NOT_INITIALIZED 0x0210 +#define APPLICATION_VERIFIER_LOCK_ALREADY_INITIALIZED 0x0211 +#define APPLICATION_VERIFIER_LOCK_IN_FREED_VMEM 0x0212 +#define APPLICATION_VERIFIER_LOCK_IN_UNMAPPED_MEM 0x0213 +#define APPLICATION_VERIFIER_THREAD_NOT_LOCK_OWNER 0x0214 + +#define APPLICATION_VERIFIER_INVALID_HANDLE 0x0300 +#define APPLICATION_VERIFIER_INVALID_TLS_VALUE 0x0301 +#define APPLICATION_VERIFIER_INCORRECT_WAIT_CALL 0x0302 +#define APPLICATION_VERIFIER_NULL_HANDLE 0x0303 +#define APPLICATION_VERIFIER_WAIT_IN_DLLMAIN 0x0304 + +#define APPLICATION_VERIFIER_COM_ERROR 0x0400 +#define APPLICATION_VERIFIER_COM_API_IN_DLLMAIN 0x0401 +#define APPLICATION_VERIFIER_COM_UNHANDLED_EXCEPTION 0x0402 +#define APPLICATION_VERIFIER_COM_UNBALANCED_COINIT 0x0403 +#define APPLICATION_VERIFIER_COM_UNBALANCED_OLEINIT 0x0404 +#define APPLICATION_VERIFIER_COM_UNBALANCED_SWC 0x0405 +#define APPLICATION_VERIFIER_COM_NULL_DACL 0x0406 +#define APPLICATION_VERIFIER_COM_UNSAFE_IMPERSONATION 0x0407 +#define APPLICATION_VERIFIER_COM_SMUGGLED_WRAPPER 0x0408 +#define APPLICATION_VERIFIER_COM_SMUGGLED_PROXY 0x0409 +#define APPLICATION_VERIFIER_COM_CF_SUCCESS_WITH_NULL 0x040A +#define APPLICATION_VERIFIER_COM_GCO_SUCCESS_WITH_NULL 0x040B +#define APPLICATION_VERIFIER_COM_OBJECT_IN_FREED_MEMORY 0x040C +#define APPLICATION_VERIFIER_COM_OBJECT_IN_UNLOADED_DLL 0x040D +#define APPLICATION_VERIFIER_COM_VTBL_IN_FREED_MEMORY 0x040E +#define APPLICATION_VERIFIER_COM_VTBL_IN_UNLOADED_DLL 0x040F +#define APPLICATION_VERIFIER_COM_HOLDING_LOCKS_ON_CALL 0x0410 + +#define APPLICATION_VERIFIER_RPC_ERROR 0x0500 + +#define APPLICATION_VERIFIER_INVALID_FREEMEM 0x0600 +#define APPLICATION_VERIFIER_INVALID_ALLOCMEM 0x0601 +#define APPLICATION_VERIFIER_INVALID_MAPVIEW 0x0602 +#define APPLICATION_VERIFIER_PROBE_INVALID_ADDRESS 0x0603 +#define APPLICATION_VERIFIER_PROBE_FREE_MEM 0x0604 +#define APPLICATION_VERIFIER_PROBE_GUARD_PAGE 0x0605 +#define APPLICATION_VERIFIER_PROBE_NULL 0x0606 +#define APPLICATION_VERIFIER_PROBE_INVALID_START_OR_SIZE 0x0607 +#define APPLICATION_VERIFIER_SIZE_HEAP_UNEXPECTED_EXCEPTION 0x0618 + +#define VERIFIER_STOP(Code,Msg,P1,S1,P2,S2,P3,S3,P4,S4) { RtlApplicationVerifierStop ((Code),(Msg),(ULONG_PTR)(P1),(S1),(ULONG_PTR)(P2),(S2),(ULONG_PTR)(P3),(S3),(ULONG_PTR)(P4),(S4)); } + + VOID NTAPI RtlApplicationVerifierStop(ULONG_PTR Code,PSTR Message,ULONG_PTR Param1,PSTR Description1,ULONG_PTR Param2,PSTR Description2,ULONG_PTR Param3,PSTR Description3,ULONG_PTR Param4,PSTR Description4); + + typedef LONG (NTAPI *PVECTORED_EXCEPTION_HANDLER)(struct _EXCEPTION_POINTERS *ExceptionInfo); +#define SEF_DACL_AUTO_INHERIT 0x01 +#define SEF_SACL_AUTO_INHERIT 0x02 +#define SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT 0x04 +#define SEF_AVOID_PRIVILEGE_CHECK 0x08 +#define SEF_AVOID_OWNER_CHECK 0x10 +#define SEF_DEFAULT_OWNER_FROM_PARENT 0x20 +#define SEF_DEFAULT_GROUP_FROM_PARENT 0x40 + + typedef enum _HEAP_INFORMATION_CLASS { + HeapCompatibilityInformation + } HEAP_INFORMATION_CLASS; + + NTSYSAPI DWORD NTAPI RtlSetHeapInformation(PVOID HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,PVOID HeapInformation,SIZE_T HeapInformationLength); + NTSYSAPI DWORD NTAPI RtlQueryHeapInformation(PVOID HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,PVOID HeapInformation,SIZE_T HeapInformationLength,PSIZE_T ReturnLength); + DWORD NTAPI RtlMultipleAllocateHeap(PVOID HeapHandle,DWORD Flags,SIZE_T Size,DWORD Count,PVOID *Array); + DWORD NTAPI RtlMultipleFreeHeap(PVOID HeapHandle,DWORD Flags,DWORD Count,PVOID *Array); + +#define WT_EXECUTEDEFAULT 0x00000000 +#define WT_EXECUTEINIOTHREAD 0x00000001 +#define WT_EXECUTEINUITHREAD 0x00000002 +#define WT_EXECUTEINWAITTHREAD 0x00000004 +#define WT_EXECUTEONLYONCE 0x00000008 +#define WT_EXECUTEINTIMERTHREAD 0x00000020 +#define WT_EXECUTELONGFUNCTION 0x00000010 +#define WT_EXECUTEINPERSISTENTIOTHREAD 0x00000040 +#define WT_EXECUTEINPERSISTENTTHREAD 0x00000080 +#define WT_TRANSFER_IMPERSONATION 0x00000100 +#define WT_SET_MAX_THREADPOOL_THREADS(Flags,Limit) ((Flags) |= (Limit)<<16) + typedef VOID (NTAPI *WAITORTIMERCALLBACKFUNC)(PVOID,BOOLEAN); + typedef VOID (NTAPI *WORKERCALLBACKFUNC)(PVOID); + typedef VOID (NTAPI *APC_CALLBACK_FUNCTION)(DWORD ,PVOID,PVOID); + typedef + VOID + (NTAPI *PFLS_CALLBACK_FUNCTION)(PVOID lpFlsData); +#define WT_EXECUTEINLONGTHREAD 0x00000010 +#define WT_EXECUTEDELETEWAIT 0x00000008 + + typedef enum _ACTIVATION_CONTEXT_INFO_CLASS { + ActivationContextBasicInformation = 1,ActivationContextDetailedInformation = 2,AssemblyDetailedInformationInActivationContext = 3,FileInformationInAssemblyOfAssemblyInActivationContext = 4,MaxActivationContextInfoClass,AssemblyDetailedInformationInActivationContxt = 3,FileInformationInAssemblyOfAssemblyInActivationContxt = 4 + } ACTIVATION_CONTEXT_INFO_CLASS; + +#define ACTIVATIONCONTEXTINFOCLASS ACTIVATION_CONTEXT_INFO_CLASS + + typedef struct _ACTIVATION_CONTEXT_QUERY_INDEX { + DWORD ulAssemblyIndex; + DWORD ulFileIndexInAssembly; + } ACTIVATION_CONTEXT_QUERY_INDEX,*PACTIVATION_CONTEXT_QUERY_INDEX; + + typedef const struct _ACTIVATION_CONTEXT_QUERY_INDEX *PCACTIVATION_CONTEXT_QUERY_INDEX; + +#define ACTIVATION_CONTEXT_PATH_TYPE_NONE (1) +#define ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE (2) +#define ACTIVATION_CONTEXT_PATH_TYPE_URL (3) +#define ACTIVATION_CONTEXT_PATH_TYPE_ASSEMBLYREF (4) + + typedef struct _ASSEMBLY_FILE_DETAILED_INFORMATION { + DWORD ulFlags; + DWORD ulFilenameLength; + DWORD ulPathLength; + + PCWSTR lpFileName; + PCWSTR lpFilePath; + } ASSEMBLY_FILE_DETAILED_INFORMATION,*PASSEMBLY_FILE_DETAILED_INFORMATION; + typedef const ASSEMBLY_FILE_DETAILED_INFORMATION *PCASSEMBLY_FILE_DETAILED_INFORMATION; + +#define _ASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION _ASSEMBLY_FILE_DETAILED_INFORMATION +#define ASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION ASSEMBLY_FILE_DETAILED_INFORMATION +#define PASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION PASSEMBLY_FILE_DETAILED_INFORMATION +#define PCASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION PCASSEMBLY_FILE_DETAILED_INFORMATION + + typedef struct _ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION { + DWORD ulFlags; + DWORD ulEncodedAssemblyIdentityLength; + DWORD ulManifestPathType; + DWORD ulManifestPathLength; + LARGE_INTEGER liManifestLastWriteTime; + DWORD ulPolicyPathType; + DWORD ulPolicyPathLength; + LARGE_INTEGER liPolicyLastWriteTime; + DWORD ulMetadataSatelliteRosterIndex; + DWORD ulManifestVersionMajor; + DWORD ulManifestVersionMinor; + DWORD ulPolicyVersionMajor; + DWORD ulPolicyVersionMinor; + DWORD ulAssemblyDirectoryNameLength; + PCWSTR lpAssemblyEncodedAssemblyIdentity; + PCWSTR lpAssemblyManifestPath; + PCWSTR lpAssemblyPolicyPath; + PCWSTR lpAssemblyDirectoryName; + DWORD ulFileCount; + } ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION,*PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION; + + typedef const struct _ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *PCACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION; + + typedef struct _ACTIVATION_CONTEXT_DETAILED_INFORMATION { + DWORD dwFlags; + DWORD ulFormatVersion; + DWORD ulAssemblyCount; + DWORD ulRootManifestPathType; + DWORD ulRootManifestPathChars; + DWORD ulRootConfigurationPathType; + DWORD ulRootConfigurationPathChars; + DWORD ulAppDirPathType; + DWORD ulAppDirPathChars; + PCWSTR lpRootManifestPath; + PCWSTR lpRootConfigurationPath; + PCWSTR lpAppDirPath; + } ACTIVATION_CONTEXT_DETAILED_INFORMATION,*PACTIVATION_CONTEXT_DETAILED_INFORMATION; + + typedef const struct _ACTIVATION_CONTEXT_DETAILED_INFORMATION *PCACTIVATION_CONTEXT_DETAILED_INFORMATION; + +#define DLL_PROCESS_ATTACH 1 +#define DLL_THREAD_ATTACH 2 +#define DLL_THREAD_DETACH 3 +#define DLL_PROCESS_DETACH 0 +#define DLL_PROCESS_VERIFIER 4 + +#define EVENTLOG_SEQUENTIAL_READ 0x0001 +#define EVENTLOG_SEEK_READ 0x0002 +#define EVENTLOG_FORWARDS_READ 0x0004 +#define EVENTLOG_BACKWARDS_READ 0x0008 + +#define EVENTLOG_SUCCESS 0x0000 +#define EVENTLOG_ERROR_TYPE 0x0001 +#define EVENTLOG_WARNING_TYPE 0x0002 +#define EVENTLOG_INFORMATION_TYPE 0x0004 +#define EVENTLOG_AUDIT_SUCCESS 0x0008 +#define EVENTLOG_AUDIT_FAILURE 0x0010 + +#define EVENTLOG_START_PAIRED_EVENT 0x0001 +#define EVENTLOG_END_PAIRED_EVENT 0x0002 +#define EVENTLOG_END_ALL_PAIRED_EVENTS 0x0004 +#define EVENTLOG_PAIRED_EVENT_ACTIVE 0x0008 +#define EVENTLOG_PAIRED_EVENT_INACTIVE 0x0010 + + typedef struct _EVENTLOGRECORD { + DWORD Length; + DWORD Reserved; + DWORD RecordNumber; + DWORD TimeGenerated; + DWORD TimeWritten; + DWORD EventID; + WORD EventType; + WORD NumStrings; + WORD EventCategory; + WORD ReservedFlags; + DWORD ClosingRecordNumber; + DWORD StringOffset; + DWORD UserSidLength; + DWORD UserSidOffset; + DWORD DataLength; + DWORD DataOffset; + } EVENTLOGRECORD,*PEVENTLOGRECORD; + +#define MAXLOGICALLOGNAMESIZE 256 + + typedef struct _EVENTSFORLOGFILE{ + DWORD ulSize; + WCHAR szLogicalLogFile[MAXLOGICALLOGNAMESIZE]; + DWORD ulNumRecords; + EVENTLOGRECORD pEventLogRecords[]; + } EVENTSFORLOGFILE,*PEVENTSFORLOGFILE; + + typedef struct _PACKEDEVENTINFO{ + DWORD ulSize; + DWORD ulNumEventsForLogFile; + DWORD ulOffsets[]; + } PACKEDEVENTINFO,*PPACKEDEVENTINFO; + +#define KEY_QUERY_VALUE (0x0001) +#define KEY_SET_VALUE (0x0002) +#define KEY_CREATE_SUB_KEY (0x0004) +#define KEY_ENUMERATE_SUB_KEYS (0x0008) +#define KEY_NOTIFY (0x0010) +#define KEY_CREATE_LINK (0x0020) +#define KEY_WOW64_32KEY (0x0200) +#define KEY_WOW64_64KEY (0x0100) +#define KEY_WOW64_RES (0x0300) + +#define KEY_READ ((STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & (~SYNCHRONIZE)) +#define KEY_WRITE ((STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE)) +#define KEY_EXECUTE ((KEY_READ) & (~SYNCHRONIZE)) +#define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK) & (~SYNCHRONIZE)) +#define REG_OPTION_RESERVED (0x00000000L) + +#define REG_OPTION_NON_VOLATILE (0x00000000L) +#define REG_OPTION_VOLATILE (0x00000001L) +#define REG_OPTION_CREATE_LINK (0x00000002L) +#define REG_OPTION_BACKUP_RESTORE (0x00000004L) +#define REG_OPTION_OPEN_LINK (0x00000008L) +#define REG_LEGAL_OPTION (REG_OPTION_RESERVED | REG_OPTION_NON_VOLATILE | REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK | REG_OPTION_BACKUP_RESTORE | REG_OPTION_OPEN_LINK) +#define REG_CREATED_NEW_KEY (0x00000001L) +#define REG_OPENED_EXISTING_KEY (0x00000002L) +#define REG_STANDARD_FORMAT 1 +#define REG_LATEST_FORMAT 2 +#define REG_NO_COMPRESSION 4 +#define REG_WHOLE_HIVE_VOLATILE (0x00000001L) +#define REG_REFRESH_HIVE (0x00000002L) +#define REG_NO_LAZY_FLUSH (0x00000004L) +#define REG_FORCE_RESTORE (0x00000008L) +#define REG_FORCE_UNLOAD 1 + +#define REG_NOTIFY_CHANGE_NAME (0x00000001L) +#define REG_NOTIFY_CHANGE_ATTRIBUTES (0x00000002L) +#define REG_NOTIFY_CHANGE_LAST_SET (0x00000004L) +#define REG_NOTIFY_CHANGE_SECURITY (0x00000008L) + +#define REG_LEGAL_CHANGE_FILTER (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY) + +#define REG_NONE (0) +#define REG_SZ (1) +#define REG_EXPAND_SZ (2) + +#define REG_BINARY (3) +#define REG_DWORD (4) +#define REG_DWORD_LITTLE_ENDIAN (4) +#define REG_DWORD_BIG_ENDIAN (5) +#define REG_LINK (6) +#define REG_MULTI_SZ (7) +#define REG_RESOURCE_LIST (8) +#define REG_FULL_RESOURCE_DESCRIPTOR (9) +#define REG_RESOURCE_REQUIREMENTS_LIST (10) +#define REG_QWORD (11) +#define REG_QWORD_LITTLE_ENDIAN (11) + +#define SERVICE_KERNEL_DRIVER 0x00000001 +#define SERVICE_FILE_SYSTEM_DRIVER 0x00000002 +#define SERVICE_ADAPTER 0x00000004 +#define SERVICE_RECOGNIZER_DRIVER 0x00000008 + +#define SERVICE_DRIVER (SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER) + +#define SERVICE_WIN32_OWN_PROCESS 0x00000010 +#define SERVICE_WIN32_SHARE_PROCESS 0x00000020 +#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS) + +#define SERVICE_INTERACTIVE_PROCESS 0x00000100 + +#define SERVICE_TYPE_ALL (SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS) + +#define SERVICE_BOOT_START 0x00000000 +#define SERVICE_SYSTEM_START 0x00000001 +#define SERVICE_AUTO_START 0x00000002 +#define SERVICE_DEMAND_START 0x00000003 +#define SERVICE_DISABLED 0x00000004 + +#define SERVICE_ERROR_IGNORE 0x00000000 +#define SERVICE_ERROR_NORMAL 0x00000001 +#define SERVICE_ERROR_SEVERE 0x00000002 +#define SERVICE_ERROR_CRITICAL 0x00000003 + + typedef enum _CM_SERVICE_NODE_TYPE { + DriverType = SERVICE_KERNEL_DRIVER,FileSystemType = SERVICE_FILE_SYSTEM_DRIVER,Win32ServiceOwnProcess = SERVICE_WIN32_OWN_PROCESS, + Win32ServiceShareProcess = SERVICE_WIN32_SHARE_PROCESS,AdapterType = SERVICE_ADAPTER,RecognizerType = SERVICE_RECOGNIZER_DRIVER + } SERVICE_NODE_TYPE; + + typedef enum _CM_SERVICE_LOAD_TYPE { + BootLoad = SERVICE_BOOT_START,SystemLoad = SERVICE_SYSTEM_START,AutoLoad = SERVICE_AUTO_START,DemandLoad = SERVICE_DEMAND_START, + DisableLoad = SERVICE_DISABLED + } SERVICE_LOAD_TYPE; + + typedef enum _CM_ERROR_CONTROL_TYPE { + IgnoreError = SERVICE_ERROR_IGNORE,NormalError = SERVICE_ERROR_NORMAL,SevereError = SERVICE_ERROR_SEVERE,CriticalError = SERVICE_ERROR_CRITICAL + } SERVICE_ERROR_TYPE; + +#define TAPE_ERASE_SHORT 0L +#define TAPE_ERASE_LONG 1L + + typedef struct _TAPE_ERASE { + DWORD Type; + BOOLEAN Immediate; + } TAPE_ERASE,*PTAPE_ERASE; + +#define TAPE_LOAD 0L +#define TAPE_UNLOAD 1L +#define TAPE_TENSION 2L +#define TAPE_LOCK 3L +#define TAPE_UNLOCK 4L +#define TAPE_FORMAT 5L + + typedef struct _TAPE_PREPARE { + DWORD Operation; + BOOLEAN Immediate; + } TAPE_PREPARE,*PTAPE_PREPARE; + +#define TAPE_SETMARKS 0L +#define TAPE_FILEMARKS 1L +#define TAPE_SHORT_FILEMARKS 2L +#define TAPE_LONG_FILEMARKS 3L + + typedef struct _TAPE_WRITE_MARKS { + DWORD Type; + DWORD Count; + BOOLEAN Immediate; + } TAPE_WRITE_MARKS,*PTAPE_WRITE_MARKS; + +#define TAPE_ABSOLUTE_POSITION 0L +#define TAPE_LOGICAL_POSITION 1L +#define TAPE_PSEUDO_LOGICAL_POSITION 2L + + typedef struct _TAPE_GET_POSITION { + DWORD Type; + DWORD Partition; + LARGE_INTEGER Offset; + } TAPE_GET_POSITION,*PTAPE_GET_POSITION; + +#define TAPE_REWIND 0L +#define TAPE_ABSOLUTE_BLOCK 1L +#define TAPE_LOGICAL_BLOCK 2L +#define TAPE_PSEUDO_LOGICAL_BLOCK 3L +#define TAPE_SPACE_END_OF_DATA 4L +#define TAPE_SPACE_RELATIVE_BLOCKS 5L +#define TAPE_SPACE_FILEMARKS 6L +#define TAPE_SPACE_SEQUENTIAL_FMKS 7L +#define TAPE_SPACE_SETMARKS 8L +#define TAPE_SPACE_SEQUENTIAL_SMKS 9L + + typedef struct _TAPE_SET_POSITION { + DWORD Method; + DWORD Partition; + LARGE_INTEGER Offset; + BOOLEAN Immediate; + } TAPE_SET_POSITION,*PTAPE_SET_POSITION; + +#define TAPE_DRIVE_FIXED 0x00000001 +#define TAPE_DRIVE_SELECT 0x00000002 +#define TAPE_DRIVE_INITIATOR 0x00000004 + +#define TAPE_DRIVE_ERASE_SHORT 0x00000010 +#define TAPE_DRIVE_ERASE_LONG 0x00000020 +#define TAPE_DRIVE_ERASE_BOP_ONLY 0x00000040 +#define TAPE_DRIVE_ERASE_IMMEDIATE 0x00000080 + +#define TAPE_DRIVE_TAPE_CAPACITY 0x00000100 +#define TAPE_DRIVE_TAPE_REMAINING 0x00000200 +#define TAPE_DRIVE_FIXED_BLOCK 0x00000400 +#define TAPE_DRIVE_VARIABLE_BLOCK 0x00000800 + +#define TAPE_DRIVE_WRITE_PROTECT 0x00001000 +#define TAPE_DRIVE_EOT_WZ_SIZE 0x00002000 + +#define TAPE_DRIVE_ECC 0x00010000 +#define TAPE_DRIVE_COMPRESSION 0x00020000 +#define TAPE_DRIVE_PADDING 0x00040000 +#define TAPE_DRIVE_REPORT_SMKS 0x00080000 + +#define TAPE_DRIVE_GET_ABSOLUTE_BLK 0x00100000 +#define TAPE_DRIVE_GET_LOGICAL_BLK 0x00200000 +#define TAPE_DRIVE_SET_EOT_WZ_SIZE 0x00400000 + +#define TAPE_DRIVE_EJECT_MEDIA 0x01000000 +#define TAPE_DRIVE_CLEAN_REQUESTS 0x02000000 +#define TAPE_DRIVE_SET_CMP_BOP_ONLY 0x04000000 + #define TAPE_DRIVE_RESERVED_BIT 0x80000000 + #define TAPE_DRIVE_LOAD_UNLOAD 0x80000001 #define TAPE_DRIVE_TENSION 0x80000002 #define TAPE_DRIVE_LOCK_UNLOCK 0x80000004 #define TAPE_DRIVE_REWIND_IMMEDIATE 0x80000008 + #define TAPE_DRIVE_SET_BLOCK_SIZE 0x80000010 #define TAPE_DRIVE_LOAD_UNLD_IMMED 0x80000020 #define TAPE_DRIVE_TENSION_IMMED 0x80000040 #define TAPE_DRIVE_LOCK_UNLK_IMMED 0x80000080 + #define TAPE_DRIVE_SET_ECC 0x80000100 #define TAPE_DRIVE_SET_COMPRESSION 0x80000200 #define TAPE_DRIVE_SET_PADDING 0x80000400 #define TAPE_DRIVE_SET_REPORT_SMKS 0x80000800 + #define TAPE_DRIVE_ABSOLUTE_BLK 0x80001000 #define TAPE_DRIVE_ABS_BLK_IMMED 0x80002000 #define TAPE_DRIVE_LOGICAL_BLK 0x80004000 #define TAPE_DRIVE_LOG_BLK_IMMED 0x80008000 + #define TAPE_DRIVE_END_OF_DATA 0x80010000 #define TAPE_DRIVE_RELATIVE_BLKS 0x80020000 #define TAPE_DRIVE_FILEMARKS 0x80040000 #define TAPE_DRIVE_SEQUENTIAL_FMKS 0x80080000 + #define TAPE_DRIVE_SETMARKS 0x80100000 #define TAPE_DRIVE_SEQUENTIAL_SMKS 0x80200000 #define TAPE_DRIVE_REVERSE_POSITION 0x80400000 #define TAPE_DRIVE_SPACE_IMMEDIATE 0x80800000 + #define TAPE_DRIVE_WRITE_SETMARKS 0x81000000 #define TAPE_DRIVE_WRITE_FILEMARKS 0x82000000 #define TAPE_DRIVE_WRITE_SHORT_FMKS 0x84000000 #define TAPE_DRIVE_WRITE_LONG_FMKS 0x88000000 + #define TAPE_DRIVE_WRITE_MARK_IMMED 0x90000000 #define TAPE_DRIVE_FORMAT 0xA0000000 #define TAPE_DRIVE_FORMAT_IMMEDIATE 0xC0000000 #define TAPE_DRIVE_HIGH_FEATURES 0x80000000 -#define TAPE_FIXED_PARTITIONS 0 -#define TAPE_INITIATOR_PARTITIONS 2 -#define TAPE_SELECT_PARTITIONS 1 -#define TAPE_FILEMARKS 1 -#define TAPE_LONG_FILEMARKS 3 -#define TAPE_SETMARKS 0 -#define TAPE_SHORT_FILEMARKS 2 -#define TAPE_ERASE_LONG 1 -#define TAPE_ERASE_SHORT 0 -#define TAPE_LOAD 0 -#define TAPE_UNLOAD 1 -#define TAPE_TENSION 2 -#define TAPE_LOCK 3 -#define TAPE_UNLOCK 4 -#define TAPE_FORMAT 5 -#define VER_PLATFORM_WIN32s 0 -#define VER_PLATFORM_WIN32_WINDOWS 1 -#define VER_PLATFORM_WIN32_NT 2 -#define VER_NT_WORKSTATION 1 -#define VER_NT_DOMAIN_CONTROLLER 2 -#define VER_NT_SERVER 3 -#define VER_SUITE_SMALLBUSINESS 1 -#define VER_SUITE_ENTERPRISE 2 -#define VER_SUITE_BACKOFFICE 4 -#define VER_SUITE_TERMINAL 16 -#define VER_SUITE_SMALLBUSINESS_RESTRICTED 32 -#define VER_SUITE_DATACENTER 128 -#define VER_SUITE_PERSONAL 512 -#define BTYPE(x) ((x)&N_BTMASK) -#define ISPTR(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)) -#define ISFCN(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_FUNCTION<<N_BTSHFT)) -#define ISARY(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_ARRAY<<N_BTSHFT)) -#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG||(x)==IMAGE_SYM_CLASS_UNION_TAG||(x)==IMAGE_SYM_CLASS_ENUM_TAG) -#define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK)) -#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) -#define TLS_MINIMUM_AVAILABLE 64 -#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) -#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer) -#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384 -#define IO_REPARSE_TAG_RESERVED_ZERO 0 -#define IO_REPARSE_TAG_RESERVED_ONE 1 -#define IO_REPARSE_TAG_RESERVED_RANGE IO_REPARSE_TAG_RESERVED_ONE -#define IsReparseTagMicrosoft(x) ((x)&0x80000000) -#define IsReparseTagHighLatency(x) ((x)&0x40000000) -#define IsReparseTagNameSurrogate(x) ((x)&0x20000000) -#define IO_REPARSE_TAG_VALID_VALUES 0xE000FFFF -#define IsReparseTagValid(x) (!((x)&~IO_REPARSE_TAG_VALID_VALUES)&&((x)>IO_REPARSE_TAG_RESERVED_RANGE)) -#define IO_REPARSE_TAG_SYMBOLIC_LINK IO_REPARSE_TAG_RESERVED_ZERO -#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003 -#ifndef RC_INVOKED -typedef DWORD ACCESS_MASK, *PACCESS_MASK; -#ifndef _GUID_DEFINED /* also defined in basetyps.h */ -#define _GUID_DEFINED -typedef struct _GUID { - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} GUID, *REFGUID, *LPGUID; -#define SYSTEM_LUID { QuadPart:999 } -#endif /* _GUID_DEFINED */ -typedef struct _GENERIC_MAPPING { - ACCESS_MASK GenericRead; - ACCESS_MASK GenericWrite; - ACCESS_MASK GenericExecute; - ACCESS_MASK GenericAll; -} GENERIC_MAPPING, *PGENERIC_MAPPING; -typedef struct _ACE_HEADER { - BYTE AceType; - BYTE AceFlags; - WORD AceSize; -} ACE_HEADER; -typedef struct _ACCESS_ALLOWED_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD SidStart; -} ACCESS_ALLOWED_ACE; -typedef struct _ACCESS_DENIED_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD SidStart; -} ACCESS_DENIED_ACE; -typedef struct _SYSTEM_AUDIT_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD SidStart; -} SYSTEM_AUDIT_ACE; -typedef SYSTEM_AUDIT_ACE *PSYSTEM_AUDIT_ACE; -typedef struct _SYSTEM_ALARM_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD SidStart; -} SYSTEM_ALARM_ACE,*PSYSTEM_ALARM_ACE; -typedef struct _ACCESS_ALLOWED_OBJECT_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD Flags; - GUID ObjectType; - GUID InheritedObjectType; - DWORD SidStart; -} ACCESS_ALLOWED_OBJECT_ACE,*PACCESS_ALLOWED_OBJECT_ACE; -typedef struct _ACCESS_DENIED_OBJECT_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD Flags; - GUID ObjectType; - GUID InheritedObjectType; - DWORD SidStart; -} ACCESS_DENIED_OBJECT_ACE,*PACCESS_DENIED_OBJECT_ACE; -typedef struct _SYSTEM_AUDIT_OBJECT_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD Flags; - GUID ObjectType; - GUID InheritedObjectType; - DWORD SidStart; -} SYSTEM_AUDIT_OBJECT_ACE,*PSYSTEM_AUDIT_OBJECT_ACE; -typedef struct _SYSTEM_ALARM_OBJECT_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD Flags; - GUID ObjectType; - GUID InheritedObjectType; - DWORD SidStart; -} SYSTEM_ALARM_OBJECT_ACE,*PSYSTEM_ALARM_OBJECT_ACE; -typedef struct _ACL { - BYTE AclRevision; - BYTE Sbz1; - WORD AclSize; - WORD AceCount; - WORD Sbz2; -} ACL,*PACL; -typedef struct _ACL_REVISION_INFORMATION { - DWORD AclRevision; -} ACL_REVISION_INFORMATION; -typedef struct _ACL_SIZE_INFORMATION { - DWORD AceCount; - DWORD AclBytesInUse; - DWORD AclBytesFree; -} ACL_SIZE_INFORMATION; - -/* FIXME: add more machines */ -#ifdef _X86_ -#define SIZE_OF_80387_REGISTERS 80 -#define CONTEXT_i386 0x10000 -#define CONTEXT_i486 0x10000 -#define CONTEXT_CONTROL (CONTEXT_i386|0x00000001L) -#define CONTEXT_INTEGER (CONTEXT_i386|0x00000002L) -#define CONTEXT_SEGMENTS (CONTEXT_i386|0x00000004L) -#define CONTEXT_FLOATING_POINT (CONTEXT_i386|0x00000008L) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386|0x00000010L) -#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386|0x00000020L) -#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS) -#define MAXIMUM_SUPPORTED_EXTENSION 512 -typedef struct _FLOATING_SAVE_AREA { - DWORD ControlWord; - DWORD StatusWord; - DWORD TagWord; - DWORD ErrorOffset; - DWORD ErrorSelector; - DWORD DataOffset; - DWORD DataSelector; - BYTE RegisterArea[80]; - DWORD Cr0NpxState; -} FLOATING_SAVE_AREA; -typedef struct _CONTEXT { - DWORD ContextFlags; - DWORD Dr0; - DWORD Dr1; - DWORD Dr2; - DWORD Dr3; - DWORD Dr6; - DWORD Dr7; - FLOATING_SAVE_AREA FloatSave; - DWORD SegGs; - DWORD SegFs; - DWORD SegEs; - DWORD SegDs; - DWORD Edi; - DWORD Esi; - DWORD Ebx; - DWORD Edx; - DWORD Ecx; - DWORD Eax; - DWORD Ebp; - DWORD Eip; - DWORD SegCs; - DWORD EFlags; - DWORD Esp; - DWORD SegSs; - BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; -} CONTEXT; -#elif defined(_PPC_) -#define CONTEXT_CONTROL 1L -#define CONTEXT_FLOATING_POINT 2L -#define CONTEXT_INTEGER 4L -#define CONTEXT_DEBUG_REGISTERS 8L -#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|CONTEXT_INTEGER) -typedef struct { - double Fpr0; - double Fpr1; - double Fpr2; - double Fpr3; - double Fpr4; - double Fpr5; - double Fpr6; - double Fpr7; - double Fpr8; - double Fpr9; - double Fpr10; - double Fpr11; - double Fpr12; - double Fpr13; - double Fpr14; - double Fpr15; - double Fpr16; - double Fpr17; - double Fpr18; - double Fpr19; - double Fpr20; - double Fpr21; - double Fpr22; - double Fpr23; - double Fpr24; - double Fpr25; - double Fpr26; - double Fpr27; - double Fpr28; - double Fpr29; - double Fpr30; - double Fpr31; - double Fpscr; - DWORD Gpr0; - DWORD Gpr1; - DWORD Gpr2; - DWORD Gpr3; - DWORD Gpr4; - DWORD Gpr5; - DWORD Gpr6; - DWORD Gpr7; - DWORD Gpr8; - DWORD Gpr9; - DWORD Gpr10; - DWORD Gpr11; - DWORD Gpr12; - DWORD Gpr13; - DWORD Gpr14; - DWORD Gpr15; - DWORD Gpr16; - DWORD Gpr17; - DWORD Gpr18; - DWORD Gpr19; - DWORD Gpr20; - DWORD Gpr21; - DWORD Gpr22; - DWORD Gpr23; - DWORD Gpr24; - DWORD Gpr25; - DWORD Gpr26; - DWORD Gpr27; - DWORD Gpr28; - DWORD Gpr29; - DWORD Gpr30; - DWORD Gpr31; - DWORD Cr; - DWORD Xer; - DWORD Msr; - DWORD Iar; - DWORD Lr; - DWORD Ctr; - DWORD ContextFlags; - DWORD Fill[3]; - DWORD Dr0; - DWORD Dr1; - DWORD Dr2; - DWORD Dr3; - DWORD Dr4; - DWORD Dr5; - DWORD Dr6; - DWORD Dr7; -} CONTEXT; -#elif defined(_ALPHA_) -#define CONTEXT_ALPHA 0x20000 -#define CONTEXT_CONTROL (CONTEXT_ALPHA|1L) -#define CONTEXT_FLOATING_POINT (CONTEXT_ALPHA|2L) -#define CONTEXT_INTEGER (CONTEXT_ALPHA|4L) -#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|CONTEXT_INTEGER) -typedef struct _CONTEXT { - ULONGLONG FltF0; - ULONGLONG FltF1; - ULONGLONG FltF2; - ULONGLONG FltF3; - ULONGLONG FltF4; - ULONGLONG FltF5; - ULONGLONG FltF6; - ULONGLONG FltF7; - ULONGLONG FltF8; - ULONGLONG FltF9; - ULONGLONG FltF10; - ULONGLONG FltF11; - ULONGLONG FltF12; - ULONGLONG FltF13; - ULONGLONG FltF14; - ULONGLONG FltF15; - ULONGLONG FltF16; - ULONGLONG FltF17; - ULONGLONG FltF18; - ULONGLONG FltF19; - ULONGLONG FltF20; - ULONGLONG FltF21; - ULONGLONG FltF22; - ULONGLONG FltF23; - ULONGLONG FltF24; - ULONGLONG FltF25; - ULONGLONG FltF26; - ULONGLONG FltF27; - ULONGLONG FltF28; - ULONGLONG FltF29; - ULONGLONG FltF30; - ULONGLONG FltF31; - ULONGLONG IntV0; - ULONGLONG IntT0; - ULONGLONG IntT1; - ULONGLONG IntT2; - ULONGLONG IntT3; - ULONGLONG IntT4; - ULONGLONG IntT5; - ULONGLONG IntT6; - ULONGLONG IntT7; - ULONGLONG IntS0; - ULONGLONG IntS1; - ULONGLONG IntS2; - ULONGLONG IntS3; - ULONGLONG IntS4; - ULONGLONG IntS5; - ULONGLONG IntFp; - ULONGLONG IntA0; - ULONGLONG IntA1; - ULONGLONG IntA2; - ULONGLONG IntA3; - ULONGLONG IntA4; - ULONGLONG IntA5; - ULONGLONG IntT8; - ULONGLONG IntT9; - ULONGLONG IntT10; - ULONGLONG IntT11; - ULONGLONG IntRa; - ULONGLONG IntT12; - ULONGLONG IntAt; - ULONGLONG IntGp; - ULONGLONG IntSp; - ULONGLONG IntZero; - ULONGLONG Fpcr; - ULONGLONG SoftFpcr; - ULONGLONG Fir; - DWORD Psr; - DWORD ContextFlags; - DWORD Fill[4]; -} CONTEXT; -#elif defined(SHx) - -/* These are the debug or break registers on the SH3 */ -typedef struct _DEBUG_REGISTERS { - ULONG BarA; - UCHAR BasrA; - UCHAR BamrA; - USHORT BbrA; - ULONG BarB; - UCHAR BasrB; - UCHAR BamrB; - USHORT BbrB; - ULONG BdrB; - ULONG BdmrB; - USHORT Brcr; - USHORT Align; -} DEBUG_REGISTERS, *PDEBUG_REGISTERS; - -/* The following flags control the contents of the CONTEXT structure. */ - -#define CONTEXT_SH3 0x00000040 -#define CONTEXT_SH4 0x000000c0 /* CONTEXT_SH3 | 0x80 - must contain the SH3 bits */ - -#ifdef SH3 -#define CONTEXT_CONTROL (CONTEXT_SH3 | 0x00000001L) -#define CONTEXT_INTEGER (CONTEXT_SH3 | 0x00000002L) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_SH3 | 0x00000008L) -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_DEBUG_REGISTERS) -#else /* SH4 */ -#define CONTEXT_CONTROL (CONTEXT_SH4 | 0x00000001L) -#define CONTEXT_INTEGER (CONTEXT_SH4 | 0x00000002L) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_SH4 | 0x00000008L) -#define CONTEXT_FLOATING_POINT (CONTEXT_SH4 | 0x00000004L) -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_DEBUG_REGISTERS | CONTEXT_FLOATING_POINT) -#endif - -/* Context Frame */ - -/* This frame is used to store a limited processor context into the */ -/* Thread structure for CPUs which have no floating point support. */ - -typedef struct _CONTEXT { - /* The flags values within this flag control the contents of */ - /* a CONTEXT record. */ - - /* If the context record is used as an input parameter, then */ - /* for each portion of the context record controlled by a flag */ - /* whose value is set, it is assumed that that portion of the */ - /* context record contains valid context. If the context record */ - /* is being used to modify a thread's context, then only that */ - /* portion of the threads context will be modified. */ - - /* If the context record is used as an IN OUT parameter to capture */ - /* the context of a thread, then only those portions of the thread's */ - /* context corresponding to set flags will be returned. */ - - /* The context record is never used as an OUT only parameter. */ - - - ULONG ContextFlags; - - /* This section is specified/returned if the ContextFlags word contains */ - /* the flag CONTEXT_INTEGER. */ - - /* N.B. The registers RA and R15 are defined in this section, but are */ - /* considered part of the control context rather than part of the integer */ - /* context. */ - - ULONG PR; - ULONG MACH; - ULONG MACL; - ULONG GBR; - ULONG R0; - ULONG R1; - ULONG R2; - ULONG R3; - ULONG R4; - ULONG R5; - ULONG R6; - ULONG R7; - ULONG R8; - ULONG R9; - ULONG R10; - ULONG R11; - ULONG R12; - ULONG R13; - ULONG R14; - ULONG R15; - - /* This section is specified/returned if the ContextFlags word contains */ - /* the flag CONTEXT_CONTROL. */ - - /* N.B. The registers r15 and ra are defined in the integer section, */ - /* but are considered part of the control context rather than part of */ - /* the integer context. */ - - ULONG Fir; - ULONG Psr; - -#if !defined(SH3e) && !defined(SH4) - ULONG OldStuff[2]; - DEBUG_REGISTERS DebugRegisters; -#else - ULONG Fpscr; - ULONG Fpul; - ULONG FRegs[16]; -#if defined(SH4) - ULONG xFRegs[16]; -#endif -#endif -} CONTEXT; - -#elif defined(MIPS) - -/* The following flags control the contents of the CONTEXT structure. */ - -#define CONTEXT_R4000 0x00010000 /* r4000 context */ - -#define CONTEXT_CONTROL (CONTEXT_R4000 | 0x00000001L) -#define CONTEXT_FLOATING_POINT (CONTEXT_R4000 | 0x00000002L) -#define CONTEXT_INTEGER (CONTEXT_R4000 | 0x00000004L) - -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) - -/* Context Frame */ - -/* N.B. This frame must be exactly a multiple of 16 bytes in length. */ - -/* This frame has a several purposes: 1) it is used as an argument to */ -/* NtContinue, 2) it is used to constuct a call frame for APC delivery, */ -/* 3) it is used to construct a call frame for exception dispatching */ -/* in user mode, and 4) it is used in the user level thread creation */ -/* routines. */ - -/* The layout of the record conforms to a standard call frame. */ - - -typedef struct _CONTEXT { - - /* This section is always present and is used as an argument build */ - /* area. */ - - DWORD Argument[4]; - - /* This section is specified/returned if the ContextFlags word contains */ - /* the flag CONTEXT_FLOATING_POINT. */ - - DWORD FltF0; - DWORD FltF1; - DWORD FltF2; - DWORD FltF3; - DWORD FltF4; - DWORD FltF5; - DWORD FltF6; - DWORD FltF7; - DWORD FltF8; - DWORD FltF9; - DWORD FltF10; - DWORD FltF11; - DWORD FltF12; - DWORD FltF13; - DWORD FltF14; - DWORD FltF15; - DWORD FltF16; - DWORD FltF17; - DWORD FltF18; - DWORD FltF19; - DWORD FltF20; - DWORD FltF21; - DWORD FltF22; - DWORD FltF23; - DWORD FltF24; - DWORD FltF25; - DWORD FltF26; - DWORD FltF27; - DWORD FltF28; - DWORD FltF29; - DWORD FltF30; - DWORD FltF31; - - /* This section is specified/returned if the ContextFlags word contains */ - /* the flag CONTEXT_INTEGER. */ - - /* N.B. The registers gp, sp, and ra are defined in this section, but are */ - /* considered part of the control context rather than part of the integer */ - /* context. */ - - /* N.B. Register zero is not stored in the frame. */ - - DWORD IntZero; - DWORD IntAt; - DWORD IntV0; - DWORD IntV1; - DWORD IntA0; - DWORD IntA1; - DWORD IntA2; - DWORD IntA3; - DWORD IntT0; - DWORD IntT1; - DWORD IntT2; - DWORD IntT3; - DWORD IntT4; - DWORD IntT5; - DWORD IntT6; - DWORD IntT7; - DWORD IntS0; - DWORD IntS1; - DWORD IntS2; - DWORD IntS3; - DWORD IntS4; - DWORD IntS5; - DWORD IntS6; - DWORD IntS7; - DWORD IntT8; - DWORD IntT9; - DWORD IntK0; - DWORD IntK1; - DWORD IntGp; - DWORD IntSp; - DWORD IntS8; - DWORD IntRa; - DWORD IntLo; - DWORD IntHi; - - /* This section is specified/returned if the ContextFlags word contains */ - /* the flag CONTEXT_FLOATING_POINT. */ - - DWORD Fsr; - - /* This section is specified/returned if the ContextFlags word contains */ - /* the flag CONTEXT_CONTROL. */ - - /* N.B. The registers gp, sp, and ra are defined in the integer section, */ - /* but are considered part of the control context rather than part of */ - /* the integer context. */ - - DWORD Fir; - DWORD Psr; - - /* The flags values within this flag control the contents of */ - /* a CONTEXT record. */ - - /* If the context record is used as an input parameter, then */ - /* for each portion of the context record controlled by a flag */ - /* whose value is set, it is assumed that that portion of the */ - /* context record contains valid context. If the context record */ - /* is being used to modify a thread's context, then only that */ - /* portion of the threads context will be modified. */ - - /* If the context record is used as an IN OUT parameter to capture */ - /* the context of a thread, then only those portions of the thread's */ - /* context corresponding to set flags will be returned. */ - - /* The context record is never used as an OUT only parameter. */ - - DWORD ContextFlags; - - DWORD Fill[2]; - -} CONTEXT; -#elif defined(ARM) - -/* The following flags control the contents of the CONTEXT structure. */ - -#define CONTEXT_ARM 0x0000040 -#define CONTEXT_CONTROL (CONTEXT_ARM | 0x00000001L) -#define CONTEXT_INTEGER (CONTEXT_ARM | 0x00000002L) - -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER) - -typedef struct _CONTEXT { - /* The flags values within this flag control the contents of - a CONTEXT record. - - If the context record is used as an input parameter, then - for each portion of the context record controlled by a flag - whose value is set, it is assumed that that portion of the - context record contains valid context. If the context record - is being used to modify a thread's context, then only that - portion of the threads context will be modified. - - If the context record is used as an IN OUT parameter to capture - the context of a thread, then only those portions of the thread's - context corresponding to set flags will be returned. - - The context record is never used as an OUT only parameter. */ - - ULONG ContextFlags; - - /* This section is specified/returned if the ContextFlags word contains - the flag CONTEXT_INTEGER. */ - ULONG R0; - ULONG R1; - ULONG R2; - ULONG R3; - ULONG R4; - ULONG R5; - ULONG R6; - ULONG R7; - ULONG R8; - ULONG R9; - ULONG R10; - ULONG R11; - ULONG R12; - - ULONG Sp; - ULONG Lr; - ULONG Pc; - ULONG Psr; -} CONTEXT; -#else -#error "undefined processor type" -#endif -typedef CONTEXT *PCONTEXT,*LPCONTEXT; -typedef struct _EXCEPTION_RECORD { - DWORD ExceptionCode; - DWORD ExceptionFlags; - struct _EXCEPTION_RECORD *ExceptionRecord; - PVOID ExceptionAddress; - DWORD NumberParameters; - DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; -} EXCEPTION_RECORD,*PEXCEPTION_RECORD; -typedef struct _EXCEPTION_POINTERS { - PEXCEPTION_RECORD ExceptionRecord; - PCONTEXT ContextRecord; -} EXCEPTION_POINTERS,*PEXCEPTION_POINTERS,*LPEXCEPTION_POINTERS; -typedef union _LARGE_INTEGER { - struct { - DWORD LowPart; - LONG HighPart; - } u; -#if ! defined(NONAMELESSUNION) || defined(__cplusplus) - _ANONYMOUS_STRUCT struct { - DWORD LowPart; - LONG HighPart; - }; -#endif /* NONAMELESSUNION */ - LONGLONG QuadPart; -} LARGE_INTEGER, *PLARGE_INTEGER; -typedef union _ULARGE_INTEGER { - struct { - DWORD LowPart; - DWORD HighPart; - } u; -#if ! defined(NONAMELESSUNION) || defined(__cplusplus) - _ANONYMOUS_STRUCT struct { - DWORD LowPart; - DWORD HighPart; - }; -#endif /* NONAMELESSUNION */ - ULONGLONG QuadPart; -} ULARGE_INTEGER, *PULARGE_INTEGER; -typedef LARGE_INTEGER LUID,*PLUID; -#pragma pack(push,4) -typedef struct _LUID_AND_ATTRIBUTES { - LUID Luid; - DWORD Attributes; -} LUID_AND_ATTRIBUTES; -#pragma pack(pop) -typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY]; -typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY; -typedef struct _PRIVILEGE_SET { - DWORD PrivilegeCount; - DWORD Control; - LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]; -} PRIVILEGE_SET,*PPRIVILEGE_SET; -typedef struct _SECURITY_ATTRIBUTES { - DWORD nLength; - LPVOID lpSecurityDescriptor; - BOOL bInheritHandle; -} SECURITY_ATTRIBUTES,*PSECURITY_ATTRIBUTES,*LPSECURITY_ATTRIBUTES; -typedef enum _SECURITY_IMPERSONATION_LEVEL { - SecurityAnonymous, - SecurityIdentification, - SecurityImpersonation, - SecurityDelegation -} SECURITY_IMPERSONATION_LEVEL; -typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,*PSECURITY_CONTEXT_TRACKING_MODE; -typedef struct _SECURITY_QUALITY_OF_SERVICE { - DWORD Length; - SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; - SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode; - BOOLEAN EffectiveOnly; -} SECURITY_QUALITY_OF_SERVICE,*PSECURITY_QUALITY_OF_SERVICE; -typedef PVOID PACCESS_TOKEN; -typedef struct _SE_IMPERSONATION_STATE { - PACCESS_TOKEN Token; - BOOLEAN CopyOnOpen; - BOOLEAN EffectiveOnly; - SECURITY_IMPERSONATION_LEVEL Level; -} SE_IMPERSONATION_STATE,*PSE_IMPERSONATION_STATE; -typedef struct _SID_IDENTIFIER_AUTHORITY { - BYTE Value[6]; -} SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY; -typedef PVOID PSID; -typedef struct _SID { - BYTE Revision; - BYTE SubAuthorityCount; - SID_IDENTIFIER_AUTHORITY IdentifierAuthority; - DWORD SubAuthority[ANYSIZE_ARRAY]; -} SID, *PISID; -typedef struct _SID_AND_ATTRIBUTES { - PSID Sid; - DWORD Attributes; -} SID_AND_ATTRIBUTES; -typedef SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY]; -typedef SID_AND_ATTRIBUTES_ARRAY *PSID_AND_ATTRIBUTES_ARRAY; -typedef struct _TOKEN_SOURCE { - CHAR SourceName[TOKEN_SOURCE_LENGTH]; - LUID SourceIdentifier; -} TOKEN_SOURCE,*PTOKEN_SOURCE; -typedef struct _TOKEN_CONTROL { - LUID TokenId; - LUID AuthenticationId; - LUID ModifiedId; - TOKEN_SOURCE TokenSource; -} TOKEN_CONTROL,*PTOKEN_CONTROL; -typedef struct _TOKEN_DEFAULT_DACL { - PACL DefaultDacl; -} TOKEN_DEFAULT_DACL,*PTOKEN_DEFAULT_DACL; -typedef struct _TOKEN_GROUPS { - DWORD GroupCount; - SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; -} TOKEN_GROUPS,*PTOKEN_GROUPS,*LPTOKEN_GROUPS; -typedef struct _TOKEN_OWNER { - PSID Owner; -} TOKEN_OWNER,*PTOKEN_OWNER; -typedef struct _TOKEN_PRIMARY_GROUP { - PSID PrimaryGroup; -} TOKEN_PRIMARY_GROUP,*PTOKEN_PRIMARY_GROUP; -typedef struct _TOKEN_PRIVILEGES { - DWORD PrivilegeCount; - LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; -} TOKEN_PRIVILEGES,*PTOKEN_PRIVILEGES,*LPTOKEN_PRIVILEGES; -typedef enum tagTOKEN_TYPE { TokenPrimary=1,TokenImpersonation }TOKEN_TYPE; -typedef struct _TOKEN_STATISTICS { - LUID TokenId; - LUID AuthenticationId; - LARGE_INTEGER ExpirationTime; - TOKEN_TYPE TokenType; - SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; - DWORD DynamicCharged; - DWORD DynamicAvailable; - DWORD GroupCount; - DWORD PrivilegeCount; - LUID ModifiedId; -} TOKEN_STATISTICS; -typedef struct _TOKEN_USER { - SID_AND_ATTRIBUTES User; -} TOKEN_USER, *PTOKEN_USER; -typedef DWORD SECURITY_INFORMATION,*PSECURITY_INFORMATION; -typedef WORD SECURITY_DESCRIPTOR_CONTROL,*PSECURITY_DESCRIPTOR_CONTROL; -typedef struct _SECURITY_DESCRIPTOR { - BYTE Revision; - BYTE Sbz1; - SECURITY_DESCRIPTOR_CONTROL Control; - PSID Owner; - PSID Group; - PACL Sacl; - PACL Dacl; -} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR; -typedef enum _TOKEN_INFORMATION_CLASS { - TokenUser=1,TokenGroups,TokenPrivileges,TokenOwner, - TokenPrimaryGroup,TokenDefaultDacl,TokenSource,TokenType, - TokenImpersonationLevel,TokenStatistics,TokenRestrictedSids, - TokenSessionId -} TOKEN_INFORMATION_CLASS; -typedef enum _SID_NAME_USE { - SidTypeUser=1,SidTypeGroup,SidTypeDomain,SidTypeAlias,SidTypeWellKnownGroup, - SidTypeDeletedAccount,SidTypeInvalid,SidTypeUnknown -} SID_NAME_USE,*PSID_NAME_USE; -typedef struct _QUOTA_LIMITS { - SIZE_T PagedPoolLimit; - SIZE_T NonPagedPoolLimit; - SIZE_T MinimumWorkingSetSize; - SIZE_T MaximumWorkingSetSize; - SIZE_T PagefileLimit; - LARGE_INTEGER TimeLimit; -} QUOTA_LIMITS,*PQUOTA_LIMITS; -typedef struct _IO_COUNTERS { - ULONGLONG ReadOperationCount; - ULONGLONG WriteOperationCount; - ULONGLONG OtherOperationCount; - ULONGLONG ReadTransferCount; - ULONGLONG WriteTransferCount; - ULONGLONG OtherTransferCount; -} IO_COUNTERS, *PIO_COUNTERS; -typedef struct _FILE_NOTIFY_INFORMATION { - DWORD NextEntryOffset; - DWORD Action; - DWORD FileNameLength; - WCHAR FileName[1]; -} FILE_NOTIFY_INFORMATION,*PFILE_NOTIFY_INFORMATION; -typedef struct _TAPE_ERASE { - DWORD Type; - BOOLEAN Immediate; -} TAPE_ERASE,*PTAPE_ERASE; -typedef struct _TAPE_GET_DRIVE_PARAMETERS { - BOOLEAN ECC; - BOOLEAN Compression; - BOOLEAN DataPadding; - BOOLEAN ReportSetmarks; - DWORD DefaultBlockSize; - DWORD MaximumBlockSize; - DWORD MinimumBlockSize; - DWORD MaximumPartitionCount; - DWORD FeaturesLow; - DWORD FeaturesHigh; - DWORD EOTWarningZoneSize; -} TAPE_GET_DRIVE_PARAMETERS,*PTAPE_GET_DRIVE_PARAMETERS; -typedef struct _TAPE_GET_MEDIA_PARAMETERS { - LARGE_INTEGER Capacity; - LARGE_INTEGER Remaining; - DWORD BlockSize; - DWORD PartitionCount; - BOOLEAN WriteProtected; -} TAPE_GET_MEDIA_PARAMETERS,*PTAPE_GET_MEDIA_PARAMETERS; -typedef struct _TAPE_GET_POSITION { - ULONG Type; - ULONG Partition; - ULONG OffsetLow; - ULONG OffsetHigh; -} TAPE_GET_POSITION,*PTAPE_GET_POSITION; -typedef struct _TAPE_PREPARE { - DWORD Operation; - BOOLEAN Immediate; -} TAPE_PREPARE,*PTAPE_PREPARE; -typedef struct _TAPE_SET_DRIVE_PARAMETERS { - BOOLEAN ECC; - BOOLEAN Compression; - BOOLEAN DataPadding; - BOOLEAN ReportSetmarks; - ULONG EOTWarningZoneSize; -} TAPE_SET_DRIVE_PARAMETERS,*PTAPE_SET_DRIVE_PARAMETERS; -typedef struct _TAPE_SET_MEDIA_PARAMETERS { - ULONG BlockSize; -} TAPE_SET_MEDIA_PARAMETERS,*PTAPE_SET_MEDIA_PARAMETERS; -typedef struct _TAPE_SET_POSITION { - DWORD Method; - DWORD Partition; - LARGE_INTEGER Offset; - BOOLEAN Immediate; -} TAPE_SET_POSITION,*PTAPE_SET_POSITION; -typedef struct _TAPE_WRITE_MARKS { - DWORD Type; - DWORD Count; - BOOLEAN Immediate; -} TAPE_WRITE_MARKS,*PTAPE_WRITE_MARKS; -typedef struct _TAPE_CREATE_PARTITION { - DWORD Method; - DWORD Count; - DWORD Size; -} TAPE_CREATE_PARTITION,*PTAPE_CREATE_PARTITION; -typedef struct _MEMORY_BASIC_INFORMATION { - PVOID BaseAddress; - PVOID AllocationBase; - DWORD AllocationProtect; - DWORD RegionSize; - DWORD State; - DWORD Protect; - DWORD Type; -} MEMORY_BASIC_INFORMATION,*PMEMORY_BASIC_INFORMATION; -typedef struct _MESSAGE_RESOURCE_ENTRY { - WORD Length; - WORD Flags; - BYTE Text[1]; -} MESSAGE_RESOURCE_ENTRY,*PMESSAGE_RESOURCE_ENTRY; -typedef struct _MESSAGE_RESOURCE_BLOCK { - DWORD LowId; - DWORD HighId; - DWORD OffsetToEntries; -} MESSAGE_RESOURCE_BLOCK,*PMESSAGE_RESOURCE_BLOCK; -typedef struct _MESSAGE_RESOURCE_DATA { - DWORD NumberOfBlocks; - MESSAGE_RESOURCE_BLOCK Blocks[1]; -} MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA; -typedef struct _LIST_ENTRY { - struct _LIST_ENTRY *Flink; - struct _LIST_ENTRY *Blink; -} LIST_ENTRY,*PLIST_ENTRY; -typedef struct _RTL_CRITICAL_SECTION_DEBUG { - WORD Type; - WORD CreatorBackTraceIndex; - struct _RTL_CRITICAL_SECTION *CriticalSection; - LIST_ENTRY ProcessLocksList; - DWORD EntryCount; - DWORD ContentionCount; - DWORD Spare[2]; -} RTL_CRITICAL_SECTION_DEBUG,*PRTL_CRITICAL_SECTION_DEBUG; -typedef struct _RTL_CRITICAL_SECTION { - PRTL_CRITICAL_SECTION_DEBUG DebugInfo; - LONG LockCount; - LONG RecursionCount; - HANDLE OwningThread; - HANDLE LockSemaphore; - DWORD Reserved; -} RTL_CRITICAL_SECTION,*PRTL_CRITICAL_SECTION; -typedef struct _EVENTLOGRECORD { - DWORD Length; - DWORD Reserved; - DWORD RecordNumber; - DWORD TimeGenerated; - DWORD TimeWritten; - DWORD EventID; - WORD EventType; - WORD NumStrings; - WORD EventCategory; - WORD ReservedFlags; - DWORD ClosingRecordNumber; - DWORD StringOffset; - DWORD UserSidLength; - DWORD UserSidOffset; - DWORD DataLength; - DWORD DataOffset; -} EVENTLOGRECORD,*PEVENTLOGRECORD; -typedef struct _OSVERSIONINFOA { - DWORD dwOSVersionInfoSize; - DWORD dwMajorVersion; - DWORD dwMinorVersion; - DWORD dwBuildNumber; - DWORD dwPlatformId; - CHAR szCSDVersion[128]; -} OSVERSIONINFOA,*POSVERSIONINFOA,*LPOSVERSIONINFOA; -typedef struct _OSVERSIONINFOW { - DWORD dwOSVersionInfoSize; - DWORD dwMajorVersion; - DWORD dwMinorVersion; - DWORD dwBuildNumber; - DWORD dwPlatformId; - WCHAR szCSDVersion[128]; -} OSVERSIONINFOW,*POSVERSIONINFOW,*LPOSVERSIONINFOW; -typedef struct _OSVERSIONINFOEXA { - DWORD dwOSVersionInfoSize; - DWORD dwMajorVersion; - DWORD dwMinorVersion; - DWORD dwBuildNumber; - DWORD dwPlatformId; - CHAR szCSDVersion[128]; - WORD wServicePackMajor; - WORD wServicePackMinor; - WORD wSuiteMask; - BYTE wProductType; - BYTE wReserved; -} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA; -typedef struct _OSVERSIONINFOEXW { - DWORD dwOSVersionInfoSize; - DWORD dwMajorVersion; - DWORD dwMinorVersion; - DWORD dwBuildNumber; - DWORD dwPlatformId; - WCHAR szCSDVersion[128]; - WORD wServicePackMajor; - WORD wServicePackMinor; - WORD wSuiteMask; - BYTE wProductType; - BYTE wReserved; -} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW; -#pragma pack(push,2) -typedef struct _IMAGE_VXD_HEADER { - WORD e32_magic; - BYTE e32_border; - BYTE e32_worder; - DWORD e32_level; - WORD e32_cpu; - WORD e32_os; - DWORD e32_ver; - DWORD e32_mflags; - DWORD e32_mpages; - DWORD e32_startobj; - DWORD e32_eip; - DWORD e32_stackobj; - DWORD e32_esp; - DWORD e32_pagesize; - DWORD e32_lastpagesize; - DWORD e32_fixupsize; - DWORD e32_fixupsum; - DWORD e32_ldrsize; - DWORD e32_ldrsum; - DWORD e32_objtab; - DWORD e32_objcnt; - DWORD e32_objmap; - DWORD e32_itermap; - DWORD e32_rsrctab; - DWORD e32_rsrccnt; - DWORD e32_restab; - DWORD e32_enttab; - DWORD e32_dirtab; - DWORD e32_dircnt; - DWORD e32_fpagetab; - DWORD e32_frectab; - DWORD e32_impmod; - DWORD e32_impmodcnt; - DWORD e32_impproc; - DWORD e32_pagesum; - DWORD e32_datapage; - DWORD e32_preload; - DWORD e32_nrestab; - DWORD e32_cbnrestab; - DWORD e32_nressum; - DWORD e32_autodata; - DWORD e32_debuginfo; - DWORD e32_debuglen; - DWORD e32_instpreload; - DWORD e32_instdemand; - DWORD e32_heapsize; - BYTE e32_res3[12]; - DWORD e32_winresoff; - DWORD e32_winreslen; - WORD e32_devid; - WORD e32_ddkver; -} IMAGE_VXD_HEADER,*PIMAGE_VXD_HEADER; -#pragma pack(pop) -#pragma pack(push,4) -typedef struct _IMAGE_FILE_HEADER { - WORD Machine; - WORD NumberOfSections; - DWORD TimeDateStamp; - DWORD PointerToSymbolTable; - DWORD NumberOfSymbols; - WORD SizeOfOptionalHeader; - WORD Characteristics; -} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; -typedef struct _IMAGE_DATA_DIRECTORY { - DWORD VirtualAddress; - DWORD Size; -} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; -typedef struct _IMAGE_OPTIONAL_HEADER { - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Reserved1; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; -typedef struct _IMAGE_ROM_OPTIONAL_HEADER { - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD BaseOfBss; - DWORD GprMask; - DWORD CprMask[4]; - DWORD GpValue; -} IMAGE_ROM_OPTIONAL_HEADER,*PIMAGE_ROM_OPTIONAL_HEADER; -#pragma pack(pop) -#pragma pack(push,2) -typedef struct _IMAGE_DOS_HEADER { - WORD e_magic; - WORD e_cblp; - WORD e_cp; - WORD e_crlc; - WORD e_cparhdr; - WORD e_minalloc; - WORD e_maxalloc; - WORD e_ss; - WORD e_sp; - WORD e_csum; - WORD e_ip; - WORD e_cs; - WORD e_lfarlc; - WORD e_ovno; - WORD e_res[4]; - WORD e_oemid; - WORD e_oeminfo; - WORD e_res2[10]; - LONG e_lfanew; -} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; -typedef struct _IMAGE_OS2_HEADER { - WORD ne_magic; - CHAR ne_ver; - CHAR ne_rev; - WORD ne_enttab; - WORD ne_cbenttab; - LONG ne_crc; - WORD ne_flags; - WORD ne_autodata; - WORD ne_heap; - WORD ne_stack; - LONG ne_csip; - LONG ne_sssp; - WORD ne_cseg; - WORD ne_cmod; - WORD ne_cbnrestab; - WORD ne_segtab; - WORD ne_rsrctab; - WORD ne_restab; - WORD ne_modtab; - WORD ne_imptab; - LONG ne_nrestab; - WORD ne_cmovent; - WORD ne_align; - WORD ne_cres; - BYTE ne_exetyp; - BYTE ne_flagsothers; - WORD ne_pretthunks; - WORD ne_psegrefbytes; - WORD ne_swaparea; - WORD ne_expver; -} IMAGE_OS2_HEADER,*PIMAGE_OS2_HEADER; -#pragma pack(pop) -#pragma pack(push,4) -typedef struct _IMAGE_NT_HEADERS { - DWORD Signature; - IMAGE_FILE_HEADER FileHeader; - IMAGE_OPTIONAL_HEADER OptionalHeader; -} IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS; -typedef struct _IMAGE_ROM_HEADERS { - IMAGE_FILE_HEADER FileHeader; - IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; -} IMAGE_ROM_HEADERS,*PIMAGE_ROM_HEADERS; -typedef struct _IMAGE_SECTION_HEADER { - BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; - union { - DWORD PhysicalAddress; - DWORD VirtualSize; - } Misc; - DWORD VirtualAddress; - DWORD SizeOfRawData; - DWORD PointerToRawData; - DWORD PointerToRelocations; - DWORD PointerToLinenumbers; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD Characteristics; -} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; -#pragma pack(pop) -#pragma pack(push,2) -typedef struct _IMAGE_SYMBOL { - union { - BYTE ShortName[8]; - struct { - DWORD Short; - DWORD Long; - } Name; - PBYTE LongName[2]; - } N; - DWORD Value; - SHORT SectionNumber; - WORD Type; - BYTE StorageClass; - BYTE NumberOfAuxSymbols; -} IMAGE_SYMBOL,*PIMAGE_SYMBOL; -typedef union _IMAGE_AUX_SYMBOL { - struct { - DWORD TagIndex; - union { - struct { - WORD Linenumber; - WORD Size; - } LnSz; - DWORD TotalSize; - } Misc; - union { - struct { - DWORD PointerToLinenumber; - DWORD PointerToNextFunction; - } Function; - struct { - WORD Dimension[4]; - } Array; - } FcnAry; - WORD TvIndex; - } Sym; - struct { - BYTE Name[IMAGE_SIZEOF_SYMBOL]; - } File; - struct { - DWORD Length; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD CheckSum; - SHORT Number; - BYTE Selection; - } Section; -} IMAGE_AUX_SYMBOL,*PIMAGE_AUX_SYMBOL; -typedef struct _IMAGE_COFF_SYMBOLS_HEADER { - DWORD NumberOfSymbols; - DWORD LvaToFirstSymbol; - DWORD NumberOfLinenumbers; - DWORD LvaToFirstLinenumber; - DWORD RvaToFirstByteOfCode; - DWORD RvaToLastByteOfCode; - DWORD RvaToFirstByteOfData; - DWORD RvaToLastByteOfData; -} IMAGE_COFF_SYMBOLS_HEADER,*PIMAGE_COFF_SYMBOLS_HEADER; -typedef struct _IMAGE_RELOCATION { - _ANONYMOUS_UNION union { - DWORD VirtualAddress; - DWORD RelocCount; - } DUMMYUNIONNAME; - DWORD SymbolTableIndex; - WORD Type; -} IMAGE_RELOCATION,*PIMAGE_RELOCATION; -#pragma pack(pop) -#pragma pack(push,4) -typedef struct _IMAGE_BASE_RELOCATION { - DWORD VirtualAddress; - DWORD SizeOfBlock; -} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; -#pragma pack(pop) -#pragma pack(push,2) -typedef struct _IMAGE_LINENUMBER { - union { - DWORD SymbolTableIndex; - DWORD VirtualAddress; - } Type; - WORD Linenumber; -} IMAGE_LINENUMBER,*PIMAGE_LINENUMBER; -#pragma pack(pop) -#pragma pack(push,4) -typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { - BYTE Name[16]; - BYTE Date[12]; - BYTE UserID[6]; - BYTE GroupID[6]; - BYTE Mode[8]; - BYTE Size[10]; - BYTE EndHeader[2]; -} IMAGE_ARCHIVE_MEMBER_HEADER,*PIMAGE_ARCHIVE_MEMBER_HEADER; -typedef struct _IMAGE_EXPORT_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - DWORD Name; - DWORD Base; - DWORD NumberOfFunctions; - DWORD NumberOfNames; - PDWORD *AddressOfFunctions; - PDWORD *AddressOfNames; - PWORD *AddressOfNameOrdinals; -} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; -typedef struct _IMAGE_IMPORT_BY_NAME { - WORD Hint; - BYTE Name[1]; -} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; -typedef struct _IMAGE_THUNK_DATA { - union { - PBYTE ForwarderString; - PDWORD Function; - DWORD Ordinal; - PIMAGE_IMPORT_BY_NAME AddressOfData; - } u1; -} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA; -typedef struct _IMAGE_IMPORT_DESCRIPTOR { - _ANONYMOUS_UNION union { - DWORD Characteristics; - PIMAGE_THUNK_DATA OriginalFirstThunk; - } DUMMYUNIONNAME; - DWORD TimeDateStamp; - DWORD ForwarderChain; - DWORD Name; - PIMAGE_THUNK_DATA FirstThunk; -} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; -typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR { - DWORD TimeDateStamp; - WORD OffsetModuleName; - WORD NumberOfModuleForwarderRefs; -} IMAGE_BOUND_IMPORT_DESCRIPTOR,*PIMAGE_BOUND_IMPORT_DESCRIPTOR; -typedef struct _IMAGE_BOUND_FORWARDER_REF { - DWORD TimeDateStamp; - WORD OffsetModuleName; - WORD Reserved; -} IMAGE_BOUND_FORWARDER_REF,*PIMAGE_BOUND_FORWARDER_REF; -typedef void(NTAPI *PIMAGE_TLS_CALLBACK)(PVOID,DWORD,PVOID); -typedef struct _IMAGE_TLS_DIRECTORY { - DWORD StartAddressOfRawData; - DWORD EndAddressOfRawData; - PDWORD AddressOfIndex; - PIMAGE_TLS_CALLBACK *AddressOfCallBacks; - DWORD SizeOfZeroFill; - DWORD Characteristics; -} IMAGE_TLS_DIRECTORY,*PIMAGE_TLS_DIRECTORY; -typedef struct _IMAGE_RESOURCE_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - WORD NumberOfNamedEntries; - WORD NumberOfIdEntries; -} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; -_ANONYMOUS_STRUCT typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { - _ANONYMOUS_UNION union { - _ANONYMOUS_STRUCT struct { - DWORD NameOffset:31; - DWORD NameIsString:1; - }DUMMYSTRUCTNAME; - DWORD Name; - WORD Id; - } DUMMYUNIONNAME; - _ANONYMOUS_UNION union { - DWORD OffsetToData; - _ANONYMOUS_STRUCT struct { - DWORD OffsetToDirectory:31; - DWORD DataIsDirectory:1; - } DUMMYSTRUCTNAME2; - } DUMMYUNIONNAME2; -} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; -typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { - WORD Length; - CHAR NameString[1]; -} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING; -typedef struct _IMAGE_RESOURCE_DIR_STRING_U { - WORD Length; - WCHAR NameString[1]; -} IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U; -typedef struct _IMAGE_RESOURCE_DATA_ENTRY { - DWORD OffsetToData; - DWORD Size; - DWORD CodePage; - DWORD Reserved; -} IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY; -typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - DWORD GlobalFlagsClear; - DWORD GlobalFlagsSet; - DWORD CriticalSectionDefaultTimeout; - DWORD DeCommitFreeBlockThreshold; - DWORD DeCommitTotalFreeThreshold; - PVOID LockPrefixTable; - DWORD MaximumAllocationSize; - DWORD VirtualMemoryThreshold; - DWORD ProcessHeapFlags; - DWORD Reserved[4]; -} IMAGE_LOAD_CONFIG_DIRECTORY,*PIMAGE_LOAD_CONFIG_DIRECTORY; -typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY { - DWORD BeginAddress; - DWORD EndAddress; - PVOID ExceptionHandler; - PVOID HandlerData; - DWORD PrologEndAddress; -} IMAGE_RUNTIME_FUNCTION_ENTRY,*PIMAGE_RUNTIME_FUNCTION_ENTRY; -typedef struct _IMAGE_DEBUG_DIRECTORY { - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - DWORD Type; - DWORD SizeOfData; - DWORD AddressOfRawData; - DWORD PointerToRawData; -} IMAGE_DEBUG_DIRECTORY,*PIMAGE_DEBUG_DIRECTORY; -typedef struct _FPO_DATA { - DWORD ulOffStart; - DWORD cbProcSize; - DWORD cdwLocals; - WORD cdwParams; - WORD cbProlog:8; - WORD cbRegs:3; - WORD fHasSEH:1; - WORD fUseBP:1; - WORD reserved:1; - WORD cbFrame:2; -} FPO_DATA,*PFPO_DATA; -typedef struct _IMAGE_DEBUG_MISC { - DWORD DataType; - DWORD Length; - BOOLEAN Unicode; - BYTE Reserved[3]; - BYTE Data[1]; -} IMAGE_DEBUG_MISC,*PIMAGE_DEBUG_MISC; -typedef struct _IMAGE_FUNCTION_ENTRY { - DWORD StartingAddress; - DWORD EndingAddress; - DWORD EndOfPrologue; -} IMAGE_FUNCTION_ENTRY,*PIMAGE_FUNCTION_ENTRY; -typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { - WORD Signature; - WORD Flags; - WORD Machine; - WORD Characteristics; - DWORD TimeDateStamp; - DWORD CheckSum; - DWORD ImageBase; - DWORD SizeOfImage; - DWORD NumberOfSections; - DWORD ExportedNamesSize; - DWORD DebugDirectorySize; - DWORD Reserved[3]; -} IMAGE_SEPARATE_DEBUG_HEADER,*PIMAGE_SEPARATE_DEBUG_HEADER; -#pragma pack(pop) -typedef enum _CM_SERVICE_NODE_TYPE { - DriverType=SERVICE_KERNEL_DRIVER, - FileSystemType=SERVICE_FILE_SYSTEM_DRIVER, - Win32ServiceOwnProcess=SERVICE_WIN32_OWN_PROCESS, - Win32ServiceShareProcess=SERVICE_WIN32_SHARE_PROCESS, - AdapterType=SERVICE_ADAPTER, - RecognizerType=SERVICE_RECOGNIZER_DRIVER -} SERVICE_NODE_TYPE; -typedef enum _CM_SERVICE_LOAD_TYPE { - BootLoad=SERVICE_BOOT_START, - SystemLoad=SERVICE_SYSTEM_START, - AutoLoad=SERVICE_AUTO_START, - DemandLoad=SERVICE_DEMAND_START, - DisableLoad=SERVICE_DISABLED -} SERVICE_LOAD_TYPE; -typedef enum _CM_ERROR_CONTROL_TYPE { - IgnoreError=SERVICE_ERROR_IGNORE, - NormalError=SERVICE_ERROR_NORMAL, - SevereError=SERVICE_ERROR_SEVERE, - CriticalError=SERVICE_ERROR_CRITICAL -} SERVICE_ERROR_TYPE; -typedef struct _NT_TIB { - struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; - PVOID StackBase; - PVOID StackLimit; - PVOID SubSystemTib; - _ANONYMOUS_UNION union { - PVOID FiberData; - DWORD Version; - } DUMMYUNIONNAME; - PVOID ArbitraryUserPointer; - struct _NT_TIB *Self; -} NT_TIB,*PNT_TIB; -typedef struct _REPARSE_DATA_BUFFER { - DWORD ReparseTag; - WORD ReparseDataLength; - WORD Reserved; - _ANONYMOUS_UNION union { - struct { - WORD SubstituteNameOffset; - WORD SubstituteNameLength; - WORD PrintNameOffset; - WORD PrintNameLength; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - WORD SubstituteNameOffset; - WORD SubstituteNameLength; - WORD PrintNameOffset; - WORD PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - BYTE DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; -typedef struct _REPARSE_GUID_DATA_BUFFER { - DWORD ReparseTag; - WORD ReparseDataLength; - WORD Reserved; - GUID ReparseGuid; - struct { - BYTE DataBuffer[1]; - } GenericReparseBuffer; -} REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER; -typedef struct _REPARSE_POINT_INFORMATION { - WORD ReparseDataLength; - WORD UnparsedNameLength; -} REPARSE_POINT_INFORMATION, *PREPARSE_POINT_INFORMATION; + typedef struct _TAPE_GET_DRIVE_PARAMETERS { + BOOLEAN ECC; + BOOLEAN Compression; + BOOLEAN DataPadding; + BOOLEAN ReportSetmarks; + DWORD DefaultBlockSize; + DWORD MaximumBlockSize; + DWORD MinimumBlockSize; + DWORD MaximumPartitionCount; + DWORD FeaturesLow; + DWORD FeaturesHigh; + DWORD EOTWarningZoneSize; + } TAPE_GET_DRIVE_PARAMETERS,*PTAPE_GET_DRIVE_PARAMETERS; -#ifdef UNICODE -typedef OSVERSIONINFOW OSVERSIONINFO,*POSVERSIONINFO,*LPOSVERSIONINFO; -typedef OSVERSIONINFOEXW OSVERSIONINFOEX,*POSVERSIONINFOEX,*LPOSVERSIONINFOEX; -#else -typedef OSVERSIONINFOA OSVERSIONINFO,*POSVERSIONINFO,*LPOSVERSIONINFO; -typedef OSVERSIONINFOEXA OSVERSIONINFOEX,*POSVERSIONINFOEX,*LPOSVERSIONINFOEX; -#endif + typedef struct _TAPE_SET_DRIVE_PARAMETERS { + BOOLEAN ECC; + BOOLEAN Compression; + BOOLEAN DataPadding; + BOOLEAN ReportSetmarks; + DWORD EOTWarningZoneSize; + } TAPE_SET_DRIVE_PARAMETERS,*PTAPE_SET_DRIVE_PARAMETERS; -#if defined(__GNUC__) + typedef struct _TAPE_GET_MEDIA_PARAMETERS { + LARGE_INTEGER Capacity; + LARGE_INTEGER Remaining; + DWORD BlockSize; + DWORD PartitionCount; + BOOLEAN WriteProtected; + } TAPE_GET_MEDIA_PARAMETERS,*PTAPE_GET_MEDIA_PARAMETERS; -PVOID GetCurrentFiber(void); -PVOID GetFiberData(void); + typedef struct _TAPE_SET_MEDIA_PARAMETERS { + DWORD BlockSize; + } TAPE_SET_MEDIA_PARAMETERS,*PTAPE_SET_MEDIA_PARAMETERS; -PVOID GetCurrentFiber(void); -extern __inline__ PVOID GetCurrentFiber(void) -{ - void* ret; - __asm__ volatile ( - "movl %%fs:0x10,%0" - : "=r" (ret) /* allow use of reg eax,ebx,ecx,edx,esi,edi */ - : - ); - return ret; -} - -PVOID GetFiberData(void); -extern __inline__ PVOID GetFiberData(void) -{ - void* ret; - __asm__ volatile ( - "movl %%fs:0x10,%0\n" - "movl (%0),%0" - : "=r" (ret) /* allow use of reg eax,ebx,ecx,edx,esi,edi */ - : - ); - return ret; -} +#define TAPE_FIXED_PARTITIONS 0L +#define TAPE_SELECT_PARTITIONS 1L +#define TAPE_INITIATOR_PARTITIONS 2L -#else + typedef struct _TAPE_CREATE_PARTITION { + DWORD Method; + DWORD Count; + DWORD Size; + } TAPE_CREATE_PARTITION,*PTAPE_CREATE_PARTITION; + +#define TAPE_QUERY_DRIVE_PARAMETERS 0L +#define TAPE_QUERY_MEDIA_CAPACITY 1L +#define TAPE_CHECK_FOR_DRIVE_PROBLEM 2L +#define TAPE_QUERY_IO_ERROR_DATA 3L +#define TAPE_QUERY_DEVICE_ERROR_DATA 4L + + typedef struct _TAPE_WMI_OPERATIONS { + DWORD Method; + DWORD DataBufferSize; + PVOID DataBuffer; + } TAPE_WMI_OPERATIONS,*PTAPE_WMI_OPERATIONS; -extern PVOID GetCurrentFiber(void); -#pragma aux GetCurrentFiber = \ - "mov eax, dword ptr fs:0x10" \ - value [eax] \ - modify [eax]; + typedef enum _TAPE_DRIVE_PROBLEM_TYPE { + TapeDriveProblemNone,TapeDriveReadWriteWarning,TapeDriveReadWriteError,TapeDriveReadWarning,TapeDriveWriteWarning,TapeDriveReadError,TapeDriveWriteError,TapeDriveHardwareError,TapeDriveUnsupportedMedia,TapeDriveScsiConnectionError,TapeDriveTimetoClean,TapeDriveCleanDriveNow,TapeDriveMediaLifeExpired,TapeDriveSnappedTape + } TAPE_DRIVE_PROBLEM_TYPE; -extern PVOID GetFiberData(void); -#pragma aux GetFiberData = \ - "mov eax, dword ptr fs:0x10" \ - "mov eax, [eax]" \ - value [eax] \ - modify [eax]; - -#endif /* __GNUC__ */ +#if defined(__x86_64) + __CRT_INLINE struct _TEB *NtCurrentTeb(VOID) { return (struct _TEB *)__readgsqword(FIELD_OFFSET(NT_TIB,Self)); } + __CRT_INLINE PVOID GetCurrentFiber(VOID) { return(PVOID)__readgsqword(FIELD_OFFSET(NT_TIB,FiberData)); } + __CRT_INLINE PVOID GetFiberData(VOID) { + return *(PVOID *)GetCurrentFiber(); + } +#endif +#if(defined(_X86_) && !defined(__x86_64)) +#define PcTeb 0x18 + __CRT_INLINE struct _TEB *NtCurrentTeb(void) { + struct _TEB *ret; + __asm__ volatile ("movl %%fs:0x18,%0" + : "=r" (ret)); + return ret; + } #endif + +#define ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION (1) +#define ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION (2) +#define ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION (3) +#define ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION (4) +#define ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION (5) +#define ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION (6) +#define ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION (7) +#define ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE (8) +#define ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES (9) +#define ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS (10) + #ifdef __cplusplus -} + } #endif #endif - diff --git a/tinyc/win32/include/winapi/winreg.h b/tinyc/win32/include/winapi/winreg.h index 21020b833..f158d2820 100644 --- a/tinyc/win32/include/winapi/winreg.h +++ b/tinyc/win32/include/winapi/winreg.h @@ -1,114 +1,129 @@ -#ifndef _WINREG_H -#define _WINREG_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINREG_ +#define _WINREG_ #ifdef __cplusplus extern "C" { #endif -#define HKEY_CLASSES_ROOT ((HKEY)0x80000000) -#define HKEY_CURRENT_USER ((HKEY)0x80000001) -#define HKEY_LOCAL_MACHINE ((HKEY)0x80000002) -#define HKEY_USERS ((HKEY)0x80000003) -#define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004) -#define HKEY_CURRENT_CONFIG ((HKEY)0x80000005) -#define HKEY_DYN_DATA ((HKEY)0x80000006) -#define REG_OPTION_VOLATILE 1 -#define REG_OPTION_NON_VOLATILE 0 -#define REG_CREATED_NEW_KEY 1 -#define REG_OPENED_EXISTING_KEY 2 -#define REG_NONE 0 -#define REG_SZ 1 -#define REG_EXPAND_SZ 2 -#define REG_BINARY 3 -#define REG_DWORD 4 -#define REG_DWORD_BIG_ENDIAN 5 -#define REG_DWORD_LITTLE_ENDIAN 4 -#define REG_LINK 6 -#define REG_MULTI_SZ 7 -#define REG_RESOURCE_LIST 8 -#define REG_FULL_RESOURCE_DESCRIPTOR 9 -#define REG_RESOURCE_REQUIREMENTS_LIST 10 -#define REG_NOTIFY_CHANGE_NAME 1 -#define REG_NOTIFY_CHANGE_ATTRIBUTES 2 -#define REG_NOTIFY_CHANGE_LAST_SET 4 -#define REG_NOTIFY_CHANGE_SECURITY 8 - -#ifndef RC_INVOKED -typedef ACCESS_MASK REGSAM; -typedef struct value_entA { - LPSTR ve_valuename; - DWORD ve_valuelen; - DWORD ve_valueptr; - DWORD ve_type; -} VALENTA,*PVALENTA; -typedef struct value_entW { - LPWSTR ve_valuename; - DWORD ve_valuelen; - DWORD ve_valueptr; - DWORD ve_type; -} VALENTW,*PVALENTW; -BOOL WINAPI AbortSystemShutdownA(LPCSTR); -BOOL WINAPI AbortSystemShutdownW(LPCWSTR); -BOOL WINAPI InitiateSystemShutdownA(LPSTR,LPSTR,DWORD,BOOL,BOOL); -BOOL WINAPI InitiateSystemShutdownW(LPWSTR,LPWSTR,DWORD,BOOL,BOOL); -LONG WINAPI RegCloseKey(HKEY); -LONG WINAPI RegConnectRegistryA(LPSTR,HKEY,PHKEY); -LONG WINAPI RegConnectRegistryW(LPWSTR,HKEY,PHKEY); -LONG WINAPI RegCreateKeyA(HKEY,LPCSTR,PHKEY); -LONG WINAPI RegCreateKeyExA(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM,LPSECURITY_ATTRIBUTES,PHKEY,PDWORD); -LONG WINAPI RegCreateKeyExW(HKEY,LPCWSTR,DWORD,LPWSTR,DWORD,REGSAM,LPSECURITY_ATTRIBUTES,PHKEY,PDWORD); -LONG WINAPI RegCreateKeyW(HKEY,LPCWSTR,PHKEY); -LONG WINAPI RegDeleteKeyA(HKEY,LPCSTR); -LONG WINAPI RegDeleteKeyW(HKEY,LPCWSTR); -LONG WINAPI RegDeleteValueA (HKEY,LPCSTR); -LONG WINAPI RegDeleteValueW(HKEY,LPCWSTR); -LONG WINAPI RegEnumKeyA (HKEY,DWORD,LPSTR,DWORD); -LONG WINAPI RegEnumKeyW(HKEY,DWORD,LPWSTR,DWORD); -LONG WINAPI RegEnumKeyExA(HKEY,DWORD,LPSTR,PDWORD,PDWORD,LPSTR,PDWORD,PFILETIME); -LONG WINAPI RegEnumKeyExW(HKEY,DWORD,LPWSTR,PDWORD,PDWORD,LPWSTR,PDWORD,PFILETIME); -LONG WINAPI RegEnumValueA(HKEY,DWORD,LPSTR,PDWORD,PDWORD,PDWORD,LPBYTE,PDWORD); -LONG WINAPI RegEnumValueW(HKEY,DWORD,LPWSTR,PDWORD,PDWORD,PDWORD,LPBYTE,PDWORD); -LONG WINAPI RegFlushKey(HKEY); -LONG WINAPI RegGetKeySecurity(HKEY,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,PDWORD); -LONG WINAPI RegLoadKeyA(HKEY,LPCSTR,LPCSTR); -LONG WINAPI RegLoadKeyW(HKEY,LPCWSTR,LPCWSTR); -LONG WINAPI RegNotifyChangeKeyValue(HKEY,BOOL,DWORD,HANDLE,BOOL); -LONG WINAPI RegOpenKeyA(HKEY,LPCSTR,PHKEY); -LONG WINAPI RegOpenKeyExA(HKEY,LPCSTR,DWORD,REGSAM,PHKEY); -LONG WINAPI RegOpenKeyExW(HKEY,LPCWSTR,DWORD,REGSAM,PHKEY); -LONG WINAPI RegOpenKeyW(HKEY,LPCWSTR,PHKEY); -LONG WINAPI RegQueryInfoKeyA(HKEY,LPSTR,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PFILETIME); -LONG WINAPI RegQueryInfoKeyW(HKEY,LPWSTR,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PFILETIME); -LONG WINAPI RegQueryMultipleValuesA(HKEY,PVALENTA,DWORD,LPSTR,PDWORD); -LONG WINAPI RegQueryMultipleValuesW(HKEY,PVALENTW,DWORD,LPWSTR,PDWORD); -LONG WINAPI RegQueryValueA(HKEY,LPCSTR,LPSTR,PLONG); -LONG WINAPI RegQueryValueExA (HKEY,LPCSTR,PDWORD,PDWORD,LPBYTE,PDWORD); -LONG WINAPI RegQueryValueExW(HKEY,LPCWSTR,PDWORD,PDWORD,LPBYTE,PDWORD); -LONG WINAPI RegQueryValueW(HKEY,LPCWSTR,LPWSTR,PLONG); -LONG WINAPI RegReplaceKeyA(HKEY,LPCSTR,LPCSTR,LPCSTR); -LONG WINAPI RegReplaceKeyW(HKEY,LPCWSTR,LPCWSTR,LPCWSTR); -LONG WINAPI RegRestoreKeyA (HKEY,LPCSTR,DWORD); -LONG WINAPI RegRestoreKeyW(HKEY,LPCWSTR,DWORD); -LONG WINAPI RegSaveKeyA(HKEY,LPCSTR,LPSECURITY_ATTRIBUTES); -LONG WINAPI RegSaveKeyW(HKEY,LPCWSTR,LPSECURITY_ATTRIBUTES); -LONG WINAPI RegSetKeySecurity(HKEY,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); -LONG WINAPI RegSetValueA(HKEY,LPCSTR,DWORD,LPCSTR,DWORD); -LONG WINAPI RegSetValueExA(HKEY,LPCSTR,DWORD,DWORD,const BYTE*,DWORD); -LONG WINAPI RegSetValueExW(HKEY,LPCWSTR,DWORD,DWORD,const BYTE*,DWORD); -LONG WINAPI RegSetValueW(HKEY,LPCWSTR,DWORD,LPCWSTR,DWORD); -LONG WINAPI RegUnLoadKeyA(HKEY,LPCSTR); -LONG WINAPI RegUnLoadKeyW(HKEY,LPCWSTR); + +#ifndef WINVER +#define WINVER 0x0502 +#endif + +#define RRF_RT_REG_NONE 0x00000001 +#define RRF_RT_REG_SZ 0x00000002 +#define RRF_RT_REG_EXPAND_SZ 0x00000004 +#define RRF_RT_REG_BINARY 0x00000008 +#define RRF_RT_REG_DWORD 0x00000010 +#define RRF_RT_REG_MULTI_SZ 0x00000020 +#define RRF_RT_REG_QWORD 0x00000040 + +#define RRF_RT_DWORD (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD) +#define RRF_RT_QWORD (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD) +#define RRF_RT_ANY 0x0000ffff + +#define RRF_NOEXPAND 0x10000000 +#define RRF_ZEROONFAILURE 0x20000000 + + typedef ACCESS_MASK REGSAM; + +#define HKEY_CLASSES_ROOT ((HKEY) (ULONG_PTR)((LONG)0x80000000)) +#define HKEY_CURRENT_USER ((HKEY) (ULONG_PTR)((LONG)0x80000001)) +#define HKEY_LOCAL_MACHINE ((HKEY) (ULONG_PTR)((LONG)0x80000002)) +#define HKEY_USERS ((HKEY) (ULONG_PTR)((LONG)0x80000003)) +#define HKEY_PERFORMANCE_DATA ((HKEY) (ULONG_PTR)((LONG)0x80000004)) +#define HKEY_PERFORMANCE_TEXT ((HKEY) (ULONG_PTR)((LONG)0x80000050)) +#define HKEY_PERFORMANCE_NLSTEXT ((HKEY) (ULONG_PTR)((LONG)0x80000060)) +#define HKEY_CURRENT_CONFIG ((HKEY) (ULONG_PTR)((LONG)0x80000005)) +#define HKEY_DYN_DATA ((HKEY) (ULONG_PTR)((LONG)0x80000006)) + +#define REG_SECURE_CONNECTION 1 + +#ifndef _PROVIDER_STRUCTS_DEFINED +#define _PROVIDER_STRUCTS_DEFINED + +#define PROVIDER_KEEPS_VALUE_LENGTH 0x1 + struct val_context { + int valuelen; + LPVOID value_context; + LPVOID val_buff_ptr; + }; + + typedef struct val_context *PVALCONTEXT; + + typedef struct pvalueA { + LPSTR pv_valuename; + int pv_valuelen; + LPVOID pv_value_context; + DWORD pv_type; + }PVALUEA,*PPVALUEA; + + typedef struct pvalueW { + LPWSTR pv_valuename; + int pv_valuelen; + LPVOID pv_value_context; + DWORD pv_type; + }PVALUEW,*PPVALUEW; + +#ifdef UNICODE + typedef PVALUEW PVALUE; + typedef PPVALUEW PPVALUE; +#else + typedef PVALUEA PVALUE; + typedef PPVALUEA PPVALUE; +#endif + + typedef DWORD __cdecl QUERYHANDLER(LPVOID keycontext,PVALCONTEXT val_list,DWORD num_vals,LPVOID outputbuffer,DWORD *total_outlen,DWORD input_blen); + + typedef QUERYHANDLER *PQUERYHANDLER; + + typedef struct provider_info { + PQUERYHANDLER pi_R0_1val; + PQUERYHANDLER pi_R0_allvals; + PQUERYHANDLER pi_R3_1val; + PQUERYHANDLER pi_R3_allvals; + DWORD pi_flags; + LPVOID pi_key_context; + } REG_PROVIDER; + + typedef struct provider_info *PPROVIDER; + + typedef struct value_entA { + LPSTR ve_valuename; + DWORD ve_valuelen; + DWORD_PTR ve_valueptr; + DWORD ve_type; + } VALENTA,*PVALENTA; + + typedef struct value_entW { + LPWSTR ve_valuename; + DWORD ve_valuelen; + DWORD_PTR ve_valueptr; + DWORD ve_type; + } VALENTW,*PVALENTW; + +#ifdef UNICODE + typedef VALENTW VALENT; + typedef PVALENTW PVALENT; +#else + typedef VALENTA VALENT; + typedef PVALENTA PVALENT; +#endif +#endif + +#define WIN31_CLASS NULL #ifdef UNICODE -typedef VALENTW VALENT,*PVALENT; -#define AbortSystemShutdown AbortSystemShutdownW -#define InitiateSystemShutdown InitiateSystemShutdownW #define RegConnectRegistry RegConnectRegistryW +#define RegConnectRegistryEx RegConnectRegistryExW #define RegCreateKey RegCreateKeyW #define RegCreateKeyEx RegCreateKeyExW #define RegDeleteKey RegDeleteKeyW +#define RegDeleteKeyEx RegDeleteKeyExW #define RegDeleteValue RegDeleteValueW #define RegEnumKey RegEnumKeyW #define RegEnumKeyEx RegEnumKeyExW @@ -117,8 +132,8 @@ typedef VALENTW VALENT,*PVALENT; #define RegOpenKey RegOpenKeyW #define RegOpenKeyEx RegOpenKeyExW #define RegQueryInfoKey RegQueryInfoKeyW -#define RegQueryMultipleValues RegQueryMultipleValuesW #define RegQueryValue RegQueryValueW +#define RegQueryMultipleValues RegQueryMultipleValuesW #define RegQueryValueEx RegQueryValueExW #define RegReplaceKey RegReplaceKeyW #define RegRestoreKey RegRestoreKeyW @@ -126,14 +141,16 @@ typedef VALENTW VALENT,*PVALENT; #define RegSetValue RegSetValueW #define RegSetValueEx RegSetValueExW #define RegUnLoadKey RegUnLoadKeyW +#define RegGetValue RegGetValueW +#define InitiateSystemShutdown InitiateSystemShutdownW +#define AbortSystemShutdown AbortSystemShutdownW #else -typedef VALENTA VALENT,*PVALENT; -#define AbortSystemShutdown AbortSystemShutdownA -#define InitiateSystemShutdown InitiateSystemShutdownA #define RegConnectRegistry RegConnectRegistryA +#define RegConnectRegistryEx RegConnectRegistryExA #define RegCreateKey RegCreateKeyA #define RegCreateKeyEx RegCreateKeyExA #define RegDeleteKey RegDeleteKeyA +#define RegDeleteKeyEx RegDeleteKeyExA #define RegDeleteValue RegDeleteValueA #define RegEnumKey RegEnumKeyA #define RegEnumKeyEx RegEnumKeyExA @@ -142,8 +159,8 @@ typedef VALENTA VALENT,*PVALENT; #define RegOpenKey RegOpenKeyA #define RegOpenKeyEx RegOpenKeyExA #define RegQueryInfoKey RegQueryInfoKeyA -#define RegQueryMultipleValues RegQueryMultipleValuesA #define RegQueryValue RegQueryValueA +#define RegQueryMultipleValues RegQueryMultipleValuesA #define RegQueryValueEx RegQueryValueExA #define RegReplaceKey RegReplaceKeyA #define RegRestoreKey RegRestoreKeyA @@ -151,8 +168,104 @@ typedef VALENTA VALENT,*PVALENT; #define RegSetValue RegSetValueA #define RegSetValueEx RegSetValueExA #define RegUnLoadKey RegUnLoadKeyA +#define RegGetValue RegGetValueA +#define InitiateSystemShutdown InitiateSystemShutdownA +#define AbortSystemShutdown AbortSystemShutdownA #endif + + WINADVAPI LONG WINAPI RegCloseKey(HKEY hKey); + WINADVAPI LONG WINAPI RegOverridePredefKey(HKEY hKey,HKEY hNewHKey); + WINADVAPI LONG WINAPI RegOpenUserClassesRoot(HANDLE hToken,DWORD dwOptions,REGSAM samDesired,PHKEY phkResult); + WINADVAPI LONG WINAPI RegOpenCurrentUser(REGSAM samDesired,PHKEY phkResult); + WINADVAPI LONG WINAPI RegDisablePredefinedCache(); + WINADVAPI LONG WINAPI RegConnectRegistryA(LPCSTR lpMachineName,HKEY hKey,PHKEY phkResult); + WINADVAPI LONG WINAPI RegConnectRegistryW(LPCWSTR lpMachineName,HKEY hKey,PHKEY phkResult); + WINADVAPI LONG WINAPI RegConnectRegistryExA(LPCSTR lpMachineName,HKEY hKey,ULONG Flags,PHKEY phkResult); + WINADVAPI LONG WINAPI RegConnectRegistryExW(LPCWSTR lpMachineName,HKEY hKey,ULONG Flags,PHKEY phkResult); + WINADVAPI LONG WINAPI RegCreateKeyA(HKEY hKey,LPCSTR lpSubKey,PHKEY phkResult); + WINADVAPI LONG WINAPI RegCreateKeyW(HKEY hKey,LPCWSTR lpSubKey,PHKEY phkResult); + WINADVAPI LONG WINAPI RegCreateKeyExA(HKEY hKey,LPCSTR lpSubKey,DWORD Reserved,LPSTR lpClass,DWORD dwOptions,REGSAM samDesired,LPSECURITY_ATTRIBUTES lpSecurityAttributes,PHKEY phkResult,LPDWORD lpdwDisposition); + WINADVAPI LONG WINAPI RegCreateKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD Reserved,LPWSTR lpClass,DWORD dwOptions,REGSAM samDesired,LPSECURITY_ATTRIBUTES lpSecurityAttributes,PHKEY phkResult,LPDWORD lpdwDisposition); + WINADVAPI LONG WINAPI RegDeleteKeyA(HKEY hKey,LPCSTR lpSubKey); + WINADVAPI LONG WINAPI RegDeleteKeyW(HKEY hKey,LPCWSTR lpSubKey); + WINADVAPI LONG WINAPI RegDeleteKeyExA(HKEY hKey,LPCSTR lpSubKey,REGSAM samDesired,DWORD Reserved); + WINADVAPI LONG WINAPI RegDeleteKeyExW(HKEY hKey,LPCWSTR lpSubKey,REGSAM samDesired,DWORD Reserved); + WINADVAPI LONG WINAPI RegDisableReflectionKey(HKEY hBase); + WINADVAPI LONG WINAPI RegEnableReflectionKey(HKEY hBase); + WINADVAPI LONG WINAPI RegQueryReflectionKey(HKEY hBase,WINBOOL *bIsReflectionDisabled); + WINADVAPI LONG WINAPI RegDeleteValueA(HKEY hKey,LPCSTR lpValueName); + WINADVAPI LONG WINAPI RegDeleteValueW(HKEY hKey,LPCWSTR lpValueName); + WINADVAPI LONG WINAPI RegEnumKeyA(HKEY hKey,DWORD dwIndex,LPSTR lpName,DWORD cchName); + WINADVAPI LONG WINAPI RegEnumKeyW(HKEY hKey,DWORD dwIndex,LPWSTR lpName,DWORD cchName); + WINADVAPI LONG WINAPI RegEnumKeyExA(HKEY hKey,DWORD dwIndex,LPSTR lpName,LPDWORD lpcchName,LPDWORD lpReserved,LPSTR lpClass,LPDWORD lpcchClass,PFILETIME lpftLastWriteTime); + WINADVAPI LONG WINAPI RegEnumKeyExW(HKEY hKey,DWORD dwIndex,LPWSTR lpName,LPDWORD lpcchName,LPDWORD lpReserved,LPWSTR lpClass,LPDWORD lpcchClass,PFILETIME lpftLastWriteTime); + WINADVAPI LONG WINAPI RegEnumValueA(HKEY hKey,DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData); + WINADVAPI LONG WINAPI RegEnumValueW(HKEY hKey,DWORD dwIndex,LPWSTR lpValueName,LPDWORD lpcchValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData); + WINADVAPI LONG WINAPI RegFlushKey(HKEY hKey); + WINADVAPI LONG WINAPI RegGetKeySecurity(HKEY hKey,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,LPDWORD lpcbSecurityDescriptor); + WINADVAPI LONG WINAPI RegLoadKeyA(HKEY hKey,LPCSTR lpSubKey,LPCSTR lpFile); + WINADVAPI LONG WINAPI RegLoadKeyW(HKEY hKey,LPCWSTR lpSubKey,LPCWSTR lpFile); + WINADVAPI LONG WINAPI RegNotifyChangeKeyValue(HKEY hKey,WINBOOL bWatchSubtree,DWORD dwNotifyFilter,HANDLE hEvent,WINBOOL fAsynchronous); + WINADVAPI LONG WINAPI RegOpenKeyA(HKEY hKey,LPCSTR lpSubKey,PHKEY phkResult); + WINADVAPI LONG WINAPI RegOpenKeyW(HKEY hKey,LPCWSTR lpSubKey,PHKEY phkResult); + WINADVAPI LONG WINAPI RegOpenKeyExA(HKEY hKey,LPCSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult); + WINADVAPI LONG WINAPI RegOpenKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult); + WINADVAPI LONG WINAPI RegQueryInfoKeyA(HKEY hKey,LPSTR lpClass,LPDWORD lpcchClass,LPDWORD lpReserved,LPDWORD lpcSubKeys,LPDWORD lpcbMaxSubKeyLen,LPDWORD lpcbMaxClassLen,LPDWORD lpcValues,LPDWORD lpcbMaxValueNameLen,LPDWORD lpcbMaxValueLen,LPDWORD lpcbSecurityDescriptor,PFILETIME lpftLastWriteTime); + WINADVAPI LONG WINAPI RegQueryInfoKeyW(HKEY hKey,LPWSTR lpClass,LPDWORD lpcchClass,LPDWORD lpReserved,LPDWORD lpcSubKeys,LPDWORD lpcbMaxSubKeyLen,LPDWORD lpcbMaxClassLen,LPDWORD lpcValues,LPDWORD lpcbMaxValueNameLen,LPDWORD lpcbMaxValueLen,LPDWORD lpcbSecurityDescriptor,PFILETIME lpftLastWriteTime); + WINADVAPI LONG WINAPI RegQueryValueA(HKEY hKey,LPCSTR lpSubKey,LPSTR lpData,PLONG lpcbData); + WINADVAPI LONG WINAPI RegQueryValueW(HKEY hKey,LPCWSTR lpSubKey,LPWSTR lpData,PLONG lpcbData); + WINADVAPI LONG WINAPI RegQueryMultipleValuesA(HKEY hKey,PVALENTA val_list,DWORD num_vals,LPSTR lpValueBuf,LPDWORD ldwTotsize); + WINADVAPI LONG WINAPI RegQueryMultipleValuesW(HKEY hKey,PVALENTW val_list,DWORD num_vals,LPWSTR lpValueBuf,LPDWORD ldwTotsize); + WINADVAPI LONG WINAPI RegQueryValueExA(HKEY hKey,LPCSTR lpValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData); + WINADVAPI LONG WINAPI RegQueryValueExW(HKEY hKey,LPCWSTR lpValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData); + WINADVAPI LONG WINAPI RegReplaceKeyA(HKEY hKey,LPCSTR lpSubKey,LPCSTR lpNewFile,LPCSTR lpOldFile); + WINADVAPI LONG WINAPI RegReplaceKeyW(HKEY hKey,LPCWSTR lpSubKey,LPCWSTR lpNewFile,LPCWSTR lpOldFile); + WINADVAPI LONG WINAPI RegRestoreKeyA(HKEY hKey,LPCSTR lpFile,DWORD dwFlags); + WINADVAPI LONG WINAPI RegRestoreKeyW(HKEY hKey,LPCWSTR lpFile,DWORD dwFlags); + WINADVAPI LONG WINAPI RegSaveKeyA(HKEY hKey,LPCSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINADVAPI LONG WINAPI RegSaveKeyW(HKEY hKey,LPCWSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes); + WINADVAPI LONG WINAPI RegSetKeySecurity(HKEY hKey,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor); + WINADVAPI LONG WINAPI RegSetValueA(HKEY hKey,LPCSTR lpSubKey,DWORD dwType,LPCSTR lpData,DWORD cbData); + WINADVAPI LONG WINAPI RegSetValueW(HKEY hKey,LPCWSTR lpSubKey,DWORD dwType,LPCWSTR lpData,DWORD cbData); + WINADVAPI LONG WINAPI RegSetValueExA(HKEY hKey,LPCSTR lpValueName,DWORD Reserved,DWORD dwType,CONST BYTE *lpData,DWORD cbData); + WINADVAPI LONG WINAPI RegSetValueExW(HKEY hKey,LPCWSTR lpValueName,DWORD Reserved,DWORD dwType,CONST BYTE *lpData,DWORD cbData); + WINADVAPI LONG WINAPI RegUnLoadKeyA(HKEY hKey,LPCSTR lpSubKey); + WINADVAPI LONG WINAPI RegUnLoadKeyW(HKEY hKey,LPCWSTR lpSubKey); + WINADVAPI LONG WINAPI RegGetValueA(HKEY hkey,LPCSTR lpSubKey,LPCSTR lpValue,DWORD dwFlags,LPDWORD pdwType,PVOID pvData,LPDWORD pcbData); + WINADVAPI LONG WINAPI RegGetValueW(HKEY hkey,LPCWSTR lpSubKey,LPCWSTR lpValue,DWORD dwFlags,LPDWORD pdwType,PVOID pvData,LPDWORD pcbData); + WINADVAPI WINBOOL WINAPI InitiateSystemShutdownA(LPSTR lpMachineName,LPSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown); + WINADVAPI WINBOOL WINAPI InitiateSystemShutdownW(LPWSTR lpMachineName,LPWSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown); + WINADVAPI WINBOOL WINAPI AbortSystemShutdownA(LPSTR lpMachineName); + WINADVAPI WINBOOL WINAPI AbortSystemShutdownW(LPWSTR lpMachineName); + +//gr #include <reason.h> + +#define REASON_SWINSTALL SHTDN_REASON_MAJOR_SOFTWARE|SHTDN_REASON_MINOR_INSTALLATION +#define REASON_HWINSTALL SHTDN_REASON_MAJOR_HARDWARE|SHTDN_REASON_MINOR_INSTALLATION +#define REASON_SERVICEHANG SHTDN_REASON_MAJOR_SOFTWARE|SHTDN_REASON_MINOR_HUNG +#define REASON_UNSTABLE SHTDN_REASON_MAJOR_SYSTEM|SHTDN_REASON_MINOR_UNSTABLE +#define REASON_SWHWRECONF SHTDN_REASON_MAJOR_SOFTWARE|SHTDN_REASON_MINOR_RECONFIG +#define REASON_OTHER SHTDN_REASON_MAJOR_OTHER|SHTDN_REASON_MINOR_OTHER +#define REASON_UNKNOWN SHTDN_REASON_UNKNOWN +#define REASON_LEGACY_API SHTDN_REASON_LEGACY_API +#define REASON_PLANNED_FLAG SHTDN_REASON_FLAG_PLANNED + +#define MAX_SHUTDOWN_TIMEOUT (10*365*24*60*60) + +#ifdef UNICODE +#define InitiateSystemShutdownEx InitiateSystemShutdownExW +#define RegSaveKeyEx RegSaveKeyExW +#else +#define InitiateSystemShutdownEx InitiateSystemShutdownExA +#define RegSaveKeyEx RegSaveKeyExA #endif + + WINADVAPI WINBOOL WINAPI InitiateSystemShutdownExA(LPSTR lpMachineName,LPSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown,DWORD dwReason); + WINADVAPI WINBOOL WINAPI InitiateSystemShutdownExW(LPWSTR lpMachineName,LPWSTR lpMessage,DWORD dwTimeout,WINBOOL bForceAppsClosed,WINBOOL bRebootAfterShutdown,DWORD dwReason); + WINADVAPI LONG WINAPI RegSaveKeyExA(HKEY hKey,LPCSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD Flags); + WINADVAPI LONG WINAPI RegSaveKeyExW(HKEY hKey,LPCWSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD Flags); + WINADVAPI LONG WINAPI Wow64Win32ApiEntry (DWORD dwFuncNumber,DWORD dwFlag,DWORD dwRes); + #ifdef __cplusplus } #endif diff --git a/tinyc/win32/include/winapi/winsvc.h b/tinyc/win32/include/winapi/winsvc.h deleted file mode 100644 index ae60d46a2..000000000 --- a/tinyc/win32/include/winapi/winsvc.h +++ /dev/null @@ -1,309 +0,0 @@ -#ifndef _WINSVC_H -#define _WINSVC_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif -#define SERVICES_ACTIVE_DATABASEA "ServicesActive" -#define SERVICES_ACTIVE_DATABASEW L"ServicesActive" -#define SERVICES_FAILED_DATABASEA "ServicesFailed" -#define SERVICES_FAILED_DATABASEW L"ServicesFailed" -#define SC_GROUP_IDENTIFIERA '+' -#define SC_GROUP_IDENTIFIERW L'+' -#define SC_MANAGER_ALL_ACCESS 0xf003f -#define SC_MANAGER_CONNECT 1 -#define SC_MANAGER_CREATE_SERVICE 2 -#define SC_MANAGER_ENUMERATE_SERVICE 4 -#define SC_MANAGER_LOCK 8 -#define SC_MANAGER_QUERY_LOCK_STATUS 16 -#define SC_MANAGER_MODIFY_BOOT_CONFIG 32 -#define SERVICE_NO_CHANGE (-1) -#define SERVICE_STOPPED 1 -#define SERVICE_START_PENDING 2 -#define SERVICE_STOP_PENDING 3 -#define SERVICE_RUNNING 4 -#define SERVICE_CONTINUE_PENDING 5 -#define SERVICE_PAUSE_PENDING 6 -#define SERVICE_PAUSED 7 -#define SERVICE_ACCEPT_STOP 1 -#define SERVICE_ACCEPT_PAUSE_CONTINUE 2 -#define SERVICE_ACCEPT_SHUTDOWN 4 -#define SERVICE_ACCEPT_PARAMCHANGE 8 -#define SERVICE_ACCEPT_NETBINDCHANGE 16 -#define SERVICE_ACCEPT_HARDWAREPROFILECHANGE 32 -#define SERVICE_ACCEPT_POWEREVENT 64 -#define SERVICE_ACCEPT_SESSIONCHANGE 128 -#define SERVICE_CONTROL_STOP 1 -#define SERVICE_CONTROL_PAUSE 2 -#define SERVICE_CONTROL_CONTINUE 3 -#define SERVICE_CONTROL_INTERROGATE 4 -#define SERVICE_CONTROL_SHUTDOWN 5 -#define SERVICE_CONTROL_PARAMCHANGE 6 -#define SERVICE_CONTROL_NETBINDADD 7 -#define SERVICE_CONTROL_NETBINDREMOVE 8 -#define SERVICE_CONTROL_NETBINDENABLE 9 -#define SERVICE_CONTROL_NETBINDDISABLE 10 -#define SERVICE_CONTROL_DEVICEEVENT 11 -#define SERVICE_CONTROL_HARDWAREPROFILECHANGE 12 -#define SERVICE_CONTROL_POWEREVENT 13 -#define SERVICE_CONTROL_SESSIONCHANGE 14 -#define SERVICE_ACTIVE 1 -#define SERVICE_INACTIVE 2 -#define SERVICE_STATE_ALL 3 -#define SERVICE_QUERY_CONFIG 1 -#define SERVICE_CHANGE_CONFIG 2 -#define SERVICE_QUERY_STATUS 4 -#define SERVICE_ENUMERATE_DEPENDENTS 8 -#define SERVICE_START 16 -#define SERVICE_STOP 32 -#define SERVICE_PAUSE_CONTINUE 64 -#define SERVICE_INTERROGATE 128 -#define SERVICE_USER_DEFINED_CONTROL 256 -#define SERVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SERVICE_QUERY_CONFIG|SERVICE_CHANGE_CONFIG|SERVICE_QUERY_STATUS|SERVICE_ENUMERATE_DEPENDENTS|SERVICE_START|SERVICE_STOP|SERVICE_PAUSE_CONTINUE|SERVICE_INTERROGATE|SERVICE_USER_DEFINED_CONTROL) -#define SERVICE_RUNS_IN_SYSTEM_PROCESS 1 -#define SERVICE_CONFIG_DESCRIPTION 1 -#define SERVICE_CONFIG_FAILURE_ACTIONS 2 - -typedef struct _SERVICE_STATUS { - DWORD dwServiceType; - DWORD dwCurrentState; - DWORD dwControlsAccepted; - DWORD dwWin32ExitCode; - DWORD dwServiceSpecificExitCode; - DWORD dwCheckPoint; - DWORD dwWaitHint; -} SERVICE_STATUS,*LPSERVICE_STATUS; -typedef struct _SERVICE_STATUS_PROCESS { - DWORD dwServiceType; - DWORD dwCurrentState; - DWORD dwControlsAccepted; - DWORD dwWin32ExitCode; - DWORD dwServiceSpecificExitCode; - DWORD dwCheckPoint; - DWORD dwWaitHint; - DWORD dwProcessId; - DWORD dwServiceFlags; -} SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS; -typedef enum _SC_STATUS_TYPE { - SC_STATUS_PROCESS_INFO = 0 -} SC_STATUS_TYPE; -typedef enum _SC_ENUM_TYPE { - SC_ENUM_PROCESS_INFO = 0 -} SC_ENUM_TYPE; -typedef struct _ENUM_SERVICE_STATUSA { - LPSTR lpServiceName; - LPSTR lpDisplayName; - SERVICE_STATUS ServiceStatus; -} ENUM_SERVICE_STATUSA,*LPENUM_SERVICE_STATUSA; -typedef struct _ENUM_SERVICE_STATUSW { - LPWSTR lpServiceName; - LPWSTR lpDisplayName; - SERVICE_STATUS ServiceStatus; -} ENUM_SERVICE_STATUSW,*LPENUM_SERVICE_STATUSW; -typedef struct _ENUM_SERVICE_STATUS_PROCESSA { - LPSTR lpServiceName; - LPSTR lpDisplayName; - SERVICE_STATUS_PROCESS ServiceStatusProcess; -} ENUM_SERVICE_STATUS_PROCESSA,*LPENUM_SERVICE_STATUS_PROCESSA; -typedef struct _ENUM_SERVICE_STATUS_PROCESSW { - LPWSTR lpServiceName; - LPWSTR lpDisplayName; - SERVICE_STATUS_PROCESS ServiceStatusProcess; -} ENUM_SERVICE_STATUS_PROCESSW,*LPENUM_SERVICE_STATUS_PROCESSW; -typedef struct _QUERY_SERVICE_CONFIGA { - DWORD dwServiceType; - DWORD dwStartType; - DWORD dwErrorControl; - LPSTR lpBinaryPathName; - LPSTR lpLoadOrderGroup; - DWORD dwTagId; - LPSTR lpDependencies; - LPSTR lpServiceStartName; - LPSTR lpDisplayName; -} QUERY_SERVICE_CONFIGA,*LPQUERY_SERVICE_CONFIGA; -typedef struct _QUERY_SERVICE_CONFIGW { - DWORD dwServiceType; - DWORD dwStartType; - DWORD dwErrorControl; - LPWSTR lpBinaryPathName; - LPWSTR lpLoadOrderGroup; - DWORD dwTagId; - LPWSTR lpDependencies; - LPWSTR lpServiceStartName; - LPWSTR lpDisplayName; -} QUERY_SERVICE_CONFIGW,*LPQUERY_SERVICE_CONFIGW; -typedef struct _QUERY_SERVICE_LOCK_STATUSA { - DWORD fIsLocked; - LPSTR lpLockOwner; - DWORD dwLockDuration; -} QUERY_SERVICE_LOCK_STATUSA,*LPQUERY_SERVICE_LOCK_STATUSA; -typedef struct _QUERY_SERVICE_LOCK_STATUSW { - DWORD fIsLocked; - LPWSTR lpLockOwner; - DWORD dwLockDuration; -} QUERY_SERVICE_LOCK_STATUSW,*LPQUERY_SERVICE_LOCK_STATUSW; -typedef void (WINAPI *LPSERVICE_MAIN_FUNCTIONA)(DWORD,LPSTR*); -typedef void (WINAPI *LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR*); -typedef struct _SERVICE_TABLE_ENTRYA { - LPSTR lpServiceName; - LPSERVICE_MAIN_FUNCTIONA lpServiceProc; -} SERVICE_TABLE_ENTRYA,*LPSERVICE_TABLE_ENTRYA; -typedef struct _SERVICE_TABLE_ENTRYW { - LPWSTR lpServiceName; - LPSERVICE_MAIN_FUNCTIONW lpServiceProc; -} SERVICE_TABLE_ENTRYW,*LPSERVICE_TABLE_ENTRYW; -DECLARE_HANDLE(SC_HANDLE); -typedef SC_HANDLE *LPSC_HANDLE; -typedef PVOID SC_LOCK; -typedef DWORD SERVICE_STATUS_HANDLE; -typedef VOID(WINAPI *LPHANDLER_FUNCTION)(DWORD); -typedef DWORD (WINAPI *LPHANDLER_FUNCTION_EX)(DWORD,DWORD,LPVOID,LPVOID); -typedef struct _SERVICE_DESCRIPTIONA { - LPSTR lpDescription; -} SERVICE_DESCRIPTIONA,*LPSERVICE_DESCRIPTIONA; -typedef struct _SERVICE_DESCRIPTIONW { - LPWSTR lpDescription; -} SERVICE_DESCRIPTIONW,*LPSERVICE_DESCRIPTIONW; -typedef enum _SC_ACTION_TYPE { - SC_ACTION_NONE = 0, - SC_ACTION_RESTART = 1, - SC_ACTION_REBOOT = 2, - SC_ACTION_RUN_COMMAND = 3 -} SC_ACTION_TYPE; -typedef struct _SC_ACTION { - SC_ACTION_TYPE Type; - DWORD Delay; -} SC_ACTION,*LPSC_ACTION; -typedef struct _SERVICE_FAILURE_ACTIONSA { - DWORD dwResetPeriod; - LPSTR lpRebootMsg; - LPSTR lpCommand; - DWORD cActions; - SC_ACTION * lpsaActions; -} SERVICE_FAILURE_ACTIONSA,*LPSERVICE_FAILURE_ACTIONSA; -typedef struct _SERVICE_FAILURE_ACTIONSW { - DWORD dwResetPeriod; - LPWSTR lpRebootMsg; - LPWSTR lpCommand; - DWORD cActions; - SC_ACTION * lpsaActions; -} SERVICE_FAILURE_ACTIONSW,*LPSERVICE_FAILURE_ACTIONSW; - -BOOL WINAPI ChangeServiceConfigA(SC_HANDLE,DWORD,DWORD,DWORD,LPCSTR,LPCSTR,LPDWORD,LPCSTR,LPCSTR,LPCSTR,LPCSTR); -BOOL WINAPI ChangeServiceConfigW(SC_HANDLE,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,LPDWORD,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR); -BOOL WINAPI ChangeServiceConfig2A(SC_HANDLE,DWORD,LPVOID); -BOOL WINAPI ChangeServiceConfig2W(SC_HANDLE,DWORD,LPVOID); -BOOL WINAPI CloseServiceHandle(SC_HANDLE); -BOOL WINAPI ControlService(SC_HANDLE,DWORD,LPSERVICE_STATUS); -SC_HANDLE WINAPI CreateServiceA(SC_HANDLE,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,DWORD,LPCSTR,LPCSTR,PDWORD,LPCSTR,LPCSTR,LPCSTR); -SC_HANDLE WINAPI CreateServiceW(SC_HANDLE,LPCWSTR,LPCWSTR,DWORD,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,PDWORD,LPCWSTR,LPCWSTR,LPCWSTR); -BOOL WINAPI DeleteService(SC_HANDLE); -BOOL WINAPI EnumDependentServicesA(SC_HANDLE,DWORD,LPENUM_SERVICE_STATUSA,DWORD,PDWORD,PDWORD); -BOOL WINAPI EnumDependentServicesW(SC_HANDLE,DWORD,LPENUM_SERVICE_STATUSW,DWORD,PDWORD,PDWORD); -BOOL WINAPI EnumServicesStatusA(SC_HANDLE,DWORD,DWORD,LPENUM_SERVICE_STATUSA,DWORD,PDWORD,PDWORD,PDWORD); -BOOL WINAPI EnumServicesStatusW(SC_HANDLE,DWORD,DWORD,LPENUM_SERVICE_STATUSW,DWORD,PDWORD,PDWORD,PDWORD); -BOOL WINAPI EnumServicesStatusExA(SC_HANDLE,SC_ENUM_TYPE,DWORD,DWORD,LPBYTE,DWORD,LPDWORD,LPDWORD,LPDWORD,LPCSTR); -BOOL WINAPI EnumServicesStatusExW(SC_HANDLE,SC_ENUM_TYPE,DWORD,DWORD,LPBYTE,DWORD,LPDWORD,LPDWORD,LPDWORD,LPCWSTR); -BOOL WINAPI GetServiceDisplayNameA(SC_HANDLE,LPCSTR,LPSTR,PDWORD); -BOOL WINAPI GetServiceDisplayNameW(SC_HANDLE,LPCWSTR,LPWSTR,PDWORD); -BOOL WINAPI GetServiceKeyNameA(SC_HANDLE,LPCSTR,LPSTR,PDWORD); -BOOL WINAPI GetServiceKeyNameW(SC_HANDLE,LPCWSTR,LPWSTR,PDWORD); -SC_LOCK WINAPI LockServiceDatabase(SC_HANDLE); -BOOL WINAPI NotifyBootConfigStatus(BOOL); -SC_HANDLE WINAPI OpenSCManagerA(LPCSTR,LPCSTR,DWORD); -SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR,LPCWSTR,DWORD); -SC_HANDLE WINAPI OpenServiceA(SC_HANDLE,LPCSTR,DWORD); -SC_HANDLE WINAPI OpenServiceW(SC_HANDLE,LPCWSTR,DWORD); -BOOL WINAPI QueryServiceConfigA(SC_HANDLE,LPQUERY_SERVICE_CONFIGA,DWORD,PDWORD); -BOOL WINAPI QueryServiceConfigW(SC_HANDLE,LPQUERY_SERVICE_CONFIGW,DWORD,PDWORD); -BOOL WINAPI QueryServiceConfig2A(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD); -BOOL WINAPI QueryServiceConfig2W(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD); -BOOL WINAPI QueryServiceLockStatusA(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSA,DWORD,PDWORD); -BOOL WINAPI QueryServiceLockStatusW(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSW,DWORD,PDWORD); -BOOL WINAPI QueryServiceObjectSecurity(SC_HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD); -BOOL WINAPI QueryServiceStatus(SC_HANDLE,LPSERVICE_STATUS); -BOOL WINAPI QueryServiceStatusEx(SC_HANDLE,SC_STATUS_TYPE,LPBYTE,DWORD,LPDWORD); -SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerA(LPCSTR,LPHANDLER_FUNCTION); -SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerW(LPCWSTR,LPHANDLER_FUNCTION); -SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExA(LPCSTR,LPHANDLER_FUNCTION_EX,LPVOID); -SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW(LPCWSTR,LPHANDLER_FUNCTION_EX,LPVOID); -BOOL WINAPI SetServiceObjectSecurity(SC_HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); -BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS); -BOOL WINAPI StartServiceA(SC_HANDLE,DWORD,LPCSTR*); -BOOL WINAPI StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA); -BOOL WINAPI StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW); -BOOL WINAPI StartServiceW(SC_HANDLE,DWORD,LPCWSTR); -BOOL WINAPI UnlockServiceDatabase(SC_LOCK); - -#ifdef UNICODE -typedef ENUM_SERVICE_STATUSW ENUM_SERVICE_STATUS,*LPENUM_SERVICE_STATUS; -typedef ENUM_SERVICE_STATUS_PROCESSW ENUM_SERVICE_STATUS_PROCESS; -typedef LPENUM_SERVICE_STATUS_PROCESSW LPENUM_SERVICE_STATUS_PROCESS; -typedef QUERY_SERVICE_CONFIGW QUERY_SERVICE_CONFIG,*LPQUERY_SERVICE_CONFIG; -typedef QUERY_SERVICE_LOCK_STATUSW QUERY_SERVICE_LOCK_STATUS,*LPQUERY_SERVICE_LOCK_STATUS; -typedef SERVICE_TABLE_ENTRYW SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY; -typedef LPSERVICE_MAIN_FUNCTIONW LPSERVICE_MAIN_FUNCTION; -typedef SERVICE_DESCRIPTIONW SERVICE_DESCRIPTION; -typedef LPSERVICE_DESCRIPTIONW LPSERVICE_DESCRIPTION; -typedef SERVICE_FAILURE_ACTIONSW SERVICE_FAILURE_ACTIONS; -typedef LPSERVICE_FAILURE_ACTIONSW LPSERVICE_FAILURE_ACTIONS; -#define SERVICES_ACTIVE_DATABASE SERVICES_ACTIVE_DATABASEW -#define SERVICES_FAILED_DATABASE SERVICES_FAILED_DATABASEW -#define SC_GROUP_IDENTIFIER SC_GROUP_IDENTIFIERW -#define ChangeServiceConfig ChangeServiceConfigW -#define ChangeServiceConfig2 ChangeServiceConfig2W -#define CreateService CreateServiceW -#define EnumDependentServices EnumDependentServicesW -#define EnumServicesStatus EnumServicesStatusW -#define EnumServicesStatusEx EnumServicesStatusExW -#define GetServiceDisplayName GetServiceDisplayNameW -#define GetServiceKeyName GetServiceKeyNameW -#define OpenSCManager OpenSCManagerW -#define OpenService OpenServiceW -#define QueryServiceConfig QueryServiceConfigW -#define QueryServiceConfig2 QueryServiceConfig2W -#define QueryServiceLockStatus QueryServiceLockStatusW -#define RegisterServiceCtrlHandler RegisterServiceCtrlHandlerW -#define RegisterServiceCtrlHandlerEx RegisterServiceCtrlHandlerExW -#define StartService StartServiceW -#define StartServiceCtrlDispatcher StartServiceCtrlDispatcherW -#else -typedef ENUM_SERVICE_STATUSA ENUM_SERVICE_STATUS,*LPENUM_SERVICE_STATUS; -typedef ENUM_SERVICE_STATUS_PROCESSA ENUM_SERVICE_STATUS_PROCESS; -typedef LPENUM_SERVICE_STATUS_PROCESSA LPENUM_SERVICE_STATUS_PROCESS; -typedef QUERY_SERVICE_CONFIGA QUERY_SERVICE_CONFIG,*LPQUERY_SERVICE_CONFIG; -typedef QUERY_SERVICE_LOCK_STATUSA QUERY_SERVICE_LOCK_STATUS,*LPQUERY_SERVICE_LOCK_STATUS; -typedef SERVICE_TABLE_ENTRYA SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY; -typedef LPSERVICE_MAIN_FUNCTIONA LPSERVICE_MAIN_FUNCTION; -typedef SERVICE_DESCRIPTIONA SERVICE_DESCRIPTION; -typedef LPSERVICE_DESCRIPTIONA LPSERVICE_DESCRIPTION; -typedef SERVICE_FAILURE_ACTIONSA SERVICE_FAILURE_ACTIONS; -typedef LPSERVICE_FAILURE_ACTIONSA LPSERVICE_FAILURE_ACTIONS; -#define SERVICES_ACTIVE_DATABASE SERVICES_ACTIVE_DATABASEA -#define SERVICES_FAILED_DATABASE SERVICES_FAILED_DATABASEA -#define SC_GROUP_IDENTIFIER SC_GROUP_IDENTIFIERA -#define ChangeServiceConfig ChangeServiceConfigA -#define ChangeServiceConfig2 ChangeServiceConfig2A -#define CreateService CreateServiceA -#define EnumDependentServices EnumDependentServicesA -#define EnumServicesStatus EnumServicesStatusA -#define EnumServicesStatusEx EnumServicesStatusExA -#define GetServiceDisplayName GetServiceDisplayNameA -#define GetServiceKeyName GetServiceKeyNameA -#define OpenSCManager OpenSCManagerA -#define OpenService OpenServiceA -#define QueryServiceConfig QueryServiceConfigA -#define QueryServiceConfig2 QueryServiceConfig2A -#define QueryServiceLockStatus QueryServiceLockStatusA -#define RegisterServiceCtrlHandler RegisterServiceCtrlHandlerA -#define RegisterServiceCtrlHandlerEx RegisterServiceCtrlHandlerExA -#define StartService StartServiceA -#define StartServiceCtrlDispatcher StartServiceCtrlDispatcherA -#endif -#ifdef __cplusplus -} -#endif -#endif /* _WINSVC_H */ diff --git a/tinyc/win32/include/winapi/winuser.h b/tinyc/win32/include/winapi/winuser.h index 8929c6be6..4cd9ffb56 100644 --- a/tinyc/win32/include/winapi/winuser.h +++ b/tinyc/win32/include/winapi/winuser.h @@ -1,529 +1,104 @@ -#ifndef _WINUSER_H -#define _WINUSER_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef _WINUSER_ +#define _WINUSER_ + +#define WINUSERAPI DECLSPEC_IMPORT #ifdef __cplusplus extern "C" { #endif -#define WC_DIALOG MAKEINTATOM(0x8002) -#define FALT 16 -#define FCONTROL 8 -#define FNOINVERT 2 -#define FSHIFT 4 -#define FVIRTKEY 1 -#define ATF_TIMEOUTON 1 -#define ATF_ONOFFFEEDBACK 2 -#define ATF_AVAILABLE 4 /* May be obsolete. Not in recent MS docs. */ -#define WH_MIN (-1) -#define WH_MSGFILTER (-1) -#define WH_JOURNALRECORD 0 -#define WH_JOURNALPLAYBACK 1 -#define WH_KEYBOARD 2 -#define WH_GETMESSAGE 3 -#define WH_CALLWNDPROC 4 -#define WH_CBT 5 -#define WH_SYSMSGFILTER 6 -#define WH_MOUSE 7 -#define WH_HARDWARE 8 -#define WH_DEBUG 9 -#define WH_SHELL 10 -#define WH_FOREGROUNDIDLE 11 -#define WH_CALLWNDPROCRET 12 -#define WH_KEYBOARD_LL 13 -#define WH_MOUSE_LL 14 -#define WH_MAX 14 -#define WH_MINHOOK WH_MIN -#define WH_MAXHOOK WH_MAX -#define HC_ACTION 0 -#define HC_GETNEXT 1 -#define HC_SKIP 2 -#define HC_NOREMOVE 3 -#define HC_NOREM 3 -#define HC_SYSMODALON 4 -#define HC_SYSMODALOFF 5 -#define HCBT_MOVESIZE 0 -#define HCBT_MINMAX 1 -#define HCBT_QS 2 -#define HCBT_CREATEWND 3 -#define HCBT_DESTROYWND 4 -#define HCBT_ACTIVATE 5 -#define HCBT_CLICKSKIPPED 6 -#define HCBT_KEYSKIPPED 7 -#define HCBT_SYSCOMMAND 8 -#define HCBT_SETFOCUS 9 -#define CF_TEXT 1 -#define CF_BITMAP 2 -#define CF_METAFILEPICT 3 -#define CF_SYLK 4 -#define CF_DIF 5 -#define CF_TIFF 6 -#define CF_OEMTEXT 7 -#define CF_DIB 8 -#define CF_PALETTE 9 -#define CF_PENDATA 10 -#define CF_RIFF 11 -#define CF_WAVE 12 -#define CF_UNICODETEXT 13 -#define CF_ENHMETAFILE 14 -#define CF_HDROP 15 -#define CF_LOCALE 16 -#define CF_MAX 17 -#define CF_OWNERDISPLAY 128 -#define CF_DSPTEXT 129 -#define CF_DSPBITMAP 130 -#define CF_DSPMETAFILEPICT 131 -#define CF_DSPENHMETAFILE 142 -#define CF_PRIVATEFIRST 512 -#define CF_PRIVATELAST 767 -#define CF_GDIOBJFIRST 768 -#define CF_GDIOBJLAST 1023 -#define HKL_NEXT 1 -#define HKL_PREV 0 -#define KLF_ACTIVATE 1 -#define KLF_SUBSTITUTE_OK 2 -#define KLF_UNLOADPREVIOUS 4 -#define KLF_REORDER 8 -#define KLF_REPLACELANG 16 -#define KLF_NOTELLSHELL 128 -#define KLF_SETFORPROCESS 256 -#define KL_NAMELENGTH 9 -#define MF_ENABLED 0 -#define MF_GRAYED 1 -#define MF_DISABLED 2 -#define MF_BITMAP 4 -#define MF_CHECKED 8 -#define MF_MENUBARBREAK 32 -#define MF_MENUBREAK 64 -#define MF_OWNERDRAW 256 -#define MF_POPUP 16 -#define MF_SEPARATOR 0x800 -#define MF_STRING 0 -#define MF_UNCHECKED 0 -#define MF_DEFAULT 4096 -#define MF_SYSMENU 0x2000 -#define MF_HELP 0x4000 -#define MF_END 128 -#define MF_RIGHTJUSTIFY 0x4000 -#define MF_MOUSESELECT 0x8000 -#define MF_INSERT 0 -#define MF_CHANGE 128 -#define MF_APPEND 256 -#define MF_DELETE 512 -#define MF_REMOVE 4096 -#define MF_USECHECKBITMAPS 512 -#define MF_UNHILITE 0 -#define MF_HILITE 128 -#define BSF_IGNORECURRENTTASK 2 -#define BSF_QUERY 1 -#define BSF_FLUSHDISK 4 -#define BSF_NOHANG 8 -#define BSF_POSTMESSAGE 16 -#define BSF_FORCEIFHUNG 32 -#define BSF_NOTIMEOUTIFNOTHUNG 64 -#define BSM_ALLCOMPONENTS 0 -#define BSM_APPLICATIONS 8 -#define BSM_ALLDESKTOPS 16 -#define BSM_INSTALLABLEDRIVERS 4 -#define BSM_NETDRIVER 2 -#define BSM_VXDS 1 -#define BROADCAST_QUERY_DENY 1112363332 -#define ENUM_CURRENT_SETTINGS ((DWORD)-1) -#define ENUM_REGISTRY_SETTINGS ((DWORD)-2) -#define DM_BITSPERPEL 0x40000 -#define DM_PELSWIDTH 0x80000 -#define DM_PELSHEIGHT 0x100000 -#define DM_DISPLAYFLAGS 0x200000 -#define DM_DISPLAYFREQUENCY 0x400000 -#define CDS_UPDATEREGISTRY 1 -#define CDS_TEST 2 -#define CDS_FULLSCREEN 4 -#define CDS_GLOBAL 8 -#define CDS_SET_PRIMARY 16 -#define CDS_RESET 0x40000000 -#define CDS_SETRECT 0x20000000 -#define CDS_NORESET 0x10000000 -#define DISP_CHANGE_SUCCESSFUL 0 -#define DISP_CHANGE_RESTART 1 -#define DISP_CHANGE_BADFLAGS (-4) -#define DISP_CHANGE_BADPARAM (-5) -#define DISP_CHANGE_FAILED (-1) -#define DISP_CHANGE_BADMODE (-2) -#define DISP_CHANGE_NOTUPDATED (-3) -#define BST_CHECKED 1 -#define BST_INDETERMINATE 2 -#define BST_UNCHECKED 0 -#define BST_FOCUS 8 -#define BST_PUSHED 4 -#define MF_BYCOMMAND 0 -#define MF_BYPOSITION 1024 -#define MF_UNCHECKED 0 -#define MF_HILITE 128 -#define MF_UNHILITE 0 -#define CWP_ALL 0 -#define CWP_SKIPINVISIBLE 1 -#define CWP_SKIPDISABLED 2 -#define CWP_SKIPTRANSPARENT 4 -#define IMAGE_BITMAP 0 -#define IMAGE_ICON 1 -#define IMAGE_CURSOR 2 -#define IMAGE_ENHMETAFILE 3 -#define DF_ALLOWOTHERACCOUNTHOOK 1 -#define DESKTOP_CREATEMENU 4 -#define DESKTOP_CREATEWINDOW 2 -#define DESKTOP_ENUMERATE 64 -#define DESKTOP_HOOKCONTROL 8 -#define DESKTOP_JOURNALPLAYBACK 32 -#define DESKTOP_JOURNALRECORD 16 -#define DESKTOP_READOBJECTS 1 -#define DESKTOP_SWITCHDESKTOP 256 -#define DESKTOP_WRITEOBJECTS 128 -#define CW_USEDEFAULT 0x80000000 -#define WS_BORDER 0x800000 -#define WS_CAPTION 0xc00000 -#define WS_CHILD 0x40000000 -#define WS_CHILDWINDOW 0x40000000 -#define WS_CLIPCHILDREN 0x2000000 -#define WS_CLIPSIBLINGS 0x4000000 -#define WS_DISABLED 0x8000000 -#define WS_DLGFRAME 0x400000 -#define WS_GROUP 0x20000 -#define WS_HSCROLL 0x100000 -#define WS_ICONIC 0x20000000 -#define WS_MAXIMIZE 0x1000000 -#define WS_MAXIMIZEBOX 0x10000 -#define WS_MINIMIZE 0x20000000 -#define WS_MINIMIZEBOX 0x20000 -#define WS_OVERLAPPED 0 -#define WS_OVERLAPPEDWINDOW 0xcf0000 -#define WS_POPUP 0x80000000 -#define WS_POPUPWINDOW 0x80880000 -#define WS_SIZEBOX 0x40000 -#define WS_SYSMENU 0x80000 -#define WS_TABSTOP 0x10000 -#define WS_THICKFRAME 0x40000 -#define WS_TILED 0 -#define WS_TILEDWINDOW 0xcf0000 -#define WS_VISIBLE 0x10000000 -#define WS_VSCROLL 0x200000 -#define MDIS_ALLCHILDSTYLES 1 -#define BS_3STATE 5 -#define BS_AUTO3STATE 6 -#define BS_AUTOCHECKBOX 3 -#define BS_AUTORADIOBUTTON 9 -#define BS_BITMAP 128 -#define BS_BOTTOM 0x800 -#define BS_CENTER 0x300 -#define BS_CHECKBOX 2 -#define BS_DEFPUSHBUTTON 1 -#define BS_GROUPBOX 7 -#define BS_ICON 64 -#define BS_LEFT 256 -#define BS_LEFTTEXT 32 -#define BS_MULTILINE 0x2000 -#define BS_NOTIFY 0x4000 -#define BS_OWNERDRAW 0xb -#define BS_PUSHBUTTON 0 -#define BS_PUSHLIKE 4096 -#define BS_RADIOBUTTON 4 -#define BS_RIGHT 512 -#define BS_RIGHTBUTTON 32 -#define BS_TEXT 0 -#define BS_TOP 0x400 -#define BS_USERBUTTON 8 -#define BS_VCENTER 0xc00 -#define BS_FLAT 0x8000 -#define CBS_AUTOHSCROLL 64 -#define CBS_DISABLENOSCROLL 0x800 -#define CBS_DROPDOWN 2 -#define CBS_DROPDOWNLIST 3 -#define CBS_HASSTRINGS 512 -#define CBS_LOWERCASE 0x4000 -#define CBS_NOINTEGRALHEIGHT 0x400 -#define CBS_OEMCONVERT 128 -#define CBS_OWNERDRAWFIXED 16 -#define CBS_OWNERDRAWVARIABLE 32 -#define CBS_SIMPLE 1 -#define CBS_SORT 256 -#define CBS_UPPERCASE 0x2000 -#define ES_AUTOHSCROLL 128 -#define ES_AUTOVSCROLL 64 -#define ES_CENTER 1 -#define ES_LEFT 0 -#define ES_LOWERCASE 16 -#define ES_MULTILINE 4 -#define ES_NOHIDESEL 256 -#define ES_NUMBER 0x2000 -#define ES_OEMCONVERT 0x400 -#define ES_PASSWORD 32 -#define ES_READONLY 0x800 -#define ES_RIGHT 2 -#define ES_UPPERCASE 8 -#define ES_WANTRETURN 4096 -#define LBS_DISABLENOSCROLL 4096 -#define LBS_EXTENDEDSEL 0x800 -#define LBS_HASSTRINGS 64 -#define LBS_MULTICOLUMN 512 -#define LBS_MULTIPLESEL 8 -#define LBS_NODATA 0x2000 -#define LBS_NOINTEGRALHEIGHT 256 -#define LBS_NOREDRAW 4 -#define LBS_NOSEL 0x4000 -#define LBS_NOTIFY 1 -#define LBS_OWNERDRAWFIXED 16 -#define LBS_OWNERDRAWVARIABLE 32 -#define LBS_SORT 2 -#define LBS_STANDARD 0xa00003 -#define LBS_USETABSTOPS 128 -#define LBS_WANTKEYBOARDINPUT 0x400 -#define SBS_BOTTOMALIGN 4 -#define SBS_HORZ 0 -#define SBS_LEFTALIGN 2 -#define SBS_RIGHTALIGN 4 -#define SBS_SIZEBOX 8 -#define SBS_SIZEBOXBOTTOMRIGHTALIGN 4 -#define SBS_SIZEBOXTOPLEFTALIGN 2 -#define SBS_SIZEGRIP 16 -#define SBS_TOPALIGN 2 -#define SBS_VERT 1 -#define SS_BITMAP 14 -#define SS_BLACKFRAME 7 -#define SS_BLACKRECT 4 -#define SS_CENTER 1 -#define SS_CENTERIMAGE 512 -#define SS_ENHMETAFILE 15 -#define SS_ETCHEDFRAME 18 -#define SS_ETCHEDHORZ 16 -#define SS_ETCHEDVERT 17 -#define SS_GRAYFRAME 8 -#define SS_GRAYRECT 5 -#define SS_ICON 3 -#define SS_LEFT 0 -#define SS_LEFTNOWORDWRAP 0xc -#define SS_NOPREFIX 128 -#define SS_NOTIFY 256 -#define SS_OWNERDRAW 0xd -#define SS_REALSIZEIMAGE 0x800 -#define SS_RIGHT 2 -#define SS_RIGHTJUST 0x400 -#define SS_SIMPLE 11 -#define SS_SUNKEN 4096 -#define SS_WHITEFRAME 9 -#define SS_WHITERECT 6 -#define SS_USERITEM 10 -#define SS_TYPEMASK 0x0000001FL -#define SS_ENDELLIPSIS 0x00004000L -#define SS_PATHELLIPSIS 0x00008000L -#define SS_WORDELLIPSIS 0x0000C000L -#define SS_ELLIPSISMASK 0x0000C000L -#define DS_3DLOOK 4 -#define DS_ABSALIGN 1 -#define DS_CENTER 0x800 -#define DS_CENTERMOUSE 4096 -#define DS_CONTEXTHELP 0x2000 -#define DS_CONTROL 0x400 -#define DS_FIXEDSYS 8 -#define DS_LOCALEDIT 32 -#define DS_MODALFRAME 128 -#define DS_NOFAILCREATE 16 -#define DS_NOIDLEMSG 256 -#define DS_SETFONT 64 -#define DS_SETFOREGROUND 512 -#define DS_SYSMODAL 2 -#define WS_EX_ACCEPTFILES 16 -#define WS_EX_APPWINDOW 0x40000 -#define WS_EX_CLIENTEDGE 512 -#define WS_EX_COMPOSITED 0x2000000 /* XP */ -#define WS_EX_CONTEXTHELP 0x400 -#define WS_EX_CONTROLPARENT 0x10000 -#define WS_EX_DLGMODALFRAME 1 -#define WS_EX_LAYERED 0x80000 /* w2k */ -#define WS_EX_LAYOUTRTL 0x400000 /* w98, w2k */ -#define WS_EX_LEFT 0 -#define WS_EX_LEFTSCROLLBAR 0x4000 -#define WS_EX_LTRREADING 0 -#define WS_EX_MDICHILD 64 -#define WS_EX_NOACTIVATE 0x8000000 /* w2k */ -#define WS_EX_NOINHERITLAYOUT 0x100000 /* w2k */ -#define WS_EX_NOPARENTNOTIFY 4 -#define WS_EX_OVERLAPPEDWINDOW 0x300 -#define WS_EX_PALETTEWINDOW 0x188 -#define WS_EX_RIGHT 0x1000 -#define WS_EX_RIGHTSCROLLBAR 0 -#define WS_EX_RTLREADING 0x2000 -#define WS_EX_STATICEDGE 0x20000 -#define WS_EX_TOOLWINDOW 128 -#define WS_EX_TOPMOST 8 -#define WS_EX_TRANSPARENT 32 -#define WS_EX_WINDOWEDGE 256 -#define WINSTA_ACCESSCLIPBOARD 4 -#define WINSTA_ACCESSGLOBALATOMS 32 -#define WINSTA_CREATEDESKTOP 8 -#define WINSTA_ENUMDESKTOPS 1 -#define WINSTA_ENUMERATE 256 -#define WINSTA_EXITWINDOWS 64 -#define WINSTA_READATTRIBUTES 2 -#define WINSTA_READSCREEN 512 -#define WINSTA_WRITEATTRIBUTES 16 -#define DDL_READWRITE 0 -#define DDL_READONLY 1 -#define DDL_HIDDEN 2 -#define DDL_SYSTEM 4 -#define DDL_DIRECTORY 16 -#define DDL_ARCHIVE 32 -#define DDL_POSTMSGS 8192 -#define DDL_DRIVES 16384 -#define DDL_EXCLUSIVE 32768 -#define DC_ACTIVE 1 -#define DC_SMALLCAP 2 -#define DC_ICON 4 -#define DC_TEXT 8 -#define DC_INBUTTON 16 -#define DC_CAPTION (DC_ICON|DC_TEXT|DC_BUTTONS) -#define DC_NC (DC_CAPTION|DC_FRAME) -#define BDR_RAISEDOUTER 1 -#define BDR_SUNKENOUTER 2 -#define BDR_RAISEDINNER 4 -#define BDR_SUNKENINNER 8 -#define BDR_OUTER 3 -#define BDR_INNER 0xc -#define BDR_RAISED 5 -#define BDR_SUNKEN 10 -#define EDGE_RAISED (BDR_RAISEDOUTER|BDR_RAISEDINNER) -#define EDGE_SUNKEN (BDR_SUNKENOUTER|BDR_SUNKENINNER) -#define EDGE_ETCHED (BDR_SUNKENOUTER|BDR_RAISEDINNER) -#define EDGE_BUMP (BDR_RAISEDOUTER|BDR_SUNKENINNER) -#define BF_LEFT 1 -#define BF_TOP 2 -#define BF_RIGHT 4 -#define BF_BOTTOM 8 -#define BF_TOPLEFT (BF_TOP|BF_LEFT) -#define BF_TOPRIGHT (BF_TOP|BF_RIGHT) -#define BF_BOTTOMLEFT (BF_BOTTOM|BF_LEFT) -#define BF_BOTTOMRIGHT (BF_BOTTOM|BF_RIGHT) -#define BF_RECT (BF_LEFT|BF_TOP|BF_RIGHT|BF_BOTTOM) -#define BF_DIAGONAL 16 -#define BF_DIAGONAL_ENDTOPRIGHT (BF_DIAGONAL|BF_TOP|BF_RIGHT) -#define BF_DIAGONAL_ENDTOPLEFT (BF_DIAGONAL|BF_TOP|BF_LEFT) -#define BF_DIAGONAL_ENDBOTTOMLEFT (BF_DIAGONAL|BF_BOTTOM|BF_LEFT) -#define BF_DIAGONAL_ENDBOTTOMRIGHT (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT) -#define BF_MIDDLE 0x800 -#define BF_SOFT 0x1000 -#define BF_ADJUST 0x2000 -#define BF_FLAT 0x4000 -#define BF_MONO 0x8000 -#define DFC_CAPTION 1 -#define DFC_MENU 2 -#define DFC_SCROLL 3 -#define DFC_BUTTON 4 -#define DFCS_CAPTIONCLOSE 0 -#define DFCS_CAPTIONMIN 1 -#define DFCS_CAPTIONMAX 2 -#define DFCS_CAPTIONRESTORE 3 -#define DFCS_CAPTIONHELP 4 -#define DFCS_MENUARROW 0 -#define DFCS_MENUCHECK 1 -#define DFCS_MENUBULLET 2 -#define DFCS_MENUARROWRIGHT 4 -#define DFCS_SCROLLUP 0 -#define DFCS_SCROLLDOWN 1 -#define DFCS_SCROLLLEFT 2 -#define DFCS_SCROLLRIGHT 3 -#define DFCS_SCROLLCOMBOBOX 5 -#define DFCS_SCROLLSIZEGRIP 8 -#define DFCS_SCROLLSIZEGRIPRIGHT 16 -#define DFCS_BUTTONCHECK 0 -#define DFCS_BUTTONRADIOIMAGE 1 -#define DFCS_BUTTONRADIOMASK 2 -#define DFCS_BUTTONRADIO 4 -#define DFCS_BUTTON3STATE 8 -#define DFCS_BUTTONPUSH 16 -#define DFCS_INACTIVE 256 -#define DFCS_PUSHED 512 -#define DFCS_CHECKED 1024 -#define DFCS_ADJUSTRECT 0x2000 -#define DFCS_FLAT 0x4000 -#define DFCS_MONO 0x8000 -#define DST_COMPLEX 0 -#define DST_TEXT 1 -#define DST_PREFIXTEXT 2 -#define DST_ICON 3 -#define DST_BITMAP 4 -#define DSS_NORMAL 0 -#define DSS_UNION 16 -#define DSS_DISABLED 32 -#define DSS_MONO 128 -#define DSS_RIGHT 0x8000 -#define DT_BOTTOM 8 -#define DT_CALCRECT 1024 -#define DT_CENTER 1 -#define DT_EDITCONTROL 8192 -#define DT_END_ELLIPSIS 32768 -#define DT_PATH_ELLIPSIS 16384 -#define DT_WORD_ELLIPSIS 0x40000 -#define DT_EXPANDTABS 64 -#define DT_EXTERNALLEADING 512 -#define DT_LEFT 0 -#define DT_MODIFYSTRING 65536 -#define DT_NOCLIP 256 -#define DT_NOPREFIX 2048 -#define DT_RIGHT 2 -#define DT_RTLREADING 131072 -#define DT_SINGLELINE 32 -#define DT_TABSTOP 128 -#define DT_TOP 0 -#define DT_VCENTER 4 -#define DT_WORDBREAK 16 -#define DT_INTERNAL 4096 -#define WB_ISDELIMITER 2 -#define WB_LEFT 0 -#define WB_RIGHT 1 -#define SB_HORZ 0 -#define SB_VERT 1 -#define SB_CTL 2 -#define SB_BOTH 3 -#define ESB_DISABLE_BOTH 3 -#define ESB_DISABLE_DOWN 2 -#define ESB_DISABLE_LEFT 1 -#define ESB_DISABLE_LTUP 1 -#define ESB_DISABLE_RIGHT 2 -#define ESB_DISABLE_RTDN 2 -#define ESB_DISABLE_UP 1 -#define ESB_ENABLE_BOTH 0 -#define SB_LINEUP 0 -#define SB_LINEDOWN 1 -#define SB_LINELEFT 0 -#define SB_LINERIGHT 1 -#define SB_PAGEUP 2 -#define SB_PAGEDOWN 3 -#define SB_PAGELEFT 2 -#define SB_PAGERIGHT 3 -#define SB_THUMBPOSITION 4 -#define SB_THUMBTRACK 5 -#define SB_ENDSCROLL 8 -#define SB_LEFT 6 -#define SB_RIGHT 7 -#define SB_BOTTOM 7 -#define SB_TOP 6 -#define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i))) -#define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i))) -#ifndef XFree86Server -# define RT_CURSOR MAKEINTRESOURCE(1) -# define RT_FONT MAKEINTRESOURCE(8) -#endif /* ndef XFree86Server */ + +#ifndef WINVER +#define WINVER 0x0502 +#endif + +#include <stdarg.h> + +#ifndef NOUSER + typedef HANDLE HDWP; + typedef VOID MENUTEMPLATEA; + typedef VOID MENUTEMPLATEW; + typedef PVOID LPMENUTEMPLATEA; + typedef PVOID LPMENUTEMPLATEW; + +#ifdef UNICODE + typedef MENUTEMPLATEW MENUTEMPLATE; + typedef LPMENUTEMPLATEW LPMENUTEMPLATE; +#else + typedef MENUTEMPLATEA MENUTEMPLATE; + typedef LPMENUTEMPLATEA LPMENUTEMPLATE; +#endif + + typedef LRESULT (CALLBACK *WNDPROC)(HWND,UINT,WPARAM,LPARAM); + typedef INT_PTR (CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM); + typedef VOID (CALLBACK *TIMERPROC)(HWND,UINT,UINT_PTR,DWORD); + typedef WINBOOL (CALLBACK *GRAYSTRINGPROC)(HDC,LPARAM,int); + typedef WINBOOL (CALLBACK *WNDENUMPROC)(HWND,LPARAM); + typedef LRESULT (CALLBACK *HOOKPROC)(int code,WPARAM wParam,LPARAM lParam); + typedef VOID (CALLBACK *SENDASYNCPROC)(HWND,UINT,ULONG_PTR,LRESULT); + typedef WINBOOL (CALLBACK *PROPENUMPROCA)(HWND,LPCSTR,HANDLE); + typedef WINBOOL (CALLBACK *PROPENUMPROCW)(HWND,LPCWSTR,HANDLE); + typedef WINBOOL (CALLBACK *PROPENUMPROCEXA)(HWND,LPSTR,HANDLE,ULONG_PTR); + typedef WINBOOL (CALLBACK *PROPENUMPROCEXW)(HWND,LPWSTR,HANDLE,ULONG_PTR); + typedef int (CALLBACK *EDITWORDBREAKPROCA)(LPSTR lpch,int ichCurrent,int cch,int code); + typedef int (CALLBACK *EDITWORDBREAKPROCW)(LPWSTR lpch,int ichCurrent,int cch,int code); + typedef WINBOOL (CALLBACK *DRAWSTATEPROC)(HDC hdc,LPARAM lData,WPARAM wData,int cx,int cy); + +#ifdef UNICODE + typedef PROPENUMPROCW PROPENUMPROC; + typedef PROPENUMPROCEXW PROPENUMPROCEX; + typedef EDITWORDBREAKPROCW EDITWORDBREAKPROC; +#else + typedef PROPENUMPROCA PROPENUMPROC; + typedef PROPENUMPROCEXA PROPENUMPROCEX; + typedef EDITWORDBREAKPROCA EDITWORDBREAKPROC; +#endif + + typedef WINBOOL (CALLBACK *NAMEENUMPROCA)(LPSTR,LPARAM); + typedef WINBOOL (CALLBACK *NAMEENUMPROCW)(LPWSTR,LPARAM); + typedef NAMEENUMPROCA WINSTAENUMPROCA; + typedef NAMEENUMPROCA DESKTOPENUMPROCA; + typedef NAMEENUMPROCW WINSTAENUMPROCW; + typedef NAMEENUMPROCW DESKTOPENUMPROCW; + +#ifdef UNICODE + typedef WINSTAENUMPROCW WINSTAENUMPROC; + typedef DESKTOPENUMPROCW DESKTOPENUMPROC; +#else + typedef WINSTAENUMPROCA WINSTAENUMPROC; + typedef DESKTOPENUMPROCA DESKTOPENUMPROC; +#endif + +#define IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16)==0) +#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i)))) +#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i)))) +#ifdef UNICODE +#define MAKEINTRESOURCE MAKEINTRESOURCEW +#else +#define MAKEINTRESOURCE MAKEINTRESOURCEA +#endif + +#ifndef NORESOURCE + +#define RT_CURSOR MAKEINTRESOURCE(1) #define RT_BITMAP MAKEINTRESOURCE(2) #define RT_ICON MAKEINTRESOURCE(3) #define RT_MENU MAKEINTRESOURCE(4) #define RT_DIALOG MAKEINTRESOURCE(5) #define RT_STRING MAKEINTRESOURCE(6) #define RT_FONTDIR MAKEINTRESOURCE(7) +#define RT_FONT MAKEINTRESOURCE(8) #define RT_ACCELERATOR MAKEINTRESOURCE(9) #define RT_RCDATA MAKEINTRESOURCE(10) #define RT_MESSAGETABLE MAKEINTRESOURCE(11) + #define DIFFERENCE 11 -#define RT_GROUP_CURSOR MAKEINTRESOURCE((DWORD)RT_CURSOR+DIFFERENCE) -#define RT_GROUP_ICON MAKEINTRESOURCE((DWORD)RT_ICON+DIFFERENCE) +#define RT_GROUP_CURSOR MAKEINTRESOURCE((ULONG_PTR)RT_CURSOR + DIFFERENCE) +#define RT_GROUP_ICON MAKEINTRESOURCE((ULONG_PTR)RT_ICON + DIFFERENCE) #define RT_VERSION MAKEINTRESOURCE(16) #define RT_DLGINCLUDE MAKEINTRESOURCE(17) #define RT_PLUGPLAY MAKEINTRESOURCE(19) @@ -531,116 +106,68 @@ extern "C" { #define RT_ANICURSOR MAKEINTRESOURCE(21) #define RT_ANIICON MAKEINTRESOURCE(22) #define RT_HTML MAKEINTRESOURCE(23) -#define EWX_FORCE 4 -#define EWX_LOGOFF 0 -#define EWX_POWEROFF 8 -#define EWX_REBOOT 2 -#define EWX_SHUTDOWN 1 -#define CS_BYTEALIGNCLIENT 4096 -#define CS_BYTEALIGNWINDOW 8192 -#define CS_KEYCVTWINDOW 4 -#define CS_NOKEYCVT 256 -#define CS_CLASSDC 64 -#define CS_DBLCLKS 8 -#define CS_GLOBALCLASS 16384 -#define CS_HREDRAW 2 -#define CS_NOCLOSE 512 -#define CS_OWNDC 32 -#define CS_PARENTDC 128 -#define CS_SAVEBITS 2048 -#define CS_VREDRAW 1 -#define CS_IME 0x10000 -#define GCW_ATOM (-32) -#define GCL_CBCLSEXTRA (-20) -#define GCL_CBWNDEXTRA (-18) -#define GCL_HBRBACKGROUND (-10) -#define GCL_HCURSOR (-12) -#define GCL_HICON (-14) -#define GCL_HICONSM (-34) -#define GCL_HMODULE (-16) -#define GCL_MENUNAME (-8) -#define GCL_STYLE (-26) -#define GCL_WNDPROC (-24) -#if 0 - /* This is supposed to be defined by the program using it not defined - in the win32api headers. I've left it here for documentation purposes. - */ -#ifndef IDC_STATIC /* May be predefined by resource compiler. */ -#define IDC_STATIC (-1) +#ifdef RC_INVOKED +#define RT_MANIFEST 24 +#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 +#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2 +#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3 +#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID 1 +#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID 16 +#else +#define RT_MANIFEST MAKEINTRESOURCE(24) +#define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) +#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2) +#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(3) +#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(1) +#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16) #endif #endif -#define IDC_ARROW MAKEINTRESOURCE(32512) -#define IDC_IBEAM MAKEINTRESOURCE(32513) -#define IDC_WAIT MAKEINTRESOURCE(32514) -#define IDC_CROSS MAKEINTRESOURCE(32515) -#define IDC_UPARROW MAKEINTRESOURCE(32516) -#define IDC_SIZENWSE MAKEINTRESOURCE(32642) -#define IDC_SIZENESW MAKEINTRESOURCE(32643) -#define IDC_SIZEWE MAKEINTRESOURCE(32644) -#define IDC_SIZENS MAKEINTRESOURCE(32645) -#define IDC_SIZEALL MAKEINTRESOURCE(32646) -#define IDC_NO MAKEINTRESOURCE(32648) -#define IDC_HAND MAKEINTRESOURCE(32649) -#define IDC_APPSTARTING MAKEINTRESOURCE(32650) -#define IDC_HELP MAKEINTRESOURCE(32651) -#define IDC_ICON MAKEINTRESOURCE(32641) -#define IDC_SIZE MAKEINTRESOURCE(32640) -#ifndef RC_INVOKED -#define IDI_APPLICATION MAKEINTRESOURCE(32512) -#define IDI_HAND MAKEINTRESOURCE(32513) -#define IDI_QUESTION MAKEINTRESOURCE(32514) -#define IDI_EXCLAMATION MAKEINTRESOURCE(32515) -#define IDI_ASTERISK MAKEINTRESOURCE(32516) -#define IDI_WINLOGO MAKEINTRESOURCE(32517) + +#ifdef UNICODE +#define wvsprintf wvsprintfW +#define wsprintf wsprintfW #else -#define IDI_APPLICATION 32512 -#define IDI_HAND 32513 -#define IDI_QUESTION 32514 -#define IDI_EXCLAMATION 32515 -#define IDI_ASTERISK 32516 -#define IDI_WINLOGO 32517 +#define wvsprintf wvsprintfA +#define wsprintf wsprintfA #endif -#define IDI_WARNING IDI_EXCLAMATION -#define IDI_ERROR IDI_HAND -#define IDI_INFORMATION IDI_ASTERISK -#define MIIM_STATE 1 -#define MIIM_ID 2 -#define MIIM_SUBMENU 4 -#define MIIM_CHECKMARKS 8 -#define MIIM_TYPE 16 -#define MIIM_DATA 32 -#define MIIM_STRING 64 -#define MIIM_BITMAP 128 -#define MIIM_FTYPE 256 -#define MFT_BITMAP 4 -#define MFT_MENUBARBREAK 32 -#define MFT_MENUBREAK 64 -#define MFT_OWNERDRAW 256 -#define MFT_RADIOCHECK 512 -#define MFT_RIGHTJUSTIFY 0x4000 -#define MFT_SEPARATOR 0x800 -#define MFT_RIGHTORDER 0x2000L -#define MFT_STRING 0 -#define MFS_CHECKED 8 -#define MFS_DEFAULT 4096 -#define MFS_DISABLED 3 -#define MFS_ENABLED 0 -#define MFS_GRAYED 3 -#define MFS_HILITE 128 -#define MFS_UNCHECKED 0 -#define MFS_UNHILITE 0 -#define GW_HWNDNEXT 2 -#define GW_HWNDPREV 3 -#define GW_CHILD 5 -#define GW_HWNDFIRST 0 -#define GW_HWNDLAST 1 -#define GW_OWNER 4 + + WINUSERAPI int WINAPI wvsprintfA(LPSTR,LPCSTR,va_list arglist); + WINUSERAPI int WINAPI wvsprintfW(LPWSTR,LPCWSTR,va_list arglist); + WINUSERAPI int WINAPIV wsprintfA(LPSTR,LPCSTR,...); + WINUSERAPI int WINAPIV wsprintfW(LPWSTR,LPCWSTR,...); + +#define SETWALLPAPER_DEFAULT ((LPWSTR)-1) + +#ifndef NOSCROLL +#define SB_HORZ 0 +#define SB_VERT 1 +#define SB_CTL 2 +#define SB_BOTH 3 + +#define SB_LINEUP 0 +#define SB_LINELEFT 0 +#define SB_LINEDOWN 1 +#define SB_LINERIGHT 1 +#define SB_PAGEUP 2 +#define SB_PAGELEFT 2 +#define SB_PAGEDOWN 3 +#define SB_PAGERIGHT 3 +#define SB_THUMBPOSITION 4 +#define SB_THUMBTRACK 5 +#define SB_TOP 6 +#define SB_LEFT 6 +#define SB_BOTTOM 7 +#define SB_RIGHT 7 +#define SB_ENDSCROLL 8 +#endif + +#ifndef NOSHOWWINDOW #define SW_HIDE 0 -#define SW_NORMAL 1 #define SW_SHOWNORMAL 1 +#define SW_NORMAL 1 #define SW_SHOWMINIMIZED 2 -#define SW_MAXIMIZE 3 #define SW_SHOWMAXIMIZED 3 +#define SW_MAXIMIZE 3 #define SW_SHOWNOACTIVATE 4 #define SW_SHOW 5 #define SW_MINIMIZE 6 @@ -649,128 +176,2367 @@ extern "C" { #define SW_RESTORE 9 #define SW_SHOWDEFAULT 10 #define SW_FORCEMINIMIZE 11 -#define SW_MAX 11 -#define MB_USERICON 128 -#define MB_ICONASTERISK 64 -#define MB_ICONEXCLAMATION 0x30 -#define MB_ICONWARNING 0x30 -#define MB_ICONERROR 16 -#define MB_ICONHAND 16 -#define MB_ICONQUESTION 32 -#define MB_OK 0 -#define MB_ABORTRETRYIGNORE 2 -#define MB_APPLMODAL 0 -#define MB_DEFAULT_DESKTOP_ONLY 0x20000 -#define MB_HELP 0x4000 -#define MB_RIGHT 0x80000 -#define MB_RTLREADING 0x100000 -#define MB_TOPMOST 0x40000 -#define MB_DEFBUTTON1 0 -#define MB_DEFBUTTON2 256 -#define MB_DEFBUTTON3 512 -#define MB_DEFBUTTON4 0x300 -#define MB_ICONINFORMATION 64 -#define MB_ICONSTOP 16 -#define MB_OKCANCEL 1 -#define MB_RETRYCANCEL 5 -#ifdef _WIN32_WINNT -#if (_WIN32_WINNT >= 0x0400) -#define MB_SERVICE_NOTIFICATION 0x00200000 -#else -#define MB_SERVICE_NOTIFICATION 0x00040000 -#endif -#define MB_SERVICE_NOTIFICATION_NT3X 0x00040000 -#endif -#define MB_SETFOREGROUND 0x10000 -#define MB_SYSTEMMODAL 4096 -#define MB_TASKMODAL 0x2000 -#define MB_YESNO 4 -#define MB_YESNOCANCEL 3 -#define MB_ICONMASK 240 -#define MB_DEFMASK 3840 -#define MB_MODEMASK 0x00003000 -#define MB_MISCMASK 0x0000C000 -#define MB_NOFOCUS 0x00008000 -#define MB_TYPEMASK 15 -#define MB_TOPMOST 0x40000 -#define IDABORT 3 -#define IDCANCEL 2 -#define IDCLOSE 8 -#define IDHELP 9 -#define IDIGNORE 5 -#define IDNO 7 -#define IDOK 1 -#define IDRETRY 4 -#define IDYES 6 -#define GWL_EXSTYLE (-20) -#define GWL_STYLE (-16) +#define SW_MAX 11 + +#define HIDE_WINDOW 0 +#define SHOW_OPENWINDOW 1 +#define SHOW_ICONWINDOW 2 +#define SHOW_FULLSCREEN 3 +#define SHOW_OPENNOACTIVATE 4 + +#define SW_PARENTCLOSING 1 +#define SW_OTHERZOOM 2 +#define SW_PARENTOPENING 3 +#define SW_OTHERUNZOOM 4 +#endif + +#define AW_HOR_POSITIVE 0x00000001 +#define AW_HOR_NEGATIVE 0x00000002 +#define AW_VER_POSITIVE 0x00000004 +#define AW_VER_NEGATIVE 0x00000008 +#define AW_CENTER 0x00000010 +#define AW_HIDE 0x00010000 +#define AW_ACTIVATE 0x00020000 +#define AW_SLIDE 0x00040000 +#define AW_BLEND 0x00080000 + +#define KF_EXTENDED 0x0100 +#define KF_DLGMODE 0x0800 +#define KF_MENUMODE 0x1000 +#define KF_ALTDOWN 0x2000 +#define KF_REPEAT 0x4000 +#define KF_UP 0x8000 + +#ifndef NOVIRTUALKEYCODES + +#define VK_LBUTTON 0x01 +#define VK_RBUTTON 0x02 +#define VK_CANCEL 0x03 +#define VK_MBUTTON 0x04 +#define VK_XBUTTON1 0x05 +#define VK_XBUTTON2 0x06 +#define VK_BACK 0x08 +#define VK_TAB 0x09 +#define VK_CLEAR 0x0C +#define VK_RETURN 0x0D +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 +#define VK_KANA 0x15 +#define VK_HANGEUL 0x15 +#define VK_HANGUL 0x15 +#define VK_JUNJA 0x17 +#define VK_FINAL 0x18 +#define VK_HANJA 0x19 +#define VK_KANJI 0x19 +#define VK_ESCAPE 0x1B +#define VK_CONVERT 0x1C +#define VK_NONCONVERT 0x1D +#define VK_ACCEPT 0x1E +#define VK_MODECHANGE 0x1F +#define VK_SPACE 0x20 +#define VK_PRIOR 0x21 +#define VK_NEXT 0x22 +#define VK_END 0x23 +#define VK_HOME 0x24 +#define VK_LEFT 0x25 +#define VK_UP 0x26 +#define VK_RIGHT 0x27 +#define VK_DOWN 0x28 +#define VK_SELECT 0x29 +#define VK_PRINT 0x2A +#define VK_EXECUTE 0x2B +#define VK_SNAPSHOT 0x2C +#define VK_INSERT 0x2D +#define VK_DELETE 0x2E +#define VK_HELP 0x2F + +#define VK_LWIN 0x5B +#define VK_RWIN 0x5C +#define VK_APPS 0x5D +#define VK_SLEEP 0x5F +#define VK_NUMPAD0 0x60 +#define VK_NUMPAD1 0x61 +#define VK_NUMPAD2 0x62 +#define VK_NUMPAD3 0x63 +#define VK_NUMPAD4 0x64 +#define VK_NUMPAD5 0x65 +#define VK_NUMPAD6 0x66 +#define VK_NUMPAD7 0x67 +#define VK_NUMPAD8 0x68 +#define VK_NUMPAD9 0x69 +#define VK_MULTIPLY 0x6A +#define VK_ADD 0x6B +#define VK_SEPARATOR 0x6C +#define VK_SUBTRACT 0x6D +#define VK_DECIMAL 0x6E +#define VK_DIVIDE 0x6F +#define VK_F1 0x70 +#define VK_F2 0x71 +#define VK_F3 0x72 +#define VK_F4 0x73 +#define VK_F5 0x74 +#define VK_F6 0x75 +#define VK_F7 0x76 +#define VK_F8 0x77 +#define VK_F9 0x78 +#define VK_F10 0x79 +#define VK_F11 0x7A +#define VK_F12 0x7B +#define VK_F13 0x7C +#define VK_F14 0x7D +#define VK_F15 0x7E +#define VK_F16 0x7F +#define VK_F17 0x80 +#define VK_F18 0x81 +#define VK_F19 0x82 +#define VK_F20 0x83 +#define VK_F21 0x84 +#define VK_F22 0x85 +#define VK_F23 0x86 +#define VK_F24 0x87 +#define VK_NUMLOCK 0x90 +#define VK_SCROLL 0x91 +#define VK_OEM_NEC_EQUAL 0x92 +#define VK_OEM_FJ_JISHO 0x92 +#define VK_OEM_FJ_MASSHOU 0x93 +#define VK_OEM_FJ_TOUROKU 0x94 +#define VK_OEM_FJ_LOYA 0x95 +#define VK_OEM_FJ_ROYA 0x96 +#define VK_LSHIFT 0xA0 +#define VK_RSHIFT 0xA1 +#define VK_LCONTROL 0xA2 +#define VK_RCONTROL 0xA3 +#define VK_LMENU 0xA4 +#define VK_RMENU 0xA5 +#define VK_BROWSER_BACK 0xA6 +#define VK_BROWSER_FORWARD 0xA7 +#define VK_BROWSER_REFRESH 0xA8 +#define VK_BROWSER_STOP 0xA9 +#define VK_BROWSER_SEARCH 0xAA +#define VK_BROWSER_FAVORITES 0xAB +#define VK_BROWSER_HOME 0xAC +#define VK_VOLUME_MUTE 0xAD +#define VK_VOLUME_DOWN 0xAE +#define VK_VOLUME_UP 0xAF +#define VK_MEDIA_NEXT_TRACK 0xB0 +#define VK_MEDIA_PREV_TRACK 0xB1 +#define VK_MEDIA_STOP 0xB2 +#define VK_MEDIA_PLAY_PAUSE 0xB3 +#define VK_LAUNCH_MAIL 0xB4 +#define VK_LAUNCH_MEDIA_SELECT 0xB5 +#define VK_LAUNCH_APP1 0xB6 +#define VK_LAUNCH_APP2 0xB7 +#define VK_OEM_1 0xBA +#define VK_OEM_PLUS 0xBB +#define VK_OEM_COMMA 0xBC +#define VK_OEM_MINUS 0xBD +#define VK_OEM_PERIOD 0xBE +#define VK_OEM_2 0xBF +#define VK_OEM_3 0xC0 +#define VK_OEM_4 0xDB +#define VK_OEM_5 0xDC +#define VK_OEM_6 0xDD +#define VK_OEM_7 0xDE +#define VK_OEM_8 0xDF +#define VK_OEM_AX 0xE1 +#define VK_OEM_102 0xE2 +#define VK_ICO_HELP 0xE3 +#define VK_ICO_00 0xE4 +#define VK_PROCESSKEY 0xE5 +#define VK_ICO_CLEAR 0xE6 +#define VK_PACKET 0xE7 +#define VK_OEM_RESET 0xE9 +#define VK_OEM_JUMP 0xEA +#define VK_OEM_PA1 0xEB +#define VK_OEM_PA2 0xEC +#define VK_OEM_PA3 0xED +#define VK_OEM_WSCTRL 0xEE +#define VK_OEM_CUSEL 0xEF +#define VK_OEM_ATTN 0xF0 +#define VK_OEM_FINISH 0xF1 +#define VK_OEM_COPY 0xF2 +#define VK_OEM_AUTO 0xF3 +#define VK_OEM_ENLW 0xF4 +#define VK_OEM_BACKTAB 0xF5 +#define VK_ATTN 0xF6 +#define VK_CRSEL 0xF7 +#define VK_EXSEL 0xF8 +#define VK_EREOF 0xF9 +#define VK_PLAY 0xFA +#define VK_ZOOM 0xFB +#define VK_NONAME 0xFC +#define VK_PA1 0xFD +#define VK_OEM_CLEAR 0xFE +#endif + +#ifndef NOWH + +#define WH_MIN (-1) +#define WH_MSGFILTER (-1) +#define WH_JOURNALRECORD 0 +#define WH_JOURNALPLAYBACK 1 +#define WH_KEYBOARD 2 +#define WH_GETMESSAGE 3 +#define WH_CALLWNDPROC 4 +#define WH_CBT 5 +#define WH_SYSMSGFILTER 6 +#define WH_MOUSE 7 +#define WH_HARDWARE 8 +#define WH_DEBUG 9 +#define WH_SHELL 10 +#define WH_FOREGROUNDIDLE 11 +#define WH_CALLWNDPROCRET 12 + +#define WH_KEYBOARD_LL 13 +#define WH_MOUSE_LL 14 + +#define WH_MAX 14 + +#define WH_MINHOOK WH_MIN +#define WH_MAXHOOK WH_MAX + +#define HC_ACTION 0 +#define HC_GETNEXT 1 +#define HC_SKIP 2 +#define HC_NOREMOVE 3 +#define HC_NOREM HC_NOREMOVE +#define HC_SYSMODALON 4 +#define HC_SYSMODALOFF 5 + +#define HCBT_MOVESIZE 0 +#define HCBT_MINMAX 1 +#define HCBT_QS 2 +#define HCBT_CREATEWND 3 +#define HCBT_DESTROYWND 4 +#define HCBT_ACTIVATE 5 +#define HCBT_CLICKSKIPPED 6 +#define HCBT_KEYSKIPPED 7 +#define HCBT_SYSCOMMAND 8 +#define HCBT_SETFOCUS 9 + + typedef struct tagCBT_CREATEWNDA { + struct tagCREATESTRUCTA *lpcs; + HWND hwndInsertAfter; + } CBT_CREATEWNDA,*LPCBT_CREATEWNDA; + + typedef struct tagCBT_CREATEWNDW { + struct tagCREATESTRUCTW *lpcs; + HWND hwndInsertAfter; + } CBT_CREATEWNDW,*LPCBT_CREATEWNDW; +#ifdef UNICODE + typedef CBT_CREATEWNDW CBT_CREATEWND; + typedef LPCBT_CREATEWNDW LPCBT_CREATEWND; +#else + typedef CBT_CREATEWNDA CBT_CREATEWND; + typedef LPCBT_CREATEWNDA LPCBT_CREATEWND; +#endif + + typedef struct tagCBTACTIVATESTRUCT + { + WINBOOL fMouse; + HWND hWndActive; + } CBTACTIVATESTRUCT,*LPCBTACTIVATESTRUCT; + + typedef struct tagWTSSESSION_NOTIFICATION { + DWORD cbSize; + DWORD dwSessionId; + + } WTSSESSION_NOTIFICATION,*PWTSSESSION_NOTIFICATION; + +#define WTS_CONSOLE_CONNECT 0x1 +#define WTS_CONSOLE_DISCONNECT 0x2 +#define WTS_REMOTE_CONNECT 0x3 +#define WTS_REMOTE_DISCONNECT 0x4 +#define WTS_SESSION_LOGON 0x5 +#define WTS_SESSION_LOGOFF 0x6 +#define WTS_SESSION_LOCK 0x7 +#define WTS_SESSION_UNLOCK 0x8 +#define WTS_SESSION_REMOTE_CONTROL 0x9 + +#define MSGF_DIALOGBOX 0 +#define MSGF_MESSAGEBOX 1 +#define MSGF_MENU 2 +#define MSGF_SCROLLBAR 5 +#define MSGF_NEXTWINDOW 6 +#define MSGF_MAX 8 +#define MSGF_USER 4096 + +#define HSHELL_WINDOWCREATED 1 +#define HSHELL_WINDOWDESTROYED 2 +#define HSHELL_ACTIVATESHELLWINDOW 3 + +#define HSHELL_WINDOWACTIVATED 4 +#define HSHELL_GETMINRECT 5 +#define HSHELL_REDRAW 6 +#define HSHELL_TASKMAN 7 +#define HSHELL_LANGUAGE 8 +#define HSHELL_SYSMENU 9 +#define HSHELL_ENDTASK 10 +#define HSHELL_ACCESSIBILITYSTATE 11 +#define HSHELL_APPCOMMAND 12 +#define HSHELL_WINDOWREPLACED 13 +#define HSHELL_WINDOWREPLACING 14 +#define HSHELL_HIGHBIT 0x8000 +#define HSHELL_FLASH (HSHELL_REDRAW|HSHELL_HIGHBIT) +#define HSHELL_RUDEAPPACTIVATED (HSHELL_WINDOWACTIVATED|HSHELL_HIGHBIT) + +#define ACCESS_STICKYKEYS 0x0001 +#define ACCESS_FILTERKEYS 0x0002 +#define ACCESS_MOUSEKEYS 0x0003 + +#define APPCOMMAND_BROWSER_BACKWARD 1 +#define APPCOMMAND_BROWSER_FORWARD 2 +#define APPCOMMAND_BROWSER_REFRESH 3 +#define APPCOMMAND_BROWSER_STOP 4 +#define APPCOMMAND_BROWSER_SEARCH 5 +#define APPCOMMAND_BROWSER_FAVORITES 6 +#define APPCOMMAND_BROWSER_HOME 7 +#define APPCOMMAND_VOLUME_MUTE 8 +#define APPCOMMAND_VOLUME_DOWN 9 +#define APPCOMMAND_VOLUME_UP 10 +#define APPCOMMAND_MEDIA_NEXTTRACK 11 +#define APPCOMMAND_MEDIA_PREVIOUSTRACK 12 +#define APPCOMMAND_MEDIA_STOP 13 +#define APPCOMMAND_MEDIA_PLAY_PAUSE 14 +#define APPCOMMAND_LAUNCH_MAIL 15 +#define APPCOMMAND_LAUNCH_MEDIA_SELECT 16 +#define APPCOMMAND_LAUNCH_APP1 17 +#define APPCOMMAND_LAUNCH_APP2 18 +#define APPCOMMAND_BASS_DOWN 19 +#define APPCOMMAND_BASS_BOOST 20 +#define APPCOMMAND_BASS_UP 21 +#define APPCOMMAND_TREBLE_DOWN 22 +#define APPCOMMAND_TREBLE_UP 23 +#define APPCOMMAND_MICROPHONE_VOLUME_MUTE 24 +#define APPCOMMAND_MICROPHONE_VOLUME_DOWN 25 +#define APPCOMMAND_MICROPHONE_VOLUME_UP 26 +#define APPCOMMAND_HELP 27 +#define APPCOMMAND_FIND 28 +#define APPCOMMAND_NEW 29 +#define APPCOMMAND_OPEN 30 +#define APPCOMMAND_CLOSE 31 +#define APPCOMMAND_SAVE 32 +#define APPCOMMAND_PRINT 33 +#define APPCOMMAND_UNDO 34 +#define APPCOMMAND_REDO 35 +#define APPCOMMAND_COPY 36 +#define APPCOMMAND_CUT 37 +#define APPCOMMAND_PASTE 38 +#define APPCOMMAND_REPLY_TO_MAIL 39 +#define APPCOMMAND_FORWARD_MAIL 40 +#define APPCOMMAND_SEND_MAIL 41 +#define APPCOMMAND_SPELL_CHECK 42 +#define APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE 43 +#define APPCOMMAND_MIC_ON_OFF_TOGGLE 44 +#define APPCOMMAND_CORRECTION_LIST 45 +#define APPCOMMAND_MEDIA_PLAY 46 +#define APPCOMMAND_MEDIA_PAUSE 47 +#define APPCOMMAND_MEDIA_RECORD 48 +#define APPCOMMAND_MEDIA_FAST_FORWARD 49 +#define APPCOMMAND_MEDIA_REWIND 50 +#define APPCOMMAND_MEDIA_CHANNEL_UP 51 +#define APPCOMMAND_MEDIA_CHANNEL_DOWN 52 + +#define FAPPCOMMAND_MOUSE 0x8000 +#define FAPPCOMMAND_KEY 0 +#define FAPPCOMMAND_OEM 0x1000 +#define FAPPCOMMAND_MASK 0xF000 + +#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK)) +#define GET_DEVICE_LPARAM(lParam) ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK)) +#define GET_MOUSEORKEY_LPARAM GET_DEVICE_LPARAM +#define GET_FLAGS_LPARAM(lParam) (LOWORD(lParam)) +#define GET_KEYSTATE_LPARAM(lParam) GET_FLAGS_LPARAM(lParam) + + typedef struct { + HWND hwnd; + RECT rc; + } SHELLHOOKINFO,*LPSHELLHOOKINFO; + + typedef struct tagEVENTMSG { + UINT message; + UINT paramL; + UINT paramH; + DWORD time; + HWND hwnd; + } EVENTMSG,*PEVENTMSGMSG,*NPEVENTMSGMSG,*LPEVENTMSGMSG; + + typedef struct tagEVENTMSG *PEVENTMSG,*NPEVENTMSG,*LPEVENTMSG; + + typedef struct tagCWPSTRUCT { + LPARAM lParam; + WPARAM wParam; + UINT message; + HWND hwnd; + } CWPSTRUCT,*PCWPSTRUCT,*NPCWPSTRUCT,*LPCWPSTRUCT; + + typedef struct tagCWPRETSTRUCT { + LRESULT lResult; + LPARAM lParam; + WPARAM wParam; + UINT message; + HWND hwnd; + } CWPRETSTRUCT,*PCWPRETSTRUCT,*NPCWPRETSTRUCT,*LPCWPRETSTRUCT; + +#define LLKHF_EXTENDED (KF_EXTENDED >> 8) +#define LLKHF_INJECTED 0x00000010 +#define LLKHF_ALTDOWN (KF_ALTDOWN >> 8) +#define LLKHF_UP (KF_UP >> 8) + +#define LLMHF_INJECTED 0x00000001 + + typedef struct tagKBDLLHOOKSTRUCT { + DWORD vkCode; + DWORD scanCode; + DWORD flags; + DWORD time; + ULONG_PTR dwExtraInfo; + } KBDLLHOOKSTRUCT,*LPKBDLLHOOKSTRUCT,*PKBDLLHOOKSTRUCT; + + typedef struct tagMSLLHOOKSTRUCT { + POINT pt; + DWORD mouseData; + DWORD flags; + DWORD time; + ULONG_PTR dwExtraInfo; + } MSLLHOOKSTRUCT,*LPMSLLHOOKSTRUCT,*PMSLLHOOKSTRUCT; + + typedef struct tagDEBUGHOOKINFO { + DWORD idThread; + DWORD idThreadInstaller; + LPARAM lParam; + WPARAM wParam; + int code; + } DEBUGHOOKINFO,*PDEBUGHOOKINFO,*NPDEBUGHOOKINFO,*LPDEBUGHOOKINFO; + + typedef struct tagMOUSEHOOKSTRUCT { + POINT pt; + HWND hwnd; + UINT wHitTestCode; + ULONG_PTR dwExtraInfo; + } MOUSEHOOKSTRUCT,*LPMOUSEHOOKSTRUCT,*PMOUSEHOOKSTRUCT; + +#ifdef __cplusplus + typedef struct tagMOUSEHOOKSTRUCTEX : public tagMOUSEHOOKSTRUCT { + DWORD mouseData; + } MOUSEHOOKSTRUCTEX,*LPMOUSEHOOKSTRUCTEX,*PMOUSEHOOKSTRUCTEX; +#else + typedef struct tagMOUSEHOOKSTRUCTEX { + MOUSEHOOKSTRUCT _unnamed; + DWORD mouseData; + } MOUSEHOOKSTRUCTEX,*LPMOUSEHOOKSTRUCTEX,*PMOUSEHOOKSTRUCTEX; +#endif + + typedef struct tagHARDWAREHOOKSTRUCT { + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + } HARDWAREHOOKSTRUCT,*LPHARDWAREHOOKSTRUCT,*PHARDWAREHOOKSTRUCT; +#endif + +#define HKL_PREV 0 +#define HKL_NEXT 1 + +#define KLF_ACTIVATE 0x00000001 +#define KLF_SUBSTITUTE_OK 0x00000002 +#define KLF_REORDER 0x00000008 +#define KLF_REPLACELANG 0x00000010 +#define KLF_NOTELLSHELL 0x00000080 +#define KLF_SETFORPROCESS 0x00000100 +#define KLF_SHIFTLOCK 0x00010000 +#define KLF_RESET 0x40000000 + +#define INPUTLANGCHANGE_SYSCHARSET 0x0001 +#define INPUTLANGCHANGE_FORWARD 0x0002 +#define INPUTLANGCHANGE_BACKWARD 0x0004 + +#define KL_NAMELENGTH 9 + +#ifdef UNICODE +#define LoadKeyboardLayout LoadKeyboardLayoutW +#define GetKeyboardLayoutName GetKeyboardLayoutNameW +#else +#define LoadKeyboardLayout LoadKeyboardLayoutA +#define GetKeyboardLayoutName GetKeyboardLayoutNameA +#endif + + WINUSERAPI HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID,UINT Flags); + WINUSERAPI HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID,UINT Flags); + WINUSERAPI HKL WINAPI ActivateKeyboardLayout(HKL hkl,UINT Flags); + WINUSERAPI int WINAPI ToUnicodeEx(UINT wVirtKey,UINT wScanCode,CONST BYTE *lpKeyState,LPWSTR pwszBuff,int cchBuff,UINT wFlags,HKL dwhkl); + WINUSERAPI WINBOOL WINAPI UnloadKeyboardLayout(HKL hkl); + WINUSERAPI WINBOOL WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID); + WINUSERAPI WINBOOL WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID); + WINUSERAPI int WINAPI GetKeyboardLayoutList(int nBuff,HKL *lpList); + WINUSERAPI HKL WINAPI GetKeyboardLayout(DWORD idThread); + + typedef struct tagMOUSEMOVEPOINT { + int x; + int y; + DWORD time; + ULONG_PTR dwExtraInfo; + } MOUSEMOVEPOINT,*PMOUSEMOVEPOINT,*LPMOUSEMOVEPOINT; + +#define GMMP_USE_DISPLAY_POINTS 1 +#define GMMP_USE_HIGH_RESOLUTION_POINTS 2 + + WINUSERAPI int WINAPI GetMouseMovePointsEx(UINT cbSize,LPMOUSEMOVEPOINT lppt,LPMOUSEMOVEPOINT lpptBuf,int nBufPoints,DWORD resolution); + +#ifndef NODESKTOP + +#define DESKTOP_READOBJECTS 0x0001L +#define DESKTOP_CREATEWINDOW 0x0002L +#define DESKTOP_CREATEMENU 0x0004L +#define DESKTOP_HOOKCONTROL 0x0008L +#define DESKTOP_JOURNALRECORD 0x0010L +#define DESKTOP_JOURNALPLAYBACK 0x0020L +#define DESKTOP_ENUMERATE 0x0040L +#define DESKTOP_WRITEOBJECTS 0x0080L +#define DESKTOP_SWITCHDESKTOP 0x0100L + +#define DF_ALLOWOTHERACCOUNTHOOK 0x0001L + +#ifdef _WINGDI_ +#ifndef NOGDI +#ifdef UNICODE +#define CreateDesktop CreateDesktopW +#else +#define CreateDesktop CreateDesktopA +#endif + + WINUSERAPI HDESK WINAPI CreateDesktopA(LPCSTR lpszDesktop,LPCSTR lpszDevice,LPDEVMODEA pDevmode,DWORD dwFlags,ACCESS_MASK dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa); + WINUSERAPI HDESK WINAPI CreateDesktopW(LPCWSTR lpszDesktop,LPCWSTR lpszDevice,LPDEVMODEW pDevmode,DWORD dwFlags,ACCESS_MASK dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa); +#endif +#endif + +#ifdef UNICODE +#define OpenDesktop OpenDesktopW +#define EnumDesktops EnumDesktopsW +#else +#define OpenDesktop OpenDesktopA +#define EnumDesktops EnumDesktopsA +#endif + + WINUSERAPI HDESK WINAPI OpenDesktopA(LPCSTR lpszDesktop,DWORD dwFlags,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess); + WINUSERAPI HDESK WINAPI OpenDesktopW(LPCWSTR lpszDesktop,DWORD dwFlags,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess); + WINUSERAPI HDESK WINAPI OpenInputDesktop(DWORD dwFlags,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess); + WINUSERAPI WINBOOL WINAPI EnumDesktopsA(HWINSTA hwinsta,DESKTOPENUMPROCA lpEnumFunc,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI EnumDesktopsW(HWINSTA hwinsta,DESKTOPENUMPROCW lpEnumFunc,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI EnumDesktopWindows(HDESK hDesktop,WNDENUMPROC lpfn,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI SwitchDesktop(HDESK hDesktop); + WINUSERAPI WINBOOL WINAPI SetThreadDesktop(HDESK hDesktop); + WINUSERAPI WINBOOL WINAPI CloseDesktop(HDESK hDesktop); + WINUSERAPI HDESK WINAPI GetThreadDesktop(DWORD dwThreadId); +#endif + +#ifndef NOWINDOWSTATION +#define WINSTA_ENUMDESKTOPS 0x0001L +#define WINSTA_READATTRIBUTES 0x0002L +#define WINSTA_ACCESSCLIPBOARD 0x0004L +#define WINSTA_CREATEDESKTOP 0x0008L +#define WINSTA_WRITEATTRIBUTES 0x0010L +#define WINSTA_ACCESSGLOBALATOMS 0x0020L +#define WINSTA_EXITWINDOWS 0x0040L +#define WINSTA_ENUMERATE 0x0100L +#define WINSTA_READSCREEN 0x0200L +#define WINSTA_ALL_ACCESS (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN) + +#define CWF_CREATE_ONLY 0x0001L + +#define WSF_VISIBLE 0x0001L + +#ifdef UNICODE +#define CreateWindowStation CreateWindowStationW +#define OpenWindowStation OpenWindowStationW +#define EnumWindowStations EnumWindowStationsW +#else +#define CreateWindowStation CreateWindowStationA +#define OpenWindowStation OpenWindowStationA +#define EnumWindowStations EnumWindowStationsA +#endif + + WINUSERAPI HWINSTA WINAPI CreateWindowStationA(LPCSTR lpwinsta,DWORD dwFlags,ACCESS_MASK dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa); + WINUSERAPI HWINSTA WINAPI CreateWindowStationW(LPCWSTR lpwinsta,DWORD dwFlags,ACCESS_MASK dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa); + WINUSERAPI HWINSTA WINAPI OpenWindowStationA(LPCSTR lpszWinSta,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess); + WINUSERAPI HWINSTA WINAPI OpenWindowStationW(LPCWSTR lpszWinSta,WINBOOL fInherit,ACCESS_MASK dwDesiredAccess); + WINUSERAPI WINBOOL WINAPI EnumWindowStationsA(WINSTAENUMPROCA lpEnumFunc,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI EnumWindowStationsW(WINSTAENUMPROCW lpEnumFunc,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI CloseWindowStation(HWINSTA hWinSta); + WINUSERAPI WINBOOL WINAPI SetProcessWindowStation(HWINSTA hWinSta); + WINUSERAPI HWINSTA WINAPI GetProcessWindowStation(VOID); +#endif + +#ifndef NOSECURITY + WINUSERAPI WINBOOL WINAPI SetUserObjectSecurity(HANDLE hObj,PSECURITY_INFORMATION pSIRequested,PSECURITY_DESCRIPTOR pSID); + WINUSERAPI WINBOOL WINAPI GetUserObjectSecurity(HANDLE hObj,PSECURITY_INFORMATION pSIRequested,PSECURITY_DESCRIPTOR pSID,DWORD nLength,LPDWORD lpnLengthNeeded); + +#define UOI_FLAGS 1 +#define UOI_NAME 2 +#define UOI_TYPE 3 +#define UOI_USER_SID 4 + + typedef struct tagUSEROBJECTFLAGS { + WINBOOL fInherit; + WINBOOL fReserved; + DWORD dwFlags; + } USEROBJECTFLAGS,*PUSEROBJECTFLAGS; + +#ifdef UNICODE +#define GetUserObjectInformation GetUserObjectInformationW +#define SetUserObjectInformation SetUserObjectInformationW +#else +#define GetUserObjectInformation GetUserObjectInformationA +#define SetUserObjectInformation SetUserObjectInformationA +#endif + + WINUSERAPI WINBOOL WINAPI GetUserObjectInformationA(HANDLE hObj,int nIndex,PVOID pvInfo,DWORD nLength,LPDWORD lpnLengthNeeded); + WINUSERAPI WINBOOL WINAPI GetUserObjectInformationW(HANDLE hObj,int nIndex,PVOID pvInfo,DWORD nLength,LPDWORD lpnLengthNeeded); + WINUSERAPI WINBOOL WINAPI SetUserObjectInformationA(HANDLE hObj,int nIndex,PVOID pvInfo,DWORD nLength); + WINUSERAPI WINBOOL WINAPI SetUserObjectInformationW(HANDLE hObj,int nIndex,PVOID pvInfo,DWORD nLength); +#endif + + typedef struct tagWNDCLASSEXA { + UINT cbSize; + UINT style; + WNDPROC lpfnWndProc; + int cbClsExtra; + int cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCSTR lpszMenuName; + LPCSTR lpszClassName; + HICON hIconSm; + } WNDCLASSEXA,*PWNDCLASSEXA,*NPWNDCLASSEXA,*LPWNDCLASSEXA; + + typedef struct tagWNDCLASSEXW { + UINT cbSize; + UINT style; + WNDPROC lpfnWndProc; + int cbClsExtra; + int cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCWSTR lpszMenuName; + LPCWSTR lpszClassName; + + HICON hIconSm; + } WNDCLASSEXW,*PWNDCLASSEXW,*NPWNDCLASSEXW,*LPWNDCLASSEXW; + +#ifdef UNICODE + typedef WNDCLASSEXW WNDCLASSEX; + typedef PWNDCLASSEXW PWNDCLASSEX; + typedef NPWNDCLASSEXW NPWNDCLASSEX; + typedef LPWNDCLASSEXW LPWNDCLASSEX; +#else + typedef WNDCLASSEXA WNDCLASSEX; + typedef PWNDCLASSEXA PWNDCLASSEX; + typedef NPWNDCLASSEXA NPWNDCLASSEX; + typedef LPWNDCLASSEXA LPWNDCLASSEX; +#endif + + typedef struct tagWNDCLASSA { + UINT style; + WNDPROC lpfnWndProc; + int cbClsExtra; + int cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCSTR lpszMenuName; + LPCSTR lpszClassName; + } WNDCLASSA,*PWNDCLASSA,*NPWNDCLASSA,*LPWNDCLASSA; + + typedef struct tagWNDCLASSW { + UINT style; + WNDPROC lpfnWndProc; + int cbClsExtra; + int cbWndExtra; + HINSTANCE hInstance; + HICON hIcon; + HCURSOR hCursor; + HBRUSH hbrBackground; + LPCWSTR lpszMenuName; + LPCWSTR lpszClassName; + } WNDCLASSW,*PWNDCLASSW,*NPWNDCLASSW,*LPWNDCLASSW; + +#ifdef UNICODE + typedef WNDCLASSW WNDCLASS; + typedef PWNDCLASSW PWNDCLASS; + typedef NPWNDCLASSW NPWNDCLASS; + typedef LPWNDCLASSW LPWNDCLASS; +#else + typedef WNDCLASSA WNDCLASS; + typedef PWNDCLASSA PWNDCLASS; + typedef NPWNDCLASSA NPWNDCLASS; + typedef LPWNDCLASSA LPWNDCLASS; +#endif + + WINUSERAPI WINBOOL WINAPI IsHungAppWindow(HWND hwnd); + WINUSERAPI VOID WINAPI DisableProcessWindowsGhosting(VOID); + +#ifndef NOMSG + typedef struct tagMSG { + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + DWORD time; + POINT pt; + } MSG,*PMSG,*NPMSG,*LPMSG; + +#define POINTSTOPOINT(pt,pts) { (pt).x = (LONG)(SHORT)LOWORD(*(LONG*)&pts); (pt).y = (LONG)(SHORT)HIWORD(*(LONG*)&pts); } + +#define POINTTOPOINTS(pt) (MAKELONG((short)((pt).x),(short)((pt).y))) +#define MAKEWPARAM(l,h) ((WPARAM)(DWORD)MAKELONG(l,h)) +#define MAKELPARAM(l,h) ((LPARAM)(DWORD)MAKELONG(l,h)) +#define MAKELRESULT(l,h) ((LRESULT)(DWORD)MAKELONG(l,h)) +#endif + +#ifndef NOWINOFFSETS #define GWL_WNDPROC (-4) -#define GWLP_WNDPROC (-4) #define GWL_HINSTANCE (-6) -#define GWLP_HINSTANCE (-6) #define GWL_HWNDPARENT (-8) -#define GWLP_HWNDPARENT (-8) -#define GWL_ID (-12) -#define GWLP_ID (-12) +#define GWL_STYLE (-16) +#define GWL_EXSTYLE (-20) #define GWL_USERDATA (-21) +#define GWL_ID (-12) + +#ifdef _WIN64 +#undef GWL_WNDPROC +#undef GWL_HINSTANCE +#undef GWL_HWNDPARENT +#undef GWL_USERDATA +#endif + +#define GWLP_WNDPROC (-4) +#define GWLP_HINSTANCE (-6) +#define GWLP_HWNDPARENT (-8) #define GWLP_USERDATA (-21) -#define DWL_DLGPROC 4 -#define DWLP_DLGPROC 4 -#define DWL_MSGRESULT 0 -#define DWLP_MSGRESULT 0 -#define DWL_USER 8 -#define DWLP_USER 8 -#define QS_ALLEVENTS 191 -#define QS_ALLINPUT 255 -#define QS_HOTKEY 128 -#define QS_INPUT 7 -#define QS_KEY 1 -#define QS_MOUSE 6 -#define QS_MOUSEBUTTON 4 -#define QS_MOUSEMOVE 2 -#define QS_PAINT 32 -#define QS_POSTMESSAGE 8 -#define QS_SENDMESSAGE 64 -#define QS_TIMER 16 -#define COLOR_3DDKSHADOW 21 -#define COLOR_3DFACE 15 -#define COLOR_3DHILIGHT 20 -#define COLOR_3DHIGHLIGHT 20 -#define COLOR_3DLIGHT 22 -#define COLOR_BTNHILIGHT 20 -#define COLOR_3DSHADOW 16 -#define COLOR_ACTIVEBORDER 10 -#define COLOR_ACTIVECAPTION 2 -#define COLOR_APPWORKSPACE 12 -#define COLOR_BACKGROUND 1 -#define COLOR_DESKTOP 1 -#define COLOR_BTNFACE 15 -#define COLOR_BTNHIGHLIGHT 20 -#define COLOR_BTNSHADOW 16 -#define COLOR_BTNTEXT 18 -#define COLOR_CAPTIONTEXT 9 -#define COLOR_GRAYTEXT 17 -#define COLOR_HIGHLIGHT 13 -#define COLOR_HIGHLIGHTTEXT 14 -#define COLOR_INACTIVEBORDER 11 -#define COLOR_INACTIVECAPTION 3 -#define COLOR_INACTIVECAPTIONTEXT 19 -#define COLOR_INFOBK 24 -#define COLOR_INFOTEXT 23 -#define COLOR_MENU 4 -#define COLOR_MENUTEXT 7 -#define COLOR_SCROLLBAR 0 -#define COLOR_WINDOW 5 -#define COLOR_WINDOWFRAME 6 -#define COLOR_WINDOWTEXT 8 -#define CTLCOLOR_MSGBOX 0 -#define CTLCOLOR_EDIT 1 -#define CTLCOLOR_LISTBOX 2 -#define CTLCOLOR_BTN 3 -#define CTLCOLOR_DLG 4 -#define CTLCOLOR_SCROLLBAR 5 -#define CTLCOLOR_STATIC 6 -#define CTLCOLOR_MAX 7 +#define GWLP_ID (-12) + +#define GCL_MENUNAME (-8) +#define GCL_HBRBACKGROUND (-10) +#define GCL_HCURSOR (-12) +#define GCL_HICON (-14) +#define GCL_HMODULE (-16) +#define GCL_CBWNDEXTRA (-18) +#define GCL_CBCLSEXTRA (-20) +#define GCL_WNDPROC (-24) +#define GCL_STYLE (-26) +#define GCW_ATOM (-32) +#define GCL_HICONSM (-34) + +#ifdef _WIN64 + +#undef GCL_MENUNAME +#undef GCL_HBRBACKGROUND +#undef GCL_HCURSOR +#undef GCL_HICON +#undef GCL_HMODULE +#undef GCL_WNDPROC +#undef GCL_HICONSM +#endif + +#define GCLP_MENUNAME (-8) +#define GCLP_HBRBACKGROUND (-10) +#define GCLP_HCURSOR (-12) +#define GCLP_HICON (-14) +#define GCLP_HMODULE (-16) +#define GCLP_WNDPROC (-24) +#define GCLP_HICONSM (-34) +#endif + +#ifndef NOWINMESSAGES + +#define WM_NULL 0x0000 +#define WM_CREATE 0x0001 +#define WM_DESTROY 0x0002 +#define WM_MOVE 0x0003 +#define WM_SIZE 0x0005 + +#define WM_ACTIVATE 0x0006 + +#define WA_INACTIVE 0 +#define WA_ACTIVE 1 +#define WA_CLICKACTIVE 2 + +#define WM_SETFOCUS 0x0007 +#define WM_KILLFOCUS 0x0008 +#define WM_ENABLE 0x000A +#define WM_SETREDRAW 0x000B +#define WM_SETTEXT 0x000C +#define WM_GETTEXT 0x000D +#define WM_GETTEXTLENGTH 0x000E +#define WM_PAINT 0x000F +#define WM_CLOSE 0x0010 +#ifndef _WIN32_WCE +#define WM_QUERYENDSESSION 0x0011 +#define WM_QUERYOPEN 0x0013 +#define WM_ENDSESSION 0x0016 +#endif +#define WM_QUIT 0x0012 +#define WM_ERASEBKGND 0x0014 +#define WM_SYSCOLORCHANGE 0x0015 +#define WM_SHOWWINDOW 0x0018 +#define WM_WININICHANGE 0x001A +#define WM_SETTINGCHANGE WM_WININICHANGE +#define WM_DEVMODECHANGE 0x001B +#define WM_ACTIVATEAPP 0x001C +#define WM_FONTCHANGE 0x001D +#define WM_TIMECHANGE 0x001E +#define WM_CANCELMODE 0x001F +#define WM_SETCURSOR 0x0020 +#define WM_MOUSEACTIVATE 0x0021 +#define WM_CHILDACTIVATE 0x0022 +#define WM_QUEUESYNC 0x0023 + +#define WM_GETMINMAXINFO 0x0024 + + typedef struct tagMINMAXINFO { + POINT ptReserved; + POINT ptMaxSize; + POINT ptMaxPosition; + POINT ptMinTrackSize; + POINT ptMaxTrackSize; + } MINMAXINFO,*PMINMAXINFO,*LPMINMAXINFO; + +#define WM_PAINTICON 0x0026 +#define WM_ICONERASEBKGND 0x0027 +#define WM_NEXTDLGCTL 0x0028 +#define WM_SPOOLERSTATUS 0x002A +#define WM_DRAWITEM 0x002B +#define WM_MEASUREITEM 0x002C +#define WM_DELETEITEM 0x002D +#define WM_VKEYTOITEM 0x002E +#define WM_CHARTOITEM 0x002F +#define WM_SETFONT 0x0030 +#define WM_GETFONT 0x0031 +#define WM_SETHOTKEY 0x0032 +#define WM_GETHOTKEY 0x0033 +#define WM_QUERYDRAGICON 0x0037 +#define WM_COMPAREITEM 0x0039 +#ifndef _WIN32_WCE +#define WM_GETOBJECT 0x003D +#endif +#define WM_COMPACTING 0x0041 +#define WM_COMMNOTIFY 0x0044 +#define WM_WINDOWPOSCHANGING 0x0046 +#define WM_WINDOWPOSCHANGED 0x0047 + +#define WM_POWER 0x0048 + +#define PWR_OK 1 +#define PWR_FAIL (-1) +#define PWR_SUSPENDREQUEST 1 +#define PWR_SUSPENDRESUME 2 +#define PWR_CRITICALRESUME 3 + +#define WM_COPYDATA 0x004A +#define WM_CANCELJOURNAL 0x004B + + typedef struct tagCOPYDATASTRUCT { + ULONG_PTR dwData; + DWORD cbData; + PVOID lpData; + } COPYDATASTRUCT,*PCOPYDATASTRUCT; + + typedef struct tagMDINEXTMENU { + HMENU hmenuIn; + HMENU hmenuNext; + HWND hwndNext; + } MDINEXTMENU,*PMDINEXTMENU,*LPMDINEXTMENU; + +#define WM_NOTIFY 0x004E +#define WM_INPUTLANGCHANGEREQUEST 0x0050 +#define WM_INPUTLANGCHANGE 0x0051 +#define WM_TCARD 0x0052 +#define WM_HELP 0x0053 +#define WM_USERCHANGED 0x0054 +#define WM_NOTIFYFORMAT 0x0055 + +#define NFR_ANSI 1 +#define NFR_UNICODE 2 +#define NF_QUERY 3 +#define NF_REQUERY 4 + +#define WM_CONTEXTMENU 0x007B +#define WM_STYLECHANGING 0x007C +#define WM_STYLECHANGED 0x007D +#define WM_DISPLAYCHANGE 0x007E +#define WM_GETICON 0x007F +#define WM_SETICON 0x0080 + +#define WM_NCCREATE 0x0081 +#define WM_NCDESTROY 0x0082 +#define WM_NCCALCSIZE 0x0083 +#define WM_NCHITTEST 0x0084 +#define WM_NCPAINT 0x0085 +#define WM_NCACTIVATE 0x0086 +#define WM_GETDLGCODE 0x0087 +#ifndef _WIN32_WCE +#define WM_SYNCPAINT 0x0088 +#endif +#define WM_NCMOUSEMOVE 0x00A0 +#define WM_NCLBUTTONDOWN 0x00A1 +#define WM_NCLBUTTONUP 0x00A2 +#define WM_NCLBUTTONDBLCLK 0x00A3 +#define WM_NCRBUTTONDOWN 0x00A4 +#define WM_NCRBUTTONUP 0x00A5 +#define WM_NCRBUTTONDBLCLK 0x00A6 +#define WM_NCMBUTTONDOWN 0x00A7 +#define WM_NCMBUTTONUP 0x00A8 +#define WM_NCMBUTTONDBLCLK 0x00A9 + +#define WM_NCXBUTTONDOWN 0x00AB +#define WM_NCXBUTTONUP 0x00AC +#define WM_NCXBUTTONDBLCLK 0x00AD +#define WM_INPUT 0x00FF +#define WM_KEYFIRST 0x0100 +#define WM_KEYDOWN 0x0100 +#define WM_KEYUP 0x0101 +#define WM_CHAR 0x0102 +#define WM_DEADCHAR 0x0103 +#define WM_SYSKEYDOWN 0x0104 +#define WM_SYSKEYUP 0x0105 +#define WM_SYSCHAR 0x0106 +#define WM_SYSDEADCHAR 0x0107 +#define WM_UNICHAR 0x0109 +#define WM_KEYLAST 0x0109 +#define UNICODE_NOCHAR 0xFFFF +#define WM_IME_STARTCOMPOSITION 0x010D +#define WM_IME_ENDCOMPOSITION 0x010E +#define WM_IME_COMPOSITION 0x010F +#define WM_IME_KEYLAST 0x010F +#define WM_INITDIALOG 0x0110 +#define WM_COMMAND 0x0111 +#define WM_SYSCOMMAND 0x0112 +#define WM_TIMER 0x0113 +#define WM_HSCROLL 0x0114 +#define WM_VSCROLL 0x0115 +#define WM_INITMENU 0x0116 +#define WM_INITMENUPOPUP 0x0117 +#define WM_MENUSELECT 0x011F +#define WM_MENUCHAR 0x0120 +#define WM_ENTERIDLE 0x0121 +#ifndef _WIN32_WCE +#define WM_MENURBUTTONUP 0x0122 +#define WM_MENUDRAG 0x0123 +#define WM_MENUGETOBJECT 0x0124 +#define WM_UNINITMENUPOPUP 0x0125 +#define WM_MENUCOMMAND 0x0126 + +#ifndef _WIN32_WCE +#define WM_CHANGEUISTATE 0x0127 +#define WM_UPDATEUISTATE 0x0128 +#define WM_QUERYUISTATE 0x0129 + +#define UIS_SET 1 +#define UIS_CLEAR 2 +#define UIS_INITIALIZE 3 + +#define UISF_HIDEFOCUS 0x1 +#define UISF_HIDEACCEL 0x2 +#define UISF_ACTIVE 0x4 +#endif +#endif + +#define WM_CTLCOLORMSGBOX 0x0132 +#define WM_CTLCOLOREDIT 0x0133 +#define WM_CTLCOLORLISTBOX 0x0134 +#define WM_CTLCOLORBTN 0x0135 +#define WM_CTLCOLORDLG 0x0136 +#define WM_CTLCOLORSCROLLBAR 0x0137 +#define WM_CTLCOLORSTATIC 0x0138 +#define MN_GETHMENU 0x01E1 + +#define WM_MOUSEFIRST 0x0200 +#define WM_MOUSEMOVE 0x0200 +#define WM_LBUTTONDOWN 0x0201 +#define WM_LBUTTONUP 0x0202 +#define WM_LBUTTONDBLCLK 0x0203 +#define WM_RBUTTONDOWN 0x0204 +#define WM_RBUTTONUP 0x0205 +#define WM_RBUTTONDBLCLK 0x0206 +#define WM_MBUTTONDOWN 0x0207 +#define WM_MBUTTONUP 0x0208 +#define WM_MBUTTONDBLCLK 0x0209 +#define WM_MOUSEWHEEL 0x020A +#define WM_XBUTTONDOWN 0x020B +#define WM_XBUTTONUP 0x020C +#define WM_XBUTTONDBLCLK 0x020D +#define WM_MOUSELAST 0x020D + +#define WHEEL_DELTA 120 +#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam)) + +#define WHEEL_PAGESCROLL (UINT_MAX) + +#define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam)) +#define GET_NCHITTEST_WPARAM(wParam) ((short)LOWORD(wParam)) +#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) + +#define XBUTTON1 0x0001 +#define XBUTTON2 0x0002 + +#define WM_PARENTNOTIFY 0x0210 +#define WM_ENTERMENULOOP 0x0211 +#define WM_EXITMENULOOP 0x0212 + +#define WM_NEXTMENU 0x0213 +#define WM_SIZING 0x0214 +#define WM_CAPTURECHANGED 0x0215 +#define WM_MOVING 0x0216 + +#define WM_POWERBROADCAST 0x0218 + +#ifndef _WIN32_WCE +#define PBT_APMQUERYSUSPEND 0x0000 +#define PBT_APMQUERYSTANDBY 0x0001 + +#define PBT_APMQUERYSUSPENDFAILED 0x0002 +#define PBT_APMQUERYSTANDBYFAILED 0x0003 + +#define PBT_APMSUSPEND 0x0004 +#define PBT_APMSTANDBY 0x0005 + +#define PBT_APMRESUMECRITICAL 0x0006 +#define PBT_APMRESUMESUSPEND 0x0007 +#define PBT_APMRESUMESTANDBY 0x0008 + +#define PBTF_APMRESUMEFROMFAILURE 0x00000001 + +#define PBT_APMBATTERYLOW 0x0009 +#define PBT_APMPOWERSTATUSCHANGE 0x000A + +#define PBT_APMOEMEVENT 0x000B +#define PBT_APMRESUMEAUTOMATIC 0x0012 +#endif + +#define WM_DEVICECHANGE 0x0219 + +#define WM_MDICREATE 0x0220 +#define WM_MDIDESTROY 0x0221 +#define WM_MDIACTIVATE 0x0222 +#define WM_MDIRESTORE 0x0223 +#define WM_MDINEXT 0x0224 +#define WM_MDIMAXIMIZE 0x0225 +#define WM_MDITILE 0x0226 +#define WM_MDICASCADE 0x0227 +#define WM_MDIICONARRANGE 0x0228 +#define WM_MDIGETACTIVE 0x0229 + +#define WM_MDISETMENU 0x0230 +#define WM_ENTERSIZEMOVE 0x0231 +#define WM_EXITSIZEMOVE 0x0232 +#define WM_DROPFILES 0x0233 +#define WM_MDIREFRESHMENU 0x0234 + +#define WM_IME_SETCONTEXT 0x0281 +#define WM_IME_NOTIFY 0x0282 +#define WM_IME_CONTROL 0x0283 +#define WM_IME_COMPOSITIONFULL 0x0284 +#define WM_IME_SELECT 0x0285 +#define WM_IME_CHAR 0x0286 +#define WM_IME_REQUEST 0x0288 +#define WM_IME_KEYDOWN 0x0290 +#define WM_IME_KEYUP 0x0291 + +#define WM_MOUSEHOVER 0x02A1 +#define WM_MOUSELEAVE 0x02A3 +#define WM_NCMOUSEHOVER 0x02A0 +#define WM_NCMOUSELEAVE 0x02A2 +#define WM_WTSSESSION_CHANGE 0x02B1 +#define WM_TABLET_FIRST 0x02c0 +#define WM_TABLET_LAST 0x02df +#define WM_CUT 0x0300 +#define WM_COPY 0x0301 +#define WM_PASTE 0x0302 +#define WM_CLEAR 0x0303 +#define WM_UNDO 0x0304 +#define WM_RENDERFORMAT 0x0305 +#define WM_RENDERALLFORMATS 0x0306 +#define WM_DESTROYCLIPBOARD 0x0307 +#define WM_DRAWCLIPBOARD 0x0308 +#define WM_PAINTCLIPBOARD 0x0309 +#define WM_VSCROLLCLIPBOARD 0x030A +#define WM_SIZECLIPBOARD 0x030B +#define WM_ASKCBFORMATNAME 0x030C +#define WM_CHANGECBCHAIN 0x030D +#define WM_HSCROLLCLIPBOARD 0x030E +#define WM_QUERYNEWPALETTE 0x030F +#define WM_PALETTEISCHANGING 0x0310 +#define WM_PALETTECHANGED 0x0311 +#define WM_HOTKEY 0x0312 +#define WM_PRINT 0x0317 +#define WM_PRINTCLIENT 0x0318 +#define WM_APPCOMMAND 0x0319 +#define WM_THEMECHANGED 0x031A +#define WM_HANDHELDFIRST 0x0358 +#define WM_HANDHELDLAST 0x035F +#define WM_AFXFIRST 0x0360 +#define WM_AFXLAST 0x037F +#define WM_PENWINFIRST 0x0380 +#define WM_PENWINLAST 0x038F +#define WM_APP 0x8000 +#define WM_USER 0x0400 + +#define WMSZ_LEFT 1 +#define WMSZ_RIGHT 2 +#define WMSZ_TOP 3 +#define WMSZ_TOPLEFT 4 +#define WMSZ_TOPRIGHT 5 +#define WMSZ_BOTTOM 6 +#define WMSZ_BOTTOMLEFT 7 +#define WMSZ_BOTTOMRIGHT 8 + +#ifndef NONCMESSAGES + +#define HTERROR (-2) +#define HTTRANSPARENT (-1) +#define HTNOWHERE 0 +#define HTCLIENT 1 +#define HTCAPTION 2 +#define HTSYSMENU 3 +#define HTGROWBOX 4 +#define HTSIZE HTGROWBOX +#define HTMENU 5 +#define HTHSCROLL 6 +#define HTVSCROLL 7 +#define HTMINBUTTON 8 +#define HTMAXBUTTON 9 +#define HTLEFT 10 +#define HTRIGHT 11 +#define HTTOP 12 +#define HTTOPLEFT 13 +#define HTTOPRIGHT 14 +#define HTBOTTOM 15 +#define HTBOTTOMLEFT 16 +#define HTBOTTOMRIGHT 17 +#define HTBORDER 18 +#define HTREDUCE HTMINBUTTON +#define HTZOOM HTMAXBUTTON +#define HTSIZEFIRST HTLEFT +#define HTSIZELAST HTBOTTOMRIGHT +#define HTOBJECT 19 +#define HTCLOSE 20 +#define HTHELP 21 + +#define SMTO_NORMAL 0x0000 +#define SMTO_BLOCK 0x0001 +#define SMTO_ABORTIFHUNG 0x0002 +#define SMTO_NOTIMEOUTIFNOTHUNG 0x0008 +#endif + +#define MA_ACTIVATE 1 +#define MA_ACTIVATEANDEAT 2 +#define MA_NOACTIVATE 3 +#define MA_NOACTIVATEANDEAT 4 + +#define ICON_SMALL 0 +#define ICON_BIG 1 +#define ICON_SMALL2 2 + +#ifdef UNICODE +#define RegisterWindowMessage RegisterWindowMessageW +#else +#define RegisterWindowMessage RegisterWindowMessageA +#endif + + WINUSERAPI UINT WINAPI RegisterWindowMessageA(LPCSTR lpString); + WINUSERAPI UINT WINAPI RegisterWindowMessageW(LPCWSTR lpString); + +#define SIZE_RESTORED 0 +#define SIZE_MINIMIZED 1 +#define SIZE_MAXIMIZED 2 +#define SIZE_MAXSHOW 3 +#define SIZE_MAXHIDE 4 + +#define SIZENORMAL SIZE_RESTORED +#define SIZEICONIC SIZE_MINIMIZED +#define SIZEFULLSCREEN SIZE_MAXIMIZED +#define SIZEZOOMSHOW SIZE_MAXSHOW +#define SIZEZOOMHIDE SIZE_MAXHIDE + + typedef struct tagWINDOWPOS { + HWND hwnd; + HWND hwndInsertAfter; + int x; + int y; + int cx; + int cy; + UINT flags; + } WINDOWPOS,*LPWINDOWPOS,*PWINDOWPOS; + + typedef struct tagNCCALCSIZE_PARAMS { + RECT rgrc[3]; + PWINDOWPOS lppos; + } NCCALCSIZE_PARAMS,*LPNCCALCSIZE_PARAMS; + +#define WVR_ALIGNTOP 0x0010 +#define WVR_ALIGNLEFT 0x0020 +#define WVR_ALIGNBOTTOM 0x0040 +#define WVR_ALIGNRIGHT 0x0080 +#define WVR_HREDRAW 0x0100 +#define WVR_VREDRAW 0x0200 +#define WVR_REDRAW (WVR_HREDRAW | WVR_VREDRAW) +#define WVR_VALIDRECTS 0x0400 + +#ifndef NOKEYSTATES + +#define MK_LBUTTON 0x0001 +#define MK_RBUTTON 0x0002 +#define MK_SHIFT 0x0004 +#define MK_CONTROL 0x0008 +#define MK_MBUTTON 0x0010 +#define MK_XBUTTON1 0x0020 +#define MK_XBUTTON2 0x0040 +#endif + +#ifndef NOTRACKMOUSEEVENT +#define TME_HOVER 0x00000001 +#define TME_LEAVE 0x00000002 +#define TME_NONCLIENT 0x00000010 +#define TME_QUERY 0x40000000 +#define TME_CANCEL 0x80000000 + +#define HOVER_DEFAULT 0xFFFFFFFF +#endif + + typedef struct tagTRACKMOUSEEVENT { + DWORD cbSize; + DWORD dwFlags; + HWND hwndTrack; + DWORD dwHoverTime; + } TRACKMOUSEEVENT,*LPTRACKMOUSEEVENT; + + WINUSERAPI WINBOOL WINAPI TrackMouseEvent(LPTRACKMOUSEEVENT lpEventTrack); +#endif + +#ifndef NOWINSTYLES + +#define WS_OVERLAPPED 0x00000000L +#define WS_POPUP 0x80000000L +#define WS_CHILD 0x40000000L +#define WS_MINIMIZE 0x20000000L +#define WS_VISIBLE 0x10000000L +#define WS_DISABLED 0x08000000L +#define WS_CLIPSIBLINGS 0x04000000L +#define WS_CLIPCHILDREN 0x02000000L +#define WS_MAXIMIZE 0x01000000L +#define WS_CAPTION 0x00C00000L +#define WS_BORDER 0x00800000L +#define WS_DLGFRAME 0x00400000L +#define WS_VSCROLL 0x00200000L +#define WS_HSCROLL 0x00100000L +#define WS_SYSMENU 0x00080000L +#define WS_THICKFRAME 0x00040000L +#define WS_GROUP 0x00020000L +#define WS_TABSTOP 0x00010000L +#define WS_MINIMIZEBOX 0x00020000L +#define WS_MAXIMIZEBOX 0x00010000L +#define WS_TILED WS_OVERLAPPED +#define WS_ICONIC WS_MINIMIZE +#define WS_SIZEBOX WS_THICKFRAME +#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW +#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) +#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU) +#define WS_CHILDWINDOW (WS_CHILD) + +#define WS_EX_DLGMODALFRAME 0x00000001L +#define WS_EX_NOPARENTNOTIFY 0x00000004L +#define WS_EX_TOPMOST 0x00000008L +#define WS_EX_ACCEPTFILES 0x00000010L +#define WS_EX_TRANSPARENT 0x00000020L +#define WS_EX_MDICHILD 0x00000040L +#define WS_EX_TOOLWINDOW 0x00000080L +#define WS_EX_WINDOWEDGE 0x00000100L +#define WS_EX_CLIENTEDGE 0x00000200L +#define WS_EX_CONTEXTHELP 0x00000400L +#define WS_EX_RIGHT 0x00001000L +#define WS_EX_LEFT 0x00000000L +#define WS_EX_RTLREADING 0x00002000L +#define WS_EX_LTRREADING 0x00000000L +#define WS_EX_LEFTSCROLLBAR 0x00004000L +#define WS_EX_RIGHTSCROLLBAR 0x00000000L +#define WS_EX_CONTROLPARENT 0x00010000L +#define WS_EX_STATICEDGE 0x00020000L +#define WS_EX_APPWINDOW 0x00040000L +#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE) +#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST) +#define WS_EX_LAYERED 0x00080000 +#define WS_EX_NOINHERITLAYOUT 0x00100000L +#define WS_EX_LAYOUTRTL 0x00400000L +#define WS_EX_COMPOSITED 0x02000000L +#define WS_EX_NOACTIVATE 0x08000000L + +#define CS_VREDRAW 0x0001 +#define CS_HREDRAW 0x0002 +#define CS_DBLCLKS 0x0008 +#define CS_OWNDC 0x0020 +#define CS_CLASSDC 0x0040 +#define CS_PARENTDC 0x0080 +#define CS_NOCLOSE 0x0200 +#define CS_SAVEBITS 0x0800 +#define CS_BYTEALIGNCLIENT 0x1000 +#define CS_BYTEALIGNWINDOW 0x2000 +#define CS_GLOBALCLASS 0x4000 +#define CS_IME 0x00010000 +#define CS_DROPSHADOW 0x00020000 +#endif + +#define PRF_CHECKVISIBLE 0x00000001L +#define PRF_NONCLIENT 0x00000002L +#define PRF_CLIENT 0x00000004L +#define PRF_ERASEBKGND 0x00000008L +#define PRF_CHILDREN 0x00000010L +#define PRF_OWNED 0x00000020L + +#define BDR_RAISEDOUTER 0x0001 +#define BDR_SUNKENOUTER 0x0002 +#define BDR_RAISEDINNER 0x0004 +#define BDR_SUNKENINNER 0x0008 + +#define BDR_OUTER (BDR_RAISEDOUTER | BDR_SUNKENOUTER) +#define BDR_INNER (BDR_RAISEDINNER | BDR_SUNKENINNER) +#define BDR_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER) +#define BDR_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER) + +#define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER) +#define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER) +#define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER) +#define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER) + +#define BF_LEFT 0x0001 +#define BF_TOP 0x0002 +#define BF_RIGHT 0x0004 +#define BF_BOTTOM 0x0008 + +#define BF_TOPLEFT (BF_TOP | BF_LEFT) +#define BF_TOPRIGHT (BF_TOP | BF_RIGHT) +#define BF_BOTTOMLEFT (BF_BOTTOM | BF_LEFT) +#define BF_BOTTOMRIGHT (BF_BOTTOM | BF_RIGHT) +#define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM) + +#define BF_DIAGONAL 0x0010 + +#define BF_DIAGONAL_ENDTOPRIGHT (BF_DIAGONAL | BF_TOP | BF_RIGHT) +#define BF_DIAGONAL_ENDTOPLEFT (BF_DIAGONAL | BF_TOP | BF_LEFT) +#define BF_DIAGONAL_ENDBOTTOMLEFT (BF_DIAGONAL | BF_BOTTOM | BF_LEFT) +#define BF_DIAGONAL_ENDBOTTOMRIGHT (BF_DIAGONAL | BF_BOTTOM | BF_RIGHT) + +#define BF_MIDDLE 0x0800 +#define BF_SOFT 0x1000 +#define BF_ADJUST 0x2000 +#define BF_FLAT 0x4000 +#define BF_MONO 0x8000 + + WINUSERAPI WINBOOL WINAPI DrawEdge(HDC hdc,LPRECT qrc,UINT edge,UINT grfFlags); + +#define DFC_CAPTION 1 +#define DFC_MENU 2 +#define DFC_SCROLL 3 +#define DFC_BUTTON 4 +#define DFC_POPUPMENU 5 + +#define DFCS_CAPTIONCLOSE 0x0000 +#define DFCS_CAPTIONMIN 0x0001 +#define DFCS_CAPTIONMAX 0x0002 +#define DFCS_CAPTIONRESTORE 0x0003 +#define DFCS_CAPTIONHELP 0x0004 + +#define DFCS_MENUARROW 0x0000 +#define DFCS_MENUCHECK 0x0001 +#define DFCS_MENUBULLET 0x0002 +#define DFCS_MENUARROWRIGHT 0x0004 +#define DFCS_SCROLLUP 0x0000 +#define DFCS_SCROLLDOWN 0x0001 +#define DFCS_SCROLLLEFT 0x0002 +#define DFCS_SCROLLRIGHT 0x0003 +#define DFCS_SCROLLCOMBOBOX 0x0005 +#define DFCS_SCROLLSIZEGRIP 0x0008 +#define DFCS_SCROLLSIZEGRIPRIGHT 0x0010 + +#define DFCS_BUTTONCHECK 0x0000 +#define DFCS_BUTTONRADIOIMAGE 0x0001 +#define DFCS_BUTTONRADIOMASK 0x0002 +#define DFCS_BUTTONRADIO 0x0004 +#define DFCS_BUTTON3STATE 0x0008 +#define DFCS_BUTTONPUSH 0x0010 + +#define DFCS_INACTIVE 0x0100 +#define DFCS_PUSHED 0x0200 +#define DFCS_CHECKED 0x0400 + +#define DFCS_TRANSPARENT 0x0800 +#define DFCS_HOT 0x1000 + +#define DFCS_ADJUSTRECT 0x2000 +#define DFCS_FLAT 0x4000 +#define DFCS_MONO 0x8000 + + WINUSERAPI WINBOOL WINAPI DrawFrameControl(HDC,LPRECT,UINT,UINT); + +#define DC_ACTIVE 0x0001 +#define DC_SMALLCAP 0x0002 +#define DC_ICON 0x0004 +#define DC_TEXT 0x0008 +#define DC_INBUTTON 0x0010 +#define DC_GRADIENT 0x0020 +#define DC_BUTTONS 0x1000 + + WINUSERAPI WINBOOL WINAPI DrawCaption(HWND hwnd,HDC hdc,CONST RECT *lprect,UINT flags); + +#define IDANI_OPEN 1 +#define IDANI_CAPTION 3 + + WINUSERAPI WINBOOL WINAPI DrawAnimatedRects(HWND hwnd,int idAni,CONST RECT *lprcFrom,CONST RECT *lprcTo); + +#ifndef NOCLIPBOARD + +#define CF_TEXT 1 +#define CF_BITMAP 2 +#define CF_METAFILEPICT 3 +#define CF_SYLK 4 +#define CF_DIF 5 +#define CF_TIFF 6 +#define CF_OEMTEXT 7 +#define CF_DIB 8 +#define CF_PALETTE 9 +#define CF_PENDATA 10 +#define CF_RIFF 11 +#define CF_WAVE 12 +#define CF_UNICODETEXT 13 +#define CF_ENHMETAFILE 14 +#define CF_HDROP 15 +#define CF_LOCALE 16 +#define CF_DIBV5 17 +#define CF_MAX 18 + +#define CF_OWNERDISPLAY 0x0080 +#define CF_DSPTEXT 0x0081 +#define CF_DSPBITMAP 0x0082 +#define CF_DSPMETAFILEPICT 0x0083 +#define CF_DSPENHMETAFILE 0x008E + +#define CF_PRIVATEFIRST 0x0200 +#define CF_PRIVATELAST 0x02FF + +#define CF_GDIOBJFIRST 0x0300 +#define CF_GDIOBJLAST 0x03FF +#endif + +#define FVIRTKEY TRUE +#define FNOINVERT 0x02 +#define FSHIFT 0x04 +#define FCONTROL 0x08 +#define FALT 0x10 + + typedef struct tagACCEL { + BYTE fVirt; + WORD key; + WORD cmd; + } ACCEL,*LPACCEL; + + typedef struct tagPAINTSTRUCT { + HDC hdc; + WINBOOL fErase; + RECT rcPaint; + WINBOOL fRestore; + WINBOOL fIncUpdate; + BYTE rgbReserved[32]; + } PAINTSTRUCT,*PPAINTSTRUCT,*NPPAINTSTRUCT,*LPPAINTSTRUCT; + + typedef struct tagCREATESTRUCTA { + LPVOID lpCreateParams; + HINSTANCE hInstance; + HMENU hMenu; + HWND hwndParent; + int cy; + int cx; + int y; + int x; + LONG style; + LPCSTR lpszName; + LPCSTR lpszClass; + DWORD dwExStyle; + } CREATESTRUCTA,*LPCREATESTRUCTA; + + typedef struct tagCREATESTRUCTW { + LPVOID lpCreateParams; + HINSTANCE hInstance; + HMENU hMenu; + HWND hwndParent; + int cy; + int cx; + int y; + int x; + LONG style; + LPCWSTR lpszName; + LPCWSTR lpszClass; + DWORD dwExStyle; + } CREATESTRUCTW,*LPCREATESTRUCTW; + +#ifdef UNICODE + typedef CREATESTRUCTW CREATESTRUCT; + typedef LPCREATESTRUCTW LPCREATESTRUCT; +#else + typedef CREATESTRUCTA CREATESTRUCT; + typedef LPCREATESTRUCTA LPCREATESTRUCT; +#endif + + typedef struct tagWINDOWPLACEMENT { + UINT length; + UINT flags; + UINT showCmd; + POINT ptMinPosition; + POINT ptMaxPosition; + RECT rcNormalPosition; + } WINDOWPLACEMENT; + typedef WINDOWPLACEMENT *PWINDOWPLACEMENT,*LPWINDOWPLACEMENT; + +#define WPF_SETMINPOSITION 0x0001 +#define WPF_RESTORETOMAXIMIZED 0x0002 +#define WPF_ASYNCWINDOWPLACEMENT 0x0004 + + typedef struct tagNMHDR { + HWND hwndFrom; + UINT_PTR idFrom; + UINT code; + } NMHDR; + + typedef NMHDR *LPNMHDR; + + typedef struct tagSTYLESTRUCT { + DWORD styleOld; + DWORD styleNew; + } STYLESTRUCT,*LPSTYLESTRUCT; + +#define ODT_MENU 1 +#define ODT_LISTBOX 2 +#define ODT_COMBOBOX 3 +#define ODT_BUTTON 4 +#define ODT_STATIC 5 + +#define ODA_DRAWENTIRE 0x0001 +#define ODA_SELECT 0x0002 +#define ODA_FOCUS 0x0004 + +#define ODS_SELECTED 0x0001 +#define ODS_GRAYED 0x0002 +#define ODS_DISABLED 0x0004 +#define ODS_CHECKED 0x0008 +#define ODS_FOCUS 0x0010 +#define ODS_DEFAULT 0x0020 +#define ODS_COMBOBOXEDIT 0x1000 +#define ODS_HOTLIGHT 0x0040 +#define ODS_INACTIVE 0x0080 +#define ODS_NOACCEL 0x0100 +#define ODS_NOFOCUSRECT 0x0200 + + typedef struct tagMEASUREITEMSTRUCT { + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemWidth; + UINT itemHeight; + ULONG_PTR itemData; + } MEASUREITEMSTRUCT,*PMEASUREITEMSTRUCT,*LPMEASUREITEMSTRUCT; + + typedef struct tagDRAWITEMSTRUCT { + UINT CtlType; + UINT CtlID; + UINT itemID; + UINT itemAction; + UINT itemState; + HWND hwndItem; + HDC hDC; + RECT rcItem; + ULONG_PTR itemData; + } DRAWITEMSTRUCT,*PDRAWITEMSTRUCT,*LPDRAWITEMSTRUCT; + + typedef struct tagDELETEITEMSTRUCT { + UINT CtlType; + UINT CtlID; + UINT itemID; + HWND hwndItem; + ULONG_PTR itemData; + } DELETEITEMSTRUCT,*PDELETEITEMSTRUCT,*LPDELETEITEMSTRUCT; + + typedef struct tagCOMPAREITEMSTRUCT { + UINT CtlType; + UINT CtlID; + HWND hwndItem; + UINT itemID1; + ULONG_PTR itemData1; + UINT itemID2; + ULONG_PTR itemData2; + DWORD dwLocaleId; + } COMPAREITEMSTRUCT,*PCOMPAREITEMSTRUCT,*LPCOMPAREITEMSTRUCT; + +#ifndef NOMSG +#ifdef UNICODE +#define GetMessage GetMessageW +#define DispatchMessage DispatchMessageW +#define PeekMessage PeekMessageW +#else +#define GetMessage GetMessageA +#define DispatchMessage DispatchMessageA +#define PeekMessage PeekMessageA +#endif + + WINUSERAPI WINBOOL WINAPI GetMessageA(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax); + WINUSERAPI WINBOOL WINAPI GetMessageW(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax); + WINUSERAPI WINBOOL WINAPI TranslateMessage(CONST MSG *lpMsg); + WINUSERAPI LRESULT WINAPI DispatchMessageA(CONST MSG *lpMsg); + WINUSERAPI LRESULT WINAPI DispatchMessageW(CONST MSG *lpMsg); + WINUSERAPI WINBOOL WINAPI SetMessageQueue(int cMessagesMax); + WINUSERAPI WINBOOL WINAPI PeekMessageA(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg); + WINUSERAPI WINBOOL WINAPI PeekMessageW(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg); + +#define PM_NOREMOVE 0x0000 +#define PM_REMOVE 0x0001 +#define PM_NOYIELD 0x0002 +#define PM_QS_INPUT (QS_INPUT << 16) +#define PM_QS_POSTMESSAGE ((QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16) +#define PM_QS_PAINT (QS_PAINT << 16) +#define PM_QS_SENDMESSAGE (QS_SENDMESSAGE << 16) +#endif + + WINUSERAPI WINBOOL WINAPI RegisterHotKey(HWND hWnd,int id,UINT fsModifiers,UINT vk); + WINUSERAPI WINBOOL WINAPI UnregisterHotKey(HWND hWnd,int id); + +#define MOD_ALT 0x0001 +#define MOD_CONTROL 0x0002 +#define MOD_SHIFT 0x0004 +#define MOD_WIN 0x0008 + +#define IDHOT_SNAPWINDOW (-1) +#define IDHOT_SNAPDESKTOP (-2) + +#ifdef WIN_INTERNAL +#ifndef LSTRING +#define NOLSTRING +#endif +#ifndef LFILEIO +#define NOLFILEIO +#endif +#endif + +#define ENDSESSION_LOGOFF 0x80000000 + +#define EWX_LOGOFF 0 +#define EWX_SHUTDOWN 0x00000001 +#define EWX_REBOOT 0x00000002 +#define EWX_FORCE 0x00000004 +#define EWX_POWEROFF 0x00000008 +#define EWX_FORCEIFHUNG 0x00000010 + +#define ExitWindows(dwReserved,Code) ExitWindowsEx(EWX_LOGOFF,0xFFFFFFFF) + +#ifdef UNICODE +#define SendMessage SendMessageW +#define SendMessageTimeout SendMessageTimeoutW +#define SendNotifyMessage SendNotifyMessageW +#define SendMessageCallback SendMessageCallbackW +#else +#define SendMessage SendMessageA +#define SendMessageTimeout SendMessageTimeoutA +#define SendNotifyMessage SendNotifyMessageA +#define SendMessageCallback SendMessageCallbackA +#endif + + WINUSERAPI WINBOOL WINAPI ExitWindowsEx(UINT uFlags,DWORD dwReason); + WINUSERAPI WINBOOL WINAPI SwapMouseButton(WINBOOL fSwap); + WINUSERAPI DWORD WINAPI GetMessagePos(VOID); + WINUSERAPI LONG WINAPI GetMessageTime(VOID); + WINUSERAPI LPARAM WINAPI GetMessageExtraInfo(VOID); + WINUSERAPI WINBOOL WINAPI IsWow64Message(VOID); + WINUSERAPI LPARAM WINAPI SetMessageExtraInfo(LPARAM lParam); + WINUSERAPI LRESULT WINAPI SendMessageA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI SendMessageW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI SendMessageTimeoutA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,UINT fuFlags,UINT uTimeout,PDWORD_PTR lpdwResult); + WINUSERAPI LRESULT WINAPI SendMessageTimeoutW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,UINT fuFlags,UINT uTimeout,PDWORD_PTR lpdwResult); + WINUSERAPI WINBOOL WINAPI SendNotifyMessageA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI SendNotifyMessageW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI SendMessageCallbackA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,SENDASYNCPROC lpResultCallBack,ULONG_PTR dwData); + WINUSERAPI WINBOOL WINAPI SendMessageCallbackW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,SENDASYNCPROC lpResultCallBack,ULONG_PTR dwData); + + typedef struct { + UINT cbSize; + HDESK hdesk; + HWND hwnd; + LUID luid; + } BSMINFO,*PBSMINFO; + +#ifdef UNICODE +#define BroadcastSystemMessageEx BroadcastSystemMessageExW +#define BroadcastSystemMessage BroadcastSystemMessageW +#else +#define BroadcastSystemMessageEx BroadcastSystemMessageExA +#define BroadcastSystemMessage BroadcastSystemMessageA +#endif + + WINUSERAPI long WINAPI BroadcastSystemMessageExA(DWORD flags,LPDWORD lpInfo,UINT Msg,WPARAM wParam,LPARAM lParam,PBSMINFO pbsmInfo); + WINUSERAPI long WINAPI BroadcastSystemMessageExW(DWORD flags,LPDWORD lpInfo,UINT Msg,WPARAM wParam,LPARAM lParam,PBSMINFO pbsmInfo); + WINUSERAPI long WINAPI BroadcastSystemMessageA(DWORD flags,LPDWORD lpInfo,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI long WINAPI BroadcastSystemMessageW(DWORD flags,LPDWORD lpInfo,UINT Msg,WPARAM wParam,LPARAM lParam); + +#define BSM_ALLCOMPONENTS 0x00000000 +#define BSM_VXDS 0x00000001 +#define BSM_NETDRIVER 0x00000002 +#define BSM_INSTALLABLEDRIVERS 0x00000004 +#define BSM_APPLICATIONS 0x00000008 +#define BSM_ALLDESKTOPS 0x00000010 + +#define BSF_QUERY 0x00000001 +#define BSF_IGNORECURRENTTASK 0x00000002 +#define BSF_FLUSHDISK 0x00000004 +#define BSF_NOHANG 0x00000008 +#define BSF_POSTMESSAGE 0x00000010 +#define BSF_FORCEIFHUNG 0x00000020 +#define BSF_NOTIMEOUTIFNOTHUNG 0x00000040 +#define BSF_ALLOWSFW 0x00000080 +#define BSF_SENDNOTIFYMESSAGE 0x00000100 +#define BSF_RETURNHDESK 0x00000200 +#define BSF_LUID 0x00000400 + +#define BROADCAST_QUERY_DENY 0x424D5144 + + typedef PVOID HDEVNOTIFY; + typedef HDEVNOTIFY *PHDEVNOTIFY; + +#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 +#define DEVICE_NOTIFY_SERVICE_HANDLE 0x00000001 +#define DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 0x00000004 + +#ifdef UNICODE +#define RegisterDeviceNotification RegisterDeviceNotificationW +#define PostMessage PostMessageW +#define PostThreadMessage PostThreadMessageW +#define PostAppMessage PostAppMessageW +#define DefWindowProc DefWindowProcW +#define CallWindowProc CallWindowProcW +#define RegisterClass RegisterClassW +#define UnregisterClass UnregisterClassW +#define GetClassInfo GetClassInfoW +#define RegisterClassEx RegisterClassExW +#define GetClassInfoEx GetClassInfoExW +#else +#define RegisterDeviceNotification RegisterDeviceNotificationA +#define PostMessage PostMessageA +#define PostThreadMessage PostThreadMessageA +#define PostAppMessage PostAppMessageA +#define DefWindowProc DefWindowProcA +#define CallWindowProc CallWindowProcA +#define RegisterClass RegisterClassA +#define UnregisterClass UnregisterClassA +#define GetClassInfo GetClassInfoA +#define RegisterClassEx RegisterClassExA +#define GetClassInfoEx GetClassInfoExA +#endif + + WINUSERAPI HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hRecipient,LPVOID NotificationFilter,DWORD Flags); + WINUSERAPI HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecipient,LPVOID NotificationFilter,DWORD Flags); + WINUSERAPI WINBOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY Handle); + WINUSERAPI WINBOOL WINAPI PostMessageA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI PostMessageW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI PostThreadMessageA(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI PostThreadMessageW(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM lParam); +#define PostAppMessageA(idThread,wMsg,wParam,lParam) PostThreadMessageA((DWORD)idThread,wMsg,wParam,lParam) +#define PostAppMessageW(idThread,wMsg,wParam,lParam) PostThreadMessageW((DWORD)idThread,wMsg,wParam,lParam) + +#define HWND_BROADCAST ((HWND)0xffff) +#define HWND_MESSAGE ((HWND)-3) + + WINUSERAPI WINBOOL WINAPI AttachThreadInput(DWORD idAttach,DWORD idAttachTo,WINBOOL fAttach); + WINUSERAPI WINBOOL WINAPI ReplyMessage(LRESULT lResult); + WINUSERAPI WINBOOL WINAPI WaitMessage(VOID); + WINUSERAPI DWORD WINAPI WaitForInputIdle(HANDLE hProcess,DWORD dwMilliseconds); + WINUSERAPI LRESULT WINAPI DefWindowProcA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI DefWindowProcW(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI VOID WINAPI PostQuitMessage(int nExitCode); + WINUSERAPI LRESULT WINAPI CallWindowProcA(WNDPROC lpPrevWndFunc,HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI CallWindowProcW(WNDPROC lpPrevWndFunc,HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI InSendMessage(VOID); + WINUSERAPI DWORD WINAPI InSendMessageEx(LPVOID lpReserved); + +#define ISMEX_NOSEND 0x00000000 +#define ISMEX_SEND 0x00000001 +#define ISMEX_NOTIFY 0x00000002 +#define ISMEX_CALLBACK 0x00000004 +#define ISMEX_REPLIED 0x00000008 + + WINUSERAPI UINT WINAPI GetDoubleClickTime(VOID); + WINUSERAPI WINBOOL WINAPI SetDoubleClickTime(UINT); + WINUSERAPI ATOM WINAPI RegisterClassA(CONST WNDCLASSA *lpWndClass); + WINUSERAPI ATOM WINAPI RegisterClassW(CONST WNDCLASSW *lpWndClass); + WINUSERAPI WINBOOL WINAPI UnregisterClassA(LPCSTR lpClassName,HINSTANCE hInstance); + WINUSERAPI WINBOOL WINAPI UnregisterClassW(LPCWSTR lpClassName,HINSTANCE hInstance); + WINUSERAPI WINBOOL WINAPI GetClassInfoA(HINSTANCE hInstance,LPCSTR lpClassName,LPWNDCLASSA lpWndClass); + WINUSERAPI WINBOOL WINAPI GetClassInfoW(HINSTANCE hInstance,LPCWSTR lpClassName,LPWNDCLASSW lpWndClass); + WINUSERAPI ATOM WINAPI RegisterClassExA(CONST WNDCLASSEXA *); + WINUSERAPI ATOM WINAPI RegisterClassExW(CONST WNDCLASSEXW *); + WINUSERAPI WINBOOL WINAPI GetClassInfoExA(HINSTANCE hInstance,LPCSTR lpszClass,LPWNDCLASSEXA lpwcx); + WINUSERAPI WINBOOL WINAPI GetClassInfoExW(HINSTANCE hInstance,LPCWSTR lpszClass,LPWNDCLASSEXW lpwcx); + +#define CW_USEDEFAULT ((int)0x80000000) + +#define HWND_DESKTOP ((HWND)0) + + typedef BOOLEAN (WINAPI *PREGISTERCLASSNAMEW)(LPCWSTR); + +#ifdef UNICODE +#define CreateWindowEx CreateWindowExW +#define CreateWindow CreateWindowW +#else +#define CreateWindowEx CreateWindowExA +#define CreateWindow CreateWindowA +#endif + + WINUSERAPI HWND WINAPI CreateWindowExA(DWORD dwExStyle,LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam); + WINUSERAPI HWND WINAPI CreateWindowExW(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam); +#define CreateWindowA(lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam) CreateWindowExA(0L,lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam) +#define CreateWindowW(lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam) CreateWindowExW(0L,lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam) + WINUSERAPI WINBOOL WINAPI IsWindow(HWND hWnd); + WINUSERAPI WINBOOL WINAPI IsMenu(HMENU hMenu); + WINUSERAPI WINBOOL WINAPI IsChild(HWND hWndParent,HWND hWnd); + WINUSERAPI WINBOOL WINAPI DestroyWindow(HWND hWnd); + WINUSERAPI WINBOOL WINAPI ShowWindow(HWND hWnd,int nCmdShow); + WINUSERAPI WINBOOL WINAPI AnimateWindow(HWND hWnd,DWORD dwTime,DWORD dwFlags); + +#if defined(_WINGDI_) && !defined(NOGDI) + WINUSERAPI WINBOOL WINAPI UpdateLayeredWindow(HWND hWnd,HDC hdcDst,POINT *pptDst,SIZE *psize,HDC hdcSrc,POINT *pptSrc,COLORREF crKey,BLENDFUNCTION *pblend,DWORD dwFlags); + + typedef struct tagUPDATELAYEREDWINDOWINFO { + DWORD cbSize; + HDC hdcDst; + POINT CONST *pptDst; + SIZE CONST *psize; + HDC hdcSrc; + POINT CONST *pptSrc; + COLORREF crKey; + BLENDFUNCTION CONST *pblend; + DWORD dwFlags; + RECT CONST *prcDirty; + } UPDATELAYEREDWINDOWINFO,*PUPDATELAYEREDWINDOWINFO; + + WINUSERAPI WINBOOL WINAPI UpdateLayeredWindowIndirect(HWND hWnd,UPDATELAYEREDWINDOWINFO CONST *pULWInfo); + WINUSERAPI WINBOOL WINAPI GetLayeredWindowAttributes(HWND hwnd,COLORREF *pcrKey,BYTE *pbAlpha,DWORD *pdwFlags); + +#define PW_CLIENTONLY 0x00000001 + + WINUSERAPI WINBOOL WINAPI PrintWindow(HWND hwnd,HDC hdcBlt,UINT nFlags); + WINUSERAPI WINBOOL WINAPI SetLayeredWindowAttributes(HWND hwnd,COLORREF crKey,BYTE bAlpha,DWORD dwFlags); + +#define LWA_COLORKEY 0x00000001 +#define LWA_ALPHA 0x00000002 + +#define ULW_COLORKEY 0x00000001 +#define ULW_ALPHA 0x00000002 +#define ULW_OPAQUE 0x00000004 + +#define ULW_EX_NORESIZE 0x00000008 + + WINUSERAPI WINBOOL WINAPI ShowWindowAsync(HWND hWnd,int nCmdShow); + WINUSERAPI WINBOOL WINAPI FlashWindow(HWND hWnd,WINBOOL bInvert); + + typedef struct { + UINT cbSize; + HWND hwnd; + DWORD dwFlags; + UINT uCount; + DWORD dwTimeout; + } FLASHWINFO,*PFLASHWINFO; + + WINUSERAPI WINBOOL WINAPI FlashWindowEx(PFLASHWINFO pfwi); + +#define FLASHW_STOP 0 +#define FLASHW_CAPTION 0x00000001 +#define FLASHW_TRAY 0x00000002 +#define FLASHW_ALL (FLASHW_CAPTION | FLASHW_TRAY) +#define FLASHW_TIMER 0x00000004 +#define FLASHW_TIMERNOFG 0x0000000C + + WINUSERAPI WINBOOL WINAPI ShowOwnedPopups(HWND hWnd,WINBOOL fShow); + WINUSERAPI WINBOOL WINAPI OpenIcon(HWND hWnd); + WINUSERAPI WINBOOL WINAPI CloseWindow(HWND hWnd); + WINUSERAPI WINBOOL WINAPI MoveWindow(HWND hWnd,int X,int Y,int nWidth,int nHeight,WINBOOL bRepaint); + WINUSERAPI WINBOOL WINAPI SetWindowPos(HWND hWnd,HWND hWndInsertAfter,int X,int Y,int cx,int cy,UINT uFlags); + WINUSERAPI WINBOOL WINAPI GetWindowPlacement(HWND hWnd,WINDOWPLACEMENT *lpwndpl); + WINUSERAPI WINBOOL WINAPI SetWindowPlacement(HWND hWnd,CONST WINDOWPLACEMENT *lpwndpl); + +#ifndef NODEFERWINDOWPOS + WINUSERAPI HDWP WINAPI BeginDeferWindowPos(int nNumWindows); + WINUSERAPI HDWP WINAPI DeferWindowPos(HDWP hWinPosInfo,HWND hWnd,HWND hWndInsertAfter,int x,int y,int cx,int cy,UINT uFlags); + WINUSERAPI WINBOOL WINAPI EndDeferWindowPos(HDWP hWinPosInfo); +#endif + + WINUSERAPI WINBOOL WINAPI IsWindowVisible(HWND hWnd); + WINUSERAPI WINBOOL WINAPI IsIconic(HWND hWnd); + WINUSERAPI WINBOOL WINAPI AnyPopup(VOID); + WINUSERAPI WINBOOL WINAPI BringWindowToTop(HWND hWnd); + WINUSERAPI WINBOOL WINAPI IsZoomed(HWND hWnd); + +#define SWP_NOSIZE 0x0001 +#define SWP_NOMOVE 0x0002 +#define SWP_NOZORDER 0x0004 +#define SWP_NOREDRAW 0x0008 +#define SWP_NOACTIVATE 0x0010 +#define SWP_FRAMECHANGED 0x0020 +#define SWP_SHOWWINDOW 0x0040 +#define SWP_HIDEWINDOW 0x0080 +#define SWP_NOCOPYBITS 0x0100 +#define SWP_NOOWNERZORDER 0x0200 +#define SWP_NOSENDCHANGING 0x0400 + +#define SWP_DRAWFRAME SWP_FRAMECHANGED +#define SWP_NOREPOSITION SWP_NOOWNERZORDER +#define SWP_DEFERERASE 0x2000 +#define SWP_ASYNCWINDOWPOS 0x4000 + +#define HWND_TOP ((HWND)0) +#define HWND_BOTTOM ((HWND)1) +#define HWND_TOPMOST ((HWND)-1) +#define HWND_NOTOPMOST ((HWND)-2) + +#ifndef NOCTLMGR + +#include <pshpack2.h> + + typedef struct { + DWORD style; + DWORD dwExtendedStyle; + WORD cdit; + short x; + short y; + short cx; + short cy; + } DLGTEMPLATE; + + typedef DLGTEMPLATE *LPDLGTEMPLATEA; + typedef DLGTEMPLATE *LPDLGTEMPLATEW; + +#ifdef UNICODE + typedef LPDLGTEMPLATEW LPDLGTEMPLATE; +#else + typedef LPDLGTEMPLATEA LPDLGTEMPLATE; +#endif + + typedef CONST DLGTEMPLATE *LPCDLGTEMPLATEA; + typedef CONST DLGTEMPLATE *LPCDLGTEMPLATEW; + +#ifdef UNICODE + typedef LPCDLGTEMPLATEW LPCDLGTEMPLATE; +#else + typedef LPCDLGTEMPLATEA LPCDLGTEMPLATE; +#endif + + typedef struct { + DWORD style; + DWORD dwExtendedStyle; + short x; + short y; + short cx; + short cy; + WORD id; + } DLGITEMTEMPLATE; + + typedef DLGITEMTEMPLATE *PDLGITEMTEMPLATEA; + typedef DLGITEMTEMPLATE *PDLGITEMTEMPLATEW; + +#ifdef UNICODE + typedef PDLGITEMTEMPLATEW PDLGITEMTEMPLATE; +#else + typedef PDLGITEMTEMPLATEA PDLGITEMTEMPLATE; +#endif + + typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEA; + typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEW; + +#ifdef UNICODE + typedef LPDLGITEMTEMPLATEW LPDLGITEMTEMPLATE; +#else + typedef LPDLGITEMTEMPLATEA LPDLGITEMTEMPLATE; +#endif + +#include <poppack.h> + +#ifdef UNICODE +#define CreateDialogParam CreateDialogParamW +#define CreateDialogIndirectParam CreateDialogIndirectParamW +#define CreateDialog CreateDialogW +#define CreateDialogIndirect CreateDialogIndirectW +#define DialogBoxParam DialogBoxParamW +#define DialogBoxIndirectParam DialogBoxIndirectParamW +#define DialogBox DialogBoxW +#define DialogBoxIndirect DialogBoxIndirectW +#define SetDlgItemText SetDlgItemTextW +#define GetDlgItemText GetDlgItemTextW +#define SendDlgItemMessage SendDlgItemMessageW +#define DefDlgProc DefDlgProcW +#else +#define CreateDialogParam CreateDialogParamA +#define CreateDialogIndirectParam CreateDialogIndirectParamA +#define CreateDialog CreateDialogA +#define CreateDialogIndirect CreateDialogIndirectA +#define DialogBoxParam DialogBoxParamA +#define DialogBoxIndirectParam DialogBoxIndirectParamA +#define DialogBox DialogBoxA +#define DialogBoxIndirect DialogBoxIndirectA +#define SetDlgItemText SetDlgItemTextA +#define GetDlgItemText GetDlgItemTextA +#define SendDlgItemMessage SendDlgItemMessageA +#define DefDlgProc DefDlgProcA +#endif + + WINUSERAPI HWND WINAPI CreateDialogParamA(HINSTANCE hInstance,LPCSTR lpTemplateName,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam); + WINUSERAPI HWND WINAPI CreateDialogParamW(HINSTANCE hInstance,LPCWSTR lpTemplateName,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam); + WINUSERAPI HWND WINAPI CreateDialogIndirectParamA(HINSTANCE hInstance,LPCDLGTEMPLATEA lpTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam); + WINUSERAPI HWND WINAPI CreateDialogIndirectParamW(HINSTANCE hInstance,LPCDLGTEMPLATEW lpTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam); +#define CreateDialogA(hInstance,lpName,hWndParent,lpDialogFunc) CreateDialogParamA(hInstance,lpName,hWndParent,lpDialogFunc,0L) +#define CreateDialogW(hInstance,lpName,hWndParent,lpDialogFunc) CreateDialogParamW(hInstance,lpName,hWndParent,lpDialogFunc,0L) +#define CreateDialogIndirectA(hInstance,lpTemplate,hWndParent,lpDialogFunc) CreateDialogIndirectParamA(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L) +#define CreateDialogIndirectW(hInstance,lpTemplate,hWndParent,lpDialogFunc) CreateDialogIndirectParamW(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L) + WINUSERAPI INT_PTR WINAPI DialogBoxParamA(HINSTANCE hInstance,LPCSTR lpTemplateName,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam); + WINUSERAPI INT_PTR WINAPI DialogBoxParamW(HINSTANCE hInstance,LPCWSTR lpTemplateName,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam); + WINUSERAPI INT_PTR WINAPI DialogBoxIndirectParamA(HINSTANCE hInstance,LPCDLGTEMPLATEA hDialogTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam); + WINUSERAPI INT_PTR WINAPI DialogBoxIndirectParamW(HINSTANCE hInstance,LPCDLGTEMPLATEW hDialogTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam); +#define DialogBoxA(hInstance,lpTemplate,hWndParent,lpDialogFunc) DialogBoxParamA(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L) +#define DialogBoxW(hInstance,lpTemplate,hWndParent,lpDialogFunc) DialogBoxParamW(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L) +#define DialogBoxIndirectA(hInstance,lpTemplate,hWndParent,lpDialogFunc) DialogBoxIndirectParamA(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L) +#define DialogBoxIndirectW(hInstance,lpTemplate,hWndParent,lpDialogFunc) DialogBoxIndirectParamW(hInstance,lpTemplate,hWndParent,lpDialogFunc,0L) + WINUSERAPI WINBOOL WINAPI EndDialog(HWND hDlg,INT_PTR nResult); + WINUSERAPI HWND WINAPI GetDlgItem(HWND hDlg,int nIDDlgItem); + WINUSERAPI WINBOOL WINAPI SetDlgItemInt(HWND hDlg,int nIDDlgItem,UINT uValue,WINBOOL bSigned); + WINUSERAPI UINT WINAPI GetDlgItemInt(HWND hDlg,int nIDDlgItem,WINBOOL *lpTranslated,WINBOOL bSigned); + WINUSERAPI WINBOOL WINAPI SetDlgItemTextA(HWND hDlg,int nIDDlgItem,LPCSTR lpString); + WINUSERAPI WINBOOL WINAPI SetDlgItemTextW(HWND hDlg,int nIDDlgItem,LPCWSTR lpString); + WINUSERAPI UINT WINAPI GetDlgItemTextA(HWND hDlg,int nIDDlgItem,LPSTR lpString,int cchMax); + WINUSERAPI UINT WINAPI GetDlgItemTextW(HWND hDlg,int nIDDlgItem,LPWSTR lpString,int cchMax); + WINUSERAPI WINBOOL WINAPI CheckDlgButton(HWND hDlg,int nIDButton,UINT uCheck); + WINUSERAPI WINBOOL WINAPI CheckRadioButton(HWND hDlg,int nIDFirstButton,int nIDLastButton,int nIDCheckButton); + WINUSERAPI UINT WINAPI IsDlgButtonChecked(HWND hDlg,int nIDButton); + WINUSERAPI LRESULT WINAPI SendDlgItemMessageA(HWND hDlg,int nIDDlgItem,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI SendDlgItemMessageW(HWND hDlg,int nIDDlgItem,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI HWND WINAPI GetNextDlgGroupItem(HWND hDlg,HWND hCtl,WINBOOL bPrevious); + WINUSERAPI HWND WINAPI GetNextDlgTabItem(HWND hDlg,HWND hCtl,WINBOOL bPrevious); + WINUSERAPI int WINAPI GetDlgCtrlID(HWND hWnd); + WINUSERAPI long WINAPI GetDialogBaseUnits(VOID); + WINUSERAPI LRESULT WINAPI DefDlgProcA(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI DefDlgProcW(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam); + +#define DLGWINDOWEXTRA 30 +#endif + +#ifndef NOMSG + +#ifdef UNICODE +#define CallMsgFilter CallMsgFilterW +#else +#define CallMsgFilter CallMsgFilterA +#endif + + WINUSERAPI WINBOOL WINAPI CallMsgFilterA(LPMSG lpMsg,int nCode); + WINUSERAPI WINBOOL WINAPI CallMsgFilterW(LPMSG lpMsg,int nCode); +#endif + +#ifndef NOCLIPBOARD + +#ifdef UNICODE +#define RegisterClipboardFormat RegisterClipboardFormatW +#define GetClipboardFormatName GetClipboardFormatNameW +#else +#define RegisterClipboardFormat RegisterClipboardFormatA +#define GetClipboardFormatName GetClipboardFormatNameA +#endif + + WINUSERAPI WINBOOL WINAPI OpenClipboard(HWND hWndNewOwner); + WINUSERAPI WINBOOL WINAPI CloseClipboard(VOID); + WINUSERAPI DWORD WINAPI GetClipboardSequenceNumber(VOID); + WINUSERAPI HWND WINAPI GetClipboardOwner(VOID); + WINUSERAPI HWND WINAPI SetClipboardViewer(HWND hWndNewViewer); + WINUSERAPI HWND WINAPI GetClipboardViewer(VOID); + WINUSERAPI WINBOOL WINAPI ChangeClipboardChain(HWND hWndRemove,HWND hWndNewNext); + WINUSERAPI HANDLE WINAPI SetClipboardData(UINT uFormat,HANDLE hMem); + WINUSERAPI HANDLE WINAPI GetClipboardData(UINT uFormat); + WINUSERAPI UINT WINAPI RegisterClipboardFormatA(LPCSTR lpszFormat); + WINUSERAPI UINT WINAPI RegisterClipboardFormatW(LPCWSTR lpszFormat); + WINUSERAPI int WINAPI CountClipboardFormats(VOID); + WINUSERAPI UINT WINAPI EnumClipboardFormats(UINT format); + WINUSERAPI int WINAPI GetClipboardFormatNameA(UINT format,LPSTR lpszFormatName,int cchMaxCount); + WINUSERAPI int WINAPI GetClipboardFormatNameW(UINT format,LPWSTR lpszFormatName,int cchMaxCount); + WINUSERAPI WINBOOL WINAPI EmptyClipboard(VOID); + WINUSERAPI WINBOOL WINAPI IsClipboardFormatAvailable(UINT format); + WINUSERAPI int WINAPI GetPriorityClipboardFormat(UINT *paFormatPriorityList,int cFormats); + WINUSERAPI HWND WINAPI GetOpenClipboardWindow(VOID); +#endif + +#ifdef UNICODE +#define CharToOem CharToOemW +#define OemToChar OemToCharW +#define CharToOemBuff CharToOemBuffW +#define OemToCharBuff OemToCharBuffW +#define CharUpper CharUpperW +#define CharUpperBuff CharUpperBuffW +#define CharLower CharLowerW +#define CharLowerBuff CharLowerBuffW +#define CharNext CharNextW +#define CharPrev CharPrevW +#else +#define CharToOem CharToOemA +#define OemToChar OemToCharA +#define CharToOemBuff CharToOemBuffA +#define OemToCharBuff OemToCharBuffA +#define CharUpper CharUpperA +#define CharUpperBuff CharUpperBuffA +#define CharLower CharLowerA +#define CharLowerBuff CharLowerBuffA +#define CharNext CharNextA +#define CharPrev CharPrevA +#endif + + WINUSERAPI WINBOOL WINAPI CharToOemA(LPCSTR lpszSrc,LPSTR lpszDst); + WINUSERAPI WINBOOL WINAPI CharToOemW(LPCWSTR lpszSrc,LPSTR lpszDst); + WINUSERAPI WINBOOL WINAPI OemToCharA(LPCSTR lpszSrc,LPSTR lpszDst); + WINUSERAPI WINBOOL WINAPI OemToCharW(LPCSTR lpszSrc,LPWSTR lpszDst); + WINUSERAPI WINBOOL WINAPI CharToOemBuffA(LPCSTR lpszSrc,LPSTR lpszDst,DWORD cchDstLength); + WINUSERAPI WINBOOL WINAPI CharToOemBuffW(LPCWSTR lpszSrc,LPSTR lpszDst,DWORD cchDstLength); + WINUSERAPI WINBOOL WINAPI OemToCharBuffA(LPCSTR lpszSrc,LPSTR lpszDst,DWORD cchDstLength); + WINUSERAPI WINBOOL WINAPI OemToCharBuffW(LPCSTR lpszSrc,LPWSTR lpszDst,DWORD cchDstLength); + WINUSERAPI LPSTR WINAPI CharUpperA(LPSTR lpsz); + WINUSERAPI LPWSTR WINAPI CharUpperW(LPWSTR lpsz); + WINUSERAPI DWORD WINAPI CharUpperBuffA(LPSTR lpsz,DWORD cchLength); + WINUSERAPI DWORD WINAPI CharUpperBuffW(LPWSTR lpsz,DWORD cchLength); + WINUSERAPI LPSTR WINAPI CharLowerA(LPSTR lpsz); + WINUSERAPI LPWSTR WINAPI CharLowerW(LPWSTR lpsz); + WINUSERAPI DWORD WINAPI CharLowerBuffA(LPSTR lpsz,DWORD cchLength); + WINUSERAPI DWORD WINAPI CharLowerBuffW(LPWSTR lpsz,DWORD cchLength); + WINUSERAPI LPSTR WINAPI CharNextA(LPCSTR lpsz); + WINUSERAPI LPWSTR WINAPI CharNextW(LPCWSTR lpsz); + WINUSERAPI LPSTR WINAPI CharPrevA(LPCSTR lpszStart,LPCSTR lpszCurrent); + WINUSERAPI LPWSTR WINAPI CharPrevW(LPCWSTR lpszStart,LPCWSTR lpszCurrent); + WINUSERAPI LPSTR WINAPI CharNextExA(WORD CodePage,LPCSTR lpCurrentChar,DWORD dwFlags); + WINUSERAPI LPSTR WINAPI CharPrevExA(WORD CodePage,LPCSTR lpStart,LPCSTR lpCurrentChar,DWORD dwFlags); + +#define AnsiToOem CharToOemA +#define OemToAnsi OemToCharA +#define AnsiToOemBuff CharToOemBuffA +#define OemToAnsiBuff OemToCharBuffA +#define AnsiUpper CharUpperA +#define AnsiUpperBuff CharUpperBuffA +#define AnsiLower CharLowerA +#define AnsiLowerBuff CharLowerBuffA +#define AnsiNext CharNextA +#define AnsiPrev CharPrevA + +#ifndef NOLANGUAGE + +#ifdef UNICODE +#define IsCharAlpha IsCharAlphaW +#define IsCharAlphaNumeric IsCharAlphaNumericW +#define IsCharUpper IsCharUpperW +#define IsCharLower IsCharLowerW +#else +#define IsCharAlpha IsCharAlphaA +#define IsCharAlphaNumeric IsCharAlphaNumericA +#define IsCharUpper IsCharUpperA +#define IsCharLower IsCharLowerA +#endif + + WINUSERAPI WINBOOL WINAPI IsCharAlphaA(CHAR ch); + WINUSERAPI WINBOOL WINAPI IsCharAlphaW(WCHAR ch); + WINUSERAPI WINBOOL WINAPI IsCharAlphaNumericA(CHAR ch); + WINUSERAPI WINBOOL WINAPI IsCharAlphaNumericW(WCHAR ch); + WINUSERAPI WINBOOL WINAPI IsCharUpperA(CHAR ch); + WINUSERAPI WINBOOL WINAPI IsCharUpperW(WCHAR ch); + WINUSERAPI WINBOOL WINAPI IsCharLowerA(CHAR ch); + WINUSERAPI WINBOOL WINAPI IsCharLowerW(WCHAR ch); +#endif + +#ifdef UNICODE +#define GetKeyNameText GetKeyNameTextW +#define VkKeyScan VkKeyScanW +#define VkKeyScanEx VkKeyScanExW +#else +#define GetKeyNameText GetKeyNameTextA +#define VkKeyScan VkKeyScanA +#define VkKeyScanEx VkKeyScanExA +#endif + + WINUSERAPI HWND WINAPI SetFocus(HWND hWnd); + WINUSERAPI HWND WINAPI GetActiveWindow(VOID); + WINUSERAPI HWND WINAPI GetFocus(VOID); + WINUSERAPI UINT WINAPI GetKBCodePage(VOID); + WINUSERAPI SHORT WINAPI GetKeyState(int nVirtKey); + WINUSERAPI SHORT WINAPI GetAsyncKeyState(int vKey); + WINUSERAPI WINBOOL WINAPI GetKeyboardState(PBYTE lpKeyState); + WINUSERAPI WINBOOL WINAPI SetKeyboardState(LPBYTE lpKeyState); + WINUSERAPI int WINAPI GetKeyNameTextA(LONG lParam,LPSTR lpString,int cchSize); + WINUSERAPI int WINAPI GetKeyNameTextW(LONG lParam,LPWSTR lpString,int cchSize); + WINUSERAPI int WINAPI GetKeyboardType(int nTypeFlag); + WINUSERAPI int WINAPI ToAscii(UINT uVirtKey,UINT uScanCode,CONST BYTE *lpKeyState,LPWORD lpChar,UINT uFlags); + WINUSERAPI int WINAPI ToAsciiEx(UINT uVirtKey,UINT uScanCode,CONST BYTE *lpKeyState,LPWORD lpChar,UINT uFlags,HKL dwhkl); + WINUSERAPI int WINAPI ToUnicode(UINT wVirtKey,UINT wScanCode,CONST BYTE *lpKeyState,LPWSTR pwszBuff,int cchBuff,UINT wFlags); + WINUSERAPI DWORD WINAPI OemKeyScan(WORD wOemChar); + WINUSERAPI SHORT WINAPI VkKeyScanA(CHAR ch); + WINUSERAPI SHORT WINAPI VkKeyScanW(WCHAR ch); + WINUSERAPI SHORT WINAPI VkKeyScanExA(CHAR ch,HKL dwhkl); + WINUSERAPI SHORT WINAPI VkKeyScanExW(WCHAR ch,HKL dwhkl); + +#define KEYEVENTF_EXTENDEDKEY 0x0001 +#define KEYEVENTF_KEYUP 0x0002 +#define KEYEVENTF_UNICODE 0x0004 +#define KEYEVENTF_SCANCODE 0x0008 + + WINUSERAPI VOID WINAPI keybd_event(BYTE bVk,BYTE bScan,DWORD dwFlags,ULONG_PTR dwExtraInfo); + +#define MOUSEEVENTF_MOVE 0x0001 +#define MOUSEEVENTF_LEFTDOWN 0x0002 +#define MOUSEEVENTF_LEFTUP 0x0004 +#define MOUSEEVENTF_RIGHTDOWN 0x0008 +#define MOUSEEVENTF_RIGHTUP 0x0010 +#define MOUSEEVENTF_MIDDLEDOWN 0x0020 +#define MOUSEEVENTF_MIDDLEUP 0x0040 +#define MOUSEEVENTF_XDOWN 0x0080 +#define MOUSEEVENTF_XUP 0x0100 +#define MOUSEEVENTF_WHEEL 0x0800 +#define MOUSEEVENTF_VIRTUALDESK 0x4000 +#define MOUSEEVENTF_ABSOLUTE 0x8000 + + WINUSERAPI VOID WINAPI mouse_event(DWORD dwFlags,DWORD dx,DWORD dy,DWORD dwData,ULONG_PTR dwExtraInfo); + + typedef struct tagMOUSEINPUT { + LONG dx; + LONG dy; + DWORD mouseData; + DWORD dwFlags; + DWORD time; + ULONG_PTR dwExtraInfo; + } MOUSEINPUT,*PMOUSEINPUT,*LPMOUSEINPUT; + + typedef struct tagKEYBDINPUT { + WORD wVk; + WORD wScan; + DWORD dwFlags; + DWORD time; + ULONG_PTR dwExtraInfo; + } KEYBDINPUT,*PKEYBDINPUT,*LPKEYBDINPUT; + + typedef struct tagHARDWAREINPUT { + DWORD uMsg; + WORD wParamL; + WORD wParamH; + } HARDWAREINPUT,*PHARDWAREINPUT,*LPHARDWAREINPUT; + +#define INPUT_MOUSE 0 +#define INPUT_KEYBOARD 1 +#define INPUT_HARDWARE 2 + + typedef struct tagINPUT { + DWORD type; + union { + MOUSEINPUT mi; + KEYBDINPUT ki; + HARDWAREINPUT hi; + }; + } INPUT,*PINPUT,*LPINPUT; + + WINUSERAPI UINT WINAPI SendInput(UINT cInputs,LPINPUT pInputs,int cbSize); + + typedef struct tagLASTINPUTINFO { + UINT cbSize; + DWORD dwTime; + } LASTINPUTINFO,*PLASTINPUTINFO; + +#ifdef UNICODE +#define MapVirtualKey MapVirtualKeyW +#define MapVirtualKeyEx MapVirtualKeyExW +#else +#define MapVirtualKey MapVirtualKeyA +#define MapVirtualKeyEx MapVirtualKeyExA +#endif + + WINUSERAPI WINBOOL WINAPI GetLastInputInfo(PLASTINPUTINFO plii); + WINUSERAPI UINT WINAPI MapVirtualKeyA(UINT uCode,UINT uMapType); + WINUSERAPI UINT WINAPI MapVirtualKeyW(UINT uCode,UINT uMapType); + WINUSERAPI UINT WINAPI MapVirtualKeyExA(UINT uCode,UINT uMapType,HKL dwhkl); + WINUSERAPI UINT WINAPI MapVirtualKeyExW(UINT uCode,UINT uMapType,HKL dwhkl); + WINUSERAPI WINBOOL WINAPI GetInputState(VOID); + WINUSERAPI DWORD WINAPI GetQueueStatus(UINT flags); + WINUSERAPI HWND WINAPI GetCapture(VOID); + WINUSERAPI HWND WINAPI SetCapture(HWND hWnd); + WINUSERAPI WINBOOL WINAPI ReleaseCapture(VOID); + WINUSERAPI DWORD WINAPI MsgWaitForMultipleObjects(DWORD nCount,CONST HANDLE *pHandles,WINBOOL fWaitAll,DWORD dwMilliseconds,DWORD dwWakeMask); + WINUSERAPI DWORD WINAPI MsgWaitForMultipleObjectsEx(DWORD nCount,CONST HANDLE *pHandles,DWORD dwMilliseconds,DWORD dwWakeMask,DWORD dwFlags); + +#define MWMO_WAITALL 0x0001 +#define MWMO_ALERTABLE 0x0002 +#define MWMO_INPUTAVAILABLE 0x0004 + +#define QS_KEY 0x0001 +#define QS_MOUSEMOVE 0x0002 +#define QS_MOUSEBUTTON 0x0004 +#define QS_POSTMESSAGE 0x0008 +#define QS_TIMER 0x0010 +#define QS_PAINT 0x0020 +#define QS_SENDMESSAGE 0x0040 +#define QS_HOTKEY 0x0080 +#define QS_ALLPOSTMESSAGE 0x0100 +#define QS_RAWINPUT 0x0400 +#define QS_MOUSE (QS_MOUSEMOVE | QS_MOUSEBUTTON) +#define QS_INPUT (QS_MOUSE | QS_KEY | QS_RAWINPUT) +#define QS_ALLEVENTS (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY) +#define QS_ALLINPUT (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE) + +#define USER_TIMER_MAXIMUM 0x7FFFFFFF +#define USER_TIMER_MINIMUM 0x0000000A + +#ifdef UNICODE +#define LoadAccelerators LoadAcceleratorsW +#define CreateAcceleratorTable CreateAcceleratorTableW +#define CopyAcceleratorTable CopyAcceleratorTableW +#else +#define LoadAccelerators LoadAcceleratorsA +#define CreateAcceleratorTable CreateAcceleratorTableA +#define CopyAcceleratorTable CopyAcceleratorTableA +#endif + + WINUSERAPI UINT_PTR WINAPI SetTimer(HWND hWnd,UINT_PTR nIDEvent,UINT uElapse,TIMERPROC lpTimerFunc); + WINUSERAPI WINBOOL WINAPI KillTimer(HWND hWnd,UINT_PTR uIDEvent); + WINUSERAPI WINBOOL WINAPI IsWindowUnicode(HWND hWnd); + WINUSERAPI WINBOOL WINAPI EnableWindow(HWND hWnd,WINBOOL bEnable); + WINUSERAPI WINBOOL WINAPI IsWindowEnabled(HWND hWnd); + WINUSERAPI HACCEL WINAPI LoadAcceleratorsA(HINSTANCE hInstance,LPCSTR lpTableName); + WINUSERAPI HACCEL WINAPI LoadAcceleratorsW(HINSTANCE hInstance,LPCWSTR lpTableName); + WINUSERAPI HACCEL WINAPI CreateAcceleratorTableA(LPACCEL paccel,int cAccel); + WINUSERAPI HACCEL WINAPI CreateAcceleratorTableW(LPACCEL paccel,int cAccel); + WINUSERAPI WINBOOL WINAPI DestroyAcceleratorTable(HACCEL hAccel); + WINUSERAPI int WINAPI CopyAcceleratorTableA(HACCEL hAccelSrc,LPACCEL lpAccelDst,int cAccelEntries); + WINUSERAPI int WINAPI CopyAcceleratorTableW(HACCEL hAccelSrc,LPACCEL lpAccelDst,int cAccelEntries); + +#ifndef NOMSG + +#ifdef UNICODE +#define TranslateAccelerator TranslateAcceleratorW +#else +#define TranslateAccelerator TranslateAcceleratorA +#endif + + WINUSERAPI int WINAPI TranslateAcceleratorA(HWND hWnd,HACCEL hAccTable,LPMSG lpMsg); + WINUSERAPI int WINAPI TranslateAcceleratorW(HWND hWnd,HACCEL hAccTable,LPMSG lpMsg); +#endif + +#ifndef NOSYSMETRICS + #define SM_CXSCREEN 0 #define SM_CYSCREEN 1 #define SM_CXVSCROLL 2 @@ -779,9 +2545,7 @@ extern "C" { #define SM_CXBORDER 5 #define SM_CYBORDER 6 #define SM_CXDLGFRAME 7 -#define SM_CXFIXEDFRAME 7 #define SM_CYDLGFRAME 8 -#define SM_CYFIXEDFRAME 8 #define SM_CYVTHUMB 9 #define SM_CXHTHUMB 10 #define SM_CXICON 11 @@ -805,9 +2569,7 @@ extern "C" { #define SM_CYMIN 29 #define SM_CXSIZE 30 #define SM_CYSIZE 31 -#define SM_CXSIZEFRAME 32 #define SM_CXFRAME 32 -#define SM_CYSIZEFRAME 33 #define SM_CYFRAME 33 #define SM_CXMINTRACK 34 #define SM_CYMINTRACK 35 @@ -819,6 +2581,12 @@ extern "C" { #define SM_PENWINDOWS 41 #define SM_DBCSENABLED 42 #define SM_CMOUSEBUTTONS 43 + +#define SM_CXFIXEDFRAME SM_CXDLGFRAME +#define SM_CYFIXEDFRAME SM_CYDLGFRAME +#define SM_CXSIZEFRAME SM_CXFRAME +#define SM_CYSIZEFRAME SM_CYFRAME + #define SM_SECURE 44 #define SM_CXEDGE 45 #define SM_CYEDGE 46 @@ -839,7 +2607,6 @@ extern "C" { #define SM_CXMAXIMIZED 61 #define SM_CYMAXIMIZED 62 #define SM_NETWORK 63 -#define LR_DEFAULTSIZE 64 #define SM_CLEANBOOT 67 #define SM_CXDRAG 68 #define SM_CYDRAG 69 @@ -855,72 +2622,1137 @@ extern "C" { #define SM_CYVIRTUALSCREEN 79 #define SM_CMONITORS 80 #define SM_SAMEDISPLAYFORMAT 81 -#if (_WIN32_WINNT < 0x0400) -#define SM_CMETRICS 76 -#else -#define SM_CMETRICS 83 -#endif -#define ARW_BOTTOMLEFT 0 -#define ARW_BOTTOMRIGHT 1 -#define ARW_HIDE 8 -#define ARW_TOPLEFT 2 -#define ARW_TOPRIGHT 3 -#define ARW_DOWN 4 -#define ARW_LEFT 0 -#define ARW_RIGHT 0 -#define ARW_UP 4 -#define UOI_FLAGS 1 -#define UOI_NAME 2 -#define UOI_TYPE 3 -#define UOI_USER_SID 4 -#define LR_DEFAULTCOLOR 0 -#define LR_MONOCHROME 1 -#define LR_COLOR 2 -#define LR_COPYRETURNORG 4 -#define LR_COPYDELETEORG 8 -#define LR_LOADFROMFILE 16 -#define LR_LOADTRANSPARENT 32 -#define LR_LOADREALSIZE 128 -#define LR_LOADMAP3DCOLORS 4096 -#define LR_CREATEDIBSECTION 8192 +#define SM_IMMENABLED 82 +#define SM_CXFOCUSBORDER 83 +#define SM_CYFOCUSBORDER 84 +#define SM_TABLETPC 86 +#define SM_MEDIACENTER 87 +#define SM_STARTER 88 +#define SM_SERVERR2 89 +#define SM_CMETRICS 90 +#define SM_REMOTESESSION 0x1000 +#define SM_SHUTTINGDOWN 0x2000 +#define SM_REMOTECONTROL 0x2001 +#define SM_CARETBLINKINGENABLED 0x2002 + + WINUSERAPI int WINAPI GetSystemMetrics(int nIndex); +#endif + +#ifndef NOMENUS + +#ifdef UNICODE +#define LoadMenu LoadMenuW +#define LoadMenuIndirect LoadMenuIndirectW +#define ChangeMenu ChangeMenuW +#define GetMenuString GetMenuStringW +#define InsertMenu InsertMenuW +#define AppendMenu AppendMenuW +#define ModifyMenu ModifyMenuW +#else +#define LoadMenu LoadMenuA +#define LoadMenuIndirect LoadMenuIndirectA +#define ChangeMenu ChangeMenuA +#define GetMenuString GetMenuStringA +#define InsertMenu InsertMenuA +#define AppendMenu AppendMenuA +#define ModifyMenu ModifyMenuA +#endif + + WINUSERAPI HMENU WINAPI LoadMenuA(HINSTANCE hInstance,LPCSTR lpMenuName); + WINUSERAPI HMENU WINAPI LoadMenuW(HINSTANCE hInstance,LPCWSTR lpMenuName); + WINUSERAPI HMENU WINAPI LoadMenuIndirectA(CONST MENUTEMPLATEA *lpMenuTemplate); + WINUSERAPI HMENU WINAPI LoadMenuIndirectW(CONST MENUTEMPLATEW *lpMenuTemplate); + WINUSERAPI HMENU WINAPI GetMenu(HWND hWnd); + WINUSERAPI WINBOOL WINAPI SetMenu(HWND hWnd,HMENU hMenu); + WINUSERAPI WINBOOL WINAPI ChangeMenuA(HMENU hMenu,UINT cmd,LPCSTR lpszNewItem,UINT cmdInsert,UINT flags); + WINUSERAPI WINBOOL WINAPI ChangeMenuW(HMENU hMenu,UINT cmd,LPCWSTR lpszNewItem,UINT cmdInsert,UINT flags); + WINUSERAPI WINBOOL WINAPI HiliteMenuItem(HWND hWnd,HMENU hMenu,UINT uIDHiliteItem,UINT uHilite); + WINUSERAPI int WINAPI GetMenuStringA(HMENU hMenu,UINT uIDItem,LPSTR lpString,int cchMax,UINT flags); + WINUSERAPI int WINAPI GetMenuStringW(HMENU hMenu,UINT uIDItem,LPWSTR lpString,int cchMax,UINT flags); + WINUSERAPI UINT WINAPI GetMenuState(HMENU hMenu,UINT uId,UINT uFlags); + WINUSERAPI WINBOOL WINAPI DrawMenuBar(HWND hWnd); + +#define PMB_ACTIVE 0x00000001 + + WINUSERAPI HMENU WINAPI GetSystemMenu(HWND hWnd,WINBOOL bRevert); + WINUSERAPI HMENU WINAPI CreateMenu(VOID); + WINUSERAPI HMENU WINAPI CreatePopupMenu(VOID); + WINUSERAPI WINBOOL WINAPI DestroyMenu(HMENU hMenu); + WINUSERAPI DWORD WINAPI CheckMenuItem(HMENU hMenu,UINT uIDCheckItem,UINT uCheck); + WINUSERAPI WINBOOL WINAPI EnableMenuItem(HMENU hMenu,UINT uIDEnableItem,UINT uEnable); + WINUSERAPI HMENU WINAPI GetSubMenu(HMENU hMenu,int nPos); + WINUSERAPI UINT WINAPI GetMenuItemID(HMENU hMenu,int nPos); + WINUSERAPI int WINAPI GetMenuItemCount(HMENU hMenu); + WINUSERAPI WINBOOL WINAPI InsertMenuA(HMENU hMenu,UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCSTR lpNewItem); + WINUSERAPI WINBOOL WINAPI InsertMenuW(HMENU hMenu,UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCWSTR lpNewItem); + WINUSERAPI WINBOOL WINAPI AppendMenuA(HMENU hMenu,UINT uFlags,UINT_PTR uIDNewItem,LPCSTR lpNewItem); + WINUSERAPI WINBOOL WINAPI AppendMenuW(HMENU hMenu,UINT uFlags,UINT_PTR uIDNewItem,LPCWSTR lpNewItem); + WINUSERAPI WINBOOL WINAPI ModifyMenuA(HMENU hMnu,UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCSTR lpNewItem); + WINUSERAPI WINBOOL WINAPI ModifyMenuW(HMENU hMnu,UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCWSTR lpNewItem); + WINUSERAPI WINBOOL WINAPI RemoveMenu(HMENU hMenu,UINT uPosition,UINT uFlags); + WINUSERAPI WINBOOL WINAPI DeleteMenu(HMENU hMenu,UINT uPosition,UINT uFlags); + WINUSERAPI WINBOOL WINAPI SetMenuItemBitmaps(HMENU hMenu,UINT uPosition,UINT uFlags,HBITMAP hBitmapUnchecked,HBITMAP hBitmapChecked); + WINUSERAPI LONG WINAPI GetMenuCheckMarkDimensions(VOID); + WINUSERAPI WINBOOL WINAPI TrackPopupMenu(HMENU hMenu,UINT uFlags,int x,int y,int nReserved,HWND hWnd,CONST RECT *prcRect); + +#define MNC_IGNORE 0 +#define MNC_CLOSE 1 +#define MNC_EXECUTE 2 +#define MNC_SELECT 3 + + typedef struct tagTPMPARAMS { + UINT cbSize; + RECT rcExclude; + } TPMPARAMS; + + typedef TPMPARAMS *LPTPMPARAMS; + + WINUSERAPI WINBOOL WINAPI TrackPopupMenuEx(HMENU,UINT,int,int,HWND,LPTPMPARAMS); + +#define MNS_NOCHECK 0x80000000 +#define MNS_MODELESS 0x40000000 +#define MNS_DRAGDROP 0x20000000 +#define MNS_AUTODISMISS 0x10000000 +#define MNS_NOTIFYBYPOS 0x08000000 +#define MNS_CHECKORBMP 0x04000000 + +#define MIM_MAXHEIGHT 0x00000001 +#define MIM_BACKGROUND 0x00000002 +#define MIM_HELPID 0x00000004 +#define MIM_MENUDATA 0x00000008 +#define MIM_STYLE 0x00000010 +#define MIM_APPLYTOSUBMENUS 0x80000000 + + typedef struct tagMENUINFO { + DWORD cbSize; + DWORD fMask; + DWORD dwStyle; + UINT cyMax; + HBRUSH hbrBack; + DWORD dwContextHelpID; + ULONG_PTR dwMenuData; + } MENUINFO,*LPMENUINFO; + + typedef MENUINFO CONST *LPCMENUINFO; + + WINUSERAPI WINBOOL WINAPI GetMenuInfo(HMENU,LPMENUINFO); + WINUSERAPI WINBOOL WINAPI SetMenuInfo(HMENU,LPCMENUINFO); + WINUSERAPI WINBOOL WINAPI EndMenu(VOID); + +#define MND_CONTINUE 0 +#define MND_ENDMENU 1 + + typedef struct tagMENUGETOBJECTINFO { + DWORD dwFlags; + UINT uPos; + HMENU hmenu; + PVOID riid; + PVOID pvObj; + } MENUGETOBJECTINFO,*PMENUGETOBJECTINFO; + +#define MNGOF_TOPGAP 0x00000001 +#define MNGOF_BOTTOMGAP 0x00000002 + +#define MNGO_NOINTERFACE 0x00000000 +#define MNGO_NOERROR 0x00000001 + +#define MIIM_STATE 0x00000001 +#define MIIM_ID 0x00000002 +#define MIIM_SUBMENU 0x00000004 +#define MIIM_CHECKMARKS 0x00000008 +#define MIIM_TYPE 0x00000010 +#define MIIM_DATA 0x00000020 + +#define MIIM_STRING 0x00000040 +#define MIIM_BITMAP 0x00000080 +#define MIIM_FTYPE 0x00000100 + +#define HBMMENU_CALLBACK ((HBITMAP) -1) +#define HBMMENU_SYSTEM ((HBITMAP) 1) +#define HBMMENU_MBAR_RESTORE ((HBITMAP) 2) +#define HBMMENU_MBAR_MINIMIZE ((HBITMAP) 3) +#define HBMMENU_MBAR_CLOSE ((HBITMAP) 5) +#define HBMMENU_MBAR_CLOSE_D ((HBITMAP) 6) +#define HBMMENU_MBAR_MINIMIZE_D ((HBITMAP) 7) +#define HBMMENU_POPUP_CLOSE ((HBITMAP) 8) +#define HBMMENU_POPUP_RESTORE ((HBITMAP) 9) +#define HBMMENU_POPUP_MAXIMIZE ((HBITMAP) 10) +#define HBMMENU_POPUP_MINIMIZE ((HBITMAP) 11) + + typedef struct tagMENUITEMINFOA { + UINT cbSize; + UINT fMask; + UINT fType; + UINT fState; + UINT wID; + HMENU hSubMenu; + HBITMAP hbmpChecked; + HBITMAP hbmpUnchecked; + ULONG_PTR dwItemData; + LPSTR dwTypeData; + UINT cch; + HBITMAP hbmpItem; + } MENUITEMINFOA,*LPMENUITEMINFOA; + + typedef struct tagMENUITEMINFOW { + UINT cbSize; + UINT fMask; + UINT fType; + UINT fState; + UINT wID; + HMENU hSubMenu; + HBITMAP hbmpChecked; + HBITMAP hbmpUnchecked; + ULONG_PTR dwItemData; + LPWSTR dwTypeData; + UINT cch; + HBITMAP hbmpItem; + } MENUITEMINFOW,*LPMENUITEMINFOW; + +#ifdef UNICODE + typedef MENUITEMINFOW MENUITEMINFO; + typedef LPMENUITEMINFOW LPMENUITEMINFO; +#else + typedef MENUITEMINFOA MENUITEMINFO; + typedef LPMENUITEMINFOA LPMENUITEMINFO; +#endif + typedef MENUITEMINFOA CONST *LPCMENUITEMINFOA; + typedef MENUITEMINFOW CONST *LPCMENUITEMINFOW; +#ifdef UNICODE + typedef LPCMENUITEMINFOW LPCMENUITEMINFO; +#else + typedef LPCMENUITEMINFOA LPCMENUITEMINFO; +#endif + +#ifdef UNICODE +#define InsertMenuItem InsertMenuItemW +#define GetMenuItemInfo GetMenuItemInfoW +#define SetMenuItemInfo SetMenuItemInfoW +#else +#define InsertMenuItem InsertMenuItemA +#define GetMenuItemInfo GetMenuItemInfoA +#define SetMenuItemInfo SetMenuItemInfoA +#endif + + WINUSERAPI WINBOOL WINAPI InsertMenuItemA(HMENU hmenu,UINT item,WINBOOL fByPosition,LPCMENUITEMINFOA lpmi); + WINUSERAPI WINBOOL WINAPI InsertMenuItemW(HMENU hmenu,UINT item,WINBOOL fByPosition,LPCMENUITEMINFOW lpmi); + WINUSERAPI WINBOOL WINAPI GetMenuItemInfoA(HMENU hmenu,UINT item,WINBOOL fByPosition,LPMENUITEMINFOA lpmii); + WINUSERAPI WINBOOL WINAPI GetMenuItemInfoW(HMENU hmenu,UINT item,WINBOOL fByPosition,LPMENUITEMINFOW lpmii); + WINUSERAPI WINBOOL WINAPI SetMenuItemInfoA(HMENU hmenu,UINT item,WINBOOL fByPositon,LPCMENUITEMINFOA lpmii); + WINUSERAPI WINBOOL WINAPI SetMenuItemInfoW(HMENU hmenu,UINT item,WINBOOL fByPositon,LPCMENUITEMINFOW lpmii); + +#define GMDI_USEDISABLED 0x0001L +#define GMDI_GOINTOPOPUPS 0x0002L + + WINUSERAPI UINT WINAPI GetMenuDefaultItem(HMENU hMenu,UINT fByPos,UINT gmdiFlags); + WINUSERAPI WINBOOL WINAPI SetMenuDefaultItem(HMENU hMenu,UINT uItem,UINT fByPos); + WINUSERAPI WINBOOL WINAPI GetMenuItemRect(HWND hWnd,HMENU hMenu,UINT uItem,LPRECT lprcItem); + WINUSERAPI int WINAPI MenuItemFromPoint(HWND hWnd,HMENU hMenu,POINT ptScreen); + +#define TPM_LEFTBUTTON 0x0000L +#define TPM_RIGHTBUTTON 0x0002L +#define TPM_LEFTALIGN 0x0000L +#define TPM_CENTERALIGN 0x0004L +#define TPM_RIGHTALIGN 0x0008L +#define TPM_TOPALIGN 0x0000L +#define TPM_VCENTERALIGN 0x0010L +#define TPM_BOTTOMALIGN 0x0020L + +#define TPM_HORIZONTAL 0x0000L +#define TPM_VERTICAL 0x0040L +#define TPM_NONOTIFY 0x0080L +#define TPM_RETURNCMD 0x0100L +#define TPM_RECURSE 0x0001L +#define TPM_HORPOSANIMATION 0x0400L +#define TPM_HORNEGANIMATION 0x0800L +#define TPM_VERPOSANIMATION 0x1000L +#define TPM_VERNEGANIMATION 0x2000L +#define TPM_NOANIMATION 0x4000L +#define TPM_LAYOUTRTL 0x8000L +#endif + + typedef struct tagDROPSTRUCT { + HWND hwndSource; + HWND hwndSink; + DWORD wFmt; + ULONG_PTR dwData; + POINT ptDrop; + DWORD dwControlData; + } DROPSTRUCT,*PDROPSTRUCT,*LPDROPSTRUCT; + +#define DOF_EXECUTABLE 0x8001 +#define DOF_DOCUMENT 0x8002 +#define DOF_DIRECTORY 0x8003 +#define DOF_MULTIPLE 0x8004 +#define DOF_PROGMAN 0x0001 +#define DOF_SHELLDATA 0x0002 + +#define DO_DROPFILE 0x454C4946L +#define DO_PRINTFILE 0x544E5250L + + WINUSERAPI DWORD WINAPI DragObject(HWND hwndParent,HWND hwndFrom,UINT fmt,ULONG_PTR data,HCURSOR hcur); + WINUSERAPI WINBOOL WINAPI DragDetect(HWND hwnd,POINT pt); + WINUSERAPI WINBOOL WINAPI DrawIcon(HDC hDC,int X,int Y,HICON hIcon); + +#ifndef NODRAWTEXT + +#define DT_TOP 0x00000000 +#define DT_LEFT 0x00000000 +#define DT_CENTER 0x00000001 +#define DT_RIGHT 0x00000002 +#define DT_VCENTER 0x00000004 +#define DT_BOTTOM 0x00000008 +#define DT_WORDBREAK 0x00000010 +#define DT_SINGLELINE 0x00000020 +#define DT_EXPANDTABS 0x00000040 +#define DT_TABSTOP 0x00000080 +#define DT_NOCLIP 0x00000100 +#define DT_EXTERNALLEADING 0x00000200 +#define DT_CALCRECT 0x00000400 +#define DT_NOPREFIX 0x00000800 +#define DT_INTERNAL 0x00001000 + +#define DT_EDITCONTROL 0x00002000 +#define DT_PATH_ELLIPSIS 0x00004000 +#define DT_END_ELLIPSIS 0x00008000 +#define DT_MODIFYSTRING 0x00010000 +#define DT_RTLREADING 0x00020000 +#define DT_WORD_ELLIPSIS 0x00040000 +#define DT_NOFULLWIDTHCHARBREAK 0x00080000 +#define DT_HIDEPREFIX 0x00100000 +#define DT_PREFIXONLY 0x00200000 + + typedef struct tagDRAWTEXTPARAMS { + UINT cbSize; + int iTabLength; + int iLeftMargin; + int iRightMargin; + UINT uiLengthDrawn; + } DRAWTEXTPARAMS,*LPDRAWTEXTPARAMS; + +#ifdef UNICODE +#define DrawText DrawTextW +#define DrawTextEx DrawTextExW +#else +#define DrawText DrawTextA +#define DrawTextEx DrawTextExA +#endif + + WINUSERAPI int WINAPI DrawTextA(HDC hdc,LPCSTR lpchText,int cchText,LPRECT lprc,UINT format); + WINUSERAPI int WINAPI DrawTextW(HDC hdc,LPCWSTR lpchText,int cchText,LPRECT lprc,UINT format); + WINUSERAPI int WINAPI DrawTextExA(HDC hdc,LPSTR lpchText,int cchText,LPRECT lprc,UINT format,LPDRAWTEXTPARAMS lpdtp); + WINUSERAPI int WINAPI DrawTextExW(HDC hdc,LPWSTR lpchText,int cchText,LPRECT lprc,UINT format,LPDRAWTEXTPARAMS lpdtp); +#endif + +#ifdef UNICODE +#define GrayString GrayStringW +#define DrawState DrawStateW +#define TabbedTextOut TabbedTextOutW +#define GetTabbedTextExtent GetTabbedTextExtentW +#else +#define GrayString GrayStringA +#define DrawState DrawStateA +#define TabbedTextOut TabbedTextOutA +#define GetTabbedTextExtent GetTabbedTextExtentA +#endif + + WINUSERAPI WINBOOL WINAPI GrayStringA(HDC hDC,HBRUSH hBrush,GRAYSTRINGPROC lpOutputFunc,LPARAM lpData,int nCount,int X,int Y,int nWidth,int nHeight); + WINUSERAPI WINBOOL WINAPI GrayStringW(HDC hDC,HBRUSH hBrush,GRAYSTRINGPROC lpOutputFunc,LPARAM lpData,int nCount,int X,int Y,int nWidth,int nHeight); + +#define DST_COMPLEX 0x0000 +#define DST_TEXT 0x0001 +#define DST_PREFIXTEXT 0x0002 +#define DST_ICON 0x0003 +#define DST_BITMAP 0x0004 + +#define DSS_NORMAL 0x0000 +#define DSS_UNION 0x0010 +#define DSS_DISABLED 0x0020 +#define DSS_MONO 0x0080 +#define DSS_HIDEPREFIX 0x0200 +#define DSS_PREFIXONLY 0x0400 +#define DSS_RIGHT 0x8000 + + WINUSERAPI WINBOOL WINAPI DrawStateA(HDC hdc,HBRUSH hbrFore,DRAWSTATEPROC qfnCallBack,LPARAM lData,WPARAM wData,int x,int y,int cx,int cy,UINT uFlags); + WINUSERAPI WINBOOL WINAPI DrawStateW(HDC hdc,HBRUSH hbrFore,DRAWSTATEPROC qfnCallBack,LPARAM lData,WPARAM wData,int x,int y,int cx,int cy,UINT uFlags); + WINUSERAPI LONG WINAPI TabbedTextOutA(HDC hdc,int x,int y,LPCSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions,int nTabOrigin); + WINUSERAPI LONG WINAPI TabbedTextOutW(HDC hdc,int x,int y,LPCWSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions,int nTabOrigin); + WINUSERAPI DWORD WINAPI GetTabbedTextExtentA(HDC hdc,LPCSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions); + WINUSERAPI DWORD WINAPI GetTabbedTextExtentW(HDC hdc,LPCWSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions); + WINUSERAPI WINBOOL WINAPI UpdateWindow(HWND hWnd); + WINUSERAPI HWND WINAPI SetActiveWindow(HWND hWnd); + WINUSERAPI HWND WINAPI GetForegroundWindow(VOID); + WINUSERAPI WINBOOL WINAPI PaintDesktop(HDC hdc); + WINUSERAPI VOID WINAPI SwitchToThisWindow(HWND hwnd,WINBOOL fUnknown); + WINUSERAPI WINBOOL WINAPI SetForegroundWindow(HWND hWnd); + WINUSERAPI WINBOOL WINAPI AllowSetForegroundWindow(DWORD dwProcessId); + +#define ASFW_ANY ((DWORD)-1) + + WINUSERAPI WINBOOL WINAPI LockSetForegroundWindow(UINT uLockCode); + +#define LSFW_LOCK 1 +#define LSFW_UNLOCK 2 + + WINUSERAPI HWND WINAPI WindowFromDC(HDC hDC); + WINUSERAPI HDC WINAPI GetDC(HWND hWnd); + WINUSERAPI HDC WINAPI GetDCEx(HWND hWnd,HRGN hrgnClip,DWORD flags); + +#define DCX_WINDOW 0x00000001L +#define DCX_CACHE 0x00000002L +#define DCX_NORESETATTRS 0x00000004L +#define DCX_CLIPCHILDREN 0x00000008L +#define DCX_CLIPSIBLINGS 0x00000010L +#define DCX_PARENTCLIP 0x00000020L +#define DCX_EXCLUDERGN 0x00000040L +#define DCX_INTERSECTRGN 0x00000080L +#define DCX_EXCLUDEUPDATE 0x00000100L +#define DCX_INTERSECTUPDATE 0x00000200L +#define DCX_LOCKWINDOWUPDATE 0x00000400L + +#define DCX_VALIDATE 0x00200000L + + WINUSERAPI HDC WINAPI GetWindowDC(HWND hWnd); + WINUSERAPI int WINAPI ReleaseDC(HWND hWnd,HDC hDC); + WINUSERAPI HDC WINAPI BeginPaint(HWND hWnd,LPPAINTSTRUCT lpPaint); + WINUSERAPI WINBOOL WINAPI EndPaint(HWND hWnd,CONST PAINTSTRUCT *lpPaint); + WINUSERAPI WINBOOL WINAPI GetUpdateRect(HWND hWnd,LPRECT lpRect,WINBOOL bErase); + WINUSERAPI int WINAPI GetUpdateRgn(HWND hWnd,HRGN hRgn,WINBOOL bErase); + WINUSERAPI int WINAPI SetWindowRgn(HWND hWnd,HRGN hRgn,WINBOOL bRedraw); + WINUSERAPI int WINAPI GetWindowRgn(HWND hWnd,HRGN hRgn); + WINUSERAPI int WINAPI GetWindowRgnBox(HWND hWnd,LPRECT lprc); + WINUSERAPI int WINAPI ExcludeUpdateRgn(HDC hDC,HWND hWnd); + WINUSERAPI WINBOOL WINAPI InvalidateRect(HWND hWnd,CONST RECT *lpRect,WINBOOL bErase); + WINUSERAPI WINBOOL WINAPI ValidateRect(HWND hWnd,CONST RECT *lpRect); + WINUSERAPI WINBOOL WINAPI InvalidateRgn(HWND hWnd,HRGN hRgn,WINBOOL bErase); + WINUSERAPI WINBOOL WINAPI ValidateRgn(HWND hWnd,HRGN hRgn); + WINUSERAPI WINBOOL WINAPI RedrawWindow(HWND hWnd,CONST RECT *lprcUpdate,HRGN hrgnUpdate,UINT flags); + +#define RDW_INVALIDATE 0x0001 +#define RDW_INTERNALPAINT 0x0002 +#define RDW_ERASE 0x0004 + +#define RDW_VALIDATE 0x0008 +#define RDW_NOINTERNALPAINT 0x0010 +#define RDW_NOERASE 0x0020 + +#define RDW_NOCHILDREN 0x0040 +#define RDW_ALLCHILDREN 0x0080 + +#define RDW_UPDATENOW 0x0100 +#define RDW_ERASENOW 0x0200 + +#define RDW_FRAME 0x0400 +#define RDW_NOFRAME 0x0800 + + WINUSERAPI WINBOOL WINAPI LockWindowUpdate(HWND hWndLock); + WINUSERAPI WINBOOL WINAPI ScrollWindow(HWND hWnd,int XAmount,int YAmount,CONST RECT *lpRect,CONST RECT *lpClipRect); + WINUSERAPI WINBOOL WINAPI ScrollDC(HDC hDC,int dx,int dy,CONST RECT *lprcScroll,CONST RECT *lprcClip,HRGN hrgnUpdate,LPRECT lprcUpdate); + WINUSERAPI int WINAPI ScrollWindowEx(HWND hWnd,int dx,int dy,CONST RECT *prcScroll,CONST RECT *prcClip,HRGN hrgnUpdate,LPRECT prcUpdate,UINT flags); + +#define SW_SCROLLCHILDREN 0x0001 +#define SW_INVALIDATE 0x0002 +#define SW_ERASE 0x0004 +#define SW_SMOOTHSCROLL 0x0010 + +#ifndef NOSCROLL + WINUSERAPI int WINAPI SetScrollPos(HWND hWnd,int nBar,int nPos,WINBOOL bRedraw); + WINUSERAPI int WINAPI GetScrollPos(HWND hWnd,int nBar); + WINUSERAPI WINBOOL WINAPI SetScrollRange(HWND hWnd,int nBar,int nMinPos,int nMaxPos,WINBOOL bRedraw); + WINUSERAPI WINBOOL WINAPI GetScrollRange(HWND hWnd,int nBar,LPINT lpMinPos,LPINT lpMaxPos); + WINUSERAPI WINBOOL WINAPI ShowScrollBar(HWND hWnd,int wBar,WINBOOL bShow); + WINUSERAPI WINBOOL WINAPI EnableScrollBar(HWND hWnd,UINT wSBflags,UINT wArrows); + +#define ESB_ENABLE_BOTH 0x0000 +#define ESB_DISABLE_BOTH 0x0003 + +#define ESB_DISABLE_LEFT 0x0001 +#define ESB_DISABLE_RIGHT 0x0002 + +#define ESB_DISABLE_UP 0x0001 +#define ESB_DISABLE_DOWN 0x0002 + +#define ESB_DISABLE_LTUP ESB_DISABLE_LEFT +#define ESB_DISABLE_RTDN ESB_DISABLE_RIGHT +#endif + +#ifdef UNICODE +#define SetProp SetPropW +#define GetProp GetPropW +#define RemoveProp RemovePropW +#define EnumPropsEx EnumPropsExW +#define EnumProps EnumPropsW +#define SetWindowText SetWindowTextW +#define GetWindowText GetWindowTextW +#define GetWindowTextLength GetWindowTextLengthW +#else +#define SetProp SetPropA +#define GetProp GetPropA +#define RemoveProp RemovePropA +#define EnumPropsEx EnumPropsExA +#define EnumProps EnumPropsA +#define SetWindowText SetWindowTextA +#define GetWindowText GetWindowTextA +#define GetWindowTextLength GetWindowTextLengthA +#endif + + WINUSERAPI WINBOOL WINAPI SetPropA(HWND hWnd,LPCSTR lpString,HANDLE hData); + WINUSERAPI WINBOOL WINAPI SetPropW(HWND hWnd,LPCWSTR lpString,HANDLE hData); + WINUSERAPI HANDLE WINAPI GetPropA(HWND hWnd,LPCSTR lpString); + WINUSERAPI HANDLE WINAPI GetPropW(HWND hWnd,LPCWSTR lpString); + WINUSERAPI HANDLE WINAPI RemovePropA(HWND hWnd,LPCSTR lpString); + WINUSERAPI HANDLE WINAPI RemovePropW(HWND hWnd,LPCWSTR lpString); + WINUSERAPI int WINAPI EnumPropsExA(HWND hWnd,PROPENUMPROCEXA lpEnumFunc,LPARAM lParam); + WINUSERAPI int WINAPI EnumPropsExW(HWND hWnd,PROPENUMPROCEXW lpEnumFunc,LPARAM lParam); + WINUSERAPI int WINAPI EnumPropsA(HWND hWnd,PROPENUMPROCA lpEnumFunc); + WINUSERAPI int WINAPI EnumPropsW(HWND hWnd,PROPENUMPROCW lpEnumFunc); + WINUSERAPI WINBOOL WINAPI SetWindowTextA(HWND hWnd,LPCSTR lpString); + WINUSERAPI WINBOOL WINAPI SetWindowTextW(HWND hWnd,LPCWSTR lpString); + WINUSERAPI int WINAPI GetWindowTextA(HWND hWnd,LPSTR lpString,int nMaxCount); + WINUSERAPI int WINAPI GetWindowTextW(HWND hWnd,LPWSTR lpString,int nMaxCount); + WINUSERAPI int WINAPI GetWindowTextLengthA(HWND hWnd); + WINUSERAPI int WINAPI GetWindowTextLengthW(HWND hWnd); + WINUSERAPI WINBOOL WINAPI GetClientRect(HWND hWnd,LPRECT lpRect); + WINUSERAPI WINBOOL WINAPI GetWindowRect(HWND hWnd,LPRECT lpRect); + WINUSERAPI WINBOOL WINAPI AdjustWindowRect(LPRECT lpRect,DWORD dwStyle,WINBOOL bMenu); + WINUSERAPI WINBOOL WINAPI AdjustWindowRectEx(LPRECT lpRect,DWORD dwStyle,WINBOOL bMenu,DWORD dwExStyle); + +#define HELPINFO_WINDOW 0x0001 +#define HELPINFO_MENUITEM 0x0002 + + typedef struct tagHELPINFO { + UINT cbSize; + int iContextType; + int iCtrlId; + HANDLE hItemHandle; + DWORD_PTR dwContextId; + POINT MousePos; + } HELPINFO,*LPHELPINFO; + + WINUSERAPI WINBOOL WINAPI SetWindowContextHelpId(HWND,DWORD); + WINUSERAPI DWORD WINAPI GetWindowContextHelpId(HWND); + WINUSERAPI WINBOOL WINAPI SetMenuContextHelpId(HMENU,DWORD); + WINUSERAPI DWORD WINAPI GetMenuContextHelpId(HMENU); + +#ifndef NOMB + +#define MB_OK 0x00000000L +#define MB_OKCANCEL 0x00000001L +#define MB_ABORTRETRYIGNORE 0x00000002L +#define MB_YESNOCANCEL 0x00000003L +#define MB_YESNO 0x00000004L +#define MB_RETRYCANCEL 0x00000005L +#define MB_CANCELTRYCONTINUE 0x00000006L +#define MB_ICONHAND 0x00000010L +#define MB_ICONQUESTION 0x00000020L +#define MB_ICONEXCLAMATION 0x00000030L +#define MB_ICONASTERISK 0x00000040L +#define MB_USERICON 0x00000080L +#define MB_ICONWARNING MB_ICONEXCLAMATION +#define MB_ICONERROR MB_ICONHAND +#define MB_ICONINFORMATION MB_ICONASTERISK +#define MB_ICONSTOP MB_ICONHAND +#define MB_DEFBUTTON1 0x00000000L +#define MB_DEFBUTTON2 0x00000100L +#define MB_DEFBUTTON3 0x00000200L +#define MB_DEFBUTTON4 0x00000300L +#define MB_APPLMODAL 0x00000000L +#define MB_SYSTEMMODAL 0x00001000L +#define MB_TASKMODAL 0x00002000L +#define MB_HELP 0x00004000L +#define MB_NOFOCUS 0x00008000L +#define MB_SETFOREGROUND 0x00010000L +#define MB_DEFAULT_DESKTOP_ONLY 0x00020000L +#define MB_TOPMOST 0x00040000L +#define MB_RIGHT 0x00080000L +#define MB_RTLREADING 0x00100000L +#define MB_SERVICE_NOTIFICATION 0x00200000L +#define MB_SERVICE_NOTIFICATION_NT3X 0x00040000L +#define MB_TYPEMASK 0x0000000FL +#define MB_ICONMASK 0x000000F0L +#define MB_DEFMASK 0x00000F00L +#define MB_MODEMASK 0x00003000L +#define MB_MISCMASK 0x0000C000L + +#ifdef UNICODE +#define MessageBox MessageBoxW +#define MessageBoxEx MessageBoxExW +#else +#define MessageBox MessageBoxA +#define MessageBoxEx MessageBoxExA +#endif + + WINUSERAPI int WINAPI MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType); + WINUSERAPI int WINAPI MessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType); + WINUSERAPI int WINAPI MessageBoxExA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType,WORD wLanguageId); + WINUSERAPI int WINAPI MessageBoxExW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType,WORD wLanguageId); + + typedef VOID (CALLBACK *MSGBOXCALLBACK)(LPHELPINFO lpHelpInfo); + + typedef struct tagMSGBOXPARAMSA { + UINT cbSize; + HWND hwndOwner; + HINSTANCE hInstance; + LPCSTR lpszText; + LPCSTR lpszCaption; + DWORD dwStyle; + LPCSTR lpszIcon; + DWORD_PTR dwContextHelpId; + MSGBOXCALLBACK lpfnMsgBoxCallback; + DWORD dwLanguageId; + } MSGBOXPARAMSA,*PMSGBOXPARAMSA,*LPMSGBOXPARAMSA; + + typedef struct tagMSGBOXPARAMSW { + UINT cbSize; + HWND hwndOwner; + HINSTANCE hInstance; + LPCWSTR lpszText; + LPCWSTR lpszCaption; + DWORD dwStyle; + LPCWSTR lpszIcon; + DWORD_PTR dwContextHelpId; + MSGBOXCALLBACK lpfnMsgBoxCallback; + DWORD dwLanguageId; + } MSGBOXPARAMSW,*PMSGBOXPARAMSW,*LPMSGBOXPARAMSW; + +#ifdef UNICODE + typedef MSGBOXPARAMSW MSGBOXPARAMS; + typedef PMSGBOXPARAMSW PMSGBOXPARAMS; + typedef LPMSGBOXPARAMSW LPMSGBOXPARAMS; +#else + typedef MSGBOXPARAMSA MSGBOXPARAMS; + typedef PMSGBOXPARAMSA PMSGBOXPARAMS; + typedef LPMSGBOXPARAMSA LPMSGBOXPARAMS; +#endif + +#ifdef UNICODE +#define MessageBoxIndirect MessageBoxIndirectW +#else +#define MessageBoxIndirect MessageBoxIndirectA +#endif + + WINUSERAPI int WINAPI MessageBoxIndirectA(CONST MSGBOXPARAMSA *lpmbp); + WINUSERAPI int WINAPI MessageBoxIndirectW(CONST MSGBOXPARAMSW *lpmbp); + WINUSERAPI WINBOOL WINAPI MessageBeep(UINT uType); +#endif + + WINUSERAPI int WINAPI ShowCursor(WINBOOL bShow); + WINUSERAPI WINBOOL WINAPI SetCursorPos(int X,int Y); + WINUSERAPI HCURSOR WINAPI SetCursor(HCURSOR hCursor); + WINUSERAPI WINBOOL WINAPI GetCursorPos(LPPOINT lpPoint); + WINUSERAPI WINBOOL WINAPI ClipCursor(CONST RECT *lpRect); + WINUSERAPI WINBOOL WINAPI GetClipCursor(LPRECT lpRect); + WINUSERAPI HCURSOR WINAPI GetCursor(VOID); + WINUSERAPI WINBOOL WINAPI CreateCaret(HWND hWnd,HBITMAP hBitmap,int nWidth,int nHeight); + WINUSERAPI UINT WINAPI GetCaretBlinkTime(VOID); + WINUSERAPI WINBOOL WINAPI SetCaretBlinkTime(UINT uMSeconds); + WINUSERAPI WINBOOL WINAPI DestroyCaret(VOID); + WINUSERAPI WINBOOL WINAPI HideCaret(HWND hWnd); + WINUSERAPI WINBOOL WINAPI ShowCaret(HWND hWnd); + WINUSERAPI WINBOOL WINAPI SetCaretPos(int X,int Y); + WINUSERAPI WINBOOL WINAPI GetCaretPos(LPPOINT lpPoint); + WINUSERAPI WINBOOL WINAPI ClientToScreen(HWND hWnd,LPPOINT lpPoint); + WINUSERAPI WINBOOL WINAPI ScreenToClient(HWND hWnd,LPPOINT lpPoint); + WINUSERAPI int WINAPI MapWindowPoints(HWND hWndFrom,HWND hWndTo,LPPOINT lpPoints,UINT cPoints); + WINUSERAPI HWND WINAPI WindowFromPoint(POINT Point); + WINUSERAPI HWND WINAPI ChildWindowFromPoint(HWND hWndParent,POINT Point); + +#define CWP_ALL 0x0000 +#define CWP_SKIPINVISIBLE 0x0001 +#define CWP_SKIPDISABLED 0x0002 +#define CWP_SKIPTRANSPARENT 0x0004 + + WINUSERAPI HWND WINAPI ChildWindowFromPointEx(HWND hwnd,POINT pt,UINT flags); + +#ifndef NOCOLOR + +#define CTLCOLOR_MSGBOX 0 +#define CTLCOLOR_EDIT 1 +#define CTLCOLOR_LISTBOX 2 +#define CTLCOLOR_BTN 3 +#define CTLCOLOR_DLG 4 +#define CTLCOLOR_SCROLLBAR 5 +#define CTLCOLOR_STATIC 6 +#define CTLCOLOR_MAX 7 + +#define COLOR_SCROLLBAR 0 +#define COLOR_BACKGROUND 1 +#define COLOR_ACTIVECAPTION 2 +#define COLOR_INACTIVECAPTION 3 +#define COLOR_MENU 4 +#define COLOR_WINDOW 5 +#define COLOR_WINDOWFRAME 6 +#define COLOR_MENUTEXT 7 +#define COLOR_WINDOWTEXT 8 +#define COLOR_CAPTIONTEXT 9 +#define COLOR_ACTIVEBORDER 10 +#define COLOR_INACTIVEBORDER 11 +#define COLOR_APPWORKSPACE 12 +#define COLOR_HIGHLIGHT 13 +#define COLOR_HIGHLIGHTTEXT 14 +#define COLOR_BTNFACE 15 +#define COLOR_BTNSHADOW 16 +#define COLOR_GRAYTEXT 17 +#define COLOR_BTNTEXT 18 +#define COLOR_INACTIVECAPTIONTEXT 19 +#define COLOR_BTNHIGHLIGHT 20 + +#define COLOR_3DDKSHADOW 21 +#define COLOR_3DLIGHT 22 +#define COLOR_INFOTEXT 23 +#define COLOR_INFOBK 24 + +#define COLOR_HOTLIGHT 26 +#define COLOR_GRADIENTACTIVECAPTION 27 +#define COLOR_GRADIENTINACTIVECAPTION 28 +#define COLOR_MENUHILIGHT 29 +#define COLOR_MENUBAR 30 + +#define COLOR_DESKTOP COLOR_BACKGROUND +#define COLOR_3DFACE COLOR_BTNFACE +#define COLOR_3DSHADOW COLOR_BTNSHADOW +#define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT +#define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT +#define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT + + WINUSERAPI DWORD WINAPI GetSysColor(int nIndex); + WINUSERAPI HBRUSH WINAPI GetSysColorBrush(int nIndex); + WINUSERAPI WINBOOL WINAPI SetSysColors(int cElements,CONST INT *lpaElements,CONST COLORREF *lpaRgbValues); +#endif + + WINUSERAPI WINBOOL WINAPI DrawFocusRect(HDC hDC,CONST RECT *lprc); + WINUSERAPI int WINAPI FillRect(HDC hDC,CONST RECT *lprc,HBRUSH hbr); + WINUSERAPI int WINAPI FrameRect(HDC hDC,CONST RECT *lprc,HBRUSH hbr); + WINUSERAPI WINBOOL WINAPI InvertRect(HDC hDC,CONST RECT *lprc); + WINUSERAPI WINBOOL WINAPI SetRect(LPRECT lprc,int xLeft,int yTop,int xRight,int yBottom); + WINUSERAPI WINBOOL WINAPI SetRectEmpty(LPRECT lprc); + WINUSERAPI WINBOOL WINAPI CopyRect(LPRECT lprcDst,CONST RECT *lprcSrc); + WINUSERAPI WINBOOL WINAPI InflateRect(LPRECT lprc,int dx,int dy); + WINUSERAPI WINBOOL WINAPI IntersectRect(LPRECT lprcDst,CONST RECT *lprcSrc1,CONST RECT *lprcSrc2); + WINUSERAPI WINBOOL WINAPI UnionRect(LPRECT lprcDst,CONST RECT *lprcSrc1,CONST RECT *lprcSrc2); + WINUSERAPI WINBOOL WINAPI SubtractRect(LPRECT lprcDst,CONST RECT *lprcSrc1,CONST RECT *lprcSrc2); + WINUSERAPI WINBOOL WINAPI OffsetRect(LPRECT lprc,int dx,int dy); + WINUSERAPI WINBOOL WINAPI IsRectEmpty(CONST RECT *lprc); + WINUSERAPI WINBOOL WINAPI EqualRect(CONST RECT *lprc1,CONST RECT *lprc2); + WINUSERAPI WINBOOL WINAPI PtInRect(CONST RECT *lprc,POINT pt); + +#ifndef NOWINOFFSETS + +#ifdef UNICODE +#define GetWindowLong GetWindowLongW +#define SetWindowLong SetWindowLongW +#else +#define GetWindowLong GetWindowLongA +#define SetWindowLong SetWindowLongA +#endif + + WINUSERAPI WORD WINAPI GetWindowWord(HWND hWnd,int nIndex); + WINUSERAPI WORD WINAPI SetWindowWord(HWND hWnd,int nIndex,WORD wNewWord); + WINUSERAPI LONG WINAPI GetWindowLongA(HWND hWnd,int nIndex); + WINUSERAPI LONG WINAPI GetWindowLongW(HWND hWnd,int nIndex); + WINUSERAPI LONG WINAPI SetWindowLongA(HWND hWnd,int nIndex,LONG dwNewLong); + WINUSERAPI LONG WINAPI SetWindowLongW(HWND hWnd,int nIndex,LONG dwNewLong); + +#ifdef _WIN64 + +#ifdef UNICODE +#define GetWindowLongPtr GetWindowLongPtrW +#define SetWindowLongPtr SetWindowLongPtrW +#else +#define GetWindowLongPtr GetWindowLongPtrA +#define SetWindowLongPtr SetWindowLongPtrA +#endif + + WINUSERAPI LONG_PTR WINAPI GetWindowLongPtrA(HWND hWnd,int nIndex); + WINUSERAPI LONG_PTR WINAPI GetWindowLongPtrW(HWND hWnd,int nIndex); + WINUSERAPI LONG_PTR WINAPI SetWindowLongPtrA(HWND hWnd,int nIndex,LONG_PTR dwNewLong); + WINUSERAPI LONG_PTR WINAPI SetWindowLongPtrW(HWND hWnd,int nIndex,LONG_PTR dwNewLong); +#else + +#ifdef UNICODE +#define GetWindowLongPtr GetWindowLongPtrW +#define SetWindowLongPtr SetWindowLongPtrW +#else +#define GetWindowLongPtr GetWindowLongPtrA +#define SetWindowLongPtr SetWindowLongPtrA +#endif + +#define GetWindowLongPtrA GetWindowLongA +#define GetWindowLongPtrW GetWindowLongW +#define SetWindowLongPtrA SetWindowLongA +#define SetWindowLongPtrW SetWindowLongW +#endif + +#ifdef UNICODE +#define GetClassLong GetClassLongW +#define SetClassLong SetClassLongW +#else +#define GetClassLong GetClassLongA +#define SetClassLong SetClassLongA +#endif + + WINUSERAPI WORD WINAPI GetClassWord(HWND hWnd,int nIndex); + WINUSERAPI WORD WINAPI SetClassWord(HWND hWnd,int nIndex,WORD wNewWord); + WINUSERAPI DWORD WINAPI GetClassLongA(HWND hWnd,int nIndex); + WINUSERAPI DWORD WINAPI GetClassLongW(HWND hWnd,int nIndex); + WINUSERAPI DWORD WINAPI SetClassLongA(HWND hWnd,int nIndex,LONG dwNewLong); + WINUSERAPI DWORD WINAPI SetClassLongW(HWND hWnd,int nIndex,LONG dwNewLong); + +#ifdef _WIN64 + +#ifdef UNICODE +#define GetClassLongPtr GetClassLongPtrW +#define SetClassLongPtr SetClassLongPtrW +#else +#define GetClassLongPtr GetClassLongPtrA +#define SetClassLongPtr SetClassLongPtrA +#endif + + WINUSERAPI ULONG_PTR WINAPI GetClassLongPtrA(HWND hWnd,int nIndex); + WINUSERAPI ULONG_PTR WINAPI GetClassLongPtrW(HWND hWnd,int nIndex); + WINUSERAPI ULONG_PTR WINAPI SetClassLongPtrA(HWND hWnd,int nIndex,LONG_PTR dwNewLong); + WINUSERAPI ULONG_PTR WINAPI SetClassLongPtrW(HWND hWnd,int nIndex,LONG_PTR dwNewLong); +#else +#ifdef UNICODE +#define GetClassLongPtr GetClassLongPtrW +#define SetClassLongPtr SetClassLongPtrW +#else +#define GetClassLongPtr GetClassLongPtrA +#define SetClassLongPtr SetClassLongPtrA +#endif + +#define GetClassLongPtrA GetClassLongA +#define GetClassLongPtrW GetClassLongW +#define SetClassLongPtrA SetClassLongA +#define SetClassLongPtrW SetClassLongW +#endif +#endif + +#ifdef UNICODE +#define FindWindow FindWindowW +#define FindWindowEx FindWindowExW +#define GetClassName GetClassNameW +#else +#define FindWindow FindWindowA +#define FindWindowEx FindWindowExA +#define GetClassName GetClassNameA +#endif + + WINUSERAPI WINBOOL WINAPI GetProcessDefaultLayout(DWORD *pdwDefaultLayout); + WINUSERAPI WINBOOL WINAPI SetProcessDefaultLayout(DWORD dwDefaultLayout); + WINUSERAPI HWND WINAPI GetDesktopWindow(VOID); + WINUSERAPI HWND WINAPI GetParent(HWND hWnd); + WINUSERAPI HWND WINAPI SetParent(HWND hWndChild,HWND hWndNewParent); + WINUSERAPI WINBOOL WINAPI EnumChildWindows(HWND hWndParent,WNDENUMPROC lpEnumFunc,LPARAM lParam); + WINUSERAPI HWND WINAPI FindWindowA(LPCSTR lpClassName,LPCSTR lpWindowName); + WINUSERAPI HWND WINAPI FindWindowW(LPCWSTR lpClassName,LPCWSTR lpWindowName); + WINUSERAPI HWND WINAPI FindWindowExA(HWND hWndParent,HWND hWndChildAfter,LPCSTR lpszClass,LPCSTR lpszWindow); + WINUSERAPI HWND WINAPI FindWindowExW(HWND hWndParent,HWND hWndChildAfter,LPCWSTR lpszClass,LPCWSTR lpszWindow); + WINUSERAPI HWND WINAPI GetShellWindow(VOID); + WINUSERAPI WINBOOL WINAPI RegisterShellHookWindow(HWND hwnd); + WINUSERAPI WINBOOL WINAPI DeregisterShellHookWindow(HWND hwnd); + WINUSERAPI WINBOOL WINAPI EnumWindows(WNDENUMPROC lpEnumFunc,LPARAM lParam); + WINUSERAPI WINBOOL WINAPI EnumThreadWindows(DWORD dwThreadId,WNDENUMPROC lpfn,LPARAM lParam); + +#define EnumTaskWindows(hTask,lpfn,lParam) EnumThreadWindows(HandleToUlong(hTask),lpfn,lParam) + + WINUSERAPI int WINAPI GetClassNameA(HWND hWnd,LPSTR lpClassName,int nMaxCount); + WINUSERAPI int WINAPI GetClassNameW(HWND hWnd,LPWSTR lpClassName,int nMaxCount); + WINUSERAPI HWND WINAPI GetTopWindow(HWND hWnd); + +#define GetNextWindow(hWnd,wCmd) GetWindow(hWnd,wCmd) +#define GetSysModalWindow() (NULL) +#define SetSysModalWindow(hWnd) (NULL) + + WINUSERAPI DWORD WINAPI GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId); + WINUSERAPI WINBOOL WINAPI IsGUIThread(WINBOOL bConvert); + +#define GetWindowTask(hWnd) ((HANDLE)(DWORD_PTR)GetWindowThreadProcessId(hWnd,NULL)) + + WINUSERAPI HWND WINAPI GetLastActivePopup(HWND hWnd); + +#define GW_HWNDFIRST 0 +#define GW_HWNDLAST 1 +#define GW_HWNDNEXT 2 +#define GW_HWNDPREV 3 +#define GW_OWNER 4 +#define GW_CHILD 5 +#define GW_ENABLEDPOPUP 6 +#define GW_MAX 6 + + WINUSERAPI HWND WINAPI GetWindow(HWND hWnd,UINT uCmd); + +#ifndef NOWH + +#ifdef UNICODE +#define SetWindowsHook SetWindowsHookW +#define SetWindowsHookEx SetWindowsHookExW +#else +#define SetWindowsHook SetWindowsHookA +#define SetWindowsHookEx SetWindowsHookExA +#endif + + WINUSERAPI HHOOK WINAPI SetWindowsHookA(int nFilterType,HOOKPROC pfnFilterProc); + WINUSERAPI HHOOK WINAPI SetWindowsHookW(int nFilterType,HOOKPROC pfnFilterProc); + WINUSERAPI WINBOOL WINAPI UnhookWindowsHook(int nCode,HOOKPROC pfnFilterProc); + WINUSERAPI HHOOK WINAPI SetWindowsHookExA(int idHook,HOOKPROC lpfn,HINSTANCE hmod,DWORD dwThreadId); + WINUSERAPI HHOOK WINAPI SetWindowsHookExW(int idHook,HOOKPROC lpfn,HINSTANCE hmod,DWORD dwThreadId); + WINUSERAPI WINBOOL WINAPI UnhookWindowsHookEx(HHOOK hhk); + WINUSERAPI LRESULT WINAPI CallNextHookEx(HHOOK hhk,int nCode,WPARAM wParam,LPARAM lParam); +#define DefHookProc(nCode,wParam,lParam,phhk) CallNextHookEx(*phhk,nCode,wParam,lParam) +#endif + +#ifndef NOMENUS + +#define MF_INSERT 0x00000000L +#define MF_CHANGE 0x00000080L +#define MF_APPEND 0x00000100L +#define MF_DELETE 0x00000200L +#define MF_REMOVE 0x00001000L +#define MF_BYCOMMAND 0x00000000L +#define MF_BYPOSITION 0x00000400L +#define MF_SEPARATOR 0x00000800L +#define MF_ENABLED 0x00000000L +#define MF_GRAYED 0x00000001L +#define MF_DISABLED 0x00000002L +#define MF_UNCHECKED 0x00000000L +#define MF_CHECKED 0x00000008L +#define MF_USECHECKBITMAPS 0x00000200L +#define MF_STRING 0x00000000L +#define MF_BITMAP 0x00000004L +#define MF_OWNERDRAW 0x00000100L +#define MF_POPUP 0x00000010L +#define MF_MENUBARBREAK 0x00000020L +#define MF_MENUBREAK 0x00000040L +#define MF_UNHILITE 0x00000000L +#define MF_HILITE 0x00000080L +#define MF_DEFAULT 0x00001000L +#define MF_SYSMENU 0x00002000L +#define MF_HELP 0x00004000L +#define MF_RIGHTJUSTIFY 0x00004000L +#define MF_MOUSESELECT 0x00008000L +#define MF_END 0x00000080L + +#define MFT_STRING MF_STRING +#define MFT_BITMAP MF_BITMAP +#define MFT_MENUBARBREAK MF_MENUBARBREAK +#define MFT_MENUBREAK MF_MENUBREAK +#define MFT_OWNERDRAW MF_OWNERDRAW +#define MFT_RADIOCHECK 0x00000200L +#define MFT_SEPARATOR MF_SEPARATOR +#define MFT_RIGHTORDER 0x00002000L +#define MFT_RIGHTJUSTIFY MF_RIGHTJUSTIFY + +#define MFS_GRAYED 0x00000003L +#define MFS_DISABLED MFS_GRAYED +#define MFS_CHECKED MF_CHECKED +#define MFS_HILITE MF_HILITE +#define MFS_ENABLED MF_ENABLED +#define MFS_UNCHECKED MF_UNCHECKED +#define MFS_UNHILITE MF_UNHILITE +#define MFS_DEFAULT MF_DEFAULT + + WINUSERAPI WINBOOL WINAPI CheckMenuRadioItem(HMENU hmenu,UINT first,UINT last,UINT check,UINT flags); + + typedef struct { + WORD versionNumber; + WORD offset; + } MENUITEMTEMPLATEHEADER,*PMENUITEMTEMPLATEHEADER; + + typedef struct { + WORD mtOption; + WORD mtID; + WCHAR mtString[1]; + } MENUITEMTEMPLATE,*PMENUITEMTEMPLATE; +#define MF_END 0x00000080L +#endif + +#ifndef NOSYSCOMMANDS + +#define SC_SIZE 0xF000 +#define SC_MOVE 0xF010 +#define SC_MINIMIZE 0xF020 +#define SC_MAXIMIZE 0xF030 +#define SC_NEXTWINDOW 0xF040 +#define SC_PREVWINDOW 0xF050 +#define SC_CLOSE 0xF060 +#define SC_VSCROLL 0xF070 +#define SC_HSCROLL 0xF080 +#define SC_MOUSEMENU 0xF090 +#define SC_KEYMENU 0xF100 +#define SC_ARRANGE 0xF110 +#define SC_RESTORE 0xF120 +#define SC_TASKLIST 0xF130 +#define SC_SCREENSAVE 0xF140 +#define SC_HOTKEY 0xF150 +#define SC_DEFAULT 0xF160 +#define SC_MONITORPOWER 0xF170 +#define SC_CONTEXTHELP 0xF180 +#define SC_SEPARATOR 0xF00F +#define SC_ICON SC_MINIMIZE +#define SC_ZOOM SC_MAXIMIZE +#endif + +#ifdef UNICODE +#define LoadBitmap LoadBitmapW +#define LoadCursor LoadCursorW +#define LoadCursorFromFile LoadCursorFromFileW +#else +#define LoadBitmap LoadBitmapA +#define LoadCursor LoadCursorA +#define LoadCursorFromFile LoadCursorFromFileA +#endif + + WINUSERAPI HBITMAP WINAPI LoadBitmapA(HINSTANCE hInstance,LPCSTR lpBitmapName); + WINUSERAPI HBITMAP WINAPI LoadBitmapW(HINSTANCE hInstance,LPCWSTR lpBitmapName); + WINUSERAPI HCURSOR WINAPI LoadCursorA(HINSTANCE hInstance,LPCSTR lpCursorName); + WINUSERAPI HCURSOR WINAPI LoadCursorW(HINSTANCE hInstance,LPCWSTR lpCursorName); + WINUSERAPI HCURSOR WINAPI LoadCursorFromFileA(LPCSTR lpFileName); + WINUSERAPI HCURSOR WINAPI LoadCursorFromFileW(LPCWSTR lpFileName); + WINUSERAPI HCURSOR WINAPI CreateCursor(HINSTANCE hInst,int xHotSpot,int yHotSpot,int nWidth,int nHeight,CONST VOID *pvANDPlane,CONST VOID *pvXORPlane); + WINUSERAPI WINBOOL WINAPI DestroyCursor(HCURSOR hCursor); + +#define CopyCursor(pcur) ((HCURSOR)CopyIcon((HICON)(pcur))) + +#define IDC_ARROW MAKEINTRESOURCE(32512) +#define IDC_IBEAM MAKEINTRESOURCE(32513) +#define IDC_WAIT MAKEINTRESOURCE(32514) +#define IDC_CROSS MAKEINTRESOURCE(32515) +#define IDC_UPARROW MAKEINTRESOURCE(32516) +#define IDC_SIZE MAKEINTRESOURCE(32640) +#define IDC_ICON MAKEINTRESOURCE(32641) +#define IDC_SIZENWSE MAKEINTRESOURCE(32642) +#define IDC_SIZENESW MAKEINTRESOURCE(32643) +#define IDC_SIZEWE MAKEINTRESOURCE(32644) +#define IDC_SIZENS MAKEINTRESOURCE(32645) +#define IDC_SIZEALL MAKEINTRESOURCE(32646) +#define IDC_NO MAKEINTRESOURCE(32648) +#define IDC_HAND MAKEINTRESOURCE(32649) +#define IDC_APPSTARTING MAKEINTRESOURCE(32650) +#define IDC_HELP MAKEINTRESOURCE(32651) + + WINUSERAPI WINBOOL WINAPI SetSystemCursor(HCURSOR hcur,DWORD id); + + typedef struct _ICONINFO { + WINBOOL fIcon; + DWORD xHotspot; + DWORD yHotspot; + HBITMAP hbmMask; + HBITMAP hbmColor; + } ICONINFO; + typedef ICONINFO *PICONINFO; + +#ifdef UNICODE +#define LoadIcon LoadIconW +#define PrivateExtractIcons PrivateExtractIconsW +#else +#define LoadIcon LoadIconA +#define PrivateExtractIcons PrivateExtractIconsA +#endif + + WINUSERAPI HICON WINAPI LoadIconA(HINSTANCE hInstance,LPCSTR lpIconName); + WINUSERAPI HICON WINAPI LoadIconW(HINSTANCE hInstance,LPCWSTR lpIconName); + WINUSERAPI UINT WINAPI PrivateExtractIconsA(LPCSTR szFileName,int nIconIndex,int cxIcon,int cyIcon,HICON *phicon,UINT *piconid,UINT nIcons,UINT flags); + WINUSERAPI UINT WINAPI PrivateExtractIconsW(LPCWSTR szFileName,int nIconIndex,int cxIcon,int cyIcon,HICON *phicon,UINT *piconid,UINT nIcons,UINT flags); + WINUSERAPI HICON WINAPI CreateIcon(HINSTANCE hInstance,int nWidth,int nHeight,BYTE cPlanes,BYTE cBitsPixel,CONST BYTE *lpbANDbits,CONST BYTE *lpbXORbits); + WINUSERAPI WINBOOL WINAPI DestroyIcon(HICON hIcon); + WINUSERAPI int WINAPI LookupIconIdFromDirectory(PBYTE presbits,WINBOOL fIcon); + WINUSERAPI int WINAPI LookupIconIdFromDirectoryEx(PBYTE presbits,WINBOOL fIcon,int cxDesired,int cyDesired,UINT Flags); + WINUSERAPI HICON WINAPI CreateIconFromResource(PBYTE presbits,DWORD dwResSize,WINBOOL fIcon,DWORD dwVer); + WINUSERAPI HICON WINAPI CreateIconFromResourceEx(PBYTE presbits,DWORD dwResSize,WINBOOL fIcon,DWORD dwVer,int cxDesired,int cyDesired,UINT Flags); + + typedef struct tagCURSORSHAPE { + int xHotSpot; + int yHotSpot; + int cx; + int cy; + int cbWidth; + BYTE Planes; + BYTE BitsPixel; + } CURSORSHAPE,*LPCURSORSHAPE; + +#define IMAGE_BITMAP 0 +#define IMAGE_ICON 1 +#define IMAGE_CURSOR 2 +#define IMAGE_ENHMETAFILE 3 + +#define LR_DEFAULTCOLOR 0x0000 +#define LR_MONOCHROME 0x0001 +#define LR_COLOR 0x0002 +#define LR_COPYRETURNORG 0x0004 +#define LR_COPYDELETEORG 0x0008 +#define LR_LOADFROMFILE 0x0010 +#define LR_LOADTRANSPARENT 0x0020 +#define LR_DEFAULTSIZE 0x0040 +#define LR_VGACOLOR 0x0080 +#define LR_LOADMAP3DCOLORS 0x1000 +#define LR_CREATEDIBSECTION 0x2000 #define LR_COPYFROMRESOURCE 0x4000 -#define LR_SHARED 32768 -#define KEYEVENTF_EXTENDEDKEY 1 -#define KEYEVENTF_KEYUP 2 -#define OBM_BTNCORNERS 32758 -#define OBM_BTSIZE 32761 -#define OBM_CHECK 32760 -#define OBM_CHECKBOXES 32759 +#define LR_SHARED 0x8000 + +#ifdef UNICODE +#define LoadImage LoadImageW +#else +#define LoadImage LoadImageA +#endif + + WINUSERAPI HANDLE WINAPI LoadImageA(HINSTANCE hInst,LPCSTR name,UINT type,int cx,int cy,UINT fuLoad); + WINUSERAPI HANDLE WINAPI LoadImageW(HINSTANCE hInst,LPCWSTR name,UINT type,int cx,int cy,UINT fuLoad); + WINUSERAPI HANDLE WINAPI CopyImage(HANDLE h,UINT type,int cx,int cy,UINT flags); + +#define DI_MASK 0x0001 +#define DI_IMAGE 0x0002 +#define DI_NORMAL 0x0003 +#define DI_COMPAT 0x0004 +#define DI_DEFAULTSIZE 0x0008 +#define DI_NOMIRROR 0x0010 + + WINUSERAPI WINBOOL WINAPI DrawIconEx(HDC hdc,int xLeft,int yTop,HICON hIcon,int cxWidth,int cyWidth,UINT istepIfAniCur,HBRUSH hbrFlickerFreeDraw,UINT diFlags); + WINUSERAPI HICON WINAPI CreateIconIndirect(PICONINFO piconinfo); + WINUSERAPI HICON WINAPI CopyIcon(HICON hIcon); + WINUSERAPI WINBOOL WINAPI GetIconInfo(HICON hIcon,PICONINFO piconinfo); + +#define RES_ICON 1 +#define RES_CURSOR 2 + +#ifdef OEMRESOURCE + #define OBM_CLOSE 32754 -#define OBM_COMBO 32738 +#define OBM_UPARROW 32753 #define OBM_DNARROW 32752 -#define OBM_DNARROWD 32742 -#define OBM_DNARROWI 32736 +#define OBM_RGARROW 32751 #define OBM_LFARROW 32750 -#define OBM_LFARROWI 32734 +#define OBM_REDUCE 32749 +#define OBM_ZOOM 32748 +#define OBM_RESTORE 32747 +#define OBM_REDUCED 32746 +#define OBM_ZOOMD 32745 +#define OBM_RESTORED 32744 +#define OBM_UPARROWD 32743 +#define OBM_DNARROWD 32742 +#define OBM_RGARROWD 32741 #define OBM_LFARROWD 32740 #define OBM_MNARROW 32739 +#define OBM_COMBO 32738 +#define OBM_UPARROWI 32737 +#define OBM_DNARROWI 32736 +#define OBM_RGARROWI 32735 +#define OBM_LFARROWI 32734 + #define OBM_OLD_CLOSE 32767 +#define OBM_SIZE 32766 +#define OBM_OLD_UPARROW 32765 #define OBM_OLD_DNARROW 32764 +#define OBM_OLD_RGARROW 32763 #define OBM_OLD_LFARROW 32762 +#define OBM_BTSIZE 32761 +#define OBM_CHECK 32760 +#define OBM_CHECKBOXES 32759 +#define OBM_BTNCORNERS 32758 #define OBM_OLD_REDUCE 32757 -#define OBM_OLD_RESTORE 32755 -#define OBM_OLD_RGARROW 32763 -#define OBM_OLD_UPARROW 32765 #define OBM_OLD_ZOOM 32756 -#define OBM_REDUCE 32749 -#define OBM_REDUCED 32746 -#define OBM_RESTORE 32747 -#define OBM_RESTORED 32744 -#define OBM_RGARROW 32751 -#define OBM_RGARROWD 32741 -#define OBM_RGARROWI 32735 -#define OBM_SIZE 32766 -#define OBM_UPARROW 32753 -#define OBM_UPARROWD 32743 -#define OBM_UPARROWI 32737 -#define OBM_ZOOM 32748 -#define OBM_ZOOMD 32745 +#define OBM_OLD_RESTORE 32755 + #define OCR_NORMAL 32512 #define OCR_IBEAM 32513 #define OCR_WAIT 32514 @@ -933,8 +3765,11 @@ extern "C" { #define OCR_SIZEWE 32644 #define OCR_SIZENS 32645 #define OCR_SIZEALL 32646 +#define OCR_ICOCUR 32647 #define OCR_NO 32648 +#define OCR_HAND 32649 #define OCR_APPSTARTING 32650 + #define OIC_SAMPLE 32512 #define OIC_HAND 32513 #define OIC_QUES 32514 @@ -944,2529 +3779,1873 @@ extern "C" { #define OIC_WARNING OIC_BANG #define OIC_ERROR OIC_HAND #define OIC_INFORMATION OIC_NOTE -#define HELPINFO_MENUITEM 2 -#define HELPINFO_WINDOW 1 -#define MSGF_DIALOGBOX 0 -#define MSGF_MESSAGEBOX 1 -#define MSGF_MENU 2 -#define MSGF_MOVE 3 -#define MSGF_SIZE 4 -#define MSGF_SCROLLBAR 5 -#define MSGF_NEXTWINDOW 6 -#define MSGF_MAINLOOP 8 -#define MSGF_USER 4096 -#define MOUSEEVENTF_MOVE 1 -#define MOUSEEVENTF_LEFTDOWN 2 -#define MOUSEEVENTF_LEFTUP 4 -#define MOUSEEVENTF_RIGHTDOWN 8 -#define MOUSEEVENTF_RIGHTUP 16 -#define MOUSEEVENTF_MIDDLEDOWN 32 -#define MOUSEEVENTF_MIDDLEUP 64 -#define MOUSEEVENTF_WHEEL 0x0800 -#define MOUSEEVENTF_ABSOLUTE 32768 -#define PM_NOREMOVE 0 -#define PM_REMOVE 1 -#define PM_NOYIELD 2 -#define HWND_BROADCAST ((HWND)0xffff) -#define HWND_BOTTOM ((HWND)1) -#define HWND_NOTOPMOST ((HWND)(-2)) -#define HWND_TOP ((HWND)0) -#define HWND_TOPMOST ((HWND)(-1)) -#define HWND_DESKTOP (HWND)0 -#define HWND_MESSAGE ((HWND)(-3)) /* w2k */ -#define RDW_ERASE 4 -#define RDW_FRAME 1024 -#define RDW_INTERNALPAINT 2 -#define RDW_INVALIDATE 1 -#define RDW_NOERASE 32 -#define RDW_NOFRAME 2048 -#define RDW_NOINTERNALPAINT 16 -#define RDW_VALIDATE 8 -#define RDW_ERASENOW 512 -#define RDW_UPDATENOW 256 -#define RDW_ALLCHILDREN 128 -#define RDW_NOCHILDREN 64 -#define SMTO_ABORTIFHUNG 2 -#define SMTO_BLOCK 1 -#define SMTO_NORMAL 0 -#define SIF_ALL 23 -#define SIF_PAGE 2 -#define SIF_POS 4 -#define SIF_RANGE 1 -#define SIF_DISABLENOSCROLL 8 -#define SIF_TRACKPOS 16 -#define SWP_DRAWFRAME 32 -#define SWP_FRAMECHANGED 32 -#define SWP_HIDEWINDOW 128 -#define SWP_NOACTIVATE 16 -#define SWP_NOCOPYBITS 256 -#define SWP_NOMOVE 2 -#define SWP_NOSIZE 1 -#define SWP_NOREDRAW 8 -#define SWP_NOZORDER 4 -#define SWP_SHOWWINDOW 64 -#define SWP_NOOWNERZORDER 512 -#define SWP_NOREPOSITION 512 -#define SWP_NOSENDCHANGING 1024 -#define SWP_DEFERERASE 8192 -#define SWP_ASYNCWINDOWPOS 16384 -#define HSHELL_ACTIVATESHELLWINDOW 3 -#define HSHELL_GETMINRECT 5 -#define HSHELL_LANGUAGE 8 -#define HSHELL_REDRAW 6 -#define HSHELL_TASKMAN 7 -#define HSHELL_WINDOWACTIVATED 4 -#define HSHELL_WINDOWCREATED 1 -#define HSHELL_WINDOWDESTROYED 2 -#define SPI_GETACCESSTIMEOUT 60 -#define SPI_GETANIMATION 72 -#define SPI_GETBEEP 1 -#define SPI_GETBORDER 5 -#define SPI_GETDEFAULTINPUTLANG 89 -#define SPI_GETDRAGFULLWINDOWS 38 -#define SPI_GETFASTTASKSWITCH 35 -#define SPI_GETFILTERKEYS 50 -#define SPI_GETFONTSMOOTHING 74 -#define SPI_GETGRIDGRANULARITY 18 -#define SPI_GETHIGHCONTRAST 66 -#define SPI_GETICONMETRICS 45 -#define SPI_GETICONTITLELOGFONT 31 -#define SPI_GETICONTITLEWRAP 25 -#define SPI_GETKEYBOARDDELAY 22 -#define SPI_GETKEYBOARDPREF 68 -#define SPI_GETKEYBOARDSPEED 10 -#define SPI_GETLOWPOWERACTIVE 83 -#define SPI_GETLOWPOWERTIMEOUT 79 -#define SPI_GETMENUDROPALIGNMENT 27 -#define SPI_GETMINIMIZEDMETRICS 43 -#define SPI_GETMOUSE 3 -#define SPI_GETMOUSEKEYS 54 -#define SPI_GETMOUSETRAILS 94 -#define SPI_GETNONCLIENTMETRICS 41 -#define SPI_GETPOWEROFFACTIVE 84 -#define SPI_GETPOWEROFFTIMEOUT 80 -#define SPI_GETSCREENREADER 70 -#define SPI_GETSCREENSAVEACTIVE 16 -#define SPI_GETSCREENSAVETIMEOUT 14 -#define SPI_GETSERIALKEYS 62 -#define SPI_GETSHOWSOUNDS 56 -#define SPI_GETSOUNDSENTRY 64 -#define SPI_GETSTICKYKEYS 58 -#define SPI_GETTOGGLEKEYS 52 -#define SPI_GETWINDOWSEXTENSION 92 -#define SPI_GETWORKAREA 48 -#define SPI_ICONHORIZONTALSPACING 13 -#define SPI_ICONVERTICALSPACING 24 -#define SPI_LANGDRIVER 12 -#define SPI_SCREENSAVERRUNNING 97 -#define SPI_SETACCESSTIMEOUT 61 -#define SPI_SETANIMATION 73 -#define SPI_SETBEEP 2 -#define SPI_SETBORDER 6 -#define SPI_SETDEFAULTINPUTLANG 90 -#define SPI_SETDESKPATTERN 21 -#define SPI_SETDESKWALLPAPER 20 -#define SPI_SETDOUBLECLICKTIME 32 -#define SPI_SETDOUBLECLKHEIGHT 30 -#define SPI_SETDOUBLECLKWIDTH 29 -#define SPI_SETDRAGFULLWINDOWS 37 -#define SPI_SETDRAGHEIGHT 77 -#define SPI_SETDRAGWIDTH 76 -#define SPI_SETFASTTASKSWITCH 36 -#define SPI_SETFILTERKEYS 51 -#define SPI_SETFONTSMOOTHING 75 -#define SPI_SETGRIDGRANULARITY 19 -#define SPI_SETHANDHELD 78 -#define SPI_SETHIGHCONTRAST 67 -#define SPI_SETICONMETRICS 46 -#define SPI_SETICONTITLELOGFONT 34 -#define SPI_SETICONTITLEWRAP 26 -#define SPI_SETKEYBOARDDELAY 23 -#define SPI_SETKEYBOARDPREF 69 -#define SPI_SETKEYBOARDSPEED 11 -#define SPI_SETLANGTOGGLE 91 -#define SPI_SETLOWPOWERACTIVE 85 -#define SPI_SETLOWPOWERTIMEOUT 81 -#define SPI_SETMENUDROPALIGNMENT 28 -#define SPI_SETMINIMIZEDMETRICS 44 -#define SPI_SETMOUSE 4 -#define SPI_SETMOUSEBUTTONSWAP 33 -#define SPI_SETMOUSEKEYS 55 -#define SPI_SETMOUSETRAILS 93 -#define SPI_SETNONCLIENTMETRICS 42 -#define SPI_SETPENWINDOWS 49 -#define SPI_SETPOWEROFFACTIVE 86 -#define SPI_SETPOWEROFFTIMEOUT 82 -#define SPI_SETSCREENREADER 71 -#define SPI_SETSCREENSAVEACTIVE 17 -#define SPI_SETSCREENSAVERRUNNING 97 -#define SPI_SETSCREENSAVETIMEOUT 15 -#define SPI_SETSERIALKEYS 63 -#define SPI_SETSHOWSOUNDS 57 -#define SPI_SETSOUNDSENTRY 65 -#define SPI_SETSTICKYKEYS 59 -#define SPI_SETTOGGLEKEYS 53 -#define SPI_SETWORKAREA 47 -#define SPIF_UPDATEINIFILE 1 -#define SPIF_SENDWININICHANGE 2 -#define SPIF_SENDCHANGE 2 -#define ATF_ONOFFFEEDBACK 2 -#define ATF_TIMEOUTON 1 -#define WM_APP 32768 -#define WM_ACTIVATE 6 -#define WM_ACTIVATEAPP 28 -/* FIXME/CHECK: Are WM_AFX{FIRST,LAST} valid for WINVER < 0x400? */ -#define WM_AFXFIRST 864 -#define WM_AFXLAST 895 -#define WM_ASKCBFORMATNAME 780 -#define WM_CANCELJOURNAL 75 -#define WM_CANCELMODE 31 -#define WM_CAPTURECHANGED 533 -#define WM_CHANGECBCHAIN 781 -#define WM_CHAR 258 -#define WM_CHARTOITEM 47 -#define WM_CHILDACTIVATE 34 -#define WM_CLEAR 771 -#define WM_CLOSE 16 -#define WM_COMMAND 273 -#define WM_COMMNOTIFY 68 /* obsolete */ -#define WM_COMPACTING 65 -#define WM_COMPAREITEM 57 -#define WM_CONTEXTMENU 123 -#define WM_COPY 769 -#define WM_COPYDATA 74 -#define WM_CREATE 1 -#define WM_CTLCOLORBTN 309 -#define WM_CTLCOLORDLG 310 -#define WM_CTLCOLOREDIT 307 -#define WM_CTLCOLORLISTBOX 308 -#define WM_CTLCOLORMSGBOX 306 -#define WM_CTLCOLORSCROLLBAR 311 -#define WM_CTLCOLORSTATIC 312 -#define WM_CUT 768 -#define WM_DEADCHAR 259 -#define WM_DELETEITEM 45 -#define WM_DESTROY 2 -#define WM_DESTROYCLIPBOARD 775 -#define WM_DEVICECHANGE 537 -#define WM_DEVMODECHANGE 27 -#define WM_DISPLAYCHANGE 126 -#define WM_DRAWCLIPBOARD 776 -#define WM_DRAWITEM 43 -#define WM_DROPFILES 563 -#define WM_ENABLE 10 -#define WM_ENDSESSION 22 -#define WM_ENTERIDLE 289 -#define WM_ENTERMENULOOP 529 -#define WM_ENTERSIZEMOVE 561 -#define WM_ERASEBKGND 20 -#define WM_EXITMENULOOP 530 -#define WM_EXITSIZEMOVE 562 -#define WM_FONTCHANGE 29 -#define WM_GETDLGCODE 135 -#define WM_GETFONT 49 -#define WM_GETHOTKEY 51 -#define WM_GETICON 127 -#define WM_GETMINMAXINFO 36 -#define WM_GETTEXT 13 -#define WM_GETTEXTLENGTH 14 -/* FIXME/CHECK: Are WM_HANDHEL{FIRST,LAST} valid for WINVER < 0x400? */ -#define WM_HANDHELDFIRST 856 -#define WM_HANDHELDLAST 863 -#define WM_HELP 83 -#define WM_HOTKEY 786 -#define WM_HSCROLL 276 -#define WM_HSCROLLCLIPBOARD 782 -#define WM_ICONERASEBKGND 39 -#define WM_INITDIALOG 272 -#define WM_INITMENU 278 -#define WM_INITMENUPOPUP 279 -#define WM_INPUTLANGCHANGE 81 -#define WM_INPUTLANGCHANGEREQUEST 80 -#define WM_KEYDOWN 256 -#define WM_KEYUP 257 -#define WM_KILLFOCUS 8 -#define WM_MDIACTIVATE 546 -#define WM_MDICASCADE 551 -#define WM_MDICREATE 544 -#define WM_MDIDESTROY 545 -#define WM_MDIGETACTIVE 553 -#define WM_MDIICONARRANGE 552 -#define WM_MDIMAXIMIZE 549 -#define WM_MDINEXT 548 -#define WM_MDIREFRESHMENU 564 -#define WM_MDIRESTORE 547 -#define WM_MDISETMENU 560 -#define WM_MDITILE 550 -#define WM_MEASUREITEM 44 -#define WM_MENUCHAR 288 -#define WM_MENUSELECT 287 -#define WM_NEXTMENU 531 -#define WM_MOVE 3 -#define WM_MOVING 534 -#define WM_NCACTIVATE 134 -#define WM_NCCALCSIZE 131 -#define WM_NCCREATE 129 -#define WM_NCDESTROY 130 -#define WM_NCHITTEST 132 -#define WM_NCLBUTTONDBLCLK 163 -#define WM_NCLBUTTONDOWN 161 -#define WM_NCLBUTTONUP 162 -#define WM_NCMBUTTONDBLCLK 169 -#define WM_NCMBUTTONDOWN 167 -#define WM_NCMBUTTONUP 168 -#define WM_NCMOUSEMOVE 160 -#define WM_NCPAINT 133 -#define WM_NCRBUTTONDBLCLK 166 -#define WM_NCRBUTTONDOWN 164 -#define WM_NCRBUTTONUP 165 -#define WM_NEXTDLGCTL 40 -#define WM_NEXTMENU 531 -#define WM_NOTIFY 78 -#define WM_NOTIFYFORMAT 85 -#define WM_NULL 0 -#define WM_PAINT 15 -#define WM_PAINTCLIPBOARD 777 -#define WM_PAINTICON 38 -#define WM_PALETTECHANGED 785 -#define WM_PALETTEISCHANGING 784 -#define WM_PARENTNOTIFY 528 -#define WM_PASTE 770 -#define WM_PENWINFIRST 896 -#define WM_PENWINLAST 911 -#define WM_POWER 72 -#define WM_POWERBROADCAST 536 -#define WM_PRINT 791 -#define WM_PRINTCLIENT 792 -#define WM_QUERYDRAGICON 55 -#define WM_QUERYENDSESSION 17 -#define WM_QUERYNEWPALETTE 783 -#define WM_QUERYOPEN 19 -#define WM_QUEUESYNC 35 -#define WM_QUIT 18 -#define WM_RENDERALLFORMATS 774 -#define WM_RENDERFORMAT 773 -#define WM_SETCURSOR 32 -#define WM_SETFOCUS 7 -#define WM_SETFONT 48 -#define WM_SETHOTKEY 50 -#define WM_SETICON 128 -#define WM_SETREDRAW 11 -#define WM_SETTEXT 12 -#define WM_SETTINGCHANGE 26 -#define WM_SHOWWINDOW 24 -#define WM_SIZE 5 -#define WM_SIZECLIPBOARD 779 -#define WM_SIZING 532 -#define WM_SPOOLERSTATUS 42 -#define WM_STYLECHANGED 125 -#define WM_STYLECHANGING 124 -#define WM_SYSCHAR 262 -#define WM_SYSCOLORCHANGE 21 -#define WM_SYSCOMMAND 274 -#define WM_SYSDEADCHAR 263 -#define WM_SYSKEYDOWN 260 -#define WM_SYSKEYUP 261 -#define WM_TCARD 82 -#define WM_TIMECHANGE 30 -#define WM_TIMER 275 -#define WM_UNDO 772 -#define WM_USER 1024 -#define WM_USERCHANGED 84 -#define WM_VKEYTOITEM 46 -#define WM_VSCROLL 277 -#define WM_VSCROLLCLIPBOARD 778 -#define WM_WINDOWPOSCHANGED 71 -#define WM_WINDOWPOSCHANGING 70 -#define WM_WININICHANGE 26 -#define WM_KEYFIRST 256 -#define WM_KEYLAST 264 -#define WM_SYNCPAINT 136 -#define WM_MOUSEACTIVATE 33 -#define WM_MOUSEMOVE 512 -#define WM_LBUTTONDOWN 513 -#define WM_LBUTTONUP 514 -#define WM_LBUTTONDBLCLK 515 -#define WM_RBUTTONDOWN 516 -#define WM_RBUTTONUP 517 -#define WM_RBUTTONDBLCLK 518 -#define WM_MBUTTONDOWN 519 -#define WM_MBUTTONUP 520 -#define WM_MBUTTONDBLCLK 521 -#define WM_MOUSEWHEEL 522 -#define WM_MOUSEFIRST 512 -#define WM_MOUSELAST 522 -#define WM_MOUSEHOVER 0x2A1 -#define WM_MOUSELEAVE 0x2A3 -#if(_WIN32_WINNT >= 0x0400) -#define WHEEL_DELTA 120 -#define GET_WHEEL_DELTA_WPARAM(wparam) ((short)HIWORD (wparam)) -#endif -#define BM_CLICK 245 -#define BM_GETCHECK 240 -#define BM_GETIMAGE 246 -#define BM_GETSTATE 242 -#define BM_SETCHECK 241 -#define BM_SETIMAGE 247 -#define BM_SETSTATE 243 -#define BM_SETSTYLE 244 +#endif + +#define ORD_LANGDRIVER 1 + +#ifndef NOICONS + +#ifdef RC_INVOKED +#define IDI_APPLICATION 32512 +#define IDI_HAND 32513 +#define IDI_QUESTION 32514 +#define IDI_EXCLAMATION 32515 +#define IDI_ASTERISK 32516 +#define IDI_WINLOGO 32517 +#else +#define IDI_APPLICATION MAKEINTRESOURCE(32512) +#define IDI_HAND MAKEINTRESOURCE(32513) +#define IDI_QUESTION MAKEINTRESOURCE(32514) +#define IDI_EXCLAMATION MAKEINTRESOURCE(32515) +#define IDI_ASTERISK MAKEINTRESOURCE(32516) +#define IDI_WINLOGO MAKEINTRESOURCE(32517) +#endif + +#define IDI_WARNING IDI_EXCLAMATION +#define IDI_ERROR IDI_HAND +#define IDI_INFORMATION IDI_ASTERISK +#endif + +#ifdef UNICODE +#define LoadString LoadStringW +#else +#define LoadString LoadStringA +#endif + + WINUSERAPI int WINAPI LoadStringA(HINSTANCE hInstance,UINT uID,LPSTR lpBuffer,int cchBufferMax); + WINUSERAPI int WINAPI LoadStringW(HINSTANCE hInstance,UINT uID,LPWSTR lpBuffer,int cchBufferMax); + +#define IDOK 1 +#define IDCANCEL 2 +#define IDABORT 3 +#define IDRETRY 4 +#define IDIGNORE 5 +#define IDYES 6 +#define IDNO 7 +#define IDCLOSE 8 +#define IDHELP 9 +#define IDTRYAGAIN 10 +#define IDCONTINUE 11 + +#ifndef IDTIMEOUT +#define IDTIMEOUT 32000 +#endif + +#ifndef NOCTLMGR + +#ifndef NOWINSTYLES +#define ES_LEFT 0x0000L +#define ES_CENTER 0x0001L +#define ES_RIGHT 0x0002L +#define ES_MULTILINE 0x0004L +#define ES_UPPERCASE 0x0008L +#define ES_LOWERCASE 0x0010L +#define ES_PASSWORD 0x0020L +#define ES_AUTOVSCROLL 0x0040L +#define ES_AUTOHSCROLL 0x0080L +#define ES_NOHIDESEL 0x0100L +#define ES_OEMCONVERT 0x0400L +#define ES_READONLY 0x0800L +#define ES_WANTRETURN 0x1000L +#define ES_NUMBER 0x2000L +#endif + +#define EN_SETFOCUS 0x0100 +#define EN_KILLFOCUS 0x0200 +#define EN_CHANGE 0x0300 +#define EN_UPDATE 0x0400 +#define EN_ERRSPACE 0x0500 +#define EN_MAXTEXT 0x0501 +#define EN_HSCROLL 0x0601 +#define EN_VSCROLL 0x0602 +#define EN_ALIGN_LTR_EC 0x0700 +#define EN_ALIGN_RTL_EC 0x0701 + +#define EC_LEFTMARGIN 0x0001 +#define EC_RIGHTMARGIN 0x0002 +#define EC_USEFONTINFO 0xffff + +#define EMSIS_COMPOSITIONSTRING 0x0001 + +#define EIMES_GETCOMPSTRATONCE 0x0001 +#define EIMES_CANCELCOMPSTRINFOCUS 0x0002 +#define EIMES_COMPLETECOMPSTRKILLFOCUS 0x0004 + +#ifndef NOWINMESSAGES + +#define EM_GETSEL 0x00B0 +#define EM_SETSEL 0x00B1 +#define EM_GETRECT 0x00B2 +#define EM_SETRECT 0x00B3 +#define EM_SETRECTNP 0x00B4 +#define EM_SCROLL 0x00B5 +#define EM_LINESCROLL 0x00B6 +#define EM_SCROLLCARET 0x00B7 +#define EM_GETMODIFY 0x00B8 +#define EM_SETMODIFY 0x00B9 +#define EM_GETLINECOUNT 0x00BA +#define EM_LINEINDEX 0x00BB +#define EM_SETHANDLE 0x00BC +#define EM_GETHANDLE 0x00BD +#define EM_GETTHUMB 0x00BE +#define EM_LINELENGTH 0x00C1 +#define EM_REPLACESEL 0x00C2 +#define EM_GETLINE 0x00C4 +#define EM_LIMITTEXT 0x00C5 +#define EM_CANUNDO 0x00C6 +#define EM_UNDO 0x00C7 +#define EM_FMTLINES 0x00C8 +#define EM_LINEFROMCHAR 0x00C9 +#define EM_SETTABSTOPS 0x00CB +#define EM_SETPASSWORDCHAR 0x00CC +#define EM_EMPTYUNDOBUFFER 0x00CD +#define EM_GETFIRSTVISIBLELINE 0x00CE +#define EM_SETREADONLY 0x00CF +#define EM_SETWORDBREAKPROC 0x00D0 +#define EM_GETWORDBREAKPROC 0x00D1 +#define EM_GETPASSWORDCHAR 0x00D2 +#define EM_SETMARGINS 0x00D3 +#define EM_GETMARGINS 0x00D4 +#define EM_SETLIMITTEXT EM_LIMITTEXT +#define EM_GETLIMITTEXT 0x00D5 +#define EM_POSFROMCHAR 0x00D6 +#define EM_CHARFROMPOS 0x00D7 +#define EM_SETIMESTATUS 0x00D8 +#define EM_GETIMESTATUS 0x00D9 +#endif + +#define WB_LEFT 0 +#define WB_RIGHT 1 +#define WB_ISDELIMITER 2 + +#define BS_PUSHBUTTON 0x00000000L +#define BS_DEFPUSHBUTTON 0x00000001L +#define BS_CHECKBOX 0x00000002L +#define BS_AUTOCHECKBOX 0x00000003L +#define BS_RADIOBUTTON 0x00000004L +#define BS_3STATE 0x00000005L +#define BS_AUTO3STATE 0x00000006L +#define BS_GROUPBOX 0x00000007L +#define BS_USERBUTTON 0x00000008L +#define BS_AUTORADIOBUTTON 0x00000009L +#define BS_PUSHBOX 0x0000000AL +#define BS_OWNERDRAW 0x0000000BL +#define BS_TYPEMASK 0x0000000FL +#define BS_LEFTTEXT 0x00000020L +#define BS_TEXT 0x00000000L +#define BS_ICON 0x00000040L +#define BS_BITMAP 0x00000080L +#define BS_LEFT 0x00000100L +#define BS_RIGHT 0x00000200L +#define BS_CENTER 0x00000300L +#define BS_TOP 0x00000400L +#define BS_BOTTOM 0x00000800L +#define BS_VCENTER 0x00000C00L +#define BS_PUSHLIKE 0x00001000L +#define BS_MULTILINE 0x00002000L +#define BS_NOTIFY 0x00004000L +#define BS_FLAT 0x00008000L +#define BS_RIGHTBUTTON BS_LEFTTEXT + #define BN_CLICKED 0 -#define BN_DBLCLK 5 +#define BN_PAINT 1 +#define BN_HILITE 2 +#define BN_UNHILITE 3 #define BN_DISABLE 4 #define BN_DOUBLECLICKED 5 -#define BN_HILITE 2 -#define BN_KILLFOCUS 7 -#define BN_PAINT 1 -#define BN_PUSHED 2 +#define BN_PUSHED BN_HILITE +#define BN_UNPUSHED BN_UNHILITE +#define BN_DBLCLK BN_DOUBLECLICKED #define BN_SETFOCUS 6 -#define BN_UNHILITE 3 -#define BN_UNPUSHED 3 -#define CB_ADDSTRING 323 -#define CB_DELETESTRING 324 -#define CB_DIR 325 -#define CB_FINDSTRING 332 -#define CB_FINDSTRINGEXACT 344 -#define CB_GETCOUNT 326 -#define CB_GETCURSEL 327 -#define CB_GETDROPPEDCONTROLRECT 338 -#define CB_GETDROPPEDSTATE 343 -#define CB_GETDROPPEDWIDTH 351 -#define CB_GETEDITSEL 320 -#define CB_GETEXTENDEDUI 342 -#define CB_GETHORIZONTALEXTENT 349 -#define CB_GETITEMDATA 336 -#define CB_GETITEMHEIGHT 340 -#define CB_GETLBTEXT 328 -#define CB_GETLBTEXTLEN 329 -#define CB_GETLOCALE 346 -#define CB_GETTOPINDEX 347 -#define CB_INITSTORAGE 353 -#define CB_INSERTSTRING 330 -#define CB_LIMITTEXT 321 -#define CB_RESETCONTENT 331 -#define CB_SELECTSTRING 333 -#define CB_SETCURSEL 334 -#define CB_SETDROPPEDWIDTH 352 -#define CB_SETEDITSEL 322 -#define CB_SETEXTENDEDUI 341 -#define CB_SETHORIZONTALEXTENT 350 -#define CB_SETITEMDATA 337 -#define CB_SETITEMHEIGHT 339 -#define CB_SETLOCALE 345 -#define CB_SETTOPINDEX 348 -#define CB_SHOWDROPDOWN 335 -#define CBN_CLOSEUP 8 -#define CBN_DBLCLK 2 -#define CBN_DROPDOWN 7 -#define CBN_EDITCHANGE 5 -#define CBN_EDITUPDATE 6 -#define CBN_ERRSPACE (-1) -#define CBN_KILLFOCUS 4 -#define CBN_SELCHANGE 1 -#define CBN_SELENDCANCEL 10 -#define CBN_SELENDOK 9 -#define CBN_SETFOCUS 3 -#define EM_CANUNDO 198 -#define EM_CHARFROMPOS 215 -#define EM_EMPTYUNDOBUFFER 205 -#define EM_FMTLINES 200 -#define EM_GETFIRSTVISIBLELINE 206 -#define EM_GETHANDLE 189 -#define EM_GETLIMITTEXT 213 -#define EM_GETLINE 196 -#define EM_GETLINECOUNT 186 -#define EM_GETMARGINS 212 -#define EM_GETMODIFY 184 -#define EM_GETPASSWORDCHAR 210 -#define EM_GETRECT 178 -#define EM_GETSEL 176 -#define EM_GETTHUMB 190 -#define EM_GETWORDBREAKPROC 209 -#define EM_LIMITTEXT 197 -#define EM_LINEFROMCHAR 201 -#define EM_LINEINDEX 187 -#define EM_LINELENGTH 193 -#define EM_LINESCROLL 182 -#define EM_POSFROMCHAR 214 -#define EM_REPLACESEL 194 -#define EM_SCROLL 181 -#define EM_SCROLLCARET 183 -#define EM_SETHANDLE 188 -#define EM_SETLIMITTEXT 197 -#define EM_SETMARGINS 211 -#define EM_SETMODIFY 185 -#define EM_SETPASSWORDCHAR 204 -#define EM_SETREADONLY 207 -#define EM_SETRECT 179 -#define EM_SETRECTNP 180 -#define EM_SETSEL 177 -#define EM_SETTABSTOPS 203 -#define EM_SETWORDBREAKPROC 208 -#define EM_UNDO 199 -#define EN_CHANGE 768 -#define EN_ERRSPACE 1280 -#define EN_HSCROLL 1537 -#define EN_KILLFOCUS 512 -#define EN_MAXTEXT 1281 -#define EN_SETFOCUS 256 -#define EN_UPDATE 1024 -#define EN_VSCROLL 1538 -#define LB_ADDFILE 406 -#define LB_ADDSTRING 384 -#define LB_DELETESTRING 386 -#define LB_DIR 397 -#define LB_FINDSTRING 399 -#define LB_FINDSTRINGEXACT 418 -#define LB_GETANCHORINDEX 413 -#define LB_GETCARETINDEX 415 -#define LB_GETCOUNT 395 -#define LB_GETCURSEL 392 -#define LB_GETHORIZONTALEXTENT 403 -#define LB_GETITEMDATA 409 -#define LB_GETITEMHEIGHT 417 -#define LB_GETITEMRECT 408 -#define LB_GETLOCALE 422 -#define LB_GETSEL 391 -#define LB_GETSELCOUNT 400 -#define LB_GETSELITEMS 401 -#define LB_GETTEXT 393 -#define LB_GETTEXTLEN 394 -#define LB_GETTOPINDEX 398 -#define LB_INITSTORAGE 424 -#define LB_INSERTSTRING 385 -#define LB_ITEMFROMPOINT 425 -#define LB_RESETCONTENT 388 -#define LB_SELECTSTRING 396 -#define LB_SELITEMRANGE 411 -#define LB_SELITEMRANGEEX 387 -#define LB_SETANCHORINDEX 412 -#define LB_SETCARETINDEX 414 -#define LB_SETCOLUMNWIDTH 405 -#define LB_SETCOUNT 423 -#define LB_SETCURSEL 390 -#define LB_SETHORIZONTALEXTENT 404 -#define LB_SETITEMDATA 410 -#define LB_SETITEMHEIGHT 416 -#define LB_SETLOCALE 421 -#define LB_SETSEL 389 -#define LB_SETTABSTOPS 402 -#define LB_SETTOPINDEX 407 -#define LBN_DBLCLK 2 -#define LBN_ERRSPACE (-2) -#define LBN_KILLFOCUS 5 -#define LBN_SELCANCEL 3 -#define LBN_SELCHANGE 1 -#define LBN_SETFOCUS 4 -#define SBM_ENABLE_ARROWS 228 -#define SBM_GETPOS 225 -#define SBM_GETRANGE 227 -#define SBM_GETSCROLLINFO 234 -#define SBM_SETPOS 224 -#define SBM_SETRANGE 226 -#define SBM_SETRANGEREDRAW 230 -#define SBM_SETSCROLLINFO 233 -#define STM_GETICON 369 -#define STM_GETIMAGE 371 -#define STM_SETICON 368 -#define STM_SETIMAGE 370 +#define BN_KILLFOCUS 7 + +#define BM_GETCHECK 0x00F0 +#define BM_SETCHECK 0x00F1 +#define BM_GETSTATE 0x00F2 +#define BM_SETSTATE 0x00F3 +#define BM_SETSTYLE 0x00F4 +#define BM_CLICK 0x00F5 +#define BM_GETIMAGE 0x00F6 +#define BM_SETIMAGE 0x00F7 + +#define BST_UNCHECKED 0x0000 +#define BST_CHECKED 0x0001 +#define BST_INDETERMINATE 0x0002 +#define BST_PUSHED 0x0004 +#define BST_FOCUS 0x0008 + +#define SS_LEFT 0x00000000L +#define SS_CENTER 0x00000001L +#define SS_RIGHT 0x00000002L +#define SS_ICON 0x00000003L +#define SS_BLACKRECT 0x00000004L +#define SS_GRAYRECT 0x00000005L +#define SS_WHITERECT 0x00000006L +#define SS_BLACKFRAME 0x00000007L +#define SS_GRAYFRAME 0x00000008L +#define SS_WHITEFRAME 0x00000009L +#define SS_USERITEM 0x0000000AL +#define SS_SIMPLE 0x0000000BL +#define SS_LEFTNOWORDWRAP 0x0000000CL +#define SS_OWNERDRAW 0x0000000DL +#define SS_BITMAP 0x0000000EL +#define SS_ENHMETAFILE 0x0000000FL +#define SS_ETCHEDHORZ 0x00000010L +#define SS_ETCHEDVERT 0x00000011L +#define SS_ETCHEDFRAME 0x00000012L +#define SS_TYPEMASK 0x0000001FL +#define SS_REALSIZECONTROL 0x00000040L +#define SS_NOPREFIX 0x00000080L +#define SS_NOTIFY 0x00000100L +#define SS_CENTERIMAGE 0x00000200L +#define SS_RIGHTJUST 0x00000400L +#define SS_REALSIZEIMAGE 0x00000800L +#define SS_SUNKEN 0x00001000L +#define SS_EDITCONTROL 0x00002000L +#define SS_ENDELLIPSIS 0x00004000L +#define SS_PATHELLIPSIS 0x00008000L +#define SS_WORDELLIPSIS 0x0000C000L +#define SS_ELLIPSISMASK 0x0000C000L + +#ifndef NOWINMESSAGES + +#define STM_SETICON 0x0170 +#define STM_GETICON 0x0171 +#define STM_SETIMAGE 0x0172 +#define STM_GETIMAGE 0x0173 #define STN_CLICKED 0 #define STN_DBLCLK 1 -#define STN_DISABLE 3 #define STN_ENABLE 2 -#define DM_GETDEFID WM_USER +#define STN_DISABLE 3 +#define STM_MSGMAX 0x0174 +#endif + +#define WC_DIALOG (MAKEINTATOM(0x8002)) + +#define DWL_MSGRESULT 0 +#define DWL_DLGPROC 4 +#define DWL_USER 8 + +#ifdef _WIN64 + +#undef DWL_MSGRESULT +#undef DWL_DLGPROC +#undef DWL_USER +#endif + +#define DWLP_MSGRESULT 0 +#define DWLP_DLGPROC DWLP_MSGRESULT + sizeof(LRESULT) +#define DWLP_USER DWLP_DLGPROC + sizeof(DLGPROC) + +#ifndef NOMSG + +#ifdef UNICODE +#define IsDialogMessage IsDialogMessageW +#else +#define IsDialogMessage IsDialogMessageA +#endif + + WINUSERAPI WINBOOL WINAPI IsDialogMessageA(HWND hDlg,LPMSG lpMsg); + WINUSERAPI WINBOOL WINAPI IsDialogMessageW(HWND hDlg,LPMSG lpMsg); +#endif + +#ifdef UNICODE +#define DlgDirList DlgDirListW +#define DlgDirSelectEx DlgDirSelectExW +#define DlgDirListComboBox DlgDirListComboBoxW +#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExW +#else +#define DlgDirList DlgDirListA +#define DlgDirSelectEx DlgDirSelectExA +#define DlgDirListComboBox DlgDirListComboBoxA +#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExA +#endif + + WINUSERAPI WINBOOL WINAPI MapDialogRect(HWND hDlg,LPRECT lpRect); + WINUSERAPI int WINAPI DlgDirListA(HWND hDlg,LPSTR lpPathSpec,int nIDListBox,int nIDStaticPath,UINT uFileType); + WINUSERAPI int WINAPI DlgDirListW(HWND hDlg,LPWSTR lpPathSpec,int nIDListBox,int nIDStaticPath,UINT uFileType); + +#define DDL_READWRITE 0x0000 +#define DDL_READONLY 0x0001 +#define DDL_HIDDEN 0x0002 +#define DDL_SYSTEM 0x0004 +#define DDL_DIRECTORY 0x0010 +#define DDL_ARCHIVE 0x0020 + +#define DDL_POSTMSGS 0x2000 +#define DDL_DRIVES 0x4000 +#define DDL_EXCLUSIVE 0x8000 + + WINUSERAPI WINBOOL WINAPI DlgDirSelectExA(HWND hwndDlg,LPSTR lpString,int chCount,int idListBox); + WINUSERAPI WINBOOL WINAPI DlgDirSelectExW(HWND hwndDlg,LPWSTR lpString,int chCount,int idListBox); + WINUSERAPI int WINAPI DlgDirListComboBoxA(HWND hDlg,LPSTR lpPathSpec,int nIDComboBox,int nIDStaticPath,UINT uFiletype); + WINUSERAPI int WINAPI DlgDirListComboBoxW(HWND hDlg,LPWSTR lpPathSpec,int nIDComboBox,int nIDStaticPath,UINT uFiletype); + WINUSERAPI WINBOOL WINAPI DlgDirSelectComboBoxExA(HWND hwndDlg,LPSTR lpString,int cchOut,int idComboBox); + WINUSERAPI WINBOOL WINAPI DlgDirSelectComboBoxExW(HWND hwndDlg,LPWSTR lpString,int cchOut,int idComboBox); + +#define DS_ABSALIGN 0x01L +#define DS_SYSMODAL 0x02L +#define DS_LOCALEDIT 0x20L +#define DS_SETFONT 0x40L +#define DS_MODALFRAME 0x80L +#define DS_NOIDLEMSG 0x100L +#define DS_SETFOREGROUND 0x200L + +#define DS_3DLOOK 0x0004L +#define DS_FIXEDSYS 0x0008L +#define DS_NOFAILCREATE 0x0010L +#define DS_CONTROL 0x0400L +#define DS_CENTER 0x0800L +#define DS_CENTERMOUSE 0x1000L +#define DS_CONTEXTHELP 0x2000L + +#define DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS) + +#if(_WIN32_WCE >= 0x0500) +#define DS_USEPIXELS 0x8000L +#endif + +#define DM_GETDEFID (WM_USER+0) #define DM_SETDEFID (WM_USER+1) #define DM_REPOSITION (WM_USER+2) -#define PSM_PAGEINFO (WM_USER+100) -#define PSM_SHEETINFO (WM_USER+101) -#define PSI_SETACTIVE 1 -#define PSI_KILLACTIVE 2 -#define PSI_APPLY 3 -#define PSI_RESET 4 -#define PSI_HASHELP 5 -#define PSI_HELP 6 -#define PSI_CHANGED 1 -#define PSI_GUISTART 2 -#define PSI_REBOOT 3 -#define PSI_GETSIBLINGS 4 -#define DCX_WINDOW 1 -#define DCX_CACHE 2 -#define DCX_PARENTCLIP 32 -#define DCX_CLIPSIBLINGS 16 -#define DCX_CLIPCHILDREN 8 -#define DCX_NORESETATTRS 4 -#define DCX_LOCKWINDOWUPDATE 0x400 -#define DCX_EXCLUDERGN 64 -#define DCX_INTERSECTRGN 128 -#define DCX_VALIDATE 0x200000 -#define GMDI_GOINTOPOPUPS 2 -#define GMDI_USEDISABLED 1 -#define FKF_AVAILABLE 2 -#define FKF_CLICKON 64 -#define FKF_FILTERKEYSON 1 -#define FKF_HOTKEYACTIVE 4 -#define FKF_HOTKEYSOUND 16 -#define FKF_CONFIRMHOTKEY 8 -#define FKF_INDICATOR 32 -#define HCF_HIGHCONTRASTON 1 -#define HCF_AVAILABLE 2 -#define HCF_HOTKEYACTIVE 4 -#define HCF_CONFIRMHOTKEY 8 -#define HCF_HOTKEYSOUND 16 -#define HCF_INDICATOR 32 -#define HCF_HOTKEYAVAILABLE 64 -#define MKF_AVAILABLE 2 -#define MKF_CONFIRMHOTKEY 8 -#define MKF_HOTKEYACTIVE 4 -#define MKF_HOTKEYSOUND 16 -#define MKF_INDICATOR 32 -#define MKF_MOUSEKEYSON 1 -#define MKF_MODIFIERS 64 -#define MKF_REPLACENUMBERS 128 -#define SERKF_ACTIVE 8 /* May be obsolete. Not in recent MS docs. */ -#define SERKF_AVAILABLE 2 -#define SERKF_INDICATOR 4 -#define SERKF_SERIALKEYSON 1 -#define SSF_AVAILABLE 2 -#define SSF_SOUNDSENTRYON 1 -#define SSTF_BORDER 2 -#define SSTF_CHARS 1 -#define SSTF_DISPLAY 3 -#define SSTF_NONE 0 -#define SSGF_DISPLAY 3 -#define SSGF_NONE 0 -#define SSWF_CUSTOM 4 -#define SSWF_DISPLAY 3 -#define SSWF_NONE 0 -#define SSWF_TITLE 1 -#define SSWF_WINDOW 2 -#define SKF_AUDIBLEFEEDBACK 64 -#define SKF_AVAILABLE 2 -#define SKF_CONFIRMHOTKEY 8 -#define SKF_HOTKEYACTIVE 4 -#define SKF_HOTKEYSOUND 16 -#define SKF_INDICATOR 32 -#define SKF_STICKYKEYSON 1 -#define SKF_TRISTATE 128 -#define SKF_TWOKEYSOFF 256 -#define TKF_AVAILABLE 2 -#define TKF_CONFIRMHOTKEY 8 -#define TKF_HOTKEYACTIVE 4 -#define TKF_HOTKEYSOUND 16 -#define TKF_TOGGLEKEYSON 1 -#define MDITILE_SKIPDISABLED 2 -#define MDITILE_HORIZONTAL 1 -#define MDITILE_VERTICAL 0 -#define VK_LBUTTON 1 -#define VK_RBUTTON 2 -#define VK_CANCEL 3 -#define VK_MBUTTON 4 -#define VK_BACK 8 -#define VK_TAB 9 -#define VK_CLEAR 12 -#define VK_RETURN 13 -#define VK_KANA 15 -#define VK_SHIFT 16 -#define VK_CONTROL 17 -#define VK_MENU 18 -#define VK_PAUSE 19 -#define VK_CAPITAL 20 -#define VK_ESCAPE 0x1B -#define VK_SPACE 32 -#define VK_PRIOR 33 -#define VK_NEXT 34 -#define VK_END 35 -#define VK_HOME 36 -#define VK_LEFT 37 -#define VK_UP 38 -#define VK_RIGHT 39 -#define VK_DOWN 40 -#define VK_SELECT 41 -#define VK_PRINT 42 -#define VK_EXECUTE 43 -#define VK_SNAPSHOT 44 -#define VK_INSERT 45 -#define VK_DELETE 46 -#define VK_HELP 47 -#define VK_LWIN 0x5B -#define VK_RWIN 0x5C -#define VK_APPS 0x5D -#define VK_NUMPAD0 0x60 -#define VK_NUMPAD1 0x61 -#define VK_NUMPAD2 0x62 -#define VK_NUMPAD3 0x63 -#define VK_NUMPAD4 0x64 -#define VK_NUMPAD5 0x65 -#define VK_NUMPAD6 0x66 -#define VK_NUMPAD7 0x67 -#define VK_NUMPAD8 0x68 -#define VK_NUMPAD9 0x69 -#define VK_MULTIPLY 0x6A -#define VK_ADD 0x6B -#define VK_SEPARATOR 0x6C -#define VK_SUBTRACT 0x6D -#define VK_DECIMAL 0x6E -#define VK_DIVIDE 0x6F -#define VK_F1 0x70 -#define VK_F2 0x71 -#define VK_F3 0x72 -#define VK_F4 0x73 -#define VK_F5 0x74 -#define VK_F6 0x75 -#define VK_F7 0x76 -#define VK_F8 0x77 -#define VK_F9 0x78 -#define VK_F10 0x79 -#define VK_F11 0x7A -#define VK_F12 0x7B -#define VK_F13 0x7C -#define VK_F14 0x7D -#define VK_F15 0x7E -#define VK_F16 0x7F -#define VK_F17 0x80 -#define VK_F18 0x81 -#define VK_F19 0x82 -#define VK_F20 0x83 -#define VK_F21 0x84 -#define VK_F22 0x85 -#define VK_F23 0x86 -#define VK_F24 0x87 -#define VK_NUMLOCK 0x90 -#define VK_SCROLL 0x91 -#define VK_LSHIFT 0xA0 -#define VK_RSHIFT 0xA1 -#define VK_LCONTROL 0xA2 -#define VK_RCONTROL 0xA3 -#define VK_LMENU 0xA4 -#define VK_RMENU 0xA5 -#define VK_PROCESSKEY 0xE5 -#define VK_ATTN 0xF6 -#define VK_CRSEL 0xF7 -#define VK_EXSEL 0xF8 -#define VK_EREOF 0xF9 -#define VK_PLAY 0xFA -#define VK_ZOOM 0xFB -#define VK_NONAME 0xFC -#define VK_PA1 0xFD -#define VK_OEM_CLEAR 0xFE -#define TME_HOVER 1 -#define TME_LEAVE 2 -#define TME_QUERY 0x40000000 -#define TME_CANCEL 0x80000000 -#define HOVER_DEFAULT 0xFFFFFFFF -#define MK_LBUTTON 1 -#define MK_RBUTTON 2 -#define MK_SHIFT 4 -#define MK_CONTROL 8 -#define MK_MBUTTON 16 -#define TPM_CENTERALIGN 4 -#define TPM_LEFTALIGN 0 -#define TPM_RIGHTALIGN 8 -#define TPM_LEFTBUTTON 0 -#define TPM_RIGHTBUTTON 2 -#define TPM_HORIZONTAL 0 -#define TPM_VERTICAL 64 -#define TPM_TOPALIGN 0 -#define TPM_VCENTERALIGN 16 -#define TPM_BOTTOMALIGN 32 -#define TPM_NONOTIFY 128 -#define TPM_RETURNCMD 256 -#define HELP_COMMAND 0x102 -#define HELP_CONTENTS 3 -#define HELP_CONTEXT 1 -#define HELP_CONTEXTPOPUP 8 -#define HELP_FORCEFILE 9 -#define HELP_HELPONHELP 4 -#define HELP_INDEX 3 -#define HELP_KEY 0x101 -#define HELP_MULTIKEY 0x201 -#define HELP_PARTIALKEY 0x105 -#define HELP_QUIT 2 -#define HELP_SETCONTENTS 5 -#define HELP_SETINDEX 5 -#define HELP_CONTEXTMENU 0xa -#define HELP_FINDER 0xb -#define HELP_WM_HELP 0xc -#define HELP_TCARD 0x8000 -#define HELP_TCARD_DATA 16 -#define HELP_TCARD_OTHER_CALLER 0x11 -#define IDH_NO_HELP 28440 -#define IDH_MISSING_CONTEXT 28441 -#define IDH_GENERIC_HELP_BUTTON 28442 -#define IDH_OK 28443 -#define IDH_CANCEL 28444 -#define IDH_HELP 28445 -#define LB_CTLCODE 0 + +#define DC_HASDEFID 0x534B + +#define DLGC_WANTARROWS 0x0001 +#define DLGC_WANTTAB 0x0002 +#define DLGC_WANTALLKEYS 0x0004 +#define DLGC_WANTMESSAGE 0x0004 +#define DLGC_HASSETSEL 0x0008 +#define DLGC_DEFPUSHBUTTON 0x0010 +#define DLGC_UNDEFPUSHBUTTON 0x0020 +#define DLGC_RADIOBUTTON 0x0040 +#define DLGC_WANTCHARS 0x0080 +#define DLGC_STATIC 0x0100 +#define DLGC_BUTTON 0x2000 + +#define LB_CTLCODE 0L + #define LB_OKAY 0 #define LB_ERR (-1) #define LB_ERRSPACE (-2) + +#define LBN_ERRSPACE (-2) +#define LBN_SELCHANGE 1 +#define LBN_DBLCLK 2 +#define LBN_SELCANCEL 3 +#define LBN_SETFOCUS 4 +#define LBN_KILLFOCUS 5 + +#ifndef NOWINMESSAGES + +#define LB_ADDSTRING 0x0180 +#define LB_INSERTSTRING 0x0181 +#define LB_DELETESTRING 0x0182 +#define LB_SELITEMRANGEEX 0x0183 +#define LB_RESETCONTENT 0x0184 +#define LB_SETSEL 0x0185 +#define LB_SETCURSEL 0x0186 +#define LB_GETSEL 0x0187 +#define LB_GETCURSEL 0x0188 +#define LB_GETTEXT 0x0189 +#define LB_GETTEXTLEN 0x018A +#define LB_GETCOUNT 0x018B +#define LB_SELECTSTRING 0x018C +#define LB_DIR 0x018D +#define LB_GETTOPINDEX 0x018E +#define LB_FINDSTRING 0x018F +#define LB_GETSELCOUNT 0x0190 +#define LB_GETSELITEMS 0x0191 +#define LB_SETTABSTOPS 0x0192 +#define LB_GETHORIZONTALEXTENT 0x0193 +#define LB_SETHORIZONTALEXTENT 0x0194 +#define LB_SETCOLUMNWIDTH 0x0195 +#define LB_ADDFILE 0x0196 +#define LB_SETTOPINDEX 0x0197 +#define LB_GETITEMRECT 0x0198 +#define LB_GETITEMDATA 0x0199 +#define LB_SETITEMDATA 0x019A +#define LB_SELITEMRANGE 0x019B +#define LB_SETANCHORINDEX 0x019C +#define LB_GETANCHORINDEX 0x019D +#define LB_SETCARETINDEX 0x019E +#define LB_GETCARETINDEX 0x019F +#define LB_SETITEMHEIGHT 0x01A0 +#define LB_GETITEMHEIGHT 0x01A1 +#define LB_FINDSTRINGEXACT 0x01A2 +#define LB_SETLOCALE 0x01A5 +#define LB_GETLOCALE 0x01A6 +#define LB_SETCOUNT 0x01A7 +#define LB_INITSTORAGE 0x01A8 +#define LB_ITEMFROMPOINT 0x01A9 +#if(_WIN32_WCE >= 0x0400) +#define LB_MULTIPLEADDSTRING 0x01B1 +#endif +#define LB_GETLISTBOXINFO 0x01B2 +#define LB_MSGMAX 0x01B3 +#endif + +#ifndef NOWINSTYLES + +#define LBS_NOTIFY 0x0001L +#define LBS_SORT 0x0002L +#define LBS_NOREDRAW 0x0004L +#define LBS_MULTIPLESEL 0x0008L +#define LBS_OWNERDRAWFIXED 0x0010L +#define LBS_OWNERDRAWVARIABLE 0x0020L +#define LBS_HASSTRINGS 0x0040L +#define LBS_USETABSTOPS 0x0080L +#define LBS_NOINTEGRALHEIGHT 0x0100L +#define LBS_MULTICOLUMN 0x0200L +#define LBS_WANTKEYBOARDINPUT 0x0400L +#define LBS_EXTENDEDSEL 0x0800L +#define LBS_DISABLENOSCROLL 0x1000L +#define LBS_NODATA 0x2000L +#define LBS_NOSEL 0x4000L +#define LBS_COMBOBOX 0x8000L + +#define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER) +#endif + #define CB_OKAY 0 #define CB_ERR (-1) #define CB_ERRSPACE (-2) -#define HIDE_WINDOW 0 -#define SHOW_OPENWINDOW 1 -#define SHOW_ICONWINDOW 2 -#define SHOW_FULLSCREEN 3 -#define SHOW_OPENNOACTIVATE 4 -#define SW_PARENTCLOSING 1 -#define SW_OTHERZOOM 2 -#define SW_PARENTOPENING 3 -#define SW_OTHERUNZOOM 4 -#define KF_EXTENDED 256 -#define KF_DLGMODE 2048 -#define KF_MENUMODE 4096 -#define KF_ALTDOWN 8192 -#define KF_REPEAT 16384 -#define KF_UP 32768 -#define WSF_VISIBLE 1 -#define PWR_OK 1 -#define PWR_FAIL (-1) -#define PWR_SUSPENDREQUEST 1 -#define PWR_SUSPENDRESUME 2 -#define PWR_CRITICALRESUME 3 -#define NFR_ANSI 1 -#define NFR_UNICODE 2 -#define NF_QUERY 3 -#define NF_REQUERY 4 -#define MENULOOP_WINDOW 0 -#define MENULOOP_POPUP 1 -#define WMSZ_LEFT 1 -#define WMSZ_RIGHT 2 -#define WMSZ_TOP 3 -#define WMSZ_TOPLEFT 4 -#define WMSZ_TOPRIGHT 5 -#define WMSZ_BOTTOM 6 -#define WMSZ_BOTTOMLEFT 7 -#define WMSZ_BOTTOMRIGHT 8 -#define HTERROR (-2) -#define HTTRANSPARENT (-1) -#define HTNOWHERE 0 -#define HTCLIENT 1 -#define HTCAPTION 2 -#define HTSYSMENU 3 -#define HTGROWBOX 4 -#define HTSIZE 4 -#define HTMENU 5 -#define HTHSCROLL 6 -#define HTVSCROLL 7 -#define HTMINBUTTON 8 -#define HTMAXBUTTON 9 -#define HTREDUCE 8 -#define HTZOOM 9 -#define HTLEFT 10 -#define HTSIZEFIRST 10 -#define HTRIGHT 11 -#define HTTOP 12 -#define HTTOPLEFT 13 -#define HTTOPRIGHT 14 -#define HTBOTTOM 15 -#define HTBOTTOMLEFT 16 -#define HTBOTTOMRIGHT 17 -#define HTSIZELAST 17 -#define HTBORDER 18 -#define HTOBJECT 19 -#define HTCLOSE 20 -#define HTHELP 21 -#define MA_ACTIVATE 1 -#define MA_ACTIVATEANDEAT 2 -#define MA_NOACTIVATE 3 -#define MA_NOACTIVATEANDEAT 4 -#define SIZE_RESTORED 0 -#define SIZE_MINIMIZED 1 -#define SIZE_MAXIMIZED 2 -#define SIZE_MAXSHOW 3 -#define SIZE_MAXHIDE 4 -#define SIZENORMAL 0 -#define SIZEICONIC 1 -#define SIZEFULLSCREEN 2 -#define SIZEZOOMSHOW 3 -#define SIZEZOOMHIDE 4 -#define WVR_ALIGNTOP 16 -#define WVR_ALIGNLEFT 32 -#define WVR_ALIGNBOTTOM 64 -#define WVR_ALIGNRIGHT 128 -#define WVR_HREDRAW 256 -#define WVR_VREDRAW 512 -#define WVR_REDRAW (WVR_HREDRAW|WVR_VREDRAW) -#define WVR_VALIDRECTS 1024 -#define PRF_CHECKVISIBLE 1 -#define PRF_NONCLIENT 2 -#define PRF_CLIENT 4 -#define PRF_ERASEBKGND 8 -#define PRF_CHILDREN 16 -#define PRF_OWNED 32 -#define IDANI_OPEN 1 -#define IDANI_CLOSE 2 -#define IDANI_CAPTION 3 -#define WPF_RESTORETOMAXIMIZED 2 -#define WPF_SETMINPOSITION 1 -#define ODT_MENU 1 -#define ODT_LISTBOX 2 -#define ODT_COMBOBOX 3 -#define ODT_BUTTON 4 -#define ODT_STATIC 5 -#define ODA_DRAWENTIRE 1 -#define ODA_SELECT 2 -#define ODA_FOCUS 4 -#define ODS_SELECTED 1 -#define ODS_GRAYED 2 -#define ODS_DISABLED 4 -#define ODS_CHECKED 8 -#define ODS_FOCUS 16 -#define ODS_DEFAULT 32 -#define ODS_COMBOBOXEDIT 4096 -#define IDHOT_SNAPWINDOW (-1) -#define IDHOT_SNAPDESKTOP (-2) -#define DBWF_LPARAMPOINTER 0x8000 -#define DLGWINDOWEXTRA 30 -#define MNC_IGNORE 0 -#define MNC_CLOSE 1 -#define MNC_EXECUTE 2 -#define MNC_SELECT 3 -#define DOF_EXECUTABLE 0x8001 -#define DOF_DOCUMENT 0x8002 -#define DOF_DIRECTORY 0x8003 -#define DOF_MULTIPLE 0x8004 -#define DOF_PROGMAN 1 -#define DOF_SHELLDATA 2 -#define DO_DROPFILE 0x454C4946 -#define DO_PRINTFILE 0x544E5250 -#define SW_SCROLLCHILDREN 1 -#define SW_INVALIDATE 2 -#define SW_ERASE 4 -#define SC_SIZE 0xF000 -#define SC_MOVE 0xF010 -#define SC_MINIMIZE 0xF020 -#define SC_ICON 0xf020 -#define SC_MAXIMIZE 0xF030 -#define SC_ZOOM 0xF030 -#define SC_NEXTWINDOW 0xF040 -#define SC_PREVWINDOW 0xF050 -#define SC_CLOSE 0xF060 -#define SC_VSCROLL 0xF070 -#define SC_HSCROLL 0xF080 -#define SC_MOUSEMENU 0xF090 -#define SC_KEYMENU 0xF100 -#define SC_ARRANGE 0xF110 -#define SC_RESTORE 0xF120 -#define SC_TASKLIST 0xF130 -#define SC_SCREENSAVE 0xF140 -#define SC_HOTKEY 0xF150 -#define SC_DEFAULT 0xF160 -#define SC_MONITORPOWER 0xF170 -#define SC_CONTEXTHELP 0xF180 -#define SC_SEPARATOR 0xF00F -#define EC_LEFTMARGIN 1 -#define EC_RIGHTMARGIN 2 -#define EC_USEFONTINFO 0xffff -#define DC_HASDEFID 0x534B -#define DLGC_WANTARROWS 1 -#define DLGC_WANTTAB 2 -#define DLGC_WANTALLKEYS 4 -#define DLGC_WANTMESSAGE 4 -#define DLGC_HASSETSEL 8 -#define DLGC_DEFPUSHBUTTON 16 -#define DLGC_UNDEFPUSHBUTTON 32 -#define DLGC_RADIOBUTTON 64 -#define DLGC_WANTCHARS 128 -#define DLGC_STATIC 256 -#define DLGC_BUTTON 0x2000 -#define LB_CTLCODE 0 -#define WA_INACTIVE 0 -#define WA_ACTIVE 1 -#define WA_CLICKACTIVE 2 -#define ICON_SMALL 0 -#define ICON_BIG 1 -#define HBMMENU_CALLBACK ((HBITMAP) -1) -#define HBMMENU_SYSTEM ((HBITMAP)1) -#define HBMMENU_MBAR_RESTORE ((HBITMAP)2) -#define HBMMENU_MBAR_MINIMIZE ((HBITMAP)3) -#define HBMMENU_MBAR_CLOSE ((HBITMAP)5) -#define HBMMENU_MBAR_CLOSE_D ((HBITMAP)6) -#define HBMMENU_MBAR_MINIMIZE_D ((HBITMAP)7) -#define HBMMENU_POPUP_CLOSE ((HBITMAP)8) -#define HBMMENU_POPUP_RESTORE ((HBITMAP)9) -#define HBMMENU_POPUP_MAXIMIZE ((HBITMAP)10) -#define HBMMENU_POPUP_MINIMIZE ((HBITMAP)11) -#define MOD_ALT 1 -#define MOD_CONTROL 2 -#define MOD_SHIFT 4 -#define MOD_WIN 8 -#define MOD_IGNORE_ALL_MODIFIER 1024 -#define MOD_ON_KEYUP 2048 -#define MOD_RIGHT 16384 -#define MOD_LEFT 32768 -#define LLKHF_ALTDOWN 0x00000020 - -#ifndef RC_INVOKED -typedef BOOL(CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM); -typedef VOID(CALLBACK *TIMERPROC)(HWND,UINT,UINT,DWORD); -typedef BOOL(CALLBACK *GRAYSTRINGPROC)(HDC,LPARAM,int); -typedef LRESULT(CALLBACK *HOOKPROC)(int,WPARAM,LPARAM); -typedef BOOL(CALLBACK *PROPENUMPROCA)(HWND,LPCSTR,HANDLE); -typedef BOOL(CALLBACK *PROPENUMPROCW)(HWND,LPCWSTR,HANDLE); -typedef BOOL(CALLBACK *PROPENUMPROCEXA)(HWND,LPSTR,HANDLE,DWORD); -typedef BOOL(CALLBACK *PROPENUMPROCEXW)(HWND,LPWSTR,HANDLE,DWORD); -typedef int(CALLBACK *EDITWORDBREAKPROCA)(LPSTR,int,int,int); -typedef int(CALLBACK *EDITWORDBREAKPROCW)(LPWSTR,int,int,int); -typedef LRESULT(CALLBACK *WNDPROC)(HWND,UINT,WPARAM,LPARAM); -typedef BOOL(CALLBACK *DRAWSTATEPROC)(HDC,LPARAM,WPARAM,int,int); -typedef BOOL(CALLBACK *WNDENUMPROC)(HWND,LPARAM); -typedef BOOL(CALLBACK *ENUMWINDOWSPROC)(HWND,LPARAM); -typedef BOOL(CALLBACK* MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM); -typedef BOOL(CALLBACK *NAMEENUMPROCA)(LPSTR,LPARAM); -typedef BOOL(CALLBACK *NAMEENUMPROCW)(LPWSTR,LPARAM); -typedef NAMEENUMPROCA DESKTOPENUMPROCA; -typedef NAMEENUMPROCW DESKTOPENUMPROCW; -typedef NAMEENUMPROCA WINSTAENUMPROCA; -typedef NAMEENUMPROCW WINSTAENUMPROCW; -typedef void(CALLBACK *SENDASYNCPROC)(HWND,UINT,DWORD,LRESULT); -DECLARE_HANDLE(HHOOK); -DECLARE_HANDLE(HDWP); -typedef struct tagACCEL { - BYTE fVirt; - WORD key; - WORD cmd; -} ACCEL,*LPACCEL; -typedef struct tagACCESSTIMEOUT { - UINT cbSize; - DWORD dwFlags; - DWORD iTimeOutMSec; -} ACCESSTIMEOUT, *LPACCESSTIMEOUT; -typedef struct tagANIMATIONINFO { - UINT cbSize; - int iMinAnimate; -} ANIMATIONINFO,*LPANIMATIONINFO; -typedef struct tagCREATESTRUCTA { - LPVOID lpCreateParams; - HINSTANCE hInstance; - HMENU hMenu; - HWND hwndParent; - int cy; - int cx; - int y; - int x; - LONG style; - LPCSTR lpszName; - LPCSTR lpszClass; - DWORD dwExStyle; -} CREATESTRUCTA,*LPCREATESTRUCTA; -typedef struct tagCREATESTRUCTW { - LPVOID lpCreateParams; - HINSTANCE hInstance; - HMENU hMenu; - HWND hwndParent; - int cy; - int cx; - int y; - int x; - LONG style; - LPCWSTR lpszName; - LPCWSTR lpszClass; - DWORD dwExStyle; -} CREATESTRUCTW,*LPCREATESTRUCTW; -typedef struct tagCBT_CREATEWNDA { - LPCREATESTRUCTA lpcs; - HWND hwndInsertAfter; -} CBT_CREATEWNDA, *LPCBT_CREATEWNDA; -typedef struct tagCBT_CREATEWNDW { - LPCREATESTRUCTW lpcs; - HWND hwndInsertAfter; -} CBT_CREATEWNDW, *LPCBT_CREATEWNDW; -typedef struct tagCBTACTIVATESTRUCT { - BOOL fMouse; - HWND hWndActive; -} CBTACTIVATESTRUCT,*LPCBTACTIVATESTRUCT; -typedef struct tagCLIENTCREATESTRUCT { - HANDLE hWindowMenu; - UINT idFirstChild; -} CLIENTCREATESTRUCT,*LPCLIENTCREATESTRUCT; -typedef struct tagCOMPAREITEMSTRUCT { - UINT CtlType; - UINT CtlID; - HWND hwndItem; - UINT itemID1; - DWORD itemData1; - UINT itemID2; - DWORD itemData2; - DWORD dwLocaleId; -} COMPAREITEMSTRUCT,*LPCOMPAREITEMSTRUCT; -typedef struct tagCOPYDATASTRUCT { - DWORD dwData; - DWORD cbData; - PVOID lpData; -} COPYDATASTRUCT,*PCOPYDATASTRUCT; -typedef struct tagCURSORSHAPE { - int xHotSpot; - int yHotSpot; - int cx; - int cy; - int cbWidth; - BYTE Planes; - BYTE BitsPixel; -} CURSORSHAPE,*LPCURSORSHAPE; -typedef struct tagCWPRETSTRUCT { - LRESULT lResult; - LPARAM lParam; - WPARAM wParam; - DWORD message; - HWND hwnd; -} CWPRETSTRUCT; -typedef struct tagCWPSTRUCT { - LPARAM lParam; - WPARAM wParam; - UINT message; - HWND hwnd; -} CWPSTRUCT,*PCWPSTRUCT; -typedef struct tagDEBUGHOOKINFO { - DWORD idThread; - DWORD idThreadInstaller; - LPARAM lParam; - WPARAM wParam; - int code; -} DEBUGHOOKINFO,*PDEBUGHOOKINFO,*LPDEBUGHOOKINFO; -typedef struct tagDELETEITEMSTRUCT { - UINT CtlType; - UINT CtlID; - UINT itemID; - HWND hwndItem; - UINT itemData; -} DELETEITEMSTRUCT,*PDELETEITEMSTRUCT,*LPDELETEITEMSTRUCT; -#pragma pack(push,2) -typedef struct { - DWORD style; - DWORD dwExtendedStyle; - short x; - short y; - short cx; - short cy; - WORD id; -} DLGITEMTEMPLATE,*LPDLGITEMTEMPLATE; -typedef struct { - DWORD style; - DWORD dwExtendedStyle; - WORD cdit; - short x; - short y; - short cx; - short cy; -} DLGTEMPLATE,*LPDLGTEMPLATE; -typedef const DLGTEMPLATE *LPCDLGTEMPLATE; -#pragma pack(pop) -typedef struct tagDRAWITEMSTRUCT { - UINT CtlType; - UINT CtlID; - UINT itemID; - UINT itemAction; - UINT itemState; - HWND hwndItem; - HDC hDC; - RECT rcItem; - DWORD itemData; -} DRAWITEMSTRUCT,*LPDRAWITEMSTRUCT,*PDRAWITEMSTRUCT; -typedef struct { - UINT cbSize; - int iTabLength; - int iLeftMargin; - int iRightMargin; - UINT uiLengthDrawn; -} DRAWTEXTPARAMS,*LPDRAWTEXTPARAMS; -typedef struct tagPAINTSTRUCT { - HDC hdc; - BOOL fErase; - RECT rcPaint; - BOOL fRestore; - BOOL fIncUpdate; - BYTE rgbReserved[32]; -} PAINTSTRUCT,*LPPAINTSTRUCT; -typedef struct tagMSG { - HWND hwnd; - UINT message; - WPARAM wParam; - LPARAM lParam; - DWORD time; - POINT pt; -} MSG,*LPMSG,*PMSG; -typedef struct _ICONINFO { - BOOL fIcon; - DWORD xHotspot; - DWORD yHotspot; - HBITMAP hbmMask; - HBITMAP hbmColor; -} ICONINFO,*PICONINFO; -typedef struct tagNMHDR { - HWND hwndFrom; - UINT idFrom; - UINT code; -} NMHDR,*LPNMHDR; -typedef struct _WNDCLASSA { - UINT style; - WNDPROC lpfnWndProc; - int cbClsExtra; - int cbWndExtra; - HANDLE hInstance; - HICON hIcon; - HCURSOR hCursor; - HBRUSH hbrBackground; - LPCSTR lpszMenuName; - LPCSTR lpszClassName; -} WNDCLASSA,*LPWNDCLASSA,*PWNDCLASSA; -typedef struct _WNDCLASSW { - UINT style; - WNDPROC lpfnWndProc; - int cbClsExtra; - int cbWndExtra; - HANDLE hInstance; - HICON hIcon; - HCURSOR hCursor; - HBRUSH hbrBackground; - LPCWSTR lpszMenuName; - LPCWSTR lpszClassName; -} WNDCLASSW,*LPWNDCLASSW,*PWNDCLASSW; -typedef struct _WNDCLASSEXA { - UINT cbSize; - UINT style; - WNDPROC lpfnWndProc; - int cbClsExtra; - int cbWndExtra; - HANDLE hInstance; - HICON hIcon; - HCURSOR hCursor; - HBRUSH hbrBackground; - LPCSTR lpszMenuName; - LPCSTR lpszClassName; - HICON hIconSm; -} WNDCLASSEXA,*LPWNDCLASSEXA,*PWNDCLASSEXA; -typedef struct _WNDCLASSEXW { - UINT cbSize; - UINT style; - WNDPROC lpfnWndProc; - int cbClsExtra; - int cbWndExtra; - HANDLE hInstance; - HICON hIcon; - HCURSOR hCursor; - HBRUSH hbrBackground; - LPCWSTR lpszMenuName; - LPCWSTR lpszClassName; - HICON hIconSm; -} WNDCLASSEXW,*LPWNDCLASSEXW,*PWNDCLASSEXW; -typedef struct tagMENUITEMINFOA { - UINT cbSize; - UINT fMask; - UINT fType; - UINT fState; - UINT wID; - HMENU hSubMenu; - HBITMAP hbmpChecked; - HBITMAP hbmpUnchecked; - DWORD dwItemData; - LPSTR dwTypeData; - UINT cch; -#if (_WIN32_WINNT >= 0x0500) - HBITMAP hbmpItem; -#endif -} MENUITEMINFOA,*LPMENUITEMINFOA; -typedef const MENUITEMINFOA *LPCMENUITEMINFOA; -typedef struct tagMENUITEMINFOW { - UINT cbSize; - UINT fMask; - UINT fType; - UINT fState; - UINT wID; - HMENU hSubMenu; - HBITMAP hbmpChecked; - HBITMAP hbmpUnchecked; - DWORD dwItemData; - LPWSTR dwTypeData; - UINT cch; -#if (_WIN32_WINNT >= 0x0500) - HBITMAP hbmpItem; -#endif -} MENUITEMINFOW,*LPMENUITEMINFOW; -typedef const MENUITEMINFOW *LPCMENUITEMINFOW; -typedef struct tagSCROLLINFO { - UINT cbSize; - UINT fMask; - int nMin; - int nMax; - UINT nPage; - int nPos; - int nTrackPos; -} SCROLLINFO,*LPSCROLLINFO; -typedef const SCROLLINFO *LPCSCROLLINFO; -typedef struct _WINDOWPLACEMENT { - UINT length; - UINT flags; - UINT showCmd; - POINT ptMinPosition; - POINT ptMaxPosition; - RECT rcNormalPosition; -} WINDOWPLACEMENT,*LPWINDOWPLACEMENT,*PWINDOWPLACEMENT; -typedef struct { - WORD versionNumber; - WORD offset; -} MENUITEMTEMPLATEHEADER; -typedef struct { - WORD mtOption; - WORD mtID; - WCHAR mtString[1]; -} MENUITEMTEMPLATE; -typedef void MENUTEMPLATE,MENUTEMPLATEA,MENUTEMPLATEW,*LPMENUTEMPLATEA,*LPMENUTEMPLATEW,*LPMENUTEMPLATE; -typedef struct tagHELPINFO { - UINT cbSize; - int iContextType; - int iCtrlId; - HANDLE hItemHandle; - DWORD dwContextId; - POINT MousePos; -} HELPINFO,*LPHELPINFO; -typedef void(CALLBACK *MSGBOXCALLBACK)(LPHELPINFO); -typedef struct { - UINT cbSize; - HWND hwndOwner; - HINSTANCE hInstance; - LPCSTR lpszText; - LPCSTR lpszCaption; - DWORD dwStyle; - LPCSTR lpszIcon; - DWORD dwContextHelpId; - MSGBOXCALLBACK lpfnMsgBoxCallback; - DWORD dwLanguageId; -} MSGBOXPARAMSA,*PMSGBOXPARAMSA,*LPMSGBOXPARAMSA; -typedef struct { - UINT cbSize; - HWND hwndOwner; - HINSTANCE hInstance; - LPCWSTR lpszText; - LPCWSTR lpszCaption; - DWORD dwStyle; - LPCWSTR lpszIcon; - DWORD dwContextHelpId; - MSGBOXCALLBACK lpfnMsgBoxCallback; - DWORD dwLanguageId; -} MSGBOXPARAMSW,*PMSGBOXPARAMSW,*LPMSGBOXPARAMSW; -typedef struct tagUSEROBJECTFLAGS { - BOOL fInherit; - BOOL fReserved; - DWORD dwFlags; -} USEROBJECTFLAGS; -typedef struct tagFILTERKEYS { - UINT cbSize; - DWORD dwFlags; - DWORD iWaitMSec; - DWORD iDelayMSec; - DWORD iRepeatMSec; - DWORD iBounceMSec; -} FILTERKEYS; -typedef struct tagHIGHCONTRASTA { - UINT cbSize; - DWORD dwFlags; - LPSTR lpszDefaultScheme; -} HIGHCONTRASTA,*LPHIGHCONTRASTA; -typedef struct tagHIGHCONTRASTW { - UINT cbSize; - DWORD dwFlags; - LPWSTR lpszDefaultScheme; -} HIGHCONTRASTW,*LPHIGHCONTRASTW; -typedef struct tagICONMETRICSA { - UINT cbSize; - int iHorzSpacing; - int iVertSpacing; - int iTitleWrap; - LOGFONTA lfFont; -} ICONMETRICSA,*LPICONMETRICSA; -typedef struct tagICONMETRICSW { - UINT cbSize; - int iHorzSpacing; - int iVertSpacing; - int iTitleWrap; - LOGFONTW lfFont; -} ICONMETRICSW,*LPICONMETRICSW; -typedef struct tagMINIMIZEDMETRICS { - UINT cbSize; - int iWidth; - int iHorzGap; - int iVertGap; - int iArrange; -} MINIMIZEDMETRICS,*LPMINIMIZEDMETRICS; -typedef struct tagMOUSEKEYS{ - UINT cbSize; - DWORD dwFlags; - DWORD iMaxSpeed; - DWORD iTimeToMaxSpeed; - DWORD iCtrlSpeed; - DWORD dwReserved1; - DWORD dwReserved2; -} MOUSEKEYS, *LPMOUSEKEYS; -typedef struct tagNONCLIENTMETRICSA { - UINT cbSize; - int iBorderWidth; - int iScrollWidth; - int iScrollHeight; - int iCaptionWidth; - int iCaptionHeight; - LOGFONTA lfCaptionFont; - int iSmCaptionWidth; - int iSmCaptionHeight; - LOGFONTA lfSmCaptionFont; - int iMenuWidth; - int iMenuHeight; - LOGFONTA lfMenuFont; - LOGFONTA lfStatusFont; - LOGFONTA lfMessageFont; -} NONCLIENTMETRICSA,*LPNONCLIENTMETRICSA; -typedef struct tagNONCLIENTMETRICSW { - UINT cbSize; - int iBorderWidth; - int iScrollWidth; - int iScrollHeight; - int iCaptionWidth; - int iCaptionHeight; - LOGFONTW lfCaptionFont; - int iSmCaptionWidth; - int iSmCaptionHeight; - LOGFONTW lfSmCaptionFont; - int iMenuWidth; - int iMenuHeight; - LOGFONTW lfMenuFont; - LOGFONTW lfStatusFont; - LOGFONTW lfMessageFont; -} NONCLIENTMETRICSW,*LPNONCLIENTMETRICSW; -typedef struct tagSERIALKEYSA { - UINT cbSize; - DWORD dwFlags; - LPSTR lpszActivePort; - LPSTR lpszPort; - UINT iBaudRate; - UINT iPortState; - UINT iActive; -} SERIALKEYSA,*LPSERIALKEYSA; -typedef struct tagSERIALKEYSW { - UINT cbSize; - DWORD dwFlags; - LPWSTR lpszActivePort; - LPWSTR lpszPort; - UINT iBaudRate; - UINT iPortState; - UINT iActive; -} SERIALKEYSW,*LPSERIALKEYSW; -typedef struct tagSOUNDSENTRYA { - UINT cbSize; - DWORD dwFlags; - DWORD iFSTextEffect; - DWORD iFSTextEffectMSec; - DWORD iFSTextEffectColorBits; - DWORD iFSGrafEffect; - DWORD iFSGrafEffectMSec; - DWORD iFSGrafEffectColor; - DWORD iWindowsEffect; - DWORD iWindowsEffectMSec; - LPSTR lpszWindowsEffectDLL; - DWORD iWindowsEffectOrdinal; -} SOUNDSENTRYA,*LPSOUNDSENTRYA; -typedef struct tagSOUNDSENTRYW { - UINT cbSize; - DWORD dwFlags; - DWORD iFSTextEffect; - DWORD iFSTextEffectMSec; - DWORD iFSTextEffectColorBits; - DWORD iFSGrafEffect; - DWORD iFSGrafEffectMSec; - DWORD iFSGrafEffectColor; - DWORD iWindowsEffect; - DWORD iWindowsEffectMSec; - LPWSTR lpszWindowsEffectDLL; - DWORD iWindowsEffectOrdinal; -} SOUNDSENTRYW,*LPSOUNDSENTRYW; -typedef struct tagSTICKYKEYS { - DWORD cbSize; - DWORD dwFlags; -} STICKYKEYS,*LPSTICKYKEYS; -typedef struct tagTOGGLEKEYS { - DWORD cbSize; - DWORD dwFlags; -} TOGGLEKEYS; -typedef struct tagTRACKMOUSEEVENT { - DWORD cbSize; - DWORD dwFlags; - HWND hwndTrack; - DWORD dwHoverTime; -} TRACKMOUSEEVENT,*LPTRACKMOUSEEVENT; -typedef struct tagTPMPARAMS { - UINT cbSize; - RECT rcExclude; -} TPMPARAMS,*LPTPMPARAMS; -typedef struct tagEVENTMSG { - UINT message; - UINT paramL; - UINT paramH; - DWORD time; - HWND hwnd; -} EVENTMSG,*PEVENTMSGMSG,*LPEVENTMSGMSG, *PEVENTMSG, *LPEVENTMSG; -typedef struct _WINDOWPOS { - HWND hwnd; - HWND hwndInsertAfter; - int x; - int y; - int cx; - int cy; - UINT flags; -} WINDOWPOS,*PWINDOWPOS,*LPWINDOWPOS; -typedef struct tagMDICREATESTRUCTA { - LPCSTR szClass; - LPCSTR szTitle; - HANDLE hOwner; - int x; - int y; - int cx; - int cy; - DWORD style; - LPARAM lParam; -} MDICREATESTRUCTA,*LPMDICREATESTRUCTA; -typedef struct tagMDICREATESTRUCTW { - LPCWSTR szClass; - LPCWSTR szTitle; - HANDLE hOwner; - int x; - int y; - int cx; - int cy; - DWORD style; - LPARAM lParam; -} MDICREATESTRUCTW,*LPMDICREATESTRUCTW; -typedef struct tagMINMAXINFO { - POINT ptReserved; - POINT ptMaxSize; - POINT ptMaxPosition; - POINT ptMinTrackSize; - POINT ptMaxTrackSize; -} MINMAXINFO,*PMINMAXINFO,*LPMINMAXINFO; -typedef struct tagMDINEXTMENU { - HMENU hmenuIn; - HMENU hmenuNext; - HWND hwndNext; -} MDINEXTMENU,*PMDINEXTMENU,*LPMDINEXTMENU; -typedef struct tagMEASUREITEMSTRUCT { - UINT CtlType; - UINT CtlID; - UINT itemID; - UINT itemWidth; - UINT itemHeight; - DWORD itemData; -} MEASUREITEMSTRUCT,*PMEASUREITEMSTRUCT,*LPMEASUREITEMSTRUCT; -typedef struct tagDROPSTRUCT { - HWND hwndSource; - HWND hwndSink; - DWORD wFmt; - DWORD dwData; - POINT ptDrop; - DWORD dwControlData; -} DROPSTRUCT,*PDROPSTRUCT,*LPDROPSTRUCT; -typedef DWORD HELPPOLY; -typedef struct tagMULTIKEYHELPA { - DWORD mkSize; - CHAR mkKeylist; - CHAR szKeyphrase[1]; -} MULTIKEYHELPA,*PMULTIKEYHELPA,*LPMULTIKEYHELPA; -typedef struct tagMULTIKEYHELPW { - DWORD mkSize; - WCHAR mkKeylist; - WCHAR szKeyphrase[1]; -} MULTIKEYHELPW,*PMULTIKEYHELPW,*LPMULTIKEYHELPW; -typedef struct tagHELPWININFOA { - int wStructSize; - int x; - int y; - int dx; - int dy; - int wMax; - CHAR rgchMember[2]; -} HELPWININFOA,*PHELPWININFOA,*LPHELPWININFOA; -typedef struct tagHELPWININFOW { - int wStructSize; - int x; - int y; - int dx; - int dy; - int wMax; - WCHAR rgchMember[2]; -} HELPWININFOW,*PHELPWININFOW,*LPHELPWININFOW; -typedef struct tagSTYLESTRUCT { - DWORD styleOld; - DWORD styleNew; -} STYLESTRUCT,*LPSTYLESTRUCT; -typedef struct tagALTTABINFO { - DWORD cbSize; - int cItems; - int cColumns; - int cRows; - int iColFocus; - int iRowFocus; - int cxItem; - int cyItem; - POINT ptStart; -} ALTTABINFO, *PALTTABINFO, *LPALTTABINFO; -typedef struct tagCOMBOBOXINFO { - DWORD cbSize; - RECT rcItem; - RECT rcButton; - DWORD stateButton; - HWND hwndCombo; - HWND hwndItem; - HWND hwndList; -} COMBOBOXINFO, *PCOMBOBOXINFO, *LPCOMBOBOXINFO; -typedef struct tagCURSORINFO { - DWORD cbSize; - DWORD flags; - HCURSOR hCursor; - POINT ptScreenPos; -} CURSORINFO,*PCURSORINFO,*LPCURSORINFO; -typedef struct tagMENUBARINFO { - DWORD cbSize; - RECT rcBar; - HMENU hMenu; - HWND hwndMenu; - BOOL fBarFocused:1; - BOOL fFocused:1; -} MENUBARINFO, *PMENUBARINFO; -typedef struct tagMENUINFO { - DWORD cbSize; - DWORD fMask; - DWORD dwStyle; - UINT cyMax; - HBRUSH hbrBack; - DWORD dwContextHelpID; - ULONG_PTR dwMenuData; -} MENUINFO, *LPMENUINFO; -typedef MENUINFO CONST *LPCMENUINFO; -#define CCHILDREN_SCROLLBAR 5 -typedef struct tagSCROLLBARINFO { - DWORD cbSize; - RECT rcScrollBar; - int dxyLineButton; - int xyThumbTop; - int xyThumbBottom; - int reserved; - DWORD rgstate[CCHILDREN_SCROLLBAR + 1]; -} SCROLLBARINFO, *PSCROLLBARINFO, *LPSCROLLBARINFO; -#define CCHILDREN_TITLEBAR 5 -typedef struct tagTITLEBARINFO { - DWORD cbSize; - RECT rcTitleBar; - DWORD rgstate[CCHILDREN_TITLEBAR + 1]; -} TITLEBARINFO, *PTITLEBARINFO, *LPTITLEBARINFO; -typedef struct tagWINDOWINFO { - DWORD cbSize; - RECT rcWindow; - RECT rcClient; - DWORD dwStyle; - DWORD dwExStyle; - DWORD dwWindowStatus; - UINT cxWindowBorders; - UINT cyWindowBorders; - ATOM atomWindowType; - WORD wCreatorVersion; -} WINDOWINFO, *PWINDOWINFO, *LPWINDOWINFO; -typedef struct tagLASTINPUTINFO { - UINT cbSize; - DWORD dwTime; -} LASTINPUTINFO, * PLASTINPUTINFO; -typedef struct tagMONITORINFO { - DWORD cbSize; - RECT rcMonitor; - RECT rcWork; - DWORD dwFlags; -} MONITORINFO,*LPMONITORINFO; -typedef struct tagKBDLLHOOKSTRUCT { - DWORD vkCode; - DWORD scanCode; - DWORD flags; - DWORD time; - DWORD dwExtraInfo; -} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT; +#define CBN_ERRSPACE (-1) +#define CBN_SELCHANGE 1 +#define CBN_DBLCLK 2 +#define CBN_SETFOCUS 3 +#define CBN_KILLFOCUS 4 +#define CBN_EDITCHANGE 5 +#define CBN_EDITUPDATE 6 +#define CBN_DROPDOWN 7 +#define CBN_CLOSEUP 8 +#define CBN_SELENDOK 9 +#define CBN_SELENDCANCEL 10 -#define AnsiToOem CharToOemA -#define OemToAnsi OemToCharA -#define AnsiToOemBuff CharToOemBuffA -#define OemToAnsiBuff OemToCharBuffA -#define AnsiUpper CharUpperA -#define AnsiUpperBuff CharUpperBuffA -#define AnsiLower CharLowerA -#define AnsiLowerBuff CharLowerBuffA -#define AnsiNext CharNextA -#define AnsiPrev CharPrevA -#define MAKELPARAM(l,h) ((LPARAM)MAKELONG(l,h)) -#define MAKEWPARAM(l,h) ((WPARAM)MAKELONG(l,h)) -#define MAKELRESULT(l,h) ((LRESULT)MAKELONG(l,h)) -#define POINTSTOPOINT(p,ps) { \ - (p).x=LOWORD(*(DWORD *)&ps); \ - (p).y=HIWORD(*(DWORD *)&ps); \ -} -#define POINTTOPOINTS(p) ((POINTS)MAKELONG((p).x,(p).y)) - -HKL WINAPI ActivateKeyboardLayout(HKL,UINT); -BOOL WINAPI AdjustWindowRect(LPRECT,DWORD,BOOL); -BOOL WINAPI AdjustWindowRectEx(LPRECT,DWORD,BOOL,DWORD); -BOOL WINAPI AnyPopup(void); -BOOL WINAPI AppendMenuA(HMENU,UINT,UINT,LPCSTR); -BOOL WINAPI AppendMenuW(HMENU,UINT,UINT,LPCWSTR); -UINT WINAPI ArrangeIconicWindows(HWND); -BOOL WINAPI AttachThreadInput(DWORD,DWORD,BOOL); -HDWP WINAPI BeginDeferWindowPos(int); -HDC WINAPI BeginPaint(HWND,LPPAINTSTRUCT); -BOOL WINAPI BringWindowToTop(HWND); -long WINAPI BroadcastSystemMessage(DWORD,LPDWORD,UINT,WPARAM,LPARAM); -BOOL WINAPI CallMsgFilter(PMSG,int); -LRESULT WINAPI CallNextHookEx(HHOOK,int,WPARAM,LPARAM); -LRESULT WINAPI CallWindowProcA(WNDPROC,HWND,UINT,WPARAM,LPARAM); -LRESULT WINAPI CallWindowProcW(WNDPROC,HWND,UINT,WPARAM,LPARAM); -WORD WINAPI CascadeWindows(HWND,UINT,LPCRECT,UINT,const HWND*); -BOOL WINAPI ChangeClipboardChain(HWND,HWND); -LONG WINAPI ChangeDisplaySettingsA(PDEVMODEA,DWORD); -LONG WINAPI ChangeDisplaySettingsW(PDEVMODEW,DWORD); -BOOL WINAPI ChangeMenuA(HMENU,UINT,LPCSTR,UINT,UINT); -BOOL WINAPI ChangeMenuW(HMENU,UINT,LPCWSTR,UINT,UINT); -LPSTR WINAPI CharLowerA(LPSTR); -LPWSTR WINAPI CharLowerW(LPWSTR); -DWORD WINAPI CharLowerBuffA(LPSTR,DWORD); -DWORD WINAPI CharLowerBuffW(LPWSTR,DWORD); -LPSTR WINAPI CharNextA(LPCSTR); -LPWSTR WINAPI CharNextW(LPCWSTR); -LPSTR WINAPI CharNextExA(WORD,LPCSTR,DWORD); -LPWSTR WINAPI CharNextExW(WORD,LPCWSTR,DWORD); -LPSTR WINAPI CharPrevA(LPCSTR,LPCSTR); -LPWSTR WINAPI CharPrevW(LPCWSTR,LPCWSTR); -LPSTR WINAPI CharPrevExA(WORD,LPCSTR,LPCSTR,DWORD); -LPWSTR WINAPI CharPrevExW(WORD,LPCWSTR,LPCWSTR,DWORD); -BOOL WINAPI CharToOemA(LPCSTR,LPSTR); -BOOL WINAPI CharToOemW(LPCWSTR,LPSTR); -BOOL WINAPI CharToOemBuffA(LPCSTR,LPSTR,DWORD); -BOOL WINAPI CharToOemBuffW(LPCWSTR,LPSTR,DWORD); -LPSTR WINAPI CharUpperA(LPSTR); -LPWSTR WINAPI CharUpperW(LPWSTR); -DWORD WINAPI CharUpperBuffA(LPSTR,DWORD); -DWORD WINAPI CharUpperBuffW(LPWSTR,DWORD); -BOOL WINAPI CheckDlgButton(HWND,int,UINT); -DWORD WINAPI CheckMenuItem(HMENU,UINT,UINT); -BOOL WINAPI CheckMenuRadioItem(HMENU,UINT,UINT,UINT,UINT); -BOOL WINAPI CheckRadioButton(HWND,int,int,int); -HWND WINAPI ChildWindowFromPoint(HWND,POINT); -HWND WINAPI ChildWindowFromPointEx(HWND,POINT,UINT); -BOOL WINAPI ClientToScreen(HWND,LPPOINT); -BOOL WINAPI ClipCursor(LPCRECT); -BOOL WINAPI CloseClipboard(void); -BOOL WINAPI CloseDesktop(HDESK); -BOOL WINAPI CloseWindow(HWND); -BOOL WINAPI CloseWindowStation(HWINSTA); -int WINAPI CopyAcceleratorTableA(HACCEL,LPACCEL,int); -int WINAPI CopyAcceleratorTableW(HACCEL,LPACCEL,int); -HCURSOR WINAPI CopyCursor(HCURSOR); -HICON WINAPI CopyIcon(HICON); -HANDLE WINAPI CopyImage(HANDLE,UINT,int,int,UINT); -BOOL WINAPI CopyRect(LPRECT,LPCRECT); -int WINAPI CountClipboardFormats(void); -HACCEL WINAPI CreateAcceleratorTableA(LPACCEL,int); -HACCEL WINAPI CreateAcceleratorTableW(LPACCEL,int); -BOOL WINAPI CreateCaret(HWND,HBITMAP,int,int); -HCURSOR WINAPI CreateCursor(HINSTANCE,int,int,int,int,PCVOID,PCVOID); -HDESK WINAPI CreateDesktopA(LPSTR,LPSTR,LPDEVMODEA,DWORD,DWORD,LPSECURITY_ATTRIBUTES); -HDESK WINAPI CreateDesktopW(LPWSTR,LPWSTR,LPDEVMODEW,DWORD,DWORD,LPSECURITY_ATTRIBUTES); -#define CreateDialogA(h,n,w,f) CreateDialogParamA(h,n,w,f,0) -#define CreateDialogW(h,n,w,f) CreateDialogParamW(h,n,w,f,0) -#define CreateDialogIndirectA(h,t,w,f) CreateDialogIndirectParamA(h,t,w,f,0) -#define CreateDialogIndirectW(h,t,w,f) CreateDialogIndirectParamW(h,t,w,f,0) -HWND WINAPI CreateDialogIndirectParamA(HINSTANCE,LPCDLGTEMPLATE,HWND,DLGPROC,LPARAM); -HWND WINAPI CreateDialogIndirectParamW(HINSTANCE,LPCDLGTEMPLATE,HWND,DLGPROC,LPARAM); -HWND WINAPI CreateDialogParamA(HINSTANCE,LPCSTR,HWND,DLGPROC,LPARAM); -HWND WINAPI CreateDialogParamW(HINSTANCE,LPCWSTR,HWND,DLGPROC,LPARAM); -HICON WINAPI CreateIcon(HINSTANCE,int,int,BYTE,BYTE,const BYTE*,const BYTE*); -HICON WINAPI CreateIconFromResource(PBYTE,DWORD,BOOL,DWORD); -HICON WINAPI CreateIconFromResourceEx(PBYTE,DWORD,BOOL,DWORD,int,int,UINT); -HICON WINAPI CreateIconIndirect(PICONINFO); -HWND WINAPI CreateMDIWindowA(LPSTR,LPSTR,DWORD,int,int,int,int,HWND,HINSTANCE,LPARAM); -HWND WINAPI CreateMDIWindowW(LPWSTR,LPWSTR,DWORD,int,int,int,int,HWND,HINSTANCE,LPARAM); -HMENU WINAPI CreateMenu(void); -HMENU WINAPI CreatePopupMenu(void); -#define CreateWindowA(a,b,c,d,e,f,g,h,i,j,k) CreateWindowExA(0,a,b,c,d,e,f,g,h,i,j,k) -#define CreateWindowW(a,b,c,d,e,f,g,h,i,j,k) CreateWindowExW(0,a,b,c,d,e,f,g,h,i,j,k) -HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID); -HWND WINAPI CreateWindowExW(DWORD,LPCWSTR,LPCWSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID); -HWINSTA WINAPI CreateWindowStationA(LPSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES); -HWINSTA WINAPI CreateWindowStationW(LPWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES); -LRESULT WINAPI DefDlgProcA(HWND,UINT,WPARAM,LPARAM); -LRESULT WINAPI DefDlgProcW(HWND,UINT,WPARAM,LPARAM); -HDWP WINAPI DeferWindowPos(HDWP,HWND,HWND,int,int,int,int,UINT); -LRESULT WINAPI DefFrameProcA(HWND,HWND,UINT,WPARAM,LPARAM); -LRESULT WINAPI DefFrameProcW(HWND,HWND,UINT,WPARAM,LPARAM); -#define DefHookProc(c,p,lp,h) CallNextHookEx((HHOOK)*h,c,p,lp) -LRESULT WINAPI DefMDIChildProcA(HWND,UINT,WPARAM,LPARAM); -LRESULT WINAPI DefMDIChildProcW(HWND,UINT,WPARAM,LPARAM); -LRESULT WINAPI DefWindowProcA(HWND,UINT,WPARAM,LPARAM); -LRESULT WINAPI DefWindowProcW(HWND,UINT,WPARAM,LPARAM); -BOOL WINAPI DeleteMenu(HMENU,UINT,UINT); -BOOL WINAPI DestroyAcceleratorTable(HACCEL); -BOOL WINAPI DestroyCaret(void); -BOOL WINAPI DestroyCursor(HCURSOR); -BOOL WINAPI DestroyIcon(HICON); -BOOL WINAPI DestroyMenu(HMENU); -BOOL WINAPI DestroyWindow(HWND); -#define DialogBoxA(i,t,p,f) DialogBoxParamA(i,t,p,f,0) -#define DialogBoxW(i,t,p,f) DialogBoxParamW(i,t,p,f,0) -#define DialogBoxIndirectA(i,t,p,f) DialogBoxIndirectParamA(i,t,p,f,0) -#define DialogBoxIndirectW(i,t,p,f) DialogBoxIndirectParamW(i,t,p,f,0) -int WINAPI DialogBoxIndirectParamA(HINSTANCE,LPCDLGTEMPLATE,HWND,DLGPROC,LPARAM); -int WINAPI DialogBoxIndirectParamW(HINSTANCE,LPCDLGTEMPLATE,HWND,DLGPROC,LPARAM); -int WINAPI DialogBoxParamA(HINSTANCE,LPCSTR,HWND,DLGPROC,LPARAM); -int WINAPI DialogBoxParamW(HINSTANCE,LPCWSTR,HWND,DLGPROC,LPARAM); -LONG WINAPI DispatchMessageA(const MSG*); -LONG WINAPI DispatchMessageW(const MSG*); -int WINAPI DlgDirListA(HWND,LPSTR,int,int,UINT); -int WINAPI DlgDirListW(HWND,LPWSTR,int,int,UINT); -int WINAPI DlgDirListComboBoxA(HWND,LPSTR,int,int,UINT); -int WINAPI DlgDirListComboBoxW(HWND,LPWSTR,int,int,UINT); -BOOL WINAPI DlgDirSelectComboBoxExA(HWND,LPSTR,int,int); -BOOL WINAPI DlgDirSelectComboBoxExW(HWND,LPWSTR,int,int); -BOOL WINAPI DlgDirSelectExA(HWND,LPSTR,int,int); -BOOL WINAPI DlgDirSelectExW(HWND,LPWSTR,int,int); -BOOL WINAPI DragDetect(HWND,POINT); -DWORD WINAPI DragObject(HWND,HWND,UINT,DWORD,HCURSOR); -BOOL WINAPI DrawAnimatedRects(HWND,int,LPCRECT,LPCRECT); -BOOL WINAPI DrawCaption(HWND,HDC,LPCRECT,UINT); -BOOL WINAPI DrawEdge(HDC,LPRECT,UINT,UINT); -BOOL WINAPI DrawFocusRect(HDC,LPCRECT); -BOOL WINAPI DrawFrameControl(HDC,LPRECT,UINT,UINT); -BOOL WINAPI DrawIcon(HDC,int,int,HICON); -BOOL WINAPI DrawIconEx(HDC,int,int,HICON,int,int,UINT,HBRUSH,UINT); -BOOL WINAPI DrawMenuBar(HWND); -BOOL WINAPI DrawStateA(HDC,HBRUSH,DRAWSTATEPROC,LPARAM,WPARAM,int,int,int,int,UINT); -BOOL WINAPI DrawStateW(HDC,HBRUSH,DRAWSTATEPROC,LPARAM,WPARAM,int,int,int,int,UINT); -int WINAPI DrawTextA(HDC,LPCSTR,int,LPRECT,UINT); -int WINAPI DrawTextW(HDC,LPCWSTR,int,LPRECT,UINT); -int WINAPI DrawTextExA(HDC,LPSTR,int,LPRECT,UINT,LPDRAWTEXTPARAMS); -int WINAPI DrawTextExW(HDC,LPWSTR,int,LPRECT,UINT,LPDRAWTEXTPARAMS); -BOOL WINAPI EmptyClipboard(void); -BOOL WINAPI EnableMenuItem(HMENU,UINT,UINT); -BOOL WINAPI EnableScrollBar(HWND,UINT,UINT); -BOOL WINAPI EnableWindow(HWND,BOOL); -BOOL WINAPI EndDeferWindowPos(HDWP); -BOOL WINAPI EndDialog(HWND,int); -BOOL WINAPI EndMenu(VOID); -BOOL WINAPI EndPaint(HWND,const PAINTSTRUCT*); -BOOL WINAPI EnumChildWindows(HWND,ENUMWINDOWSPROC,LPARAM); -UINT WINAPI EnumClipboardFormats(UINT); -BOOL WINAPI EnumDesktopsA(HWINSTA,DESKTOPENUMPROCA,LPARAM); -BOOL WINAPI EnumDesktopsW(HWINSTA,DESKTOPENUMPROCW,LPARAM); -BOOL WINAPI EnumDesktopWindows(HDESK,ENUMWINDOWSPROC,LPARAM); -BOOL WINAPI EnumDisplayMonitors(HDC,LPCRECT,MONITORENUMPROC,LPARAM); -BOOL WINAPI EnumDisplaySettingsA(LPCSTR,DWORD,PDEVMODEA); -BOOL WINAPI EnumDisplaySettingsW(LPCWSTR,DWORD,PDEVMODEW); -int WINAPI EnumPropsA(HWND,PROPENUMPROCA); -int WINAPI EnumPropsW(HWND,PROPENUMPROCW); -int WINAPI EnumPropsExA(HWND,PROPENUMPROCEXA,LPARAM); -int WINAPI EnumPropsExW(HWND,PROPENUMPROCEXW,LPARAM); -#define EnumTaskWindows(h,f,p) EnumThreadWindows((DWORD)h,f,p) -BOOL WINAPI EnumThreadWindows(DWORD,WNDENUMPROC,LPARAM); -BOOL WINAPI EnumWindows(WNDENUMPROC,LPARAM); -BOOL WINAPI EnumWindowStationsA(WINSTAENUMPROCA,LPARAM); -BOOL WINAPI EnumWindowStationsW(WINSTAENUMPROCW,LPARAM); -BOOL WINAPI EqualRect(LPCRECT,LPCRECT); -#define ExitWindows(r,c) ExitWindowsEx(EWX_LOGOFF,0) -BOOL WINAPI ExitWindowsEx(UINT,DWORD); -HWND WINAPI FindWindowA(LPCSTR,LPCSTR); -HWND WINAPI FindWindowExA(HWND,HWND,LPCSTR,LPCSTR); -HWND WINAPI FindWindowExW(HWND,HWND,LPCWSTR,LPCWSTR); -HWND WINAPI FindWindowW(LPCWSTR,LPCWSTR); -BOOL WINAPI FlashWindow(HWND,BOOL); -int WINAPI FrameRect(HDC,LPCRECT,HBRUSH); -BOOL WINAPI FrameRgn(HDC,HRGN,HBRUSH,int,int); -HWND WINAPI GetActiveWindow(void); -SHORT WINAPI GetAsyncKeyState(int); -HWND WINAPI GetCapture(void); -UINT WINAPI GetCaretBlinkTime(void); -BOOL WINAPI GetCaretPos(LPPOINT); -BOOL WINAPI GetClassInfoA(HINSTANCE,LPCSTR,PWNDCLASSA); -BOOL WINAPI GetClassInfoExA(HINSTANCE,LPCSTR,PWNDCLASSEXA); -BOOL WINAPI GetClassInfoW(HINSTANCE,LPCWSTR,PWNDCLASSW); -BOOL WINAPI GetClassInfoExW(HINSTANCE,LPCWSTR,PWNDCLASSEXW); -DWORD WINAPI GetClassLongA(HWND,int); -DWORD WINAPI GetClassLongW(HWND,int); -int WINAPI GetClassNameA(HWND,LPSTR,int); -int WINAPI GetClassNameW(HWND,LPWSTR,int); -WORD WINAPI GetClassWord(HWND,int); -BOOL WINAPI GetClientRect(HWND,LPRECT); -HANDLE WINAPI GetClipboardData(UINT); -int WINAPI GetClipboardFormatNameA(UINT,LPSTR,int); -int WINAPI GetClipboardFormatNameW(UINT,LPWSTR,int); -HWND WINAPI GetClipboardOwner(void); -HWND WINAPI GetClipboardViewer(void); -BOOL WINAPI GetClipCursor(LPRECT); -BOOL WINAPI GetCursorPos(LPPOINT); -HDC WINAPI GetDC(HWND); -HDC WINAPI GetDCEx(HWND,HRGN,DWORD); -HWND WINAPI GetDesktopWindow(void); -long WINAPI GetDialogBaseUnits(void); -int WINAPI GetDlgCtrlID(HWND); -HWND WINAPI GetDlgItem(HWND,int); -UINT WINAPI GetDlgItemInt(HWND,int,PBOOL,BOOL); -UINT WINAPI GetDlgItemTextA(HWND,int,LPSTR,int); -UINT WINAPI GetDlgItemTextW(HWND,int,LPWSTR,int); -UINT WINAPI GetDoubleClickTime(void); -HWND WINAPI GetFocus(void); -HWND WINAPI GetForegroundWindow(void); -BOOL WINAPI GetIconInfo(HICON,PICONINFO); -BOOL WINAPI GetInputState(void); -UINT WINAPI GetKBCodePage(void); -HKL WINAPI GetKeyboardLayout(DWORD); -int WINAPI GetKeyboardLayoutList(int,HKL*); -BOOL WINAPI GetKeyboardLayoutNameA(LPSTR); -BOOL WINAPI GetKeyboardLayoutNameW(LPWSTR); -BOOL WINAPI GetKeyboardState(PBYTE); -int WINAPI GetKeyboardType(int); -int WINAPI GetKeyNameTextA(LONG,LPSTR,int); -int WINAPI GetKeyNameTextW(LONG,LPWSTR,int); -SHORT WINAPI GetKeyState(int); -HWND WINAPI GetLastActivePopup(HWND); -DWORD WINAPI GetLastError(void); -HMENU WINAPI GetMenu(HWND); -LONG WINAPI GetMenuCheckMarkDimensions(void); -DWORD WINAPI GetMenuContextHelpId(HMENU); -UINT WINAPI GetMenuDefaultItem(HMENU,UINT,UINT); -int WINAPI GetMenuItemCount(HMENU); -UINT WINAPI GetMenuItemID(HMENU,int); -BOOL WINAPI GetMenuItemInfoA(HMENU,UINT,BOOL,LPMENUITEMINFOA); -BOOL WINAPI GetMenuItemInfoW(HMENU,UINT,BOOL,LPMENUITEMINFOW); -BOOL WINAPI GetMenuItemRect(HWND,HMENU,UINT,LPRECT); -UINT WINAPI GetMenuState(HMENU,UINT,UINT); -int WINAPI GetMenuStringA(HMENU,UINT,LPSTR,int,UINT); -int WINAPI GetMenuStringW(HMENU,UINT,LPWSTR,int,UINT); -BOOL WINAPI GetMessageA(LPMSG,HWND,UINT,UINT); -BOOL WINAPI GetMessageW(LPMSG,HWND,UINT,UINT); -LONG WINAPI GetMessageExtraInfo(void); -DWORD WINAPI GetMessagePos(void); -LONG WINAPI GetMessageTime(void); -HWND WINAPI GetNextDlgGroupItem(HWND,HWND,BOOL); -HWND WINAPI GetNextDlgTabItem(HWND,HWND,BOOL); -#define GetNextWindow(h,c) GetWindow(h,c) -HWND WINAPI GetOpenClipboardWindow(void); -HWND WINAPI GetParent(HWND); -int WINAPI GetPriorityClipboardFormat(UINT*,int); -HANDLE WINAPI GetPropA(HWND,LPCSTR); -HANDLE WINAPI GetPropW(HWND,LPCWSTR); -DWORD WINAPI GetQueueStatus(UINT); -BOOL WINAPI GetScrollInfo(HWND,int,LPSCROLLINFO); -int WINAPI GetScrollPos(HWND,int); -BOOL WINAPI GetScrollRange(HWND,int,LPINT,LPINT); -HMENU WINAPI GetSubMenu(HMENU,int); -DWORD WINAPI GetSysColor(int); -HBRUSH WINAPI GetSysColorBrush(int); -#define GetSysModalWindow() (NULL) -HMENU WINAPI GetSystemMenu(HWND,BOOL); -int WINAPI GetSystemMetrics(int); -DWORD WINAPI GetTabbedTextExtentA(HDC,LPCSTR,int,int,LPINT); -DWORD WINAPI GetTabbedTextExtentW(HDC,LPCWSTR,int,int,LPINT); -LONG WINAPI GetWindowLongA(HWND,int); -LONG WINAPI GetWindowLongW(HWND,int); -#ifdef _WIN64 -LONG_PTR WINAPI GetWindowLongPtrA(HWND,int); -LONG_PTR WINAPI GetWindowLongPtrW(HWND,int); -#else -#define GetWindowLongPtrA GetWindowLongA -#define GetWindowLongPtrW GetWindowLongW +#ifndef NOWINSTYLES + +#define CBS_SIMPLE 0x0001L +#define CBS_DROPDOWN 0x0002L +#define CBS_DROPDOWNLIST 0x0003L +#define CBS_OWNERDRAWFIXED 0x0010L +#define CBS_OWNERDRAWVARIABLE 0x0020L +#define CBS_AUTOHSCROLL 0x0040L +#define CBS_OEMCONVERT 0x0080L +#define CBS_SORT 0x0100L +#define CBS_HASSTRINGS 0x0200L +#define CBS_NOINTEGRALHEIGHT 0x0400L +#define CBS_DISABLENOSCROLL 0x0800L +#define CBS_UPPERCASE 0x2000L +#define CBS_LOWERCASE 0x4000L #endif -HDESK WINAPI GetThreadDesktop(DWORD); -HWND WINAPI GetTopWindow(HWND); -BOOL WINAPI GetUpdateRect(HWND,LPRECT,BOOL); -int WINAPI GetUpdateRgn(HWND,HRGN,BOOL); -BOOL WINAPI GetUserObjectInformationA(HANDLE,int,PVOID,DWORD,PDWORD); -BOOL WINAPI GetUserObjectInformationW(HANDLE,int,PVOID,DWORD,PDWORD); -BOOL WINAPI GetUserObjectSecurity(HANDLE,PSECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD); -HWND WINAPI GetWindow(HWND,UINT); -DWORD WINAPI GetWindowContextHelpId(HWND); -HDC WINAPI GetWindowDC(HWND); -BOOL WINAPI GetWindowExtEx(HDC,LPSIZE); -BOOL WINAPI GetWindowPlacement(HWND,WINDOWPLACEMENT*); -BOOL WINAPI GetWindowRect(HWND,LPRECT); -int WINAPI GetWindowRgn(HWND,HRGN); -#define GetWindowTask(hWnd) ((HANDLE)GetWindowThreadProcessId(hWnd, NULL)) -int WINAPI GetWindowTextA(HWND,LPSTR,int); -int WINAPI GetWindowTextLengthA(HWND); -int WINAPI GetWindowTextLengthW(HWND); -int WINAPI GetWindowTextW(HWND,LPWSTR,int); -WORD WINAPI GetWindowWord(HWND,int); -BOOL WINAPI GetAltTabInfoA(HWND,int,PALTTABINFO,LPSTR,UINT); -BOOL WINAPI GetAltTabInfoW(HWND,int,PALTTABINFO,LPWSTR,UINT); -BOOL WINAPI GetComboBoxInfo(HWND,PCOMBOBOXINFO); -BOOL WINAPI GetCursorInfo(PCURSORINFO); -BOOL WINAPI GetLastInputInfo(PLASTINPUTINFO); -DWORD WINAPI GetListBoxInfo(HWND); -BOOL WINAPI GetMenuBarInfo(HWND,LONG,LONG,PMENUBARINFO); -BOOL WINAPI GetMenuInfo(HMENU,LPMENUINFO); -BOOL WINAPI GetScrollBarInfo(HWND,LONG,PSCROLLBARINFO); -BOOL WINAPI GetTitleBarInfo(HWND,PTITLEBARINFO); -BOOL WINAPI GetWindowInfo(HWND,PWINDOWINFO); -BOOL WINAPI GetMonitorInfoA(HMONITOR,LPMONITORINFO); -BOOL WINAPI GetMonitorInfoW(HMONITOR,LPMONITORINFO); -UINT WINAPI GetWindowModuleFileNameA(HWND,LPSTR,UINT); -UINT WINAPI GetWindowModuleFileNameW(HWND,LPWSTR,UINT); -BOOL WINAPI GrayStringA(HDC,HBRUSH,GRAYSTRINGPROC,LPARAM,int,int,int,int,int); -BOOL WINAPI GrayStringW(HDC,HBRUSH,GRAYSTRINGPROC,LPARAM,int,int,int,int,int); -BOOL WINAPI HideCaret(HWND); -BOOL WINAPI HiliteMenuItem(HWND,HMENU,UINT,UINT); -BOOL WINAPI InflateRect(LPRECT,int,int); -BOOL WINAPI InSendMessage(VOID); -BOOL WINAPI InsertMenuA(HMENU,UINT,UINT,UINT,LPCSTR); -BOOL WINAPI InsertMenuW(HMENU,UINT,UINT,UINT,LPCWSTR); -BOOL WINAPI InsertMenuItemA(HMENU,UINT,BOOL,LPCMENUITEMINFOA); -BOOL WINAPI InsertMenuItemW(HMENU,UINT,BOOL,LPCMENUITEMINFOW); -BOOL WINAPI IntersectRect(LPRECT,LPCRECT,LPCRECT); -BOOL WINAPI InvalidateRect(HWND,LPCRECT,BOOL); -BOOL WINAPI InvalidateRgn(HWND,HRGN,BOOL); -BOOL WINAPI InvertRect(HDC,LPCRECT); -BOOL WINAPI IsCharAlphaA(CHAR ch); -BOOL WINAPI IsCharAlphaNumericA(CHAR); -BOOL WINAPI IsCharAlphaNumericW(WCHAR); -BOOL WINAPI IsCharAlphaW(WCHAR); -BOOL WINAPI IsCharLowerA(CHAR); -BOOL WINAPI IsCharLowerW(WCHAR); -BOOL WINAPI IsCharUpperA(CHAR); -BOOL WINAPI IsCharUpperW(WCHAR); -BOOL WINAPI IsChild(HWND,HWND); -BOOL WINAPI IsClipboardFormatAvailable(UINT); -BOOL WINAPI IsDialogMessageA(HWND,LPMSG); -BOOL WINAPI IsDialogMessageW(HWND,LPMSG); -UINT WINAPI IsDlgButtonChecked(HWND,int); -BOOL WINAPI IsIconic(HWND); -BOOL WINAPI IsMenu(HMENU); -BOOL WINAPI IsRectEmpty(LPCRECT); -BOOL WINAPI IsWindow(HWND); -BOOL WINAPI IsWindowEnabled(HWND); -BOOL WINAPI IsWindowUnicode(HWND); -BOOL WINAPI IsWindowVisible(HWND); -BOOL WINAPI IsZoomed(HWND); -VOID WINAPI keybd_event(BYTE,BYTE,DWORD,DWORD); -BOOL WINAPI KillTimer(HWND,UINT); -HACCEL WINAPI LoadAcceleratorsA(HINSTANCE,LPCSTR); -HACCEL WINAPI LoadAcceleratorsW(HINSTANCE,LPCWSTR); -HBITMAP WINAPI LoadBitmapA(HINSTANCE,LPCSTR); -HBITMAP WINAPI LoadBitmapW(HINSTANCE,LPCWSTR); -HCURSOR WINAPI LoadCursorA(HINSTANCE,LPCSTR); -HCURSOR WINAPI LoadCursorFromFileA(LPCSTR); -HCURSOR WINAPI LoadCursorFromFileW(LPCWSTR); -HCURSOR WINAPI LoadCursorW(HINSTANCE,LPCWSTR); -HICON WINAPI LoadIconA(HINSTANCE,LPCSTR); -HICON WINAPI LoadIconW(HINSTANCE,LPCWSTR); -HANDLE WINAPI LoadImageA(HINSTANCE,LPCSTR,UINT,int,int,UINT); -HANDLE WINAPI LoadImageW(HINSTANCE,LPCWSTR,UINT,int,int,UINT); -HKL WINAPI LoadKeyboardLayoutA(LPCSTR,UINT); -HKL WINAPI LoadKeyboardLayoutW(LPCWSTR,UINT); -HMENU WINAPI LoadMenuA(HINSTANCE,LPCSTR); -HMENU WINAPI LoadMenuIndirectA(const MENUTEMPLATE*); -HMENU WINAPI LoadMenuIndirectW(const MENUTEMPLATE*); -HMENU WINAPI LoadMenuW(HINSTANCE,LPCWSTR); -int WINAPI LoadStringA(HINSTANCE,UINT,LPSTR,int); -int WINAPI LoadStringW(HINSTANCE,UINT,LPWSTR,int); -BOOL WINAPI LockWindowUpdate(HWND); -int WINAPI LookupIconIdFromDirectory(PBYTE,BOOL); -int WINAPI LookupIconIdFromDirectoryEx(PBYTE,BOOL,int,int,UINT); -BOOL WINAPI MapDialogRect(HWND,LPRECT); -UINT WINAPI MapVirtualKeyA(UINT,UINT); -UINT WINAPI MapVirtualKeyExA(UINT,UINT,HKL); -UINT WINAPI MapVirtualKeyExW(UINT,UINT,HKL); -UINT WINAPI MapVirtualKeyW(UINT,UINT); -int WINAPI MapWindowPoints(HWND,HWND,LPPOINT,UINT); -int WINAPI MenuItemFromPoint(HWND,HMENU,POINT); -BOOL WINAPI MessageBeep(UINT); -int WINAPI MessageBoxA(HWND,LPCSTR,LPCSTR,UINT); -int WINAPI MessageBoxW(HWND,LPCWSTR,LPCWSTR,UINT); -int WINAPI MessageBoxExA(HWND,LPCSTR,LPCSTR,UINT,WORD); -int WINAPI MessageBoxExW(HWND,LPCWSTR,LPCWSTR,UINT,WORD); -int WINAPI MessageBoxIndirectA(LPMSGBOXPARAMSA); -int WINAPI MessageBoxIndirectW(LPMSGBOXPARAMSW); -BOOL WINAPI ModifyMenuA(HMENU,UINT,UINT,UINT,LPCSTR); -BOOL WINAPI ModifyMenuW(HMENU,UINT,UINT,UINT,LPCWSTR); -void WINAPI mouse_event(DWORD,DWORD,DWORD,DWORD,DWORD); -BOOL WINAPI MoveWindow(HWND,int,int,int,int,BOOL); -DWORD WINAPI MsgWaitForMultipleObjects(DWORD,LPHANDLE,BOOL,DWORD,DWORD); -DWORD WINAPI MsgWaitForMultipleObjectsEx(DWORD,LPHANDLE,DWORD,DWORD,DWORD); -DWORD WINAPI OemKeyScan(WORD); -BOOL WINAPI OemToCharA(LPCSTR,LPSTR); -BOOL WINAPI OemToCharBuffA(LPCSTR,LPSTR,DWORD); -BOOL WINAPI OemToCharBuffW(LPCSTR,LPWSTR,DWORD); -BOOL WINAPI OemToCharW(LPCSTR,LPWSTR); -BOOL WINAPI OffsetRect(LPRECT,int,int); -BOOL WINAPI OpenClipboard(HWND); -HDESK WINAPI OpenDesktopA(LPSTR,DWORD,BOOL,DWORD); -HDESK WINAPI OpenDesktopW(LPWSTR,DWORD,BOOL,DWORD); -BOOL WINAPI OpenIcon(HWND); -HDESK WINAPI OpenInputDesktop(DWORD,BOOL,DWORD); -HWINSTA WINAPI OpenWindowStationA(LPSTR,BOOL,DWORD); -HWINSTA WINAPI OpenWindowStationW(LPWSTR,BOOL,DWORD); -BOOL WINAPI PaintDesktop(HDC); -BOOL WINAPI PeekMessageA(LPMSG,HWND,UINT,UINT,UINT); -BOOL WINAPI PeekMessageW(LPMSG,HWND,UINT,UINT,UINT); -#define PostAppMessageA(t,m,w,l) PostThreadMessageA((DWORD)t,m,w,l) -#define PostAppMessageW(t,m,w,l) PostThreadMessageW((DWORD)t,m,w,l) -BOOL WINAPI PostMessageA(HWND,UINT,WPARAM,LPARAM); -BOOL WINAPI PostMessageW(HWND,UINT,WPARAM,LPARAM); -void WINAPI PostQuitMessage(int); -BOOL WINAPI PostThreadMessageA(DWORD,UINT,WPARAM,LPARAM); -BOOL WINAPI PostThreadMessageW(DWORD,UINT,WPARAM,LPARAM); -BOOL WINAPI PtInRect(LPCRECT,POINT); -BOOL WINAPI RedrawWindow(HWND,LPCRECT,HRGN,UINT); -ATOM WINAPI RegisterClassA(const WNDCLASSA*); -ATOM WINAPI RegisterClassW(const WNDCLASSW*); -ATOM WINAPI RegisterClassExA(const WNDCLASSEXA*); -ATOM WINAPI RegisterClassExW(const WNDCLASSEXW*); -UINT WINAPI RegisterClipboardFormatA(LPCSTR); -UINT WINAPI RegisterClipboardFormatW(LPCWSTR); -BOOL WINAPI RegisterHotKey(HWND,int,UINT,UINT); -UINT WINAPI RegisterWindowMessageA(LPCSTR); -UINT WINAPI RegisterWindowMessageW(LPCWSTR); -BOOL WINAPI ReleaseCapture(void); -int WINAPI ReleaseDC(HWND,HDC); -BOOL WINAPI RemoveMenu(HMENU,UINT,UINT); -HANDLE WINAPI RemovePropA(HWND,LPCSTR); -HANDLE WINAPI RemovePropW(HWND,LPCWSTR); -BOOL WINAPI ReplyMessage(LRESULT); -BOOL WINAPI ScreenToClient(HWND,LPPOINT); -BOOL WINAPI ScrollDC(HDC,int,int,LPCRECT,LPCRECT,HRGN,LPRECT); -BOOL WINAPI ScrollWindow(HWND,int,int,LPCRECT,LPCRECT); -int WINAPI ScrollWindowEx(HWND,int,int,LPCRECT,LPCRECT,HRGN,LPRECT,UINT); -LONG WINAPI SendDlgItemMessageA(HWND,int,UINT,WPARAM,LPARAM); -LONG WINAPI SendDlgItemMessageW(HWND,int,UINT,WPARAM,LPARAM); -LRESULT WINAPI SendMessageA(HWND,UINT,WPARAM,LPARAM); -BOOL WINAPI SendMessageCallbackA(HWND,UINT,WPARAM,LPARAM,SENDASYNCPROC,DWORD); -BOOL WINAPI SendMessageCallbackW(HWND,UINT,WPARAM,LPARAM,SENDASYNCPROC,DWORD); -LRESULT WINAPI SendMessageTimeoutA(HWND,UINT,WPARAM,LPARAM,UINT,UINT,PDWORD); -LRESULT WINAPI SendMessageTimeoutW(HWND,UINT,WPARAM,LPARAM,UINT,UINT,PDWORD); -LRESULT WINAPI SendMessageW(HWND,UINT,WPARAM,LPARAM); -BOOL WINAPI SendNotifyMessageA(HWND,UINT,WPARAM,LPARAM); -BOOL WINAPI SendNotifyMessageW(HWND,UINT,WPARAM,LPARAM); -HWND WINAPI SetActiveWindow(HWND); -HWND WINAPI SetCapture(HWND hWnd); -BOOL WINAPI SetCaretBlinkTime(UINT); -BOOL WINAPI SetCaretPos(int,int); -DWORD WINAPI SetClassLongA(HWND,int,LONG); -DWORD WINAPI SetClassLongW(HWND,int,LONG); -WORD WINAPI SetClassWord(HWND,int,WORD); -HANDLE WINAPI SetClipboardData(UINT,HANDLE); -HWND WINAPI SetClipboardViewer(HWND); -HCURSOR WINAPI SetCursor(HCURSOR); -BOOL WINAPI SetCursorPos(int,int); -VOID WINAPI SetDebugErrorLevel(DWORD); -BOOL WINAPI SetDlgItemInt(HWND,int,UINT,BOOL); -BOOL WINAPI SetDlgItemTextA(HWND,int,LPCSTR); -BOOL WINAPI SetDlgItemTextW(HWND,int,LPCWSTR); -BOOL WINAPI SetDoubleClickTime(UINT); -HWND WINAPI SetFocus(HWND); -BOOL WINAPI SetForegroundWindow(HWND); -BOOL WINAPI SetKeyboardState(PBYTE); -BOOL WINAPI SetMenu(HWND,HMENU); -BOOL WINAPI SetMenuContextHelpId(HMENU,DWORD); -BOOL WINAPI SetMenuDefaultItem(HMENU,UINT,UINT); -BOOL WINAPI SetMenuInfo(HMENU,LPCMENUINFO); -BOOL WINAPI SetMenuItemBitmaps(HMENU,UINT,UINT,HBITMAP,HBITMAP); -BOOL WINAPI SetMenuItemInfoA(HMENU,UINT,BOOL,LPCMENUITEMINFOA); -BOOL WINAPI SetMenuItemInfoW( HMENU,UINT,BOOL,LPCMENUITEMINFOW); -LPARAM WINAPI SetMessageExtraInfo(LPARAM); -BOOL WINAPI SetMessageQueue(int); -HWND WINAPI SetParent(HWND,HWND); -BOOL WINAPI SetProcessWindowStation(HWINSTA); -BOOL WINAPI SetPropA(HWND,LPCSTR,HANDLE); -BOOL WINAPI SetPropW(HWND,LPCWSTR,HANDLE); -BOOL WINAPI SetRect(LPRECT,int,int,int,int); -BOOL WINAPI SetRectEmpty(LPRECT); -int WINAPI SetScrollInfo(HWND,int,LPCSCROLLINFO,BOOL); -int WINAPI SetScrollPos(HWND,int,int,BOOL); -BOOL WINAPI SetScrollRange(HWND,int,int,int,BOOL); -BOOL WINAPI SetSysColors(int,const INT *,const COLORREF *); -#define SetSysModalWindow(h) (NULL) -BOOL WINAPI SetSystemCursor(HCURSOR,DWORD); -BOOL WINAPI SetThreadDesktop(HDESK); -UINT WINAPI SetTimer(HWND,UINT,UINT,TIMERPROC); -BOOL WINAPI SetUserObjectInformationA(HANDLE,int,PVOID,DWORD); -BOOL WINAPI SetUserObjectInformationW(HANDLE,int,PVOID,DWORD); -BOOL WINAPI SetUserObjectSecurity(HANDLE,PSECURITY_INFORMATION,PSECURITY_DESCRIPTOR); -BOOL WINAPI SetWindowContextHelpId(HWND,DWORD); -LONG WINAPI SetWindowLongA(HWND,int,LONG); -LONG WINAPI SetWindowLongW(HWND,int,LONG); -#ifdef _WIN64 -LONG_PTR WINAPI SetWindowLongPtrA(HWND,int,LONG_PTR); -LONG_PTR WINAPI SetWindowLongPtrW(HWND,int,LONG_PTR); -#else -#define SetWindowLongPtrA SetWindowLongA -#define SetWindowLongPtrW SetWindowLongW + +#ifndef NOWINMESSAGES +#define CB_GETEDITSEL 0x0140 +#define CB_LIMITTEXT 0x0141 +#define CB_SETEDITSEL 0x0142 +#define CB_ADDSTRING 0x0143 +#define CB_DELETESTRING 0x0144 +#define CB_DIR 0x0145 +#define CB_GETCOUNT 0x0146 +#define CB_GETCURSEL 0x0147 +#define CB_GETLBTEXT 0x0148 +#define CB_GETLBTEXTLEN 0x0149 +#define CB_INSERTSTRING 0x014A +#define CB_RESETCONTENT 0x014B +#define CB_FINDSTRING 0x014C +#define CB_SELECTSTRING 0x014D +#define CB_SETCURSEL 0x014E +#define CB_SHOWDROPDOWN 0x014F +#define CB_GETITEMDATA 0x0150 +#define CB_SETITEMDATA 0x0151 +#define CB_GETDROPPEDCONTROLRECT 0x0152 +#define CB_SETITEMHEIGHT 0x0153 +#define CB_GETITEMHEIGHT 0x0154 +#define CB_SETEXTENDEDUI 0x0155 +#define CB_GETEXTENDEDUI 0x0156 +#define CB_GETDROPPEDSTATE 0x0157 +#define CB_FINDSTRINGEXACT 0x0158 +#define CB_SETLOCALE 0x0159 +#define CB_GETLOCALE 0x015A +#define CB_GETTOPINDEX 0x015b +#define CB_SETTOPINDEX 0x015c +#define CB_GETHORIZONTALEXTENT 0x015d +#define CB_SETHORIZONTALEXTENT 0x015e +#define CB_GETDROPPEDWIDTH 0x015f +#define CB_SETDROPPEDWIDTH 0x0160 +#define CB_INITSTORAGE 0x0161 +#if(_WIN32_WCE >= 0x0400) +#define CB_MULTIPLEADDSTRING 0x0163 #endif -BOOL WINAPI SetWindowPlacement(HWND hWnd,const WINDOWPLACEMENT*); -BOOL WINAPI SetWindowPos(HWND,HWND,int,int,int,int,UINT); -int WINAPI SetWindowRgn(HWND,HRGN,BOOL); -HOOKPROC WINAPI SetWindowsHookA(int,HOOKPROC); -HHOOK WINAPI SetWindowsHookExA(int,HOOKPROC,HINSTANCE,DWORD); -HHOOK WINAPI SetWindowsHookExW(int,HOOKPROC,HINSTANCE,DWORD); -BOOL WINAPI SetWindowTextA(HWND,LPCSTR); -BOOL WINAPI SetWindowTextW(HWND,LPCWSTR); -WORD WINAPI SetWindowWord(HWND,int,WORD); -BOOL WINAPI ShowCaret(HWND); -int WINAPI ShowCursor(BOOL); -BOOL WINAPI ShowOwnedPopups(HWND,BOOL); -BOOL WINAPI ShowScrollBar(HWND,int,BOOL); -BOOL WINAPI ShowWindow(HWND,int); -BOOL WINAPI ShowWindowAsync(HWND,int); -BOOL WINAPI SubtractRect(LPRECT,LPCRECT,LPCRECT); -BOOL WINAPI SwapMouseButton(BOOL); -BOOL WINAPI SwitchDesktop(HDESK); -BOOL WINAPI SystemParametersInfoA(UINT,UINT,PVOID,UINT); -BOOL WINAPI SystemParametersInfoW(UINT,UINT,PVOID,UINT); -LONG WINAPI TabbedTextOutA(HDC,int,int,LPCSTR,int,int,LPINT,int); -LONG WINAPI TabbedTextOutW(HDC,int,int,LPCWSTR,int,int,LPINT,int); -WORD WINAPI TileWindows(HWND,UINT,LPCRECT,UINT,const HWND *); -int WINAPI ToAscii(UINT,UINT,PBYTE,LPWORD,UINT); -int WINAPI ToAsciiEx(UINT,UINT,PBYTE,LPWORD,UINT,HKL); -int WINAPI ToUnicode(UINT,UINT,PBYTE,LPWSTR,int,UINT); -int WINAPI ToUnicodeEx(UINT,UINT,PBYTE,LPWSTR,int,UINT,HKL); -BOOL WINAPI TrackMouseEvent(LPTRACKMOUSEEVENT); -BOOL WINAPI TrackPopupMenu(HMENU,UINT,int,int,int,HWND,LPCRECT); -BOOL WINAPI TrackPopupMenuEx(HMENU,UINT,int,int,HWND,LPTPMPARAMS); -int WINAPI TranslateAcceleratorA(HWND,HACCEL,LPMSG); -int WINAPI TranslateAcceleratorW(HWND,HACCEL,LPMSG); -BOOL WINAPI TranslateMDISysAccel(HWND,LPMSG); -BOOL WINAPI TranslateMessage(const MSG*); -BOOL WINAPI UnhookWindowsHook(int,HOOKPROC); -BOOL WINAPI UnhookWindowsHookEx(HHOOK); -BOOL WINAPI UnionRect(LPRECT,LPCRECT,LPCRECT); -BOOL WINAPI UnloadKeyboardLayout(HKL); -BOOL WINAPI UnregisterClassA(LPCSTR,HINSTANCE); -BOOL WINAPI UnregisterClassW(LPCWSTR,HINSTANCE); -BOOL WINAPI UnregisterHotKey(HWND,int); -BOOL WINAPI UpdateWindow(HWND); -BOOL WINAPI ValidateRect(HWND,LPCRECT); -BOOL WINAPI ValidateRgn(HWND,HRGN); -SHORT WINAPI VkKeyScanA(CHAR); -SHORT WINAPI VkKeyScanExA(CHAR,HKL); -SHORT WINAPI VkKeyScanExW(WCHAR,HKL); -SHORT WINAPI VkKeyScanW(WCHAR); -DWORD WINAPI WaitForInputIdle(HANDLE,DWORD); -BOOL WINAPI WaitMessage(void); -HWND WINAPI WindowFromDC(HDC hDC); -HWND WINAPI WindowFromPoint(POINT); -UINT WINAPI WinExec(LPCSTR,UINT); -BOOL WINAPI WinHelpA(HWND,LPCSTR,UINT,DWORD); -BOOL WINAPI WinHelpW(HWND,LPCWSTR,UINT,DWORD); -int WINAPIV wsprintfA(LPSTR,LPCSTR,...); -int WINAPIV wsprintfW(LPWSTR,LPCWSTR,...); -int WINAPI wvsprintfA(LPSTR,LPCSTR,va_list arglist); -int WINAPI wvsprintfW(LPWSTR,LPCWSTR,va_list arglist); - -#ifdef UNICODE -#define EDITWORDBREAKPROC EDITWORDBREAKPROCW -#define PROPENUMPROC PROPENUMPROCW -#define PROPENUMPROCEX PROPENUMPROCEXW -#define DEKSTOPENUMPROC DEKSTOPENUMPROCW -#define WINSTAENUMPROC WINSTAENUMPROCW -#define PROPENUMPROC PROPENUMPROCW -#define PROPENUMPROCEX PROPENUMPROCEXW -#define MAKEINTRESOURCE MAKEINTRESOURCEW -typedef WNDCLASSW WNDCLASS,*LPWNDCLASS,*PWNDCLASS; -typedef WNDCLASSEXW WNDCLASSEX,*LPWNDCLASSEX,*PWNDCLASSEX; -typedef MENUITEMINFOW MENUITEMINFO,*LPMENUITEMINFO; -typedef LPCMENUITEMINFOW LPCMENUITEMINFO; -typedef MSGBOXPARAMSW MSGBOXPARAMS,*PMSGBOXPARAMS,*LPMSGBOXPARAMS; -typedef HIGHCONTRASTW HIGHCONTRAST,*LPHIGHCONTRAST; -typedef ICONMETRICSW ICONMETRICS,*LPICONMETRICS; -typedef NONCLIENTMETRICSW NONCLIENTMETRICS,*LPNONCLIENTMETRICS; -typedef SERIALKEYSW SERIALKEYS,*LPSERIALKEYS; -typedef SOUNDSENTRYW SOUNDSENTRY,*LPSOUNDSENTRY; -typedef CREATESTRUCTW CREATESTRUCT, *LPCREATESTRUCT; -typedef CBT_CREATEWNDW CBT_CREATEWND, *LPCBT_CREATEWND; -typedef MDICREATESTRUCTW MDICREATESTRUCT,*LPMDICREATESTRUCT; -typedef MULTIKEYHELPW MULTIKEYHELP,*PMULTIKEYHELP,*LPMULTIKEYHELP; -#define AppendMenu AppendMenuW -#define CallWindowProc CallWindowProcW -#define ChangeDisplaySettings ChangeDisplaySettingsW -#define ChangeMenu ChangeMenuW -#define CharLower CharLowerW -#define CharLowerBuff CharLowerBuffW -#define CharNext CharNextW -#define CharNextEx CharNextExW -#define CharPrev CharPrevW -#define CharPrevEx CharPrevExW -#define CharToOem CharToOemW -#define CharToOemBuff CharToOemBuffW -#define CharUpper CharUpperW -#define CharUpperBuff CharUpperBuffW -#define CopyAcceleratorTable CopyAcceleratorTableW -#define CreateAcceleratorTable CreateAcceleratorTableW -#define CreateDesktop CreateDesktopW -#define CreateDialog CreateDialogW -#define CreateDialogIndirect CreateDialogIndirectW -#define CreateDialogIndirectParam CreateDialogIndirectParamW -#define CreateDialogParam CreateDialogParamW -#define CreateMDIWindow CreateMDIWindowW -#define CreateWindow CreateWindowW -#define CreateWindowEx CreateWindowExW -#define CreateWindowStation CreateWindowStationW -#define DefDlgProc DefDlgProcW +#define CB_GETCOMBOBOXINFO 0x0164 +#define CB_MSGMAX 0x0165 +#endif + +#ifndef NOWINSTYLES + +#define SBS_HORZ 0x0000L +#define SBS_VERT 0x0001L +#define SBS_TOPALIGN 0x0002L +#define SBS_LEFTALIGN 0x0002L +#define SBS_BOTTOMALIGN 0x0004L +#define SBS_RIGHTALIGN 0x0004L +#define SBS_SIZEBOXTOPLEFTALIGN 0x0002L +#define SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004L +#define SBS_SIZEBOX 0x0008L +#define SBS_SIZEGRIP 0x0010L +#endif + +#ifndef NOWINMESSAGES +#define SBM_SETPOS 0x00E0 +#define SBM_GETPOS 0x00E1 +#define SBM_SETRANGE 0x00E2 +#define SBM_SETRANGEREDRAW 0x00E6 +#define SBM_GETRANGE 0x00E3 +#define SBM_ENABLE_ARROWS 0x00E4 +#define SBM_SETSCROLLINFO 0x00E9 +#define SBM_GETSCROLLINFO 0x00EA +#define SBM_GETSCROLLBARINFO 0x00EB + +#define SIF_RANGE 0x0001 +#define SIF_PAGE 0x0002 +#define SIF_POS 0x0004 +#define SIF_DISABLENOSCROLL 0x0008 +#define SIF_TRACKPOS 0x0010 +#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS) + + typedef struct tagSCROLLINFO { + UINT cbSize; + UINT fMask; + int nMin; + int nMax; + UINT nPage; + int nPos; + int nTrackPos; + } SCROLLINFO,*LPSCROLLINFO; + typedef SCROLLINFO CONST *LPCSCROLLINFO; + + WINUSERAPI int WINAPI SetScrollInfo(HWND hwnd,int nBar,LPCSCROLLINFO lpsi,WINBOOL redraw); + WINUSERAPI WINBOOL WINAPI GetScrollInfo(HWND hwnd,int nBar,LPSCROLLINFO lpsi); +#endif +#endif + +#ifndef NOMDI + +#define MDIS_ALLCHILDSTYLES 0x0001 + +#define MDITILE_VERTICAL 0x0000 +#define MDITILE_HORIZONTAL 0x0001 +#define MDITILE_SKIPDISABLED 0x0002 +#define MDITILE_ZORDER 0x0004 + + typedef struct tagMDICREATESTRUCTA { + LPCSTR szClass; + LPCSTR szTitle; + HANDLE hOwner; + int x; + int y; + int cx; + int cy; + DWORD style; + LPARAM lParam; + } MDICREATESTRUCTA,*LPMDICREATESTRUCTA; + + typedef struct tagMDICREATESTRUCTW { + LPCWSTR szClass; + LPCWSTR szTitle; + HANDLE hOwner; + int x; + int y; + int cx; + int cy; + DWORD style; + LPARAM lParam; + } MDICREATESTRUCTW,*LPMDICREATESTRUCTW; + +#ifdef UNICODE + typedef MDICREATESTRUCTW MDICREATESTRUCT; + typedef LPMDICREATESTRUCTW LPMDICREATESTRUCT; +#else + typedef MDICREATESTRUCTA MDICREATESTRUCT; + typedef LPMDICREATESTRUCTA LPMDICREATESTRUCT; +#endif + + typedef struct tagCLIENTCREATESTRUCT { + HANDLE hWindowMenu; + UINT idFirstChild; + } CLIENTCREATESTRUCT,*LPCLIENTCREATESTRUCT; + +#ifdef UNICODE #define DefFrameProc DefFrameProcW #define DefMDIChildProc DefMDIChildProcW -#define DefWindowProc DefWindowProcW -#define DialogBox DialogBoxW -#define DialogBoxIndirect DialogBoxIndirectW -#define DialogBoxIndirectParam DialogBoxIndirectParamW -#define DialogBoxParam DialogBoxParamW -#define DispatchMessage DispatchMessageW -#define DlgDirList DlgDirListW -#define DlgDirListComboBox DlgDirListComboBoxW -#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExW -#define DlgDirSelectEx DlgDirSelectExW -#define DrawState DrawStateW -#define DrawText DrawTextW -#define DrawTextEx DrawTextExW -#define EnumDesktops EnumDesktopsW -#define EnumDisplaySettings EnumDisplaySettingsW -#define EnumProps EnumPropsW -#define EnumPropsEx EnumPropsExW -#define EnumWindowStations EnumWindowStationsW -#define FindWindow FindWindowW -#define FindWindowEx FindWindowExW -#define GetClassInfo GetClassInfoW -#define GetClassInfoEx GetClassInfoExW -#define GetClassLong GetClassLongW -#define GetClassName GetClassNameW -#define GetClipboardFormatName GetClipboardFormatNameW -#define GetDlgItemText GetDlgItemTextW -#define GetKeyboardLayoutName GetKeyboardLayoutNameW -#define GetKeyNameText GetKeyNameTextW -#define GetMenuItemInfo GetMenuItemInfoW -#define GetMenuString GetMenuStringW -#define GetMessage GetMessageW -#define GetMonitorInfo GetMonitorInfoW -#define GetProp GetPropW -#define GetTabbedTextExtent GetTabbedTextExtentW -#define GetUserObjectInformation GetUserObjectInformationW -#define GetWindowLong GetWindowLongW -#define GetWindowLongPtr GetWindowLongPtrW -#define GetWindowText GetWindowTextW -#define GetWindowTextLength GetWindowTextLengthW -#define GetAltTabInfo GetAltTabInfoW -#define GetWindowModuleFileName GetWindowModuleFileNameW -#define GrayString GrayStringW -#define InsertMenu InsertMenuW -#define InsertMenuItem InsertMenuItemW -#define IsCharAlpha IsCharAlphaW -#define IsCharAlphaNumeric IsCharAlphaNumericW -#define IsCharLower IsCharLowerW -#define IsCharUpper IsCharUpperW -#define IsDialogMessage IsDialogMessageW -#define LoadAccelerators LoadAcceleratorsW -#define LoadBitmap LoadBitmapW -#define LoadCursor LoadCursorW -#define LoadCursorFromFile LoadCursorFromFileW -#define LoadIcon LoadIconW -#define LoadImage LoadImageW -#define LoadKeyboardLayout LoadKeyboardLayoutW -#define LoadMenu LoadMenuW -#define LoadMenuIndirect LoadMenuIndirectW -#define LoadString LoadStringW -#define MapVirtualKey MapVirtualKeyW -#define MapVirtualKeyEx MapVirtualKeyExW -#define MessageBox MessageBoxW -#define MessageBoxEx MessageBoxExW -#define MessageBoxIndirect MessageBoxIndirectW -#define ModifyMenu ModifyMenuW -#define OemToChar OemToCharW -#define OemToCharBuff OemToCharBuffW -#define OpenDesktop OpenDesktopW -#define OpenWindowStation OpenWindowStationW -#define PeekMessage PeekMessageW -#define PostAppMessage PostAppMessageW -#define PostMessage PostMessageW -#define PostThreadMessage PostThreadMessageW -#define RegisterClass RegisterClassW -#define RegisterClassEx RegisterClassExW -#define RegisterClipboardFormat RegisterClipboardFormatW -#define RegisterWindowMessage RegisterWindowMessageW -#define RemoveProp RemovePropW -#define SendDlgItemMessage SendDlgItemMessageW -#define SendMessage SendMessageW -#define SendMessageCallback SendMessageCallbackW -#define SendMessageTimeout SendMessageTimeoutW -#define SendNotifyMessage SendNotifyMessageW -#define SetClassLong SetClassLongW -#define SetDlgItemText SetDlgItemTextW -#define SetMenuItemInfo SetMenuItemInfoW -#define SetProp SetPropW -#define SetUserObjectInformation SetUserObjectInformationW -#define SetWindowLong SetWindowLongW -#define SetWindowLongPtr SetWindowLongPtrW -#define SetWindowsHook SetWindowsHookW -#define SetWindowsHookEx SetWindowsHookExW -#define SetWindowText SetWindowTextW -#define SystemParametersInfo SystemParametersInfoW -#define TabbedTextOut TabbedTextOutW -#define TranslateAccelerator TranslateAcceleratorW -#define UnregisterClass UnregisterClassW -#define VkKeyScan VkKeyScanW -#define VkKeyScanEx VkKeyScanExW -#define WinHelp WinHelpW -#define wsprintf wsprintfW -#define wvsprintf wvsprintfW +#define CreateMDIWindow CreateMDIWindowW #else -#define EDITWORDBREAKPROC EDITWORDBREAKPROCA -#define PROPENUMPROC PROPENUMPROCA -#define PROPENUMPROCEX PROPENUMPROCEXA -#define DEKSTOPENUMPROC DEKSTOPENUMPROCA -#define WINSTAENUMPROC WINSTAENUMPROCA -#define PROPENUMPROC PROPENUMPROCA -#define PROPENUMPROCEX PROPENUMPROCEXA -#define MAKEINTRESOURCE MAKEINTRESOURCEA -typedef WNDCLASSA WNDCLASS,*LPWNDCLASS,*PWNDCLASS; -typedef WNDCLASSEXA WNDCLASSEX,*LPWNDCLASSEX,*PWNDCLASSEX; -typedef MENUITEMINFOA MENUITEMINFO,*LPMENUITEMINFO; -typedef LPCMENUITEMINFOA LPCMENUITEMINFO; -typedef MSGBOXPARAMSA MSGBOXPARAMS,*PMSGBOXPARAMS,*LPMSGBOXPARAMS; -typedef HIGHCONTRASTA HIGHCONTRAST,*LPHIGHCONTRAST; -typedef ICONMETRICSA ICONMETRICS,*LPICONMETRICS; -typedef NONCLIENTMETRICSA NONCLIENTMETRICS,*LPNONCLIENTMETRICS; -typedef SERIALKEYSA SERIALKEYS,*LPSERIALKEYS; -typedef SOUNDSENTRYA SOUNDSENTRY,*LPSOUNDSENTRY; -typedef CREATESTRUCTA CREATESTRUCT, *LPCREATESTRUCT; -typedef CBT_CREATEWNDA CBT_CREATEWND, *LPCBT_CREATEWND; -typedef MDICREATESTRUCTA MDICREATESTRUCT,*LPMDICREATESTRUCT; -typedef MULTIKEYHELPA MULTIKEYHELP,*PMULTIKEYHELP,*LPMULTIKEYHELP; -#define AppendMenu AppendMenuA -#define CallWindowProc CallWindowProcA -#define ChangeDisplaySettings ChangeDisplaySettingsA -#define ChangeMenu ChangeMenuA -#define CharLower CharLowerA -#define CharLowerBuff CharLowerBuffA -#define CharNext CharNextA -#define CharNextEx CharNextExA -#define CharPrev CharPrevA -#define CharPrevEx CharPrevExA -#define CharToOem CharToOemA -#define CharToOemBuff CharToOemBuffA -#define CharUpper CharUpperA -#define CharUpperBuff CharUpperBuffA -#define CopyAcceleratorTable CopyAcceleratorTableA -#define CreateAcceleratorTable CreateAcceleratorTableA -#define CreateDesktop CreateDesktopA -#define CreateDialog CreateDialogA -#define CreateDialogIndirect CreateDialogIndirectA -#define CreateDialogIndirectParam CreateDialogIndirectParamA -#define CreateDialogParam CreateDialogParamA -#define CreateMDIWindow CreateMDIWindowA -#define CreateWindow CreateWindowA -#define CreateWindowEx CreateWindowExA -#define CreateWindowStation CreateWindowStationA -#define DefDlgProc DefDlgProcA #define DefFrameProc DefFrameProcA #define DefMDIChildProc DefMDIChildProcA -#define DefWindowProc DefWindowProcA -#define DialogBox DialogBoxA -#define DialogBoxIndirect DialogBoxIndirectA -#define DialogBoxIndirectParam DialogBoxIndirectParamA -#define DialogBoxParam DialogBoxParamA -#define DispatchMessage DispatchMessageA -#define DlgDirList DlgDirListA -#define DlgDirListComboBox DlgDirListComboBoxA -#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExA -#define DlgDirSelectEx DlgDirSelectExA -#define DrawState DrawStateA -#define DrawText DrawTextA -#define DrawTextEx DrawTextExA -#define EnumDesktops EnumDesktopsA +#define CreateMDIWindow CreateMDIWindowA +#endif + + WINUSERAPI LRESULT WINAPI DefFrameProcA(HWND hWnd,HWND hWndMDIClient,UINT uMsg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI DefFrameProcW(HWND hWnd,HWND hWndMDIClient,UINT uMsg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI DefMDIChildProcA(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); + WINUSERAPI LRESULT WINAPI DefMDIChildProcW(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); + +#ifndef NOMSG + WINUSERAPI WINBOOL WINAPI TranslateMDISysAccel(HWND hWndClient,LPMSG lpMsg); +#endif + + WINUSERAPI UINT WINAPI ArrangeIconicWindows(HWND hWnd); + WINUSERAPI HWND WINAPI CreateMDIWindowA(LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HINSTANCE hInstance,LPARAM lParam); + WINUSERAPI HWND WINAPI CreateMDIWindowW(LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HINSTANCE hInstance,LPARAM lParam); + WINUSERAPI WORD WINAPI TileWindows(HWND hwndParent,UINT wHow,CONST RECT *lpRect,UINT cKids,const HWND *lpKids); + WINUSERAPI WORD WINAPI CascadeWindows(HWND hwndParent,UINT wHow,CONST RECT *lpRect,UINT cKids,const HWND *lpKids); +#endif +#endif + +#ifndef NOHELP + + typedef DWORD HELPPOLY; + typedef struct tagMULTIKEYHELPA { + DWORD mkSize; + CHAR mkKeylist; + CHAR szKeyphrase[1]; + } MULTIKEYHELPA,*PMULTIKEYHELPA,*LPMULTIKEYHELPA; + + typedef struct tagMULTIKEYHELPW { + DWORD mkSize; + WCHAR mkKeylist; + WCHAR szKeyphrase[1]; + } MULTIKEYHELPW,*PMULTIKEYHELPW,*LPMULTIKEYHELPW; + +#ifdef UNICODE + typedef MULTIKEYHELPW MULTIKEYHELP; + typedef PMULTIKEYHELPW PMULTIKEYHELP; + typedef LPMULTIKEYHELPW LPMULTIKEYHELP; +#else + typedef MULTIKEYHELPA MULTIKEYHELP; + typedef PMULTIKEYHELPA PMULTIKEYHELP; + typedef LPMULTIKEYHELPA LPMULTIKEYHELP; +#endif + + typedef struct tagHELPWININFOA { + int wStructSize; + int x; + int y; + int dx; + int dy; + int wMax; + CHAR rgchMember[2]; + } HELPWININFOA,*PHELPWININFOA,*LPHELPWININFOA; + + typedef struct tagHELPWININFOW { + int wStructSize; + int x; + int y; + int dx; + int dy; + int wMax; + WCHAR rgchMember[2]; + } HELPWININFOW,*PHELPWININFOW,*LPHELPWININFOW; + +#ifdef UNICODE + typedef HELPWININFOW HELPWININFO; + typedef PHELPWININFOW PHELPWININFO; + typedef LPHELPWININFOW LPHELPWININFO; +#else + typedef HELPWININFOA HELPWININFO; + typedef PHELPWININFOA PHELPWININFO; + typedef LPHELPWININFOA LPHELPWININFO; +#endif + +#define HELP_CONTEXT 0x0001L +#define HELP_QUIT 0x0002L +#define HELP_INDEX 0x0003L +#define HELP_CONTENTS 0x0003L +#define HELP_HELPONHELP 0x0004L +#define HELP_SETINDEX 0x0005L +#define HELP_SETCONTENTS 0x0005L +#define HELP_CONTEXTPOPUP 0x0008L +#define HELP_FORCEFILE 0x0009L +#define HELP_KEY 0x0101L +#define HELP_COMMAND 0x0102L +#define HELP_PARTIALKEY 0x0105L +#define HELP_MULTIKEY 0x0201L +#define HELP_SETWINPOS 0x0203L +#define HELP_CONTEXTMENU 0x000a +#define HELP_FINDER 0x000b +#define HELP_WM_HELP 0x000c +#define HELP_SETPOPUP_POS 0x000d + +#define HELP_TCARD 0x8000 +#define HELP_TCARD_DATA 0x0010 +#define HELP_TCARD_OTHER_CALLER 0x0011 + +#define IDH_NO_HELP 28440 +#define IDH_MISSING_CONTEXT 28441 +#define IDH_GENERIC_HELP_BUTTON 28442 +#define IDH_OK 28443 +#define IDH_CANCEL 28444 +#define IDH_HELP 28445 + +#ifdef UNICODE +#define WinHelp WinHelpW +#else +#define WinHelp WinHelpA +#endif + + WINUSERAPI WINBOOL WINAPI WinHelpA(HWND hWndMain,LPCSTR lpszHelp,UINT uCommand,ULONG_PTR dwData); + WINUSERAPI WINBOOL WINAPI WinHelpW(HWND hWndMain,LPCWSTR lpszHelp,UINT uCommand,ULONG_PTR dwData); +#endif + +#define GR_GDIOBJECTS 0 +#define GR_USEROBJECTS 1 + + WINUSERAPI DWORD WINAPI GetGuiResources(HANDLE hProcess,DWORD uiFlags); + +#ifndef NOSYSPARAMSINFO + +#define SPI_GETBEEP 0x0001 +#define SPI_SETBEEP 0x0002 +#define SPI_GETMOUSE 0x0003 +#define SPI_SETMOUSE 0x0004 +#define SPI_GETBORDER 0x0005 +#define SPI_SETBORDER 0x0006 +#define SPI_GETKEYBOARDSPEED 0x000A +#define SPI_SETKEYBOARDSPEED 0x000B +#define SPI_LANGDRIVER 0x000C +#define SPI_ICONHORIZONTALSPACING 0x000D +#define SPI_GETSCREENSAVETIMEOUT 0x000E +#define SPI_SETSCREENSAVETIMEOUT 0x000F +#define SPI_GETSCREENSAVEACTIVE 0x0010 +#define SPI_SETSCREENSAVEACTIVE 0x0011 +#define SPI_GETGRIDGRANULARITY 0x0012 +#define SPI_SETGRIDGRANULARITY 0x0013 +#define SPI_SETDESKWALLPAPER 0x0014 +#define SPI_SETDESKPATTERN 0x0015 +#define SPI_GETKEYBOARDDELAY 0x0016 +#define SPI_SETKEYBOARDDELAY 0x0017 +#define SPI_ICONVERTICALSPACING 0x0018 +#define SPI_GETICONTITLEWRAP 0x0019 +#define SPI_SETICONTITLEWRAP 0x001A +#define SPI_GETMENUDROPALIGNMENT 0x001B +#define SPI_SETMENUDROPALIGNMENT 0x001C +#define SPI_SETDOUBLECLKWIDTH 0x001D +#define SPI_SETDOUBLECLKHEIGHT 0x001E +#define SPI_GETICONTITLELOGFONT 0x001F +#define SPI_SETDOUBLECLICKTIME 0x0020 +#define SPI_SETMOUSEBUTTONSWAP 0x0021 +#define SPI_SETICONTITLELOGFONT 0x0022 +#define SPI_GETFASTTASKSWITCH 0x0023 +#define SPI_SETFASTTASKSWITCH 0x0024 +#define SPI_SETDRAGFULLWINDOWS 0x0025 +#define SPI_GETDRAGFULLWINDOWS 0x0026 +#define SPI_GETNONCLIENTMETRICS 0x0029 +#define SPI_SETNONCLIENTMETRICS 0x002A +#define SPI_GETMINIMIZEDMETRICS 0x002B +#define SPI_SETMINIMIZEDMETRICS 0x002C +#define SPI_GETICONMETRICS 0x002D +#define SPI_SETICONMETRICS 0x002E +#define SPI_SETWORKAREA 0x002F +#define SPI_GETWORKAREA 0x0030 +#define SPI_SETPENWINDOWS 0x0031 + +#define SPI_GETHIGHCONTRAST 0x0042 +#define SPI_SETHIGHCONTRAST 0x0043 +#define SPI_GETKEYBOARDPREF 0x0044 +#define SPI_SETKEYBOARDPREF 0x0045 +#define SPI_GETSCREENREADER 0x0046 +#define SPI_SETSCREENREADER 0x0047 +#define SPI_GETANIMATION 0x0048 +#define SPI_SETANIMATION 0x0049 +#define SPI_GETFONTSMOOTHING 0x004A +#define SPI_SETFONTSMOOTHING 0x004B +#define SPI_SETDRAGWIDTH 0x004C +#define SPI_SETDRAGHEIGHT 0x004D +#define SPI_SETHANDHELD 0x004E +#define SPI_GETLOWPOWERTIMEOUT 0x004F +#define SPI_GETPOWEROFFTIMEOUT 0x0050 +#define SPI_SETLOWPOWERTIMEOUT 0x0051 +#define SPI_SETPOWEROFFTIMEOUT 0x0052 +#define SPI_GETLOWPOWERACTIVE 0x0053 +#define SPI_GETPOWEROFFACTIVE 0x0054 +#define SPI_SETLOWPOWERACTIVE 0x0055 +#define SPI_SETPOWEROFFACTIVE 0x0056 +#define SPI_SETCURSORS 0x0057 +#define SPI_SETICONS 0x0058 +#define SPI_GETDEFAULTINPUTLANG 0x0059 +#define SPI_SETDEFAULTINPUTLANG 0x005A +#define SPI_SETLANGTOGGLE 0x005B +#define SPI_GETWINDOWSEXTENSION 0x005C +#define SPI_SETMOUSETRAILS 0x005D +#define SPI_GETMOUSETRAILS 0x005E +#define SPI_SETSCREENSAVERRUNNING 0x0061 +#define SPI_SCREENSAVERRUNNING SPI_SETSCREENSAVERRUNNING +#define SPI_GETFILTERKEYS 0x0032 +#define SPI_SETFILTERKEYS 0x0033 +#define SPI_GETTOGGLEKEYS 0x0034 +#define SPI_SETTOGGLEKEYS 0x0035 +#define SPI_GETMOUSEKEYS 0x0036 +#define SPI_SETMOUSEKEYS 0x0037 +#define SPI_GETSHOWSOUNDS 0x0038 +#define SPI_SETSHOWSOUNDS 0x0039 +#define SPI_GETSTICKYKEYS 0x003A +#define SPI_SETSTICKYKEYS 0x003B +#define SPI_GETACCESSTIMEOUT 0x003C +#define SPI_SETACCESSTIMEOUT 0x003D +#define SPI_GETSERIALKEYS 0x003E +#define SPI_SETSERIALKEYS 0x003F +#define SPI_GETSOUNDSENTRY 0x0040 +#define SPI_SETSOUNDSENTRY 0x0041 +#define SPI_GETSNAPTODEFBUTTON 0x005F +#define SPI_SETSNAPTODEFBUTTON 0x0060 +#define SPI_GETMOUSEHOVERWIDTH 0x0062 +#define SPI_SETMOUSEHOVERWIDTH 0x0063 +#define SPI_GETMOUSEHOVERHEIGHT 0x0064 +#define SPI_SETMOUSEHOVERHEIGHT 0x0065 +#define SPI_GETMOUSEHOVERTIME 0x0066 +#define SPI_SETMOUSEHOVERTIME 0x0067 +#define SPI_GETWHEELSCROLLLINES 0x0068 +#define SPI_SETWHEELSCROLLLINES 0x0069 +#define SPI_GETMENUSHOWDELAY 0x006A +#define SPI_SETMENUSHOWDELAY 0x006B +#define SPI_GETSHOWIMEUI 0x006E +#define SPI_SETSHOWIMEUI 0x006F +#define SPI_GETMOUSESPEED 0x0070 +#define SPI_SETMOUSESPEED 0x0071 +#define SPI_GETSCREENSAVERRUNNING 0x0072 +#define SPI_GETDESKWALLPAPER 0x0073 + +#define SPI_GETACTIVEWINDOWTRACKING 0x1000 +#define SPI_SETACTIVEWINDOWTRACKING 0x1001 +#define SPI_GETMENUANIMATION 0x1002 +#define SPI_SETMENUANIMATION 0x1003 +#define SPI_GETCOMBOBOXANIMATION 0x1004 +#define SPI_SETCOMBOBOXANIMATION 0x1005 +#define SPI_GETLISTBOXSMOOTHSCROLLING 0x1006 +#define SPI_SETLISTBOXSMOOTHSCROLLING 0x1007 +#define SPI_GETGRADIENTCAPTIONS 0x1008 +#define SPI_SETGRADIENTCAPTIONS 0x1009 +#define SPI_GETKEYBOARDCUES 0x100A +#define SPI_SETKEYBOARDCUES 0x100B +#define SPI_GETMENUUNDERLINES SPI_GETKEYBOARDCUES +#define SPI_SETMENUUNDERLINES SPI_SETKEYBOARDCUES +#define SPI_GETACTIVEWNDTRKZORDER 0x100C +#define SPI_SETACTIVEWNDTRKZORDER 0x100D +#define SPI_GETHOTTRACKING 0x100E +#define SPI_SETHOTTRACKING 0x100F +#define SPI_GETMENUFADE 0x1012 +#define SPI_SETMENUFADE 0x1013 +#define SPI_GETSELECTIONFADE 0x1014 +#define SPI_SETSELECTIONFADE 0x1015 +#define SPI_GETTOOLTIPANIMATION 0x1016 +#define SPI_SETTOOLTIPANIMATION 0x1017 +#define SPI_GETTOOLTIPFADE 0x1018 +#define SPI_SETTOOLTIPFADE 0x1019 +#define SPI_GETCURSORSHADOW 0x101A +#define SPI_SETCURSORSHADOW 0x101B +#define SPI_GETMOUSESONAR 0x101C +#define SPI_SETMOUSESONAR 0x101D +#define SPI_GETMOUSECLICKLOCK 0x101E +#define SPI_SETMOUSECLICKLOCK 0x101F +#define SPI_GETMOUSEVANISH 0x1020 +#define SPI_SETMOUSEVANISH 0x1021 +#define SPI_GETFLATMENU 0x1022 +#define SPI_SETFLATMENU 0x1023 +#define SPI_GETDROPSHADOW 0x1024 +#define SPI_SETDROPSHADOW 0x1025 +#define SPI_GETBLOCKSENDINPUTRESETS 0x1026 +#define SPI_SETBLOCKSENDINPUTRESETS 0x1027 +#define SPI_GETUIEFFECTS 0x103E +#define SPI_SETUIEFFECTS 0x103F +#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 +#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 +#define SPI_GETACTIVEWNDTRKTIMEOUT 0x2002 +#define SPI_SETACTIVEWNDTRKTIMEOUT 0x2003 +#define SPI_GETFOREGROUNDFLASHCOUNT 0x2004 +#define SPI_SETFOREGROUNDFLASHCOUNT 0x2005 +#define SPI_GETCARETWIDTH 0x2006 +#define SPI_SETCARETWIDTH 0x2007 +#define SPI_GETMOUSECLICKLOCKTIME 0x2008 +#define SPI_SETMOUSECLICKLOCKTIME 0x2009 +#define SPI_GETFONTSMOOTHINGTYPE 0x200A +#define SPI_SETFONTSMOOTHINGTYPE 0x200B + +#define FE_FONTSMOOTHINGSTANDARD 0x0001 +#define FE_FONTSMOOTHINGCLEARTYPE 0x0002 +#define FE_FONTSMOOTHINGDOCKING 0x8000 + +#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C +#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D +#define SPI_GETFOCUSBORDERWIDTH 0x200E +#define SPI_SETFOCUSBORDERWIDTH 0x200F +#define SPI_GETFOCUSBORDERHEIGHT 0x2010 +#define SPI_SETFOCUSBORDERHEIGHT 0x2011 +#define SPI_GETFONTSMOOTHINGORIENTATION 0x2012 +#define SPI_SETFONTSMOOTHINGORIENTATION 0x2013 + +#define FE_FONTSMOOTHINGORIENTATIONBGR 0x0000 +#define FE_FONTSMOOTHINGORIENTATIONRGB 0x0001 + +#define SPIF_UPDATEINIFILE 0x0001 +#define SPIF_SENDWININICHANGE 0x0002 +#define SPIF_SENDCHANGE SPIF_SENDWININICHANGE + +#define METRICS_USEDEFAULT -1 +#ifdef _WINGDI_ +#ifndef NOGDI + typedef struct tagNONCLIENTMETRICSA { + UINT cbSize; + int iBorderWidth; + int iScrollWidth; + int iScrollHeight; + int iCaptionWidth; + int iCaptionHeight; + LOGFONTA lfCaptionFont; + int iSmCaptionWidth; + int iSmCaptionHeight; + LOGFONTA lfSmCaptionFont; + int iMenuWidth; + int iMenuHeight; + LOGFONTA lfMenuFont; + LOGFONTA lfStatusFont; + LOGFONTA lfMessageFont; + } NONCLIENTMETRICSA,*PNONCLIENTMETRICSA,*LPNONCLIENTMETRICSA; + + typedef struct tagNONCLIENTMETRICSW { + UINT cbSize; + int iBorderWidth; + int iScrollWidth; + int iScrollHeight; + int iCaptionWidth; + int iCaptionHeight; + LOGFONTW lfCaptionFont; + int iSmCaptionWidth; + int iSmCaptionHeight; + LOGFONTW lfSmCaptionFont; + int iMenuWidth; + int iMenuHeight; + LOGFONTW lfMenuFont; + LOGFONTW lfStatusFont; + LOGFONTW lfMessageFont; + } NONCLIENTMETRICSW,*PNONCLIENTMETRICSW,*LPNONCLIENTMETRICSW; + +#ifdef UNICODE + typedef NONCLIENTMETRICSW NONCLIENTMETRICS; + typedef PNONCLIENTMETRICSW PNONCLIENTMETRICS; + typedef LPNONCLIENTMETRICSW LPNONCLIENTMETRICS; +#else + typedef NONCLIENTMETRICSA NONCLIENTMETRICS; + typedef PNONCLIENTMETRICSA PNONCLIENTMETRICS; + typedef LPNONCLIENTMETRICSA LPNONCLIENTMETRICS; +#endif +#endif +#endif + +#define ARW_BOTTOMLEFT 0x0000L +#define ARW_BOTTOMRIGHT 0x0001L +#define ARW_TOPLEFT 0x0002L +#define ARW_TOPRIGHT 0x0003L +#define ARW_STARTMASK 0x0003L +#define ARW_STARTRIGHT 0x0001L +#define ARW_STARTTOP 0x0002L + +#define ARW_LEFT 0x0000L +#define ARW_RIGHT 0x0000L +#define ARW_UP 0x0004L +#define ARW_DOWN 0x0004L +#define ARW_HIDE 0x0008L + + typedef struct tagMINIMIZEDMETRICS { + UINT cbSize; + int iWidth; + int iHorzGap; + int iVertGap; + int iArrange; + } MINIMIZEDMETRICS,*PMINIMIZEDMETRICS,*LPMINIMIZEDMETRICS; + +#ifdef _WINGDI_ +#ifndef NOGDI + typedef struct tagICONMETRICSA { + UINT cbSize; + int iHorzSpacing; + int iVertSpacing; + int iTitleWrap; + LOGFONTA lfFont; + } ICONMETRICSA,*PICONMETRICSA,*LPICONMETRICSA; + + typedef struct tagICONMETRICSW { + UINT cbSize; + int iHorzSpacing; + int iVertSpacing; + int iTitleWrap; + LOGFONTW lfFont; + } ICONMETRICSW,*PICONMETRICSW,*LPICONMETRICSW; + +#ifdef UNICODE + typedef ICONMETRICSW ICONMETRICS; + typedef PICONMETRICSW PICONMETRICS; + typedef LPICONMETRICSW LPICONMETRICS; +#else + typedef ICONMETRICSA ICONMETRICS; + typedef PICONMETRICSA PICONMETRICS; + typedef LPICONMETRICSA LPICONMETRICS; +#endif +#endif +#endif + + typedef struct tagANIMATIONINFO { + UINT cbSize; + int iMinAnimate; + } ANIMATIONINFO,*LPANIMATIONINFO; + + typedef struct tagSERIALKEYSA { + UINT cbSize; + DWORD dwFlags; + LPSTR lpszActivePort; + LPSTR lpszPort; + UINT iBaudRate; + UINT iPortState; + UINT iActive; + } SERIALKEYSA,*LPSERIALKEYSA; + + typedef struct tagSERIALKEYSW { + UINT cbSize; + DWORD dwFlags; + LPWSTR lpszActivePort; + LPWSTR lpszPort; + UINT iBaudRate; + UINT iPortState; + UINT iActive; + } SERIALKEYSW,*LPSERIALKEYSW; + +#ifdef UNICODE + typedef SERIALKEYSW SERIALKEYS; + typedef LPSERIALKEYSW LPSERIALKEYS; +#else + typedef SERIALKEYSA SERIALKEYS; + typedef LPSERIALKEYSA LPSERIALKEYS; +#endif + +#define SERKF_SERIALKEYSON 0x00000001 +#define SERKF_AVAILABLE 0x00000002 +#define SERKF_INDICATOR 0x00000004 + + typedef struct tagHIGHCONTRASTA { + UINT cbSize; + DWORD dwFlags; + LPSTR lpszDefaultScheme; + } HIGHCONTRASTA,*LPHIGHCONTRASTA; + + typedef struct tagHIGHCONTRASTW { + UINT cbSize; + DWORD dwFlags; + LPWSTR lpszDefaultScheme; + } HIGHCONTRASTW,*LPHIGHCONTRASTW; + +#ifdef UNICODE + typedef HIGHCONTRASTW HIGHCONTRAST; + typedef LPHIGHCONTRASTW LPHIGHCONTRAST; +#else + typedef HIGHCONTRASTA HIGHCONTRAST; + typedef LPHIGHCONTRASTA LPHIGHCONTRAST; +#endif + +#define HCF_HIGHCONTRASTON 0x00000001 +#define HCF_AVAILABLE 0x00000002 +#define HCF_HOTKEYACTIVE 0x00000004 +#define HCF_CONFIRMHOTKEY 0x00000008 +#define HCF_HOTKEYSOUND 0x00000010 +#define HCF_INDICATOR 0x00000020 +#define HCF_HOTKEYAVAILABLE 0x00000040 +#define HCF_LOGONDESKTOP 0x00000100 +#define HCF_DEFAULTDESKTOP 0x00000200 + +#define CDS_UPDATEREGISTRY 0x00000001 +#define CDS_TEST 0x00000002 +#define CDS_FULLSCREEN 0x00000004 +#define CDS_GLOBAL 0x00000008 +#define CDS_SET_PRIMARY 0x00000010 +#define CDS_VIDEOPARAMETERS 0x00000020 +#define CDS_RESET 0x40000000 +#define CDS_NORESET 0x10000000 + +//gr #include <tvout.h> + +#define DISP_CHANGE_SUCCESSFUL 0 +#define DISP_CHANGE_RESTART 1 +#define DISP_CHANGE_FAILED -1 +#define DISP_CHANGE_BADMODE -2 +#define DISP_CHANGE_NOTUPDATED -3 +#define DISP_CHANGE_BADFLAGS -4 +#define DISP_CHANGE_BADPARAM -5 +#define DISP_CHANGE_BADDUALVIEW -6 + +#ifdef _WINGDI_ +#ifndef NOGDI + +#ifdef UNICODE +#define ChangeDisplaySettings ChangeDisplaySettingsW +#define ChangeDisplaySettingsEx ChangeDisplaySettingsExW +#define EnumDisplaySettings EnumDisplaySettingsW +#define EnumDisplaySettingsEx EnumDisplaySettingsExW +#define EnumDisplayDevices EnumDisplayDevicesW +#else +#define ChangeDisplaySettings ChangeDisplaySettingsA +#define ChangeDisplaySettingsEx ChangeDisplaySettingsExA #define EnumDisplaySettings EnumDisplaySettingsA -#define EnumProps EnumPropsA -#define EnumPropsEx EnumPropsExA -#define EnumWindowStations EnumWindowStationsA -#define FindWindow FindWindowA -#define FindWindowEx FindWindowExA -#define GetClassInfo GetClassInfoA -#define GetClassInfoEx GetClassInfoExA -#define GetClassLong GetClassLongA -#define GetClassName GetClassNameA -#define GetClipboardFormatName GetClipboardFormatNameA -#define GetDlgItemText GetDlgItemTextA -#define GetKeyboardLayoutName GetKeyboardLayoutNameA -#define GetKeyNameText GetKeyNameTextA -#define GetMenuItemInfo GetMenuItemInfoA -#define GetMenuString GetMenuStringA -#define GetMessage GetMessageA -#define GetMonitorInfo GetMonitorInfoA -#define GetProp GetPropA -#define GetTabbedTextExtent GetTabbedTextExtentA -#define GetUserObjectInformation GetUserObjectInformationA -#define GetWindowLong GetWindowLongA -#define GetWindowLongPtr GetWindowLongPtrA -#define GetWindowText GetWindowTextA -#define GetWindowTextLength GetWindowTextLengthA -#define GetAltTabInfo GetAltTabInfoA -#define GetWindowModuleFileName GetWindowModuleFileNameA -#define GrayString GrayStringA -#define InsertMenu InsertMenuA -#define InsertMenuItem InsertMenuItemA -#define IsCharAlpha IsCharAlphaA -#define IsCharAlphaNumeric IsCharAlphaNumericA -#define IsCharLower IsCharLowerA -#define IsCharUpper IsCharUpperA -#define IsDialogMessage IsDialogMessageA -#define LoadAccelerators LoadAcceleratorsA -#define LoadBitmap LoadBitmapA -#define LoadCursor LoadCursorA -#define LoadIcon LoadIconA -#define LoadCursorFromFile LoadCursorFromFileA -#define LoadImage LoadImageA -#define LoadKeyboardLayout LoadKeyboardLayoutA -#define LoadMenu LoadMenuA -#define LoadMenuIndirect LoadMenuIndirectA -#define LoadString LoadStringA -#define MapVirtualKey MapVirtualKeyA -#define MapVirtualKeyEx MapVirtualKeyExA -#define MessageBox MessageBoxA -#define MessageBoxEx MessageBoxExA -#define MessageBoxIndirect MessageBoxIndirectA -#define ModifyMenu ModifyMenuA -#define OemToChar OemToCharA -#define OemToCharBuff OemToCharBuffA -#define OpenDesktop OpenDesktopA -#define OpenWindowStation OpenWindowStationA -#define PeekMessage PeekMessageA -#define PostAppMessage PostAppMessageA -#define PostMessage PostMessageA -#define PostThreadMessage PostThreadMessageA -#define RegisterClass RegisterClassA -#define RegisterClassEx RegisterClassExA -#define RegisterClipboardFormat RegisterClipboardFormatA -#define RegisterWindowMessage RegisterWindowMessageA -#define RemoveProp RemovePropA -#define SendDlgItemMessage SendDlgItemMessageA -#define SendMessage SendMessageA -#define SendMessageCallback SendMessageCallbackA -#define SendMessageTimeout SendMessageTimeoutA -#define SendNotifyMessage SendNotifyMessageA -#define SetClassLong SetClassLongA -#define SetDlgItemText SetDlgItemTextA -#define SetMenuItemInfo SetMenuItemInfoA -#define SetProp SetPropA -#define SetUserObjectInformation SetUserObjectInformationA -#define SetWindowLong SetWindowLongA -#define SetWindowLongPtr SetWindowLongPtrA -#define SetWindowsHook SetWindowsHookA -#define SetWindowsHookEx SetWindowsHookExA -#define SetWindowText SetWindowTextA +#define EnumDisplaySettingsEx EnumDisplaySettingsExA +#define EnumDisplayDevices EnumDisplayDevicesA +#endif + + WINUSERAPI LONG WINAPI ChangeDisplaySettingsA(LPDEVMODEA lpDevMode,DWORD dwFlags); + WINUSERAPI LONG WINAPI ChangeDisplaySettingsW(LPDEVMODEW lpDevMode,DWORD dwFlags); + WINUSERAPI LONG WINAPI ChangeDisplaySettingsExA(LPCSTR lpszDeviceName,LPDEVMODEA lpDevMode,HWND hwnd,DWORD dwflags,LPVOID lParam); + WINUSERAPI LONG WINAPI ChangeDisplaySettingsExW(LPCWSTR lpszDeviceName,LPDEVMODEW lpDevMode,HWND hwnd,DWORD dwflags,LPVOID lParam); + +#define ENUM_CURRENT_SETTINGS ((DWORD)-1) +#define ENUM_REGISTRY_SETTINGS ((DWORD)-2) + + WINUSERAPI WINBOOL WINAPI EnumDisplaySettingsA(LPCSTR lpszDeviceName,DWORD iModeNum,LPDEVMODEA lpDevMode); + WINUSERAPI WINBOOL WINAPI EnumDisplaySettingsW(LPCWSTR lpszDeviceName,DWORD iModeNum,LPDEVMODEW lpDevMode); + WINUSERAPI WINBOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName,DWORD iModeNum,LPDEVMODEA lpDevMode,DWORD dwFlags); + WINUSERAPI WINBOOL WINAPI EnumDisplaySettingsExW(LPCWSTR lpszDeviceName,DWORD iModeNum,LPDEVMODEW lpDevMode,DWORD dwFlags); + +#define EDS_RAWMODE 0x00000002 + + WINUSERAPI WINBOOL WINAPI EnumDisplayDevicesA(LPCSTR lpDevice,DWORD iDevNum,PDISPLAY_DEVICEA lpDisplayDevice,DWORD dwFlags); + WINUSERAPI WINBOOL WINAPI EnumDisplayDevicesW(LPCWSTR lpDevice,DWORD iDevNum,PDISPLAY_DEVICEW lpDisplayDevice,DWORD dwFlags); +#endif +#endif + +#ifdef UNICODE +#define SystemParametersInfo SystemParametersInfoW +#else #define SystemParametersInfo SystemParametersInfoA -#define TabbedTextOut TabbedTextOutA -#define TranslateAccelerator TranslateAcceleratorA -#define UnregisterClass UnregisterClassA -#define VkKeyScan VkKeyScanA -#define VkKeyScanEx VkKeyScanExA -#define WinHelp WinHelpA -#define wsprintf wsprintfA -#define wvsprintf wvsprintfA #endif + + WINUSERAPI WINBOOL WINAPI SystemParametersInfoA(UINT uiAction,UINT uiParam,PVOID pvParam,UINT fWinIni); + WINUSERAPI WINBOOL WINAPI SystemParametersInfoW(UINT uiAction,UINT uiParam,PVOID pvParam,UINT fWinIni); #endif + + typedef struct tagFILTERKEYS { + UINT cbSize; + DWORD dwFlags; + DWORD iWaitMSec; + DWORD iDelayMSec; + DWORD iRepeatMSec; + DWORD iBounceMSec; + } FILTERKEYS,*LPFILTERKEYS; + +#define FKF_FILTERKEYSON 0x00000001 +#define FKF_AVAILABLE 0x00000002 +#define FKF_HOTKEYACTIVE 0x00000004 +#define FKF_CONFIRMHOTKEY 0x00000008 +#define FKF_HOTKEYSOUND 0x00000010 +#define FKF_INDICATOR 0x00000020 +#define FKF_CLICKON 0x00000040 + + typedef struct tagSTICKYKEYS { + UINT cbSize; + DWORD dwFlags; + } STICKYKEYS,*LPSTICKYKEYS; + +#define SKF_STICKYKEYSON 0x00000001 +#define SKF_AVAILABLE 0x00000002 +#define SKF_HOTKEYACTIVE 0x00000004 +#define SKF_CONFIRMHOTKEY 0x00000008 +#define SKF_HOTKEYSOUND 0x00000010 +#define SKF_INDICATOR 0x00000020 +#define SKF_AUDIBLEFEEDBACK 0x00000040 +#define SKF_TRISTATE 0x00000080 +#define SKF_TWOKEYSOFF 0x00000100 +#define SKF_LALTLATCHED 0x10000000 +#define SKF_LCTLLATCHED 0x04000000 +#define SKF_LSHIFTLATCHED 0x01000000 +#define SKF_RALTLATCHED 0x20000000 +#define SKF_RCTLLATCHED 0x08000000 +#define SKF_RSHIFTLATCHED 0x02000000 +#define SKF_LWINLATCHED 0x40000000 +#define SKF_RWINLATCHED 0x80000000 +#define SKF_LALTLOCKED 0x00100000 +#define SKF_LCTLLOCKED 0x00040000 +#define SKF_LSHIFTLOCKED 0x00010000 +#define SKF_RALTLOCKED 0x00200000 +#define SKF_RCTLLOCKED 0x00080000 +#define SKF_RSHIFTLOCKED 0x00020000 +#define SKF_LWINLOCKED 0x00400000 +#define SKF_RWINLOCKED 0x00800000 + + typedef struct tagMOUSEKEYS { + UINT cbSize; + DWORD dwFlags; + DWORD iMaxSpeed; + DWORD iTimeToMaxSpeed; + DWORD iCtrlSpeed; + DWORD dwReserved1; + DWORD dwReserved2; + } MOUSEKEYS,*LPMOUSEKEYS; + +#define MKF_MOUSEKEYSON 0x00000001 +#define MKF_AVAILABLE 0x00000002 +#define MKF_HOTKEYACTIVE 0x00000004 +#define MKF_CONFIRMHOTKEY 0x00000008 +#define MKF_HOTKEYSOUND 0x00000010 +#define MKF_INDICATOR 0x00000020 +#define MKF_MODIFIERS 0x00000040 +#define MKF_REPLACENUMBERS 0x00000080 +#define MKF_LEFTBUTTONSEL 0x10000000 +#define MKF_RIGHTBUTTONSEL 0x20000000 +#define MKF_LEFTBUTTONDOWN 0x01000000 +#define MKF_RIGHTBUTTONDOWN 0x02000000 +#define MKF_MOUSEMODE 0x80000000 + + typedef struct tagACCESSTIMEOUT { + UINT cbSize; + DWORD dwFlags; + DWORD iTimeOutMSec; + } ACCESSTIMEOUT,*LPACCESSTIMEOUT; + +#define ATF_TIMEOUTON 0x00000001 +#define ATF_ONOFFFEEDBACK 0x00000002 + +#define SSGF_NONE 0 +#define SSGF_DISPLAY 3 + +#define SSTF_NONE 0 +#define SSTF_CHARS 1 +#define SSTF_BORDER 2 +#define SSTF_DISPLAY 3 + +#define SSWF_NONE 0 +#define SSWF_TITLE 1 +#define SSWF_WINDOW 2 +#define SSWF_DISPLAY 3 +#define SSWF_CUSTOM 4 + + typedef struct tagSOUNDSENTRYA { + UINT cbSize; + DWORD dwFlags; + DWORD iFSTextEffect; + DWORD iFSTextEffectMSec; + DWORD iFSTextEffectColorBits; + DWORD iFSGrafEffect; + DWORD iFSGrafEffectMSec; + DWORD iFSGrafEffectColor; + DWORD iWindowsEffect; + DWORD iWindowsEffectMSec; + LPSTR lpszWindowsEffectDLL; + DWORD iWindowsEffectOrdinal; + } SOUNDSENTRYA,*LPSOUNDSENTRYA; + + typedef struct tagSOUNDSENTRYW { + UINT cbSize; + DWORD dwFlags; + DWORD iFSTextEffect; + DWORD iFSTextEffectMSec; + DWORD iFSTextEffectColorBits; + DWORD iFSGrafEffect; + DWORD iFSGrafEffectMSec; + DWORD iFSGrafEffectColor; + DWORD iWindowsEffect; + DWORD iWindowsEffectMSec; + LPWSTR lpszWindowsEffectDLL; + DWORD iWindowsEffectOrdinal; + } SOUNDSENTRYW,*LPSOUNDSENTRYW; + +#ifdef UNICODE + typedef SOUNDSENTRYW SOUNDSENTRY; + typedef LPSOUNDSENTRYW LPSOUNDSENTRY; +#else + typedef SOUNDSENTRYA SOUNDSENTRY; + typedef LPSOUNDSENTRYA LPSOUNDSENTRY; +#endif + +#define SSF_SOUNDSENTRYON 0x00000001 +#define SSF_AVAILABLE 0x00000002 +#define SSF_INDICATOR 0x00000004 + + typedef struct tagTOGGLEKEYS { + UINT cbSize; + DWORD dwFlags; + } TOGGLEKEYS,*LPTOGGLEKEYS; + +#define TKF_TOGGLEKEYSON 0x00000001 +#define TKF_AVAILABLE 0x00000002 +#define TKF_HOTKEYACTIVE 0x00000004 +#define TKF_CONFIRMHOTKEY 0x00000008 +#define TKF_HOTKEYSOUND 0x00000010 +#define TKF_INDICATOR 0x00000020 + + WINUSERAPI VOID WINAPI SetDebugErrorLevel(DWORD dwLevel); + +#define SLE_ERROR 0x00000001 +#define SLE_MINORERROR 0x00000002 +#define SLE_WARNING 0x00000003 + + WINUSERAPI VOID WINAPI SetLastErrorEx(DWORD dwErrCode,DWORD dwType); + WINUSERAPI int WINAPI InternalGetWindowText(HWND hWnd,LPWSTR pString,int cchMaxCount); + +#ifdef WINNT + WINUSERAPI WINBOOL WINAPI EndTask(HWND hWnd,WINBOOL fShutDown,WINBOOL fForce); +#endif + +#define MONITOR_DEFAULTTONULL 0x00000000 +#define MONITOR_DEFAULTTOPRIMARY 0x00000001 +#define MONITOR_DEFAULTTONEAREST 0x00000002 + + WINUSERAPI HMONITOR WINAPI MonitorFromPoint(POINT pt,DWORD dwFlags); + WINUSERAPI HMONITOR WINAPI MonitorFromRect(LPCRECT lprc,DWORD dwFlags); + WINUSERAPI HMONITOR WINAPI MonitorFromWindow(HWND hwnd,DWORD dwFlags); + +#define MONITORINFOF_PRIMARY 0x00000001 + +#ifndef CCHDEVICENAME +#define CCHDEVICENAME 32 +#endif + + typedef struct tagMONITORINFO { + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; + } MONITORINFO,*LPMONITORINFO; + +#ifdef __cplusplus + typedef struct tagMONITORINFOEXA : public tagMONITORINFO { + CHAR szDevice[CCHDEVICENAME]; + } MONITORINFOEXA,*LPMONITORINFOEXA; + + typedef struct tagMONITORINFOEXW : public tagMONITORINFO { + WCHAR szDevice[CCHDEVICENAME]; + } MONITORINFOEXW,*LPMONITORINFOEXW; + +#ifdef UNICODE + typedef MONITORINFOEXW MONITORINFOEX; + typedef LPMONITORINFOEXW LPMONITORINFOEX; +#else + typedef MONITORINFOEXA MONITORINFOEX; + typedef LPMONITORINFOEXA LPMONITORINFOEX; +#endif +#else + typedef struct tagMONITORINFOEXA { + MONITORINFO mi; + CHAR szDevice[CCHDEVICENAME]; + } MONITORINFOEXA,*LPMONITORINFOEXA; + + typedef struct tagMONITORINFOEXW { + MONITORINFO mi; + WCHAR szDevice[CCHDEVICENAME]; + } MONITORINFOEXW,*LPMONITORINFOEXW; +#ifdef UNICODE + typedef MONITORINFOEXW MONITORINFOEX; + typedef LPMONITORINFOEXW LPMONITORINFOEX; +#else + typedef MONITORINFOEXA MONITORINFOEX; + typedef LPMONITORINFOEXA LPMONITORINFOEX; +#endif +#endif + +#ifdef UNICODE +#define GetMonitorInfo GetMonitorInfoW +#else +#define GetMonitorInfo GetMonitorInfoA +#endif + + WINUSERAPI WINBOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor,LPMONITORINFO lpmi); + WINUSERAPI WINBOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor,LPMONITORINFO lpmi); + + typedef WINBOOL (CALLBACK *MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM); + + WINUSERAPI WINBOOL WINAPI EnumDisplayMonitors(HDC hdc,LPCRECT lprcClip,MONITORENUMPROC lpfnEnum,LPARAM dwData); + +#ifndef NOWINABLE + WINUSERAPI VOID WINAPI NotifyWinEvent(DWORD event,HWND hwnd,LONG idObject,LONG idChild); + + typedef VOID (CALLBACK *WINEVENTPROC)(HWINEVENTHOOK hWinEventHook,DWORD event,HWND hwnd,LONG idObject,LONG idChild,DWORD idEventThread,DWORD dwmsEventTime); + + WINUSERAPI HWINEVENTHOOK WINAPI SetWinEventHook(DWORD eventMin,DWORD eventMax,HMODULE hmodWinEventProc,WINEVENTPROC pfnWinEventProc,DWORD idProcess,DWORD idThread,DWORD dwFlags); + WINUSERAPI WINBOOL WINAPI IsWinEventHookInstalled(DWORD event); + +#define WINEVENT_OUTOFCONTEXT 0x0000 +#define WINEVENT_SKIPOWNTHREAD 0x0001 +#define WINEVENT_SKIPOWNPROCESS 0x0002 +#define WINEVENT_INCONTEXT 0x0004 + + WINUSERAPI WINBOOL WINAPI UnhookWinEvent(HWINEVENTHOOK hWinEventHook); + +#define CHILDID_SELF 0 +#define INDEXID_OBJECT 0 +#define INDEXID_CONTAINER 0 + +#define OBJID_WINDOW ((LONG)0x00000000) +#define OBJID_SYSMENU ((LONG)0xFFFFFFFF) +#define OBJID_TITLEBAR ((LONG)0xFFFFFFFE) +#define OBJID_MENU ((LONG)0xFFFFFFFD) +#define OBJID_CLIENT ((LONG)0xFFFFFFFC) +#define OBJID_VSCROLL ((LONG)0xFFFFFFFB) +#define OBJID_HSCROLL ((LONG)0xFFFFFFFA) +#define OBJID_SIZEGRIP ((LONG)0xFFFFFFF9) +#define OBJID_CARET ((LONG)0xFFFFFFF8) +#define OBJID_CURSOR ((LONG)0xFFFFFFF7) +#define OBJID_ALERT ((LONG)0xFFFFFFF6) +#define OBJID_SOUND ((LONG)0xFFFFFFF5) +#define OBJID_QUERYCLASSNAMEIDX ((LONG)0xFFFFFFF4) +#define OBJID_NATIVEOM ((LONG)0xFFFFFFF0) + +#define EVENT_MIN 0x00000001 +#define EVENT_MAX 0x7FFFFFFF + +#define EVENT_SYSTEM_SOUND 0x0001 +#define EVENT_SYSTEM_ALERT 0x0002 +#define EVENT_SYSTEM_FOREGROUND 0x0003 +#define EVENT_SYSTEM_MENUSTART 0x0004 +#define EVENT_SYSTEM_MENUEND 0x0005 +#define EVENT_SYSTEM_MENUPOPUPSTART 0x0006 +#define EVENT_SYSTEM_MENUPOPUPEND 0x0007 +#define EVENT_SYSTEM_CAPTURESTART 0x0008 +#define EVENT_SYSTEM_CAPTUREEND 0x0009 +#define EVENT_SYSTEM_MOVESIZESTART 0x000A +#define EVENT_SYSTEM_MOVESIZEEND 0x000B +#define EVENT_SYSTEM_CONTEXTHELPSTART 0x000C +#define EVENT_SYSTEM_CONTEXTHELPEND 0x000D +#define EVENT_SYSTEM_DRAGDROPSTART 0x000E +#define EVENT_SYSTEM_DRAGDROPEND 0x000F +#define EVENT_SYSTEM_DIALOGSTART 0x0010 +#define EVENT_SYSTEM_DIALOGEND 0x0011 +#define EVENT_SYSTEM_SCROLLINGSTART 0x0012 +#define EVENT_SYSTEM_SCROLLINGEND 0x0013 +#define EVENT_SYSTEM_SWITCHSTART 0x0014 +#define EVENT_SYSTEM_SWITCHEND 0x0015 +#define EVENT_SYSTEM_MINIMIZESTART 0x0016 +#define EVENT_SYSTEM_MINIMIZEEND 0x0017 + +#define EVENT_CONSOLE_CARET 0x4001 +#define EVENT_CONSOLE_UPDATE_REGION 0x4002 +#define EVENT_CONSOLE_UPDATE_SIMPLE 0x4003 +#define EVENT_CONSOLE_UPDATE_SCROLL 0x4004 +#define EVENT_CONSOLE_LAYOUT 0x4005 +#define EVENT_CONSOLE_START_APPLICATION 0x4006 +#define EVENT_CONSOLE_END_APPLICATION 0x4007 + +#define CONSOLE_APPLICATION_16BIT 0x0001 + +#define CONSOLE_CARET_SELECTION 0x0001 +#define CONSOLE_CARET_VISIBLE 0x0002 + +#define EVENT_OBJECT_CREATE 0x8000 +#define EVENT_OBJECT_DESTROY 0x8001 +#define EVENT_OBJECT_SHOW 0x8002 +#define EVENT_OBJECT_HIDE 0x8003 +#define EVENT_OBJECT_REORDER 0x8004 + +#define EVENT_OBJECT_FOCUS 0x8005 +#define EVENT_OBJECT_SELECTION 0x8006 +#define EVENT_OBJECT_SELECTIONADD 0x8007 +#define EVENT_OBJECT_SELECTIONREMOVE 0x8008 +#define EVENT_OBJECT_SELECTIONWITHIN 0x8009 + +#define EVENT_OBJECT_STATECHANGE 0x800A + +#define EVENT_OBJECT_LOCATIONCHANGE 0x800B + +#define EVENT_OBJECT_NAMECHANGE 0x800C +#define EVENT_OBJECT_DESCRIPTIONCHANGE 0x800D +#define EVENT_OBJECT_VALUECHANGE 0x800E +#define EVENT_OBJECT_PARENTCHANGE 0x800F +#define EVENT_OBJECT_HELPCHANGE 0x8010 +#define EVENT_OBJECT_DEFACTIONCHANGE 0x8011 +#define EVENT_OBJECT_ACCELERATORCHANGE 0x8012 + +#define SOUND_SYSTEM_STARTUP 1 +#define SOUND_SYSTEM_SHUTDOWN 2 +#define SOUND_SYSTEM_BEEP 3 +#define SOUND_SYSTEM_ERROR 4 +#define SOUND_SYSTEM_QUESTION 5 +#define SOUND_SYSTEM_WARNING 6 +#define SOUND_SYSTEM_INFORMATION 7 +#define SOUND_SYSTEM_MAXIMIZE 8 +#define SOUND_SYSTEM_MINIMIZE 9 +#define SOUND_SYSTEM_RESTOREUP 10 +#define SOUND_SYSTEM_RESTOREDOWN 11 +#define SOUND_SYSTEM_APPSTART 12 +#define SOUND_SYSTEM_FAULT 13 +#define SOUND_SYSTEM_APPEND 14 +#define SOUND_SYSTEM_MENUCOMMAND 15 +#define SOUND_SYSTEM_MENUPOPUP 16 +#define CSOUND_SYSTEM 16 + +#define ALERT_SYSTEM_INFORMATIONAL 1 +#define ALERT_SYSTEM_WARNING 2 +#define ALERT_SYSTEM_ERROR 3 +#define ALERT_SYSTEM_QUERY 4 +#define ALERT_SYSTEM_CRITICAL 5 +#define CALERT_SYSTEM 6 + + typedef struct tagGUITHREADINFO { + DWORD cbSize; + DWORD flags; + HWND hwndActive; + HWND hwndFocus; + HWND hwndCapture; + HWND hwndMenuOwner; + HWND hwndMoveSize; + HWND hwndCaret; + RECT rcCaret; + } GUITHREADINFO,*PGUITHREADINFO,*LPGUITHREADINFO; + +#define GUI_CARETBLINKING 0x00000001 +#define GUI_INMOVESIZE 0x00000002 +#define GUI_INMENUMODE 0x00000004 +#define GUI_SYSTEMMENUMODE 0x00000008 +#define GUI_POPUPMENUMODE 0x00000010 +#define GUI_16BITTASK 0x00000020 + +#ifdef UNICODE +#define GetWindowModuleFileName GetWindowModuleFileNameW +#else +#define GetWindowModuleFileName GetWindowModuleFileNameA +#endif + + WINUSERAPI WINBOOL WINAPI GetGUIThreadInfo(DWORD idThread,PGUITHREADINFO pgui); + WINUSERAPI UINT WINAPI GetWindowModuleFileNameA(HWND hwnd,LPSTR pszFileName,UINT cchFileNameMax); + WINUSERAPI UINT WINAPI GetWindowModuleFileNameW(HWND hwnd,LPWSTR pszFileName,UINT cchFileNameMax); + +#ifndef NO_STATE_FLAGS +#define STATE_SYSTEM_UNAVAILABLE 0x00000001 +#define STATE_SYSTEM_SELECTED 0x00000002 +#define STATE_SYSTEM_FOCUSED 0x00000004 +#define STATE_SYSTEM_PRESSED 0x00000008 +#define STATE_SYSTEM_CHECKED 0x00000010 +#define STATE_SYSTEM_MIXED 0x00000020 +#define STATE_SYSTEM_INDETERMINATE STATE_SYSTEM_MIXED +#define STATE_SYSTEM_READONLY 0x00000040 +#define STATE_SYSTEM_HOTTRACKED 0x00000080 +#define STATE_SYSTEM_DEFAULT 0x00000100 +#define STATE_SYSTEM_EXPANDED 0x00000200 +#define STATE_SYSTEM_COLLAPSED 0x00000400 +#define STATE_SYSTEM_BUSY 0x00000800 +#define STATE_SYSTEM_FLOATING 0x00001000 +#define STATE_SYSTEM_MARQUEED 0x00002000 +#define STATE_SYSTEM_ANIMATED 0x00004000 +#define STATE_SYSTEM_INVISIBLE 0x00008000 +#define STATE_SYSTEM_OFFSCREEN 0x00010000 +#define STATE_SYSTEM_SIZEABLE 0x00020000 +#define STATE_SYSTEM_MOVEABLE 0x00040000 +#define STATE_SYSTEM_SELFVOICING 0x00080000 +#define STATE_SYSTEM_FOCUSABLE 0x00100000 +#define STATE_SYSTEM_SELECTABLE 0x00200000 +#define STATE_SYSTEM_LINKED 0x00400000 +#define STATE_SYSTEM_TRAVERSED 0x00800000 +#define STATE_SYSTEM_MULTISELECTABLE 0x01000000 +#define STATE_SYSTEM_EXTSELECTABLE 0x02000000 +#define STATE_SYSTEM_ALERT_LOW 0x04000000 +#define STATE_SYSTEM_ALERT_MEDIUM 0x08000000 +#define STATE_SYSTEM_ALERT_HIGH 0x10000000 +#define STATE_SYSTEM_PROTECTED 0x20000000 +#define STATE_SYSTEM_VALID 0x3FFFFFFF +#endif + +#define CCHILDREN_TITLEBAR 5 +#define CCHILDREN_SCROLLBAR 5 + + typedef struct tagCURSORINFO { + DWORD cbSize; + DWORD flags; + HCURSOR hCursor; + POINT ptScreenPos; + } CURSORINFO,*PCURSORINFO,*LPCURSORINFO; + +#define CURSOR_SHOWING 0x00000001 + + WINUSERAPI WINBOOL WINAPI GetCursorInfo(PCURSORINFO pci); + + typedef struct tagWINDOWINFO { + DWORD cbSize; + RECT rcWindow; + RECT rcClient; + DWORD dwStyle; + DWORD dwExStyle; + DWORD dwWindowStatus; + UINT cxWindowBorders; + UINT cyWindowBorders; + ATOM atomWindowType; + WORD wCreatorVersion; + } WINDOWINFO,*PWINDOWINFO,*LPWINDOWINFO; + +#define WS_ACTIVECAPTION 0x0001 + + WINUSERAPI WINBOOL WINAPI GetWindowInfo(HWND hwnd,PWINDOWINFO pwi); + + typedef struct tagTITLEBARINFO { + DWORD cbSize; + RECT rcTitleBar; + DWORD rgstate[CCHILDREN_TITLEBAR + 1]; + } TITLEBARINFO,*PTITLEBARINFO,*LPTITLEBARINFO; + + WINUSERAPI WINBOOL WINAPI GetTitleBarInfo(HWND hwnd,PTITLEBARINFO pti); + + typedef struct tagMENUBARINFO { + DWORD cbSize; + RECT rcBar; + HMENU hMenu; + HWND hwndMenu; + WINBOOL fBarFocused:1; + WINBOOL fFocused:1; + } MENUBARINFO,*PMENUBARINFO,*LPMENUBARINFO; + + WINUSERAPI WINBOOL WINAPI GetMenuBarInfo(HWND hwnd,LONG idObject,LONG idItem,PMENUBARINFO pmbi); + + typedef struct tagSCROLLBARINFO { + DWORD cbSize; + RECT rcScrollBar; + int dxyLineButton; + int xyThumbTop; + int xyThumbBottom; + int reserved; + DWORD rgstate[CCHILDREN_SCROLLBAR + 1]; + } SCROLLBARINFO,*PSCROLLBARINFO,*LPSCROLLBARINFO; + + WINUSERAPI WINBOOL WINAPI GetScrollBarInfo(HWND hwnd,LONG idObject,PSCROLLBARINFO psbi); + + typedef struct tagCOMBOBOXINFO { + DWORD cbSize; + RECT rcItem; + RECT rcButton; + DWORD stateButton; + HWND hwndCombo; + HWND hwndItem; + HWND hwndList; + } COMBOBOXINFO,*PCOMBOBOXINFO,*LPCOMBOBOXINFO; + + WINUSERAPI WINBOOL WINAPI GetComboBoxInfo(HWND hwndCombo,PCOMBOBOXINFO pcbi); + +#define GA_PARENT 1 +#define GA_ROOT 2 +#define GA_ROOTOWNER 3 + + WINUSERAPI HWND WINAPI GetAncestor(HWND hwnd,UINT gaFlags); + WINUSERAPI HWND WINAPI RealChildWindowFromPoint(HWND hwndParent,POINT ptParentClientCoords); + WINUSERAPI UINT WINAPI RealGetWindowClassA(HWND hwnd,LPSTR ptszClassName,UINT cchClassNameMax); + WINUSERAPI UINT WINAPI RealGetWindowClassW(HWND hwnd,LPWSTR ptszClassName,UINT cchClassNameMax); +#ifdef UNICODE +#define RealGetWindowClass RealGetWindowClassW +#else +#define RealGetWindowClass RealGetWindowClassA +#endif + + typedef struct tagALTTABINFO { + DWORD cbSize; + int cItems; + int cColumns; + int cRows; + int iColFocus; + int iRowFocus; + int cxItem; + int cyItem; + POINT ptStart; + } ALTTABINFO,*PALTTABINFO,*LPALTTABINFO; + +#ifdef UNICODE +#define GetAltTabInfo GetAltTabInfoW +#else +#define GetAltTabInfo GetAltTabInfoA +#endif + + WINUSERAPI WINBOOL WINAPI GetAltTabInfoA(HWND hwnd,int iItem,PALTTABINFO pati,LPSTR pszItemText,UINT cchItemText); + WINUSERAPI WINBOOL WINAPI GetAltTabInfoW(HWND hwnd,int iItem,PALTTABINFO pati,LPWSTR pszItemText,UINT cchItemText); + WINUSERAPI DWORD WINAPI GetListBoxInfo(HWND hwnd); +#endif + + WINUSERAPI WINBOOL WINAPI LockWorkStation(VOID); + WINUSERAPI WINBOOL WINAPI UserHandleGrantAccess(HANDLE hUserHandle,HANDLE hJob,WINBOOL bGrant); + + DECLARE_HANDLE(HRAWINPUT); + +#define GET_RAWINPUT_CODE_WPARAM(wParam) ((wParam) & 0xff) + +#define RIM_INPUT 0 +#define RIM_INPUTSINK 1 + + typedef struct tagRAWINPUTHEADER { + DWORD dwType; + DWORD dwSize; + HANDLE hDevice; + WPARAM wParam; + } RAWINPUTHEADER,*PRAWINPUTHEADER,*LPRAWINPUTHEADER; + +#define RIM_TYPEMOUSE 0 +#define RIM_TYPEKEYBOARD 1 +#define RIM_TYPEHID 2 + + typedef struct tagRAWMOUSE { + USHORT usFlags; + union { + ULONG ulButtons; + struct { + USHORT usButtonFlags; + USHORT usButtonData; + }; + }; + ULONG ulRawButtons; + LONG lLastX; + LONG lLastY; + ULONG ulExtraInformation; + } RAWMOUSE,*PRAWMOUSE,*LPRAWMOUSE; + +#define RI_MOUSE_LEFT_BUTTON_DOWN 0x0001 +#define RI_MOUSE_LEFT_BUTTON_UP 0x0002 +#define RI_MOUSE_RIGHT_BUTTON_DOWN 0x0004 +#define RI_MOUSE_RIGHT_BUTTON_UP 0x0008 +#define RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010 +#define RI_MOUSE_MIDDLE_BUTTON_UP 0x0020 + +#define RI_MOUSE_BUTTON_1_DOWN RI_MOUSE_LEFT_BUTTON_DOWN +#define RI_MOUSE_BUTTON_1_UP RI_MOUSE_LEFT_BUTTON_UP +#define RI_MOUSE_BUTTON_2_DOWN RI_MOUSE_RIGHT_BUTTON_DOWN +#define RI_MOUSE_BUTTON_2_UP RI_MOUSE_RIGHT_BUTTON_UP +#define RI_MOUSE_BUTTON_3_DOWN RI_MOUSE_MIDDLE_BUTTON_DOWN +#define RI_MOUSE_BUTTON_3_UP RI_MOUSE_MIDDLE_BUTTON_UP + +#define RI_MOUSE_BUTTON_4_DOWN 0x0040 +#define RI_MOUSE_BUTTON_4_UP 0x0080 +#define RI_MOUSE_BUTTON_5_DOWN 0x0100 +#define RI_MOUSE_BUTTON_5_UP 0x0200 + +#define RI_MOUSE_WHEEL 0x0400 + +#define MOUSE_MOVE_RELATIVE 0 +#define MOUSE_MOVE_ABSOLUTE 1 +#define MOUSE_VIRTUAL_DESKTOP 0x02 +#define MOUSE_ATTRIBUTES_CHANGED 0x04 + + typedef struct tagRAWKEYBOARD { + USHORT MakeCode; + USHORT Flags; + USHORT Reserved; + USHORT VKey; + UINT Message; + ULONG ExtraInformation; + } RAWKEYBOARD,*PRAWKEYBOARD,*LPRAWKEYBOARD; + +#define KEYBOARD_OVERRUN_MAKE_CODE 0xFF + +#define RI_KEY_MAKE 0 +#define RI_KEY_BREAK 1 +#define RI_KEY_E0 2 +#define RI_KEY_E1 4 +#define RI_KEY_TERMSRV_SET_LED 8 +#define RI_KEY_TERMSRV_SHADOW 0x10 + + typedef struct tagRAWHID { + DWORD dwSizeHid; + DWORD dwCount; + BYTE bRawData[1]; + } RAWHID,*PRAWHID,*LPRAWHID; + + typedef struct tagRAWINPUT { + RAWINPUTHEADER header; + union { + RAWMOUSE mouse; + RAWKEYBOARD keyboard; + RAWHID hid; + } data; + } RAWINPUT,*PRAWINPUT,*LPRAWINPUT; + +#ifdef _WIN64 +#define RAWINPUT_ALIGN(x) (((x) + sizeof(QWORD) - 1) & ~(sizeof(QWORD) - 1)) +#else +#define RAWINPUT_ALIGN(x) (((x) + sizeof(DWORD) - 1) & ~(sizeof(DWORD) - 1)) +#endif + +#define NEXTRAWINPUTBLOCK(ptr) ((PRAWINPUT)RAWINPUT_ALIGN((ULONG_PTR)((PBYTE)(ptr) + (ptr)->header.dwSize))) + +#define RID_INPUT 0x10000003 +#define RID_HEADER 0x10000005 + + WINUSERAPI UINT WINAPI GetRawInputData(HRAWINPUT hRawInput,UINT uiCommand,LPVOID pData,PUINT pcbSize,UINT cbSizeHeader); + +#define RIDI_PREPARSEDDATA 0x20000005 +#define RIDI_DEVICENAME 0x20000007 +#define RIDI_DEVICEINFO 0x2000000b + + typedef struct tagRID_DEVICE_INFO_MOUSE { + DWORD dwId; + DWORD dwNumberOfButtons; + DWORD dwSampleRate; + } RID_DEVICE_INFO_MOUSE,*PRID_DEVICE_INFO_MOUSE; + + typedef struct tagRID_DEVICE_INFO_KEYBOARD { + DWORD dwType; + DWORD dwSubType; + DWORD dwKeyboardMode; + DWORD dwNumberOfFunctionKeys; + DWORD dwNumberOfIndicators; + DWORD dwNumberOfKeysTotal; + } RID_DEVICE_INFO_KEYBOARD,*PRID_DEVICE_INFO_KEYBOARD; + + typedef struct tagRID_DEVICE_INFO_HID { + DWORD dwVendorId; + DWORD dwProductId; + DWORD dwVersionNumber; + USHORT usUsagePage; + USHORT usUsage; + } RID_DEVICE_INFO_HID,*PRID_DEVICE_INFO_HID; + + typedef struct tagRID_DEVICE_INFO { + DWORD cbSize; + DWORD dwType; + union { + RID_DEVICE_INFO_MOUSE mouse; + RID_DEVICE_INFO_KEYBOARD keyboard; + RID_DEVICE_INFO_HID hid; + }; + } RID_DEVICE_INFO,*PRID_DEVICE_INFO,*LPRID_DEVICE_INFO; + +#ifdef UNICODE +#define GetRawInputDeviceInfo GetRawInputDeviceInfoW +#else +#define GetRawInputDeviceInfo GetRawInputDeviceInfoA +#endif + + WINUSERAPI UINT WINAPI GetRawInputDeviceInfoA(HANDLE hDevice,UINT uiCommand,LPVOID pData,PUINT pcbSize); + WINUSERAPI UINT WINAPI GetRawInputDeviceInfoW(HANDLE hDevice,UINT uiCommand,LPVOID pData,PUINT pcbSize); + WINUSERAPI UINT WINAPI GetRawInputBuffer(PRAWINPUT pData,PUINT pcbSize,UINT cbSizeHeader); + + typedef struct tagRAWINPUTDEVICE { + USHORT usUsagePage; + USHORT usUsage; + DWORD dwFlags; + HWND hwndTarget; + } RAWINPUTDEVICE,*PRAWINPUTDEVICE,*LPRAWINPUTDEVICE; + + typedef CONST RAWINPUTDEVICE *PCRAWINPUTDEVICE; + +#define RIDEV_REMOVE 0x00000001 +#define RIDEV_EXCLUDE 0x00000010 +#define RIDEV_PAGEONLY 0x00000020 +#define RIDEV_NOLEGACY 0x00000030 +#define RIDEV_INPUTSINK 0x00000100 +#define RIDEV_CAPTUREMOUSE 0x00000200 +#define RIDEV_NOHOTKEYS 0x00000200 +#define RIDEV_APPKEYS 0x00000400 +#define RIDEV_EXMODEMASK 0x000000F0 +#define RIDEV_EXMODE(mode) ((mode) & RIDEV_EXMODEMASK) + + WINUSERAPI WINBOOL WINAPI RegisterRawInputDevices(PCRAWINPUTDEVICE pRawInputDevices,UINT uiNumDevices,UINT cbSize); + WINUSERAPI UINT WINAPI GetRegisteredRawInputDevices(PRAWINPUTDEVICE pRawInputDevices,PUINT puiNumDevices,UINT cbSize); + + typedef struct tagRAWINPUTDEVICELIST { + HANDLE hDevice; + DWORD dwType; + } RAWINPUTDEVICELIST,*PRAWINPUTDEVICELIST; + + WINUSERAPI UINT WINAPI GetRawInputDeviceList(PRAWINPUTDEVICELIST pRawInputDeviceList,PUINT puiNumDevices,UINT cbSize); + WINUSERAPI LRESULT WINAPI DefRawInputProc(PRAWINPUT *paRawInput,INT nInput,UINT cbSizeHeader); + +#endif /* NOUSER */ + #ifdef __cplusplus } #endif -#endif /* _WINUSER_H */ +#endif diff --git a/tinyc/win32/include/winapi/winver.h b/tinyc/win32/include/winapi/winver.h index f20333ac8..5c0f036bc 100644 --- a/tinyc/win32/include/winapi/winver.h +++ b/tinyc/win32/include/winapi/winver.h @@ -1,124 +1,137 @@ -#ifndef _WINVER_H -#define _WINVER_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER within this package. + */ +#ifndef VER_H +#define VER_H #ifdef __cplusplus extern "C" { #endif + #define VS_FILE_INFO RT_VERSION #define VS_VERSION_INFO 1 #define VS_USER_DEFINED 100 -#define VS_FFI_SIGNATURE 0xFEEF04BD -#define VS_FFI_STRUCVERSION 0x10000 -#define VS_FFI_FILEFLAGSMASK 0x3F -#define VS_FF_DEBUG 1 -#define VS_FF_PRERELEASE 2 -#define VS_FF_PATCHED 4 -#define VS_FF_PRIVATEBUILD 8 -#define VS_FF_INFOINFERRED 16 -#define VS_FF_SPECIALBUILD 32 -#define VOS_UNKNOWN 0 -#define VOS_DOS 0x10000 -#define VOS_OS216 0x20000 -#define VOS_OS232 0x30000 -#define VOS_NT 0x40000 -#define VOS__BASE 0 -#define VOS__WINDOWS16 1 -#define VOS__PM16 2 -#define VOS__PM32 3 -#define VOS__WINDOWS32 4 -#define VOS_DOS_WINDOWS16 0x10001 -#define VOS_DOS_WINDOWS32 0x10004 -#define VOS_OS216_PM16 0x20002 -#define VOS_OS232_PM32 0x30003 -#define VOS_NT_WINDOWS32 0x40004 -#define VFT_UNKNOWN 0 -#define VFT_APP 1 -#define VFT_DLL 2 -#define VFT_DRV 3 -#define VFT_FONT 4 -#define VFT_VXD 5 -#define VFT_STATIC_LIB 7 -#define VFT2_UNKNOWN 0 -#define VFT2_DRV_PRINTER 1 -#define VFT2_DRV_KEYBOARD 2 -#define VFT2_DRV_LANGUAGE 3 -#define VFT2_DRV_DISPLAY 4 -#define VFT2_DRV_MOUSE 5 -#define VFT2_DRV_NETWORK 6 -#define VFT2_DRV_SYSTEM 7 -#define VFT2_DRV_INSTALLABLE 8 -#define VFT2_DRV_SOUND 9 -#define VFT2_DRV_COMM 10 -#define VFT2_DRV_INPUTMETHOD 11 -#define VFT2_FONT_RASTER 1 -#define VFT2_FONT_VECTOR 2 -#define VFT2_FONT_TRUETYPE 3 -#define VFFF_ISSHAREDFILE 1 -#define VFF_CURNEDEST 1 -#define VFF_FILEINUSE 2 -#define VFF_BUFFTOOSMALL 4 -#define VIFF_FORCEINSTALL 1 -#define VIFF_DONTDELETEOLD 2 -#define VIF_TEMPFILE 1 -#define VIF_MISMATCH 2 -#define VIF_SRCOLD 4 -#define VIF_DIFFLANG 8 -#define VIF_DIFFCODEPG 16 -#define VIF_DIFFTYPE 32 -#define VIF_WRITEPROT 64 -#define VIF_FILEINUSE 128 -#define VIF_OUTOFSPACE 256 -#define VIF_ACCESSVIOLATION 512 -#define VIF_SHARINGVIOLATION 1024 -#define VIF_CANNOTCREATE 2048 -#define VIF_CANNOTDELETE 4096 -#define VIF_CANNOTRENAME 8192 -#define VIF_CANNOTDELETECUR 16384 -#define VIF_OUTOFMEMORY 32768 -#define VIF_CANNOTREADSRC 65536 -#define VIF_CANNOTREADDST 0x20000 -#define VIF_BUFFTOOSMALL 0x40000 + +#define VS_FFI_SIGNATURE 0xFEEF04BDL +#define VS_FFI_STRUCVERSION 0x00010000L +#define VS_FFI_FILEFLAGSMASK 0x0000003FL + +#define VS_FF_DEBUG 0x00000001L +#define VS_FF_PRERELEASE 0x00000002L +#define VS_FF_PATCHED 0x00000004L +#define VS_FF_PRIVATEBUILD 0x00000008L +#define VS_FF_INFOINFERRED 0x00000010L +#define VS_FF_SPECIALBUILD 0x00000020L + +#define VOS_UNKNOWN 0x00000000L +#define VOS_DOS 0x00010000L +#define VOS_OS216 0x00020000L +#define VOS_OS232 0x00030000L +#define VOS_NT 0x00040000L +#define VOS_WINCE 0x00050000L + +#define VOS__BASE 0x00000000L +#define VOS__WINDOWS16 0x00000001L +#define VOS__PM16 0x00000002L +#define VOS__PM32 0x00000003L +#define VOS__WINDOWS32 0x00000004L + +#define VOS_DOS_WINDOWS16 0x00010001L +#define VOS_DOS_WINDOWS32 0x00010004L +#define VOS_OS216_PM16 0x00020002L +#define VOS_OS232_PM32 0x00030003L +#define VOS_NT_WINDOWS32 0x00040004L + +#define VFT_UNKNOWN 0x00000000L +#define VFT_APP 0x00000001L +#define VFT_DLL 0x00000002L +#define VFT_DRV 0x00000003L +#define VFT_FONT 0x00000004L +#define VFT_VXD 0x00000005L +#define VFT_STATIC_LIB 0x00000007L + +#define VFT2_UNKNOWN 0x00000000L +#define VFT2_DRV_PRINTER 0x00000001L +#define VFT2_DRV_KEYBOARD 0x00000002L +#define VFT2_DRV_LANGUAGE 0x00000003L +#define VFT2_DRV_DISPLAY 0x00000004L +#define VFT2_DRV_MOUSE 0x00000005L +#define VFT2_DRV_NETWORK 0x00000006L +#define VFT2_DRV_SYSTEM 0x00000007L +#define VFT2_DRV_INSTALLABLE 0x00000008L +#define VFT2_DRV_SOUND 0x00000009L +#define VFT2_DRV_COMM 0x0000000AL +#define VFT2_DRV_INPUTMETHOD 0x0000000BL +#define VFT2_DRV_VERSIONED_PRINTER 0x0000000CL + +#define VFT2_FONT_RASTER 0x00000001L +#define VFT2_FONT_VECTOR 0x00000002L +#define VFT2_FONT_TRUETYPE 0x00000003L + +#define VFFF_ISSHAREDFILE 0x0001 + +#define VFF_CURNEDEST 0x0001 +#define VFF_FILEINUSE 0x0002 +#define VFF_BUFFTOOSMALL 0x0004 + +#define VIFF_FORCEINSTALL 0x0001 +#define VIFF_DONTDELETEOLD 0x0002 + +#define VIF_TEMPFILE 0x00000001L +#define VIF_MISMATCH 0x00000002L +#define VIF_SRCOLD 0x00000004L + +#define VIF_DIFFLANG 0x00000008L +#define VIF_DIFFCODEPG 0x00000010L +#define VIF_DIFFTYPE 0x00000020L + +#define VIF_WRITEPROT 0x00000040L +#define VIF_FILEINUSE 0x00000080L +#define VIF_OUTOFSPACE 0x00000100L +#define VIF_ACCESSVIOLATION 0x00000200L +#define VIF_SHARINGVIOLATION 0x00000400L +#define VIF_CANNOTCREATE 0x00000800L +#define VIF_CANNOTDELETE 0x00001000L +#define VIF_CANNOTRENAME 0x00002000L +#define VIF_CANNOTDELETECUR 0x00004000L +#define VIF_OUTOFMEMORY 0x00008000L + +#define VIF_CANNOTREADSRC 0x00010000L +#define VIF_CANNOTREADDST 0x00020000L + +#define VIF_BUFFTOOSMALL 0x00040000L +#define VIF_CANNOTLOADLZ32 0x00080000L +#define VIF_CANNOTLOADCABINET 0x00100000L + #ifndef RC_INVOKED -typedef struct tagVS_FIXEDFILEINFO { - DWORD dwSignature; - DWORD dwStrucVersion; - DWORD dwFileVersionMS; - DWORD dwFileVersionLS; - DWORD dwProductVersionMS; - DWORD dwProductVersionLS; - DWORD dwFileFlagsMask; - DWORD dwFileFlags; - DWORD dwFileOS; - DWORD dwFileType; - DWORD dwFileSubtype; - DWORD dwFileDateMS; - DWORD dwFileDateLS; -} VS_FIXEDFILEINFO; -DWORD WINAPI VerFindFileA(DWORD,LPSTR,LPSTR,LPSTR,LPSTR,PUINT,LPSTR,PUINT); -DWORD WINAPI VerFindFileW(DWORD,LPWSTR,LPWSTR,LPWSTR,LPWSTR,PUINT,LPWSTR,PUINT); -DWORD WINAPI VerInstallFileA(DWORD,LPSTR,LPSTR,LPSTR,LPSTR,LPSTR,LPSTR,PUINT); -DWORD WINAPI VerInstallFileW(DWORD,LPWSTR,LPWSTR,LPWSTR,LPWSTR,LPWSTR,LPWSTR,PUINT); -DWORD WINAPI GetFileVersionInfoSizeA(LPSTR,PDWORD); -DWORD WINAPI GetFileVersionInfoSizeW(LPWSTR,PDWORD); -BOOL WINAPI GetFileVersionInfoA(LPSTR,DWORD,DWORD,PVOID); -BOOL WINAPI GetFileVersionInfoW(LPWSTR,DWORD,DWORD,PVOID); -DWORD WINAPI VerLanguageNameA(DWORD,LPSTR,DWORD); -DWORD WINAPI VerLanguageNameW(DWORD,LPWSTR,DWORD); -BOOL WINAPI VerQueryValueA(PCVOID,LPSTR,PVOID*,PUINT); -BOOL WINAPI VerQueryValueW(PCVOID,LPWSTR,PVOID*,PUINT); + + typedef struct tagVS_FIXEDFILEINFO + { + DWORD dwSignature; + DWORD dwStrucVersion; + DWORD dwFileVersionMS; + DWORD dwFileVersionLS; + DWORD dwProductVersionMS; + DWORD dwProductVersionLS; + DWORD dwFileFlagsMask; + DWORD dwFileFlags; + DWORD dwFileOS; + DWORD dwFileType; + DWORD dwFileSubtype; + DWORD dwFileDateMS; + DWORD dwFileDateLS; + } VS_FIXEDFILEINFO; + #ifdef UNICODE #define VerFindFile VerFindFileW -#define VerQueryValue VerQueryValueW #define VerInstallFile VerInstallFileW #define GetFileVersionInfoSize GetFileVersionInfoSizeW #define GetFileVersionInfo GetFileVersionInfoW #define VerLanguageName VerLanguageNameW #define VerQueryValue VerQueryValueW #else -#define VerQueryValue VerQueryValueA #define VerFindFile VerFindFileA #define VerInstallFile VerInstallFileA #define GetFileVersionInfoSize GetFileVersionInfoSizeA @@ -126,7 +139,21 @@ BOOL WINAPI VerQueryValueW(PCVOID,LPWSTR,PVOID*,PUINT); #define VerLanguageName VerLanguageNameA #define VerQueryValue VerQueryValueA #endif + + DWORD WINAPI VerFindFileA(DWORD uFlags,LPSTR szFileName,LPSTR szWinDir,LPSTR szAppDir,LPSTR szCurDir,PUINT lpuCurDirLen,LPSTR szDestDir,PUINT lpuDestDirLen); + DWORD WINAPI VerFindFileW(DWORD uFlags,LPWSTR szFileName,LPWSTR szWinDir,LPWSTR szAppDir,LPWSTR szCurDir,PUINT lpuCurDirLen,LPWSTR szDestDir,PUINT lpuDestDirLen); + DWORD WINAPI VerInstallFileA(DWORD uFlags,LPSTR szSrcFileName,LPSTR szDestFileName,LPSTR szSrcDir,LPSTR szDestDir,LPSTR szCurDir,LPSTR szTmpFile,PUINT lpuTmpFileLen); + DWORD WINAPI VerInstallFileW(DWORD uFlags,LPWSTR szSrcFileName,LPWSTR szDestFileName,LPWSTR szSrcDir,LPWSTR szDestDir,LPWSTR szCurDir,LPWSTR szTmpFile,PUINT lpuTmpFileLen); + DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR lptstrFilename,LPDWORD lpdwHandle); + DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR lptstrFilename,LPDWORD lpdwHandle); + WINBOOL WINAPI GetFileVersionInfoA(LPCSTR lptstrFilename,DWORD dwHandle,DWORD dwLen,LPVOID lpData); + WINBOOL WINAPI GetFileVersionInfoW(LPCWSTR lptstrFilename,DWORD dwHandle,DWORD dwLen,LPVOID lpData); + DWORD WINAPI VerLanguageNameA(DWORD wLang,LPSTR szLang,DWORD nSize); + DWORD WINAPI VerLanguageNameW(DWORD wLang,LPWSTR szLang,DWORD nSize); + WINBOOL WINAPI VerQueryValueA(const LPVOID pBlock,LPSTR lpSubBlock,LPVOID *lplpBuffer,PUINT puLen); + WINBOOL WINAPI VerQueryValueW(const LPVOID pBlock,LPWSTR lpSubBlock,LPVOID *lplpBuffer,PUINT puLen); #endif + #ifdef __cplusplus } #endif diff --git a/tinyc/win32/lib/chkstk.S b/tinyc/win32/lib/chkstk.S index 837d8af2b..ec5c07ff8 100644 --- a/tinyc/win32/lib/chkstk.S +++ b/tinyc/win32/lib/chkstk.S @@ -1,29 +1,191 @@ -// ================================================= -// chkstk.s +/* ---------------------------------------------- */ +/* chkstk86.s */ + +/* ---------------------------------------------- */ +#ifndef __x86_64__ +/* ---------------------------------------------- */ -.text .globl __chkstk __chkstk: - xchg (%esp), %ebp // store ebp, get ret.addr - push %ebp // push ret.addr - lea 4(%esp), %ebp // setup frame ptr - push %ecx // save ecx - mov %ebp, %ecx + xchg (%esp),%ebp /* store ebp, get ret.addr */ + push %ebp /* push ret.addr */ + lea 4(%esp),%ebp /* setup frame ptr */ + push %ecx /* save ecx */ + mov %ebp,%ecx P0: - sub $4096,%ecx - test %eax,(%ecx) - sub $4096,%eax - cmp $4096,%eax - jge P0 - - sub %eax,%ecx - mov %esp,%eax - test %eax,(%ecx) - mov %ecx,%esp - - mov (%eax),%ecx // restore ecx - mov 4(%eax),%eax - push %eax - ret + sub $4096,%ecx + test %eax,(%ecx) + sub $4096,%eax + cmp $4096,%eax + jge P0 + sub %eax,%ecx + test %eax,(%ecx) + + mov %esp,%eax + mov %ecx,%esp + mov (%eax),%ecx /* restore ecx */ + jmp *4(%eax) + +/* ---------------------------------------------- */ +#else +/* ---------------------------------------------- */ + +.globl __chkstk + +__chkstk: + xchg (%rsp),%rbp /* store ebp, get ret.addr */ + push %rbp /* push ret.addr */ + lea 8(%rsp),%rbp /* setup frame ptr */ + push %rcx /* save ecx */ + mov %rbp,%rcx + movslq %eax,%rax +P0: + sub $4096,%rcx + test %rax,(%rcx) + sub $4096,%rax + cmp $4096,%rax + jge P0 + sub %rax,%rcx + test %rax,(%rcx) + + mov %rsp,%rax + mov %rcx,%rsp + mov (%rax),%rcx /* restore ecx */ + jmp *8(%rax) + +/* ---------------------------------------------- */ +/* setjmp/longjmp support */ + +.globl tinyc_getbp +tinyc_getbp: + mov %rbp,%rax + ret + +/* ---------------------------------------------- */ +#endif +/* ---------------------------------------------- */ + + +/* ---------------------------------------------- */ +#ifndef __x86_64__ +/* ---------------------------------------------- */ + +/* + int _except_handler3( + PEXCEPTION_RECORD exception_record, + PEXCEPTION_REGISTRATION registration, + PCONTEXT context, + PEXCEPTION_REGISTRATION dispatcher + ); + + int __cdecl _XcptFilter( + unsigned long xcptnum, + PEXCEPTION_POINTERS pxcptinfoptrs + ); + + struct _sehrec { + void *esp; // 0 + void *exception_pointers; // 1 + void *prev; // 2 + void *handler; // 3 + void *scopetable; // 4 + int trylevel; // 5 + void *ebp // 6 + }; + + // this is what the assembler code below means: + __try + { + // ... + } + __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation())) + { + exit(GetExceptionCode()); + } +*/ + +.globl _exception_info +_exception_info: + mov 1*4-24(%ebp),%eax + ret + +.globl _exception_code +_exception_code: + call _exception_info + mov (%eax),%eax + mov (%eax),%eax + ret + +seh_filter: + call _exception_info + push %eax + call _exception_code + push %eax + call _XcptFilter + add $ 8,%esp + ret + +seh_except: + mov 0*4-24(%ebp),%esp + call _exception_code + push %eax + call _exit + +// msvcrt wants scopetables aligned and in read-only segment (using .text) +.align 4 +seh_scopetable: + .long -1 + .long seh_filter + .long seh_except + +seh_handler: + jmp _except_handler3 + +.globl ___try__ +___try__: +.globl __try__ +__try__: + push %ebp + mov 8(%esp),%ebp + +// void *esp; + lea 12(%esp),%eax + mov %eax,0*4(%ebp) + +// void *exception_pointers; + xor %eax,%eax + mov %eax,1*4(%ebp) + +// void *prev; + mov %fs:0,%eax + mov %eax,2*4(%ebp) + +// void *handler; + mov $ seh_handler,%eax + mov %eax,3*4(%ebp) + +// void *scopetable; + mov $ seh_scopetable,%eax + mov %eax,4*4(%ebp) + +// int trylevel; + xor %eax,%eax + mov %eax,5*4(%ebp) + +// register new SEH + lea 2*4(%ebp),%eax + mov %eax,%fs:0 + + pop %ebp + ret + +/* ---------------------------------------------- */ +#else +/* ---------------------------------------------- */ + +/* SEH on x86-64 not implemented */ +/* ---------------------------------------------- */ +#endif +/* ---------------------------------------------- */ diff --git a/tinyc/win32/lib/crt1.c b/tinyc/win32/lib/crt1.c index 1cf12f294..0e04fc012 100644 --- a/tinyc/win32/lib/crt1.c +++ b/tinyc/win32/lib/crt1.c @@ -1,35 +1,79 @@ // ============================================= // crt1.c +// _UNICODE for tchar.h, UNICODE for API +#include <tchar.h> + +#include <stdio.h> #include <stdlib.h> -#define __UNKNOWN_APP 0 -#define __CONSOLE_APP 1 -#define __GUI_APP 2 -void __set_app_type(int); -void _controlfp(unsigned a, unsigned b); +#define _UNKNOWN_APP 0 +#define _CONSOLE_APP 1 +#define _GUI_APP 2 -typedef struct -{ - int newmode; -} _startupinfo; +#define _MCW_PC 0x00030000 // Precision Control +#define _PC_24 0x00020000 // 24 bits +#define _PC_53 0x00010000 // 53 bits +#define _PC_64 0x00000000 // 64 bits + +#ifdef _UNICODE +#define __tgetmainargs __wgetmainargs +#define _tstart _wstart +#define _tmain wmain +#define _runtmain _runwmain +#else +#define __tgetmainargs __getmainargs +#define _tstart _start +#define _tmain main +#define _runtmain _runmain +#endif -void __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*); +typedef struct { int newmode; } _startupinfo; +int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); +void __cdecl __set_app_type(int apptype); +unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); +extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]); -int main(int argc, char **argv, char **env); +/* Allow command-line globbing with "int _dowildcard = 1;" in the user source */ +int _dowildcard; -int _start(void) +void _tstart(void) { - int argc; char **argv; char **env; int ret; - _startupinfo start_info = {0}; + __TRY__ + _startupinfo start_info = {0}; - _controlfp(0x10000, 0x30000); - __set_app_type(__CONSOLE_APP); - __getmainargs(&argc, &argv, &env, 0, &start_info); + // Sets the current application type + __set_app_type(_CONSOLE_APP); - ret = main(argc, argv, env); - exit(ret); + // Set default FP precision to 53 bits (8-byte double) + // _MCW_PC (Precision control) is not supported on ARM +#if defined __i386__ || defined __x86_64__ + _controlfp(_PC_53, _MCW_PC); +#endif + + __tgetmainargs( &__argc, &__targv, &_tenviron, _dowildcard, &start_info); + exit(_tmain(__argc, __targv, _tenviron)); } -// ============================================= +int _runtmain(int argc, /* as tcc passed in */ char **argv) +{ +#ifdef UNICODE + _startupinfo start_info = {0}; + + __tgetmainargs(&__argc, &__targv, &_tenviron, _dowildcard, &start_info); + /* may be wrong when tcc has received wildcards (*.c) */ + if (argc < __argc) { + __targv += __argc - argc; + __argc = argc; + } +#else + __argc = argc; + __targv = argv; +#endif +#if defined __i386__ || defined __x86_64__ + _controlfp(_PC_53, _MCW_PC); +#endif + return _tmain(__argc, __targv, _tenviron); +} +// ============================================= diff --git a/tinyc/win32/lib/crt1w.c b/tinyc/win32/lib/crt1w.c new file mode 100644 index 000000000..2b8bbc8bc --- /dev/null +++ b/tinyc/win32/lib/crt1w.c @@ -0,0 +1,3 @@ +#define _UNICODE 1 +#define UNICODE 1 +#include "crt1.c" diff --git a/tinyc/win32/lib/dllcrt1.c b/tinyc/win32/lib/dllcrt1.c index 9fc8339cf..ba1dbd048 100644 --- a/tinyc/win32/lib/dllcrt1.c +++ b/tinyc/win32/lib/dllcrt1.c @@ -2,9 +2,9 @@ #include <windows.h> -BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved); +BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved); -BOOL WINAPI _dllstart(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +BOOL WINAPI _dllstart(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) { BOOL bRet; bRet = DllMain (hDll, dwReason, lpReserved); diff --git a/tinyc/win32/lib/dllmain.c b/tinyc/win32/lib/dllmain.c index e32df481c..2c25b98b8 100644 --- a/tinyc/win32/lib/dllmain.c +++ b/tinyc/win32/lib/dllmain.c @@ -2,7 +2,7 @@ #include <windows.h> -BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) +BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) { return TRUE; } diff --git a/tinyc/win32/lib/kernel32.def b/tinyc/win32/lib/kernel32.def index 85dd980d5..f03e17ba4 100644 --- a/tinyc/win32/lib/kernel32.def +++ b/tinyc/win32/lib/kernel32.def @@ -288,6 +288,8 @@ GetModuleFileNameA GetModuleFileNameW GetModuleHandleA GetModuleHandleW +GetModuleHandleExA +GetModuleHandleExW GetNamedPipeHandleStateA GetNamedPipeHandleStateW GetNamedPipeInfo @@ -549,9 +551,13 @@ ResetEvent ResetNLSUserInfoCache ResetWriteWatch ResumeThread +RtlAddFunctionTable +RtlDeleteFunctionTable RtlFillMemory +RtlInstallFunctionTableCallback RtlMoveMemory RtlUnwind +RtlUnwindEx RtlZeroMemory SMapLS SMapLS_IP_EBP_12 @@ -614,6 +620,7 @@ SetFileApisToOEM SetFileAttributesA SetFileAttributesW SetFilePointer +SetFilePointerEx SetFileTime SetHandleContext SetHandleCount diff --git a/tinyc/win32/lib/libtcc1.a b/tinyc/win32/lib/libtcc1.a deleted file mode 100644 index 0062e8f93..000000000 --- a/tinyc/win32/lib/libtcc1.a +++ /dev/null Binary files differdiff --git a/tinyc/win32/lib/msvcrt.def b/tinyc/win32/lib/msvcrt.def index e4f202373..742acb8bb 100644 --- a/tinyc/win32/lib/msvcrt.def +++ b/tinyc/win32/lib/msvcrt.def @@ -4,11 +4,14 @@ EXPORTS $I10_OUTPUT ??0__non_rtti_object@@QAE@ABV0@@Z ??0__non_rtti_object@@QAE@PBD@Z +??0bad_cast@@AAE@PBQBD@Z ??0bad_cast@@QAE@ABQBD@Z ??0bad_cast@@QAE@ABV0@@Z +??0bad_cast@@QAE@PBD@Z ??0bad_typeid@@QAE@ABV0@@Z ??0bad_typeid@@QAE@PBD@Z ??0exception@@QAE@ABQBD@Z +??0exception@@QAE@ABQBDH@Z ??0exception@@QAE@ABV0@@Z ??0exception@@QAE@XZ ??1__non_rtti_object@@UAE@XZ @@ -17,6 +20,7 @@ $I10_OUTPUT ??1exception@@UAE@XZ ??1type_info@@UAE@XZ ??2@YAPAXI@Z +??2@YAPAXIHPBDH@Z ??3@YAXPAX@Z ??4__non_rtti_object@@QAEAAV0@ABV0@@Z ??4bad_cast@@QAEAAV0@ABV0@@Z @@ -32,11 +36,14 @@ $I10_OUTPUT ??_Ebad_cast@@UAEPAXI@Z ??_Ebad_typeid@@UAEPAXI@Z ??_Eexception@@UAEPAXI@Z +??_Fbad_cast@@QAEXXZ +??_Fbad_typeid@@QAEXXZ ??_G__non_rtti_object@@UAEPAXI@Z ??_Gbad_cast@@UAEPAXI@Z ??_Gbad_typeid@@UAEPAXI@Z ??_Gexception@@UAEPAXI@Z ??_U@YAPAXI@Z +??_U@YAPAXIHPBDH@Z ??_V@YAXPAX@Z ?_query_new_handler@@YAP6AHI@ZXZ ?_query_new_mode@@YAHXZ @@ -68,6 +75,31 @@ _CIsinh _CIsqrt _CItan _CItanh +_CrtCheckMemory +_CrtDbgBreak +_CrtDbgReport +_CrtDbgReportV +_CrtDbgReportW +_CrtDbgReportWV +_CrtDoForAllClientObjects +_CrtDumpMemoryLeaks +_CrtIsMemoryBlock +_CrtIsValidHeapPointer +_CrtIsValidPointer +_CrtMemCheckpoint +_CrtMemDifference +_CrtMemDumpAllObjectsSince +_CrtMemDumpStatistics +_CrtReportBlockType +_CrtSetAllocHook +_CrtSetBreakAlloc +_CrtSetDbgBlockType +_CrtSetDbgFlag +_CrtSetDumpClient +_CrtSetReportFile +_CrtSetReportHook +_CrtSetReportHook2 +_CrtSetReportMode _CxxThrowException _EH_prolog _Getdays @@ -76,23 +108,47 @@ _Gettnames _HUGE _Strftime _XcptFilter +__CppXcptFilter +__CxxCallUnwindDelDtor +__CxxCallUnwindDtor +__CxxCallUnwindVecDtor +__CxxDetectRethrow +__CxxExceptionFilter __CxxFrameHandler +__CxxFrameHandler2 +__CxxFrameHandler3 __CxxLongjmpUnwind +__CxxQueryExceptionSize +__CxxRegisterExceptionObject +__CxxUnregisterExceptionObject +__DestructExceptionObject __RTCastToVoid __RTDynamicCast __RTtypeid __STRINGTOLD +___lc_codepage_func +___lc_collate_cp_func +___lc_handle_func +___mb_cur_max_func +___setlc_active_func +___unguarded_readlc_active_add_func __argc __argv __badioinfo __crtCompareStringA +__crtCompareStringW __crtGetLocaleInfoW +__crtGetStringTypeW __crtLCMapStringA +__crtLCMapStringW +__daylight __dllonexit __doserrno +__dstbias __fpecode __getmainargs __initenv +__iob_func __isascii __iscsym __iscsymf @@ -100,6 +156,27 @@ __lc_codepage __lc_collate_cp __lc_handle __lconv_init +__libm_sse2_acos +__libm_sse2_acosf +__libm_sse2_asin +__libm_sse2_asinf +__libm_sse2_atan +__libm_sse2_atan2 +__libm_sse2_atanf +__libm_sse2_cos +__libm_sse2_cosf +__libm_sse2_exp +__libm_sse2_expf +__libm_sse2_log +__libm_sse2_log10 +__libm_sse2_log10f +__libm_sse2_logf +__libm_sse2_pow +__libm_sse2_powf +__libm_sse2_sin +__libm_sse2_sinf +__libm_sse2_tan +__libm_sse2_tanf __mb_cur_max __p___argc __p___argv @@ -130,22 +207,31 @@ __p__winmajor __p__winminor __p__winver __p__wpgmptr +__pctype_func __pioinfo +__pwctype_func __pxcptinfoptrs __set_app_type __setlc_active __setusermatherr +__strncnt __threadhandle __threadid __toascii __unDName __unDNameEx +__uncaught_exception __unguarded_readlc_active __wargv +__wcserror +__wcserror_s +__wcsncnt __wgetmainargs __winitenv _abnormal_termination +_abs64 _access +_access_s _acmdln _adj_fdiv_m16i _adj_fdiv_m32 @@ -162,44 +248,97 @@ _adj_fprem1 _adj_fptan _adjust_fdiv _aexit_rtn +_aligned_free +_aligned_free_dbg +_aligned_malloc +_aligned_malloc_dbg +_aligned_offset_malloc +_aligned_offset_malloc_dbg +_aligned_offset_realloc +_aligned_offset_realloc_dbg +_aligned_realloc +_aligned_realloc_dbg _amsg_exit _assert _atodbl +_atodbl_l +_atof_l +_atoflt_l _atoi64 +_atoi64_l +_atoi_l +_atol_l _atoldbl +_atoldbl_l _beep _beginthread _beginthreadex _c_exit _cabs _callnewh +_calloc_dbg _cexit _cgets +_cgets_s +_cgetws +_cgetws_s _chdir _chdrive _chgsign _chkesp _chmod _chsize +_chsize_s +_chvalidator +_chvalidator_l _clearfp _close _commit _commode _control87 _controlfp +_controlfp_s _copysign _cprintf +_cprintf_l +_cprintf_p +_cprintf_p_l +_cprintf_s +_cprintf_s_l _cputs +_cputws _creat +_crtAssertBusy +_crtBreakAlloc +_crtDbgFlag _cscanf +_cscanf_l +_cscanf_s +_cscanf_s_l +_ctime32 +_ctime32_s _ctime64 +_ctime64_s _ctype _cwait +_cwprintf +_cwprintf_l +_cwprintf_p +_cwprintf_p_l +_cwprintf_s +_cwprintf_s_l +_cwscanf +_cwscanf_l +_cwscanf_s +_cwscanf_s_l _daylight +_difftime32 +_difftime64 _dstbias _dup _dup2 _ecvt +_ecvt_s _endthread _endthreadex _environ @@ -207,6 +346,7 @@ _eof _errno _except_handler2 _except_handler3 +_except_handler4_common _execl _execle _execlp @@ -217,8 +357,10 @@ _execvp _execvpe _exit _expand +_expand_dbg _fcloseall _fcvt +_fcvt_s _fdopen _fgetchar _fgetwchar @@ -241,21 +383,61 @@ _fmode _fpclass _fpieee_flt _fpreset +_fprintf_l +_fprintf_p +_fprintf_p_l +_fprintf_s_l _fputchar _fputwchar +_free_dbg +_freea +_freea_s +_fscanf_l +_fscanf_s_l +_fseeki64 _fsopen _fstat _fstat64 _fstati64 _ftime +_ftime32 +_ftime32_s _ftime64 +_ftime64_s _ftol +_ftol2 +_ftol2_sse +_ftol2_sse_excpt _fullpath +_fullpath_dbg _futime +_futime32 _futime64 +_fwprintf_l +_fwprintf_p +_fwprintf_p_l +_fwprintf_s_l +_fwscanf_l +_fwscanf_s_l _gcvt +_gcvt_s +_get_doserrno +_get_environ +_get_errno +_get_fileinfo +_get_fmode +_get_heap_handle _get_osfhandle +_get_osplatform +_get_osver +_get_output_format +_get_pgmptr _get_sbh_threshold +_get_wenviron +_get_winmajor +_get_winminor +_get_winver +_get_wpgmptr _getch _getche _getcwd @@ -269,9 +451,14 @@ _getmbcp _getpid _getsystime _getw +_getwch +_getwche _getws _global_unwind2 +_gmtime32 +_gmtime32_s _gmtime64 +_gmtime64_s _heapadd _heapchk _heapmin @@ -280,54 +467,118 @@ _heapused _heapwalk _hypot _i64toa +_i64toa_s _i64tow +_i64tow_s _initterm +_initterm_e _inp _inpd _inpw +_invalid_parameter _iob +_isalnum_l +_isalpha_l _isatty +_iscntrl_l _isctype +_isctype_l +_isdigit_l +_isgraph_l +_isleadbyte_l +_islower_l _ismbbalnum +_ismbbalnum_l _ismbbalpha +_ismbbalpha_l _ismbbgraph +_ismbbgraph_l _ismbbkalnum +_ismbbkalnum_l _ismbbkana +_ismbbkana_l _ismbbkprint +_ismbbkprint_l _ismbbkpunct +_ismbbkpunct_l _ismbblead +_ismbblead_l _ismbbprint +_ismbbprint_l _ismbbpunct +_ismbbpunct_l _ismbbtrail +_ismbbtrail_l _ismbcalnum +_ismbcalnum_l _ismbcalpha +_ismbcalpha_l _ismbcdigit +_ismbcdigit_l _ismbcgraph +_ismbcgraph_l _ismbchira +_ismbchira_l _ismbckata +_ismbckata_l _ismbcl0 +_ismbcl0_l _ismbcl1 +_ismbcl1_l _ismbcl2 +_ismbcl2_l _ismbclegal +_ismbclegal_l _ismbclower +_ismbclower_l _ismbcprint +_ismbcprint_l _ismbcpunct +_ismbcpunct_l _ismbcspace +_ismbcspace_l _ismbcsymbol +_ismbcsymbol_l _ismbcupper +_ismbcupper_l _ismbslead +_ismbslead_l _ismbstrail +_ismbstrail_l _isnan +_isprint_l +_isspace_l +_isupper_l +_iswalnum_l +_iswalpha_l +_iswcntrl_l +_iswctype_l +_iswdigit_l +_iswgraph_l +_iswlower_l +_iswprint_l +_iswpunct_l +_iswspace_l +_iswupper_l +_iswxdigit_l +_isxdigit_l _itoa +_itoa_s _itow +_itow_s _j0 _j1 _jn _kbhit _lfind +_lfind_s _loaddll _local_unwind2 +_local_unwind4 +_localtime32 +_localtime32_s _localtime64 +_localtime64_s _lock _locking _logb @@ -335,72 +586,167 @@ _longjmpex _lrotl _lrotr _lsearch +_lsearch_s _lseek _lseeki64 _ltoa +_ltoa_s _ltow +_ltow_s _makepath +_makepath_s +_malloc_dbg _mbbtombc +_mbbtombc_l _mbbtype _mbcasemap _mbccpy +_mbccpy_l +_mbccpy_s +_mbccpy_s_l _mbcjistojms +_mbcjistojms_l _mbcjmstojis +_mbcjmstojis_l _mbclen +_mbclen_l _mbctohira +_mbctohira_l _mbctokata +_mbctokata_l _mbctolower +_mbctolower_l _mbctombb +_mbctombb_l _mbctoupper +_mbctoupper_l _mbctype +_mblen_l _mbsbtype +_mbsbtype_l _mbscat +_mbscat_s +_mbscat_s_l _mbschr +_mbschr_l _mbscmp +_mbscmp_l _mbscoll +_mbscoll_l _mbscpy +_mbscpy_s +_mbscpy_s_l _mbscspn +_mbscspn_l _mbsdec +_mbsdec_l _mbsdup _mbsicmp +_mbsicmp_l _mbsicoll +_mbsicoll_l _mbsinc +_mbsinc_l _mbslen +_mbslen_l _mbslwr +_mbslwr_l +_mbslwr_s +_mbslwr_s_l _mbsnbcat +_mbsnbcat_l +_mbsnbcat_s +_mbsnbcat_s_l _mbsnbcmp +_mbsnbcmp_l _mbsnbcnt +_mbsnbcnt_l _mbsnbcoll +_mbsnbcoll_l _mbsnbcpy +_mbsnbcpy_l +_mbsnbcpy_s +_mbsnbcpy_s_l _mbsnbicmp +_mbsnbicmp_l _mbsnbicoll +_mbsnbicoll_l _mbsnbset +_mbsnbset_l +_mbsnbset_s +_mbsnbset_s_l _mbsncat +_mbsncat_l +_mbsncat_s +_mbsncat_s_l _mbsnccnt +_mbsnccnt_l _mbsncmp +_mbsncmp_l _mbsncoll +_mbsncoll_l _mbsncpy +_mbsncpy_l +_mbsncpy_s +_mbsncpy_s_l _mbsnextc +_mbsnextc_l _mbsnicmp +_mbsnicmp_l _mbsnicoll +_mbsnicoll_l _mbsninc +_mbsninc_l +_mbsnlen +_mbsnlen_l _mbsnset +_mbsnset_l +_mbsnset_s +_mbsnset_s_l _mbspbrk +_mbspbrk_l _mbsrchr +_mbsrchr_l _mbsrev +_mbsrev_l _mbsset +_mbsset_l +_mbsset_s +_mbsset_s_l _mbsspn +_mbsspn_l _mbsspnp +_mbsspnp_l _mbsstr +_mbsstr_l _mbstok +_mbstok_l +_mbstok_s +_mbstok_s_l +_mbstowcs_l +_mbstowcs_s_l _mbstrlen +_mbstrlen_l +_mbstrnlen +_mbstrnlen_l _mbsupr +_mbsupr_l +_mbsupr_s +_mbsupr_s_l +_mbtowc_l _memccpy _memicmp +_memicmp_l _mkdir +_mkgmtime +_mkgmtime32 +_mkgmtime64 _mktemp +_mktemp_s +_mktime32 _mktime64 _msize +_msize_debug _nextafter _onexit _open @@ -415,25 +761,52 @@ _pctype _pgmptr _pipe _popen +_printf_l +_printf_p +_printf_p_l +_printf_s_l _purecall _putch _putenv +_putenv_s _putw +_putwch _putws _pwctype _read +_realloc_dbg +_resetstkoflw _rmdir _rmtmp _rotl +_rotl64 _rotr +_rotr64 _safe_fdiv _safe_fdivr _safe_fprem _safe_fprem1 _scalb +_scanf_l +_scanf_s_l +_scprintf +_scprintf_l +_scprintf_p_l +_scwprintf +_scwprintf_l +_scwprintf_p_l _searchenv +_searchenv_s _seh_longjmp_unwind +_seh_longjmp_unwind4 +_set_SSE2_enable +_set_controlfp +_set_doserrno +_set_errno _set_error_mode +_set_fileinfo +_set_fmode +_set_output_format _set_sbh_threshold _seterrormode _setjmp @@ -444,8 +817,25 @@ _setmode _setsystime _sleep _snprintf +_snprintf_c +_snprintf_c_l +_snprintf_l +_snprintf_s +_snprintf_s_l +_snscanf +_snscanf_l +_snscanf_s +_snscanf_s_l _snwprintf +_snwprintf_l +_snwprintf_s +_snwprintf_s_l +_snwscanf +_snwscanf_l +_snwscanf_s +_snwscanf_s_l _sopen +_sopen_s _spawnl _spawnle _spawnlp @@ -455,69 +845,209 @@ _spawnve _spawnvp _spawnvpe _splitpath +_splitpath_s +_sprintf_l +_sprintf_p_l +_sprintf_s_l +_sscanf_l +_sscanf_s_l _stat _stat64 _stati64 _statusfp _strcmpi +_strcoll_l _strdate +_strdate_s _strdup +_strdup_dbg _strerror +_strerror_s _stricmp +_stricmp_l _stricoll +_stricoll_l _strlwr +_strlwr_l +_strlwr_s +_strlwr_s_l _strncoll +_strncoll_l _strnicmp +_strnicmp_l _strnicoll +_strnicoll_l _strnset +_strnset_s _strrev _strset +_strset_s _strtime +_strtime_s +_strtod_l +_strtoi64 +_strtoi64_l +_strtol_l +_strtoui64 +_strtoui64_l +_strtoul_l _strupr +_strupr_l +_strupr_s +_strupr_s_l +_strxfrm_l _swab +_swprintf +_swprintf_c +_swprintf_c_l +_swprintf_p_l +_swprintf_s_l +_swscanf_l +_swscanf_s_l _sys_errlist _sys_nerr _tell _telli64 _tempnam +_tempnam_dbg +_time32 _time64 _timezone _tolower +_tolower_l _toupper +_toupper_l +_towlower_l +_towupper_l _tzname _tzset _ui64toa +_ui64toa_s _ui64tow +_ui64tow_s _ultoa +_ultoa_s _ultow +_ultow_s _umask +_umask_s _ungetch +_ungetwch _unlink _unloaddll _unlock _utime +_utime32 _utime64 +_vcprintf +_vcprintf_l +_vcprintf_p +_vcprintf_p_l +_vcprintf_s +_vcprintf_s_l +_vcwprintf +_vcwprintf_l +_vcwprintf_p +_vcwprintf_p_l +_vcwprintf_s +_vcwprintf_s_l +_vfprintf_l +_vfprintf_p +_vfprintf_p_l +_vfprintf_s_l +_vfwprintf_l +_vfwprintf_p +_vfwprintf_p_l +_vfwprintf_s_l +_vprintf_l +_vprintf_p +_vprintf_p_l +_vprintf_s_l +_vscprintf +_vscprintf_l +_vscprintf_p_l +_vscwprintf +_vscwprintf_l +_vscwprintf_p_l _vsnprintf +_vsnprintf_c +_vsnprintf_c_l +_vsnprintf_l +_vsnprintf_s +_vsnprintf_s_l _vsnwprintf +_vsnwprintf_l +_vsnwprintf_s +_vsnwprintf_s_l +_vsprintf_l +_vsprintf_p +_vsprintf_p_l +_vsprintf_s_l +_vswprintf +_vswprintf_c +_vswprintf_c_l +_vswprintf_l +_vswprintf_p_l +_vswprintf_s_l +_vwprintf_l +_vwprintf_p +_vwprintf_p_l +_vwprintf_s_l _waccess +_waccess_s _wasctime +_wasctime_s +_wassert _wchdir _wchmod _wcmdln _wcreat +_wcscoll_l _wcsdup +_wcsdup_dbg +_wcserror +_wcserror_s +_wcsftime_l _wcsicmp +_wcsicmp_l _wcsicoll +_wcsicoll_l _wcslwr +_wcslwr_l +_wcslwr_s +_wcslwr_s_l _wcsncoll +_wcsncoll_l _wcsnicmp +_wcsnicmp_l _wcsnicoll +_wcsnicoll_l _wcsnset +_wcsnset_s _wcsrev _wcsset +_wcsset_s +_wcstoi64 +_wcstoi64_l +_wcstol_l +_wcstombs_l +_wcstombs_s_l +_wcstoui64 +_wcstoui64_l +_wcstoul_l _wcsupr +_wcsupr_l +_wcsupr_s +_wcsupr_s_l +_wcsxfrm_l _wctime +_wctime32 +_wctime32_s _wctime64 +_wctime64_s +_wctomb_l +_wctomb_s_l +_wctype _wenviron _wexecl _wexecle @@ -535,30 +1065,47 @@ _wfindnext _wfindnext64 _wfindnexti64 _wfopen +_wfopen_s _wfreopen +_wfreopen_s _wfsopen _wfullpath +_wfullpath_dbg _wgetcwd _wgetdcwd _wgetenv +_wgetenv_s _winmajor _winminor +_winput_s _winver _wmakepath +_wmakepath_s _wmkdir _wmktemp +_wmktemp_s _wopen +_woutput_s _wperror _wpgmptr _wpopen +_wprintf_l +_wprintf_p +_wprintf_p_l +_wprintf_s_l _wputenv +_wputenv_s _wremove _wrename _write _wrmdir +_wscanf_l +_wscanf_s_l _wsearchenv +_wsearchenv_s _wsetlocale _wsopen +_wsopen_s _wspawnl _wspawnle _wspawnlp @@ -568,19 +1115,30 @@ _wspawnve _wspawnvp _wspawnvpe _wsplitpath +_wsplitpath_s _wstat _wstat64 _wstati64 _wstrdate +_wstrdate_s _wstrtime +_wstrtime_s _wsystem _wtempnam +_wtempnam_dbg _wtmpnam +_wtmpnam_s +_wtof +_wtof_l _wtoi _wtoi64 +_wtoi64_l +_wtoi_l _wtol +_wtol_l _wunlink _wutime +_wutime32 _wutime64 _y0 _y1 @@ -589,6 +1147,7 @@ abort abs acos asctime +asctime_s asin atan atan2 @@ -597,9 +1156,12 @@ atof atoi atol bsearch +bsearch_s +btowc calloc ceil clearerr +clearerr_s clock cos cosh @@ -621,7 +1183,9 @@ fgetws floor fmod fopen +fopen_s fprintf +fprintf_s fputc fputs fputwc @@ -629,17 +1193,22 @@ fputws fread free freopen +freopen_s frexp fscanf +fscanf_s fseek fsetpos ftell fwprintf +fwprintf_s fwrite fwscanf +fwscanf_s getc getchar getenv +getenv_s gets getwc getwchar @@ -680,31 +1249,43 @@ log10 longjmp malloc mblen +mbrlen +mbrtowc +mbsdup_dbg +mbsrtowcs +mbsrtowcs_s mbstowcs +mbstowcs_s mbtowc memchr memcmp memcpy +memcpy_s memmove +memmove_s memset mktime modf perror pow printf +printf_s putc putchar puts putwc putwchar qsort +qsort_s raise rand +rand_s realloc remove rename rewind scanf +scanf_s setbuf setlocale setvbuf @@ -712,71 +1293,107 @@ signal sin sinh sprintf +sprintf_s sqrt srand sscanf +sscanf_s strcat +strcat_s strchr strcmp strcoll strcpy +strcpy_s strcspn strerror +strerror_s strftime strlen strncat +strncat_s strncmp strncpy +strncpy_s +strnlen strpbrk strrchr strspn strstr strtod strtok +strtok_s strtol strtoul strxfrm swprintf +swprintf_s swscanf +swscanf_s system tan tanh time tmpfile +tmpfile_s tmpnam +tmpnam_s tolower toupper towlower towupper ungetc ungetwc +utime vfprintf +vfprintf_s vfwprintf +vfwprintf_s vprintf +vprintf_s +vsnprintf vsprintf +vsprintf_s vswprintf +vswprintf_s vwprintf +vwprintf_s +wcrtomb +wcrtomb_s wcscat +wcscat_s wcschr wcscmp wcscoll wcscpy +wcscpy_s wcscspn wcsftime wcslen wcsncat +wcsncat_s wcsncmp wcsncpy +wcsncpy_s +wcsnlen wcspbrk wcsrchr +wcsrtombs +wcsrtombs_s wcsspn wcsstr wcstod wcstok +wcstok_s wcstol wcstombs +wcstombs_s wcstoul wcsxfrm +wctob wctomb +wctomb_s wprintf +wprintf_s wscanf +wscanf_s diff --git a/tinyc/win32/lib/user32.def b/tinyc/win32/lib/user32.def index 4d2f704e1..a034dac20 100644 --- a/tinyc/win32/lib/user32.def +++ b/tinyc/win32/lib/user32.def @@ -336,6 +336,10 @@ GetWindow GetWindowContextHelpId GetWindowDC GetWindowInfo +GetWindowLongPtrA +GetWindowLongPtrW +SetWindowLongPtrA +SetWindowLongPtrW GetWindowLongA GetWindowLongW GetWindowModuleFileNameA diff --git a/tinyc/win32/lib/wincrt1.c b/tinyc/win32/lib/wincrt1.c index 98edb6b9b..ce3a63f13 100644 --- a/tinyc/win32/lib/wincrt1.c +++ b/tinyc/win32/lib/wincrt1.c @@ -1,6 +1,10 @@ //+--------------------------------------------------------------------------- +// _UNICODE for tchar.h, UNICODE for API +#include <tchar.h> + #include <windows.h> +#include <stdlib.h> #define __UNKNOWN_APP 0 #define __CONSOLE_APP 1 @@ -8,42 +12,64 @@ void __set_app_type(int); void _controlfp(unsigned a, unsigned b); -int _winstart(void) +#ifdef _UNICODE +#define __tgetmainargs __wgetmainargs +#define _twinstart _wwinstart +#define _runtwinmain _runwwinmain +int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); +#else +#define __tgetmainargs __getmainargs +#define _twinstart _winstart +#define _runtwinmain _runwinmain +#endif + +typedef struct { int newmode; } _startupinfo; +int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); + +static int go_winmain(TCHAR *arg1) { - char *szCmd; STARTUPINFO startinfo; - - __set_app_type(__GUI_APP); - _controlfp(0x10000, 0x30000); - - szCmd = GetCommandLine(); - if (szCmd) - { - while (' ' == *szCmd) szCmd++; - if ('\"' == *szCmd) - { - while (*++szCmd) - if ('\"' == *szCmd) { szCmd++; break; } - } - else - { - while (*szCmd && ' ' != *szCmd) szCmd++; - } - while (' ' == *szCmd) szCmd++; - } - - GetStartupInfo(&startinfo); - exit(WinMain(GetModuleHandle(NULL), NULL, szCmd, - (startinfo.dwFlags & STARTF_USESHOWWINDOW) ? - startinfo.wShowWindow : SW_SHOWDEFAULT)); + STARTUPINFO si; + _TCHAR *szCmd, *p; + int fShow; + + GetStartupInfo(&si); + if (si.dwFlags & STARTF_USESHOWWINDOW) + fShow = si.wShowWindow; + else + fShow = SW_SHOWDEFAULT; + + szCmd = NULL, p = GetCommandLine(); + if (arg1) + szCmd = _tcsstr(p, arg1); + if (NULL == szCmd) + szCmd = _tcsdup(__T("")); + else if (szCmd > p && szCmd[-1] == __T('"')) + --szCmd; +#if defined __i386__ || defined __x86_64__ + _controlfp(0x10000, 0x30000); +#endif + return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); } -int _runwinmain(int argc, char **argv) +int _twinstart(void) { - char *szCmd = NULL; - char *p = GetCommandLine(); - if (argc > 1) szCmd = strstr(p, argv[1]); - if (NULL == szCmd) szCmd = ""; - else if (szCmd > p && szCmd[-1] == '\"') --szCmd; - return WinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT); + __TRY__ + _startupinfo start_info_con = {0}; + __set_app_type(__GUI_APP); + __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con); + exit(go_winmain(__argc > 1 ? __targv[1] : NULL)); } +int _runtwinmain(int argc, /* as tcc passed in */ char **argv) +{ +#ifdef UNICODE + _startupinfo start_info = {0}; + __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info); + /* may be wrong when tcc has received wildcards (*.c) */ + if (argc < __argc) + __targv += __argc - argc, __argc = argc; +#else + __argc = argc, __targv = argv; +#endif + return go_winmain(__argc > 1 ? __targv[1] : NULL); +} diff --git a/tinyc/win32/lib/wincrt1w.c b/tinyc/win32/lib/wincrt1w.c new file mode 100644 index 000000000..a7d349e10 --- /dev/null +++ b/tinyc/win32/lib/wincrt1w.c @@ -0,0 +1,3 @@ +#define _UNICODE 1 +#define UNICODE 1 +#include "wincrt1.c" diff --git a/tinyc/win32/libtcc/libtcc.a b/tinyc/win32/libtcc/libtcc.a deleted file mode 100644 index c2d107453..000000000 --- a/tinyc/win32/libtcc/libtcc.a +++ /dev/null Binary files differdiff --git a/tinyc/win32/libtcc/libtcc.h b/tinyc/win32/libtcc/libtcc.h deleted file mode 100644 index 96070e299..000000000 --- a/tinyc/win32/libtcc/libtcc.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef LIBTCC_H -#define LIBTCC_H - -#ifdef LIBTCC_AS_DLL -#define LIBTCCAPI __declspec(dllexport) -#else -#define LIBTCCAPI -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -struct TCCState; - -typedef struct TCCState TCCState; - -/* create a new TCC compilation context */ -LIBTCCAPI TCCState *tcc_new(void); - -/* free a TCC compilation context */ -LIBTCCAPI void tcc_delete(TCCState *s); - -/* add debug information in the generated code */ -LIBTCCAPI void tcc_enable_debug(TCCState *s); - -/* set error/warning display callback */ -LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, - void (*error_func)(void *opaque, const char *msg)); - -/* set/reset a warning */ -LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value); - -/*****************************/ -/* preprocessor */ - -/* add include path */ -LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname); - -/* add in system include path */ -LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname); - -/* define preprocessor symbol 'sym'. Can put optional value */ -LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value); - -/* undefine preprocess symbol 'sym' */ -LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym); - -/*****************************/ -/* compiling */ - -/* add a file (either a C file, dll, an object, a library or an ld - script). Return -1 if error. */ -LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename); - -/* compile a string containing a C source. Return non zero if - error. */ -LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf); - -/*****************************/ -/* linking commands */ - -/* set output type. MUST BE CALLED before any compilation */ -#define TCC_OUTPUT_MEMORY 0 /* output will be ran in memory (no - output file) (default) */ -#define TCC_OUTPUT_EXE 1 /* executable file */ -#define TCC_OUTPUT_DLL 2 /* dynamic library */ -#define TCC_OUTPUT_OBJ 3 /* object file */ -#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */ -LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type); - -#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */ -#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */ -#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */ - -/* equivalent to -Lpath option */ -LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname); - -/* the library name is the same as the argument of the '-l' option */ -LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname); - -/* add a symbol to the compiled program */ -LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val); - -/* output an executable, library or object file. DO NOT call - tcc_relocate() before. */ -LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename); - -/* link and run main() function and return its value. DO NOT call - tcc_relocate() before. */ -LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv); - -/* copy code into memory passed in by the caller and do all relocations - (needed before using tcc_get_symbol()). - returns -1 on error and required size if ptr is NULL */ -LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr); - -/* return symbol value or NULL if not found */ -LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name); - -/* set CONFIG_TCCDIR at runtime */ -LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/tinyc/win32/tcc-win32.txt b/tinyc/win32/tcc-win32.txt index c720272fc..751a8e074 100644 --- a/tinyc/win32/tcc-win32.txt +++ b/tinyc/win32/tcc-win32.txt @@ -6,40 +6,10 @@ under MS-Windows. See tcc-doc.html to have all the features. - - Compilation from source: - ------------------------ - * You can use the MinGW and MSYS tools available at - - http://www.mingw.org - - Untar the TCC archive and type in the MSYS shell: - - ./configure - make - make install - - The default install location is c:\Program Files\tcc - - - * Alternatively you can compile TCC with just GCC from MinGW using - - win32\build-tcc.bat - - To install, copy the entire contents of the win32 directory to - where you want. - - - Installation from the binary ZIP package: ----------------------------------------- Unzip the package to a directory of your choice. - - (Note that the binary package does not include libtcc. If you - want TCC as dynamic code generator, please use the source code - distribution.) - - + Set the system PATH: -------------------- @@ -48,6 +18,11 @@ system PATH. + Include and library search paths + -------------------------------- + On windows, the standard "include" and "lib" directories are searched + relatively from the location of the executables (tcc.exe, libtcc.dll). + Examples: --------- @@ -61,29 +36,45 @@ tcc hello_win.c - for the 'Hello DLL' example type + For the 'Hello DLL' example type tcc -shared dll.c - tiny_impdef dll.dll (optional) + tcc -impdef dll.dll (optional) tcc hello_dll.c dll.def + Using libtcc as JIT compiler in your program + -------------------------------------------- + Check out the 'libtcc_test' example: + + - Running it from source: + tcc -I libtcc libtcc/libtcc.def -run examples/libtcc_test.c + + - Compiling with TCC: + tcc examples/libtcc_test.c -I libtcc libtcc/libtcc.def + + - Compiling with MinGW: + gcc examples/libtcc_test.c -I libtcc libtcc.dll -o libtcc_test.exe + + - Compiling with MSVC: + lib /def:libtcc\libtcc.def /out:libtcc.lib + cl /MD examples/libtcc_test.c -I libtcc libtcc.lib + Import Definition Files: ------------------------ To link with Windows system DLLs, TCC uses import definition files (.def) instead of libraries. - The included 'tiny_impdef' program may be used to make additional - .def files for any DLL. For example: + The now built-in 'tiny_impdef' program may be used to make + additional .def files for any DLL. For example - tiny_impdef.exe opengl32.dll + tcc -impdef [-v] opengl32.dll [-o opengl32.def] Put opengl32.def into the tcc/lib directory. Specify -lopengl32 at the TCC commandline to link a program that uses opengl32.dll. - Header Files: ------------- The system header files (except _mingw.h) are from the MinGW @@ -92,8 +83,8 @@ http://www.mingw.org/ From the windows headers, only a minimal set is included. If you need - more, get MinGW's "w32api" package. - + more, get MinGW's "w32api" package. Extract the files from "include" + into your "tcc/include/winapi" directory. Resource Files: @@ -105,33 +96,54 @@ tcc app.c appres.o -o app.exe - Tiny Libmaker: -------------- - The included tiny_libmaker tool by Timovj Lahde can be used as + The now built-in tiny_libmaker tool by Timovj Lahde can be used as 'ar' replacement to make a library from several object files: - tiny_libmaker [rcs] library objectfiles ... + tcc -ar [rcsv] library objectfiles ... + Compilation from source: + ------------------------ + * You can use the MinGW and MSYS tools available at + http://www.mingw.org + http://www.mingw-w64.org + http://www.msys2.org - Limitations: - ------------ - - On the object file level, currently TCC supports only the ELF format, - not COFF as used by MinGW and MSVC. It is not possible to exchange - object files or libraries between TCC and these compilers. However - libraries for TCC from objects by TCC can be made using tiny_libmaker - or MinGW's ar. + Untar the TCC archive and type in the MSYS shell: + ./configure [--prefix installpath] + make + make install - - No leading underscore is generated in the ELF symbols. + The default install location is c:\Program Files\tcc + + Cygwin can be used too with its mingw cross-compiler installed: + ./configure --cross-prefix=i686-w64-mingw32- + (the prefix may vary) + + * Alternatively you can compile TCC with just GCC from MinGW using + > build-tcc.bat (from the win32 directory) + + Also MSVC can be used with the "VSTools Developer Command Prompt": + > build-tcc.bat -c cl - - With DLLs, only functions (not data) can be im-/exported. + or with an existing tcc (needs to be in a different directory) + > build-tcc.bat -c some-tcc-dir\tcc.exe - - Bounds checking (option -b) is not supported currently. + Also you can copy/install everything into another directory: + > build-tcc.bat -i <dir> - - 64-bit systems are not (yet) supported. + Limitations: + ------------ + - On the object file level, currently TCC supports only the ELF format, + not COFF as used by MinGW and MSVC. It is not possible to exchange + object files or libraries between TCC and these compilers. + However libraries for TCC from objects by TCC can be made using + tcc -ar lib.a files.o ,,, + - No leading underscore is generated in the ELF symbols. Documentation and License: -------------------------- @@ -143,7 +155,6 @@ http://fabrice.bellard.free.fr/tcc/ - WinAPI Help and 3rd-party tools: -------------------------------- The Windows API documentation (Win95) in a single .hlp file is @@ -154,5 +165,4 @@ "ResEd", available at the RadASM website. - --- grischka diff --git a/tinyc/win32/tools/tiny_impdef.c b/tinyc/win32/tools/tiny_impdef.c deleted file mode 100644 index 040c53acc..000000000 --- a/tinyc/win32/tools/tiny_impdef.c +++ /dev/null @@ -1,393 +0,0 @@ -/* -------------------------------------------------------------- */ -/* - * tiny_impdef creates an export definition file (.def) from a dll - * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]" - * - * Copyright (c) 2005,2007 grischka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <stdio.h> - -/* Offset to PE file signature */ -#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + \ - ((PIMAGE_DOS_HEADER)a)->e_lfanew)) - -/* MS-OS header identifies the NT PEFile signature dword; - the PEFILE header exists just after that dword. */ -#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + \ - ((PIMAGE_DOS_HEADER)a)->e_lfanew + \ - SIZE_OF_NT_SIGNATURE)) - -/* PE optional header is immediately after PEFile header. */ -#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + \ - ((PIMAGE_DOS_HEADER)a)->e_lfanew + \ - SIZE_OF_NT_SIGNATURE + \ - sizeof (IMAGE_FILE_HEADER))) - -/* Section headers are immediately after PE optional header. */ -#define SECHDROFFSET(a) ((LPVOID)((BYTE *)a + \ - ((PIMAGE_DOS_HEADER)a)->e_lfanew + \ - SIZE_OF_NT_SIGNATURE + \ - sizeof (IMAGE_FILE_HEADER) + \ - sizeof (IMAGE_OPTIONAL_HEADER))) - - -#define SIZE_OF_NT_SIGNATURE 4 - -/* -------------------------------------------------------------- */ - -int WINAPI NumOfSections ( - LPVOID lpFile) -{ - /* Number of sections is indicated in file header. */ - return (int) - ((PIMAGE_FILE_HEADER) - PEFHDROFFSET(lpFile))->NumberOfSections; -} - - -/* -------------------------------------------------------------- */ - -LPVOID WINAPI ImageDirectoryOffset ( - LPVOID lpFile, - DWORD dwIMAGE_DIRECTORY) -{ - PIMAGE_OPTIONAL_HEADER poh; - PIMAGE_SECTION_HEADER psh; - int nSections = NumOfSections (lpFile); - int i = 0; - LPVOID VAImageDir; - - /* Retrieve offsets to optional and section headers. */ - poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile); - psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile); - - /* Must be 0 thru (NumberOfRvaAndSizes-1). */ - if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes) - return NULL; - - /* Locate image directory's relative virtual address. */ - VAImageDir = (LPVOID)poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress; - - /* Locate section containing image directory. */ - while (i++<nSections) - { - if (psh->VirtualAddress <= (DWORD)VAImageDir - && psh->VirtualAddress + psh->SizeOfRawData > (DWORD)VAImageDir) - break; - psh++; - } - - if (i > nSections) - return NULL; - - /* Return image import directory offset. */ - return (LPVOID)(((int)lpFile + - (int)VAImageDir - psh->VirtualAddress) + - (int)psh->PointerToRawData); -} - -/* -------------------------------------------------------------- */ - -BOOL WINAPI GetSectionHdrByName ( - LPVOID lpFile, - IMAGE_SECTION_HEADER *sh, - char *szSection) -{ - PIMAGE_SECTION_HEADER psh; - int nSections = NumOfSections (lpFile); - int i; - - if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) != NULL) - { - /* find the section by name */ - for (i=0; i<nSections; i++) - { - if (!strcmp (psh->Name, szSection)) - { - /* copy data to header */ - memcpy ((LPVOID)sh, (LPVOID)psh, sizeof (IMAGE_SECTION_HEADER)); - return TRUE; - } - else - psh++; - } - } - return FALSE; -} - -/* -------------------------------------------------------------- */ - -BOOL WINAPI GetSectionHdrByAddress ( - LPVOID lpFile, - IMAGE_SECTION_HEADER *sh, - DWORD addr) -{ - PIMAGE_SECTION_HEADER psh; - int nSections = NumOfSections (lpFile); - int i; - - if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) != NULL) - { - /* find the section by name */ - for (i=0; i<nSections; i++) - { - if (addr >= psh->VirtualAddress - && addr < psh->VirtualAddress + psh->SizeOfRawData) - { - /* copy data to header */ - memcpy ((LPVOID)sh, (LPVOID)psh, sizeof (IMAGE_SECTION_HEADER)); - return TRUE; - } - else - psh++; - } - } - return FALSE; -} - -/* -------------------------------------------------------------- */ - -int WINAPI GetExportFunctionNames ( - LPVOID lpFile, - HANDLE hHeap, - char **pszFunctions) -{ - IMAGE_SECTION_HEADER sh; - PIMAGE_EXPORT_DIRECTORY ped; - int *pNames, *pCnt; - char *pSrc, *pDest; - int i, nCnt; - DWORD VAImageDir; - PIMAGE_OPTIONAL_HEADER poh; - char *pOffset; - - /* Get section header and pointer to data directory - for .edata section. */ - if (NULL == (ped = (PIMAGE_EXPORT_DIRECTORY) - ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT))) - return 0; - - poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile); - VAImageDir = poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - - if (FALSE == GetSectionHdrByAddress (lpFile, &sh, VAImageDir)) - return 0; - - pOffset = (char *)lpFile + (sh.PointerToRawData - sh.VirtualAddress); - - pNames = (int *)(pOffset + (DWORD)ped->AddressOfNames); - - /* Figure out how much memory to allocate for all strings. */ - nCnt = 1; - for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++) - { - pSrc = (pOffset + *pCnt++); - if (pSrc) - nCnt += strlen(pSrc)+1; - } - - /* Allocate memory off heap for function names. */ - pDest = *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nCnt); - - /* Copy all strings to buffer. */ - for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++) - { - pSrc = (pOffset + *pCnt++); - if (pSrc) { - strcpy(pDest, pSrc); - pDest += strlen(pSrc)+1; - } - } - *pDest = 0; - - return ped->NumberOfNames; -} - -/* -------------------------------------------------------------- */ -/* extract the basename of a file */ - -static char *file_basename(const char *name) -{ - const char *p = strchr(name, 0); - while (p > name - && p[-1] != '/' - && p[-1] != '\\' - ) - --p; - return (char*)p; -} - -/* -------------------------------------------------------------- */ - -int main(int argc, char **argv) -{ - HANDLE hHeap; - HANDLE hFile; - HANDLE hMapObject; - VOID *pMem; - - int nCnt, ret, n; - char *pNames; - char infile[MAX_PATH]; - char buffer[MAX_PATH]; - char outfile[MAX_PATH]; - FILE *op; - char *p; - - hHeap = NULL; - hFile = NULL; - hMapObject = NULL; - pMem = NULL; - infile[0] = 0; - outfile[0] = 0; - ret = 1; - - for (n = 1; n < argc; ++n) - { - const char *a = argv[n]; - if ('-' == a[0]) { - if (0 == strcmp(a, "-o")) { - if (++n == argc) - goto usage; - strcpy(outfile, argv[n]); - } - else - goto usage; - - } else if (0 == infile[0]) - strcpy(infile, a); - else - goto usage; - } - - if (0 == infile[0]) - { -usage: - fprintf(stderr, - "tiny_impdef creates an export definition file (.def) from a dll\n" - "Usage: tiny_impdef library.dll [-o outputfile]\n" - ); - goto the_end; - } - - if (SearchPath(NULL, infile, ".dll", sizeof buffer, buffer, NULL)) - strcpy(infile, buffer); - - if (0 == outfile[0]) - { - char *p; - strcpy(outfile, file_basename(infile)); - p = strrchr(outfile, '.'); - if (NULL == p) - p = strchr(outfile, 0); - strcpy(p, ".def"); - } - - hFile = CreateFile( - infile, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - 0, - NULL - ); - - if (hFile == INVALID_HANDLE_VALUE) - { - fprintf(stderr, "No such file: %s\n", infile); - goto the_end; - } - - - hMapObject = CreateFileMapping( - hFile, - NULL, - PAGE_READONLY, - 0, 0, - NULL - ); - - if (NULL == hMapObject) - { - fprintf(stderr, "Could not create file mapping: %s\n", infile); - goto the_end; - } - - pMem = MapViewOfFile( - hMapObject, // object to map view of - FILE_MAP_READ, // read access - 0, // high offset: map from - 0, // low offset: beginning - 0); // default: map entire file - - if (NULL == pMem) - { - fprintf(stderr, "Could not map view of file: %s\n", infile); - goto the_end; - } - - if (0 != strncmp(NTSIGNATURE(pMem), "PE", 2)) - { - fprintf(stderr, "Not a PE file: %s\n", infile); - goto the_end; - } - - - hHeap = GetProcessHeap(); - nCnt = GetExportFunctionNames(pMem, hHeap, &pNames); - if (0 == nCnt) { - fprintf(stderr, "Could not get exported function names: %s\n", infile); - goto the_end; - } - - printf("--> %s\n", infile); - - op = fopen(outfile, "w"); - if (NULL == op) - { - fprintf(stderr, "Could not create file: %s\n", outfile); - goto the_end; - } - - printf("<-- %s\n", outfile); - - fprintf(op, "LIBRARY %s\n\nEXPORTS\n", file_basename(infile)); - for (n = 0, p = pNames; n < nCnt; ++n) - { - fprintf(op, "%s\n", p); - while (*p++); - } - ret = 0; - -the_end: - if (pMem) - UnmapViewOfFile(pMem); - - if (hMapObject) - CloseHandle(hMapObject); - - if (hFile) - CloseHandle(hFile); - - return ret; -} - -/* -------------------------------------------------------------- */ diff --git a/tinyc/win32/tools/tiny_libmaker.c b/tinyc/win32/tools/tiny_libmaker.c deleted file mode 100644 index cf9ac67bc..000000000 --- a/tinyc/win32/tools/tiny_libmaker.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * This program is for making libtcc1.a without ar - * tiny_libmaker - tiny elf lib maker - * usage: tiny_libmaker [lib] files... - * Copyright (c) 2007 Timppa - * - * This program is free software but WITHOUT ANY WARRANTY - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef _WIN32 -#include <io.h> /* for mktemp */ -#endif - -/* #include "ar-elf.h" */ -/* "ar-elf.h" */ -/* ELF_v1.2.pdf */ -typedef unsigned short int Elf32_Half; -typedef int Elf32_Sword; -typedef unsigned int Elf32_Word; -typedef unsigned int Elf32_Addr; -typedef unsigned int Elf32_Off; -typedef unsigned short int Elf32_Section; - -#define EI_NIDENT 16 -typedef struct { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; -} Elf32_Ehdr; - -typedef struct { - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; -} Elf32_Shdr; - -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 - -typedef struct { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; -} Elf32_Sym; - -#define ELF32_ST_BIND(i) ((i)>>4) -#define ELF32_ST_TYPE(i) ((i)&0xf) -#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) - -#define STT_NOTYPE 0 -#define STT_OBJECT 1 -#define STT_FUNC 2 -#define STT_SECTION 3 -#define STT_FILE 4 -#define STT_LOPROC 13 -#define STT_HIPROC 15 - -#define STB_LOCAL 0 -#define STB_GLOBAL 1 -#define STB_WEAK 2 -#define STB_LOPROC 13 -#define STB_HIPROC 15 - -typedef struct { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; -/* "ar-elf.h" ends */ - -#define ARMAG "!<arch>\n" -#define ARFMAG "`\n" - -typedef struct ArHdr { - char ar_name[16]; - char ar_date[12]; - char ar_uid[6]; - char ar_gid[6]; - char ar_mode[8]; - char ar_size[10]; - char ar_fmag[2]; -} ArHdr; - - -unsigned long le2belong(unsigned long ul) { - return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) + - ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8); -} - -ArHdr arhdr = { - "/ ", - " ", - "0 ", - "0 ", - "0 ", - " ", - ARFMAG - }; - -ArHdr arhdro = { - " ", - " ", - "0 ", - "0 ", - "0 ", - " ", - ARFMAG - }; - -int main(int argc, char **argv) -{ - FILE *fi, *fh, *fo; - Elf32_Ehdr *ehdr; - Elf32_Shdr *shdr; - Elf32_Sym *sym; - int i, fsize, iarg; - char *buf, *shstr, *symtab = NULL, *strtab = NULL; - int symtabsize = 0, strtabsize = 0; - char *anames = NULL; - int *afpos = NULL; - int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs; - char afile[260], tfile[260], stmp[20]; - - - strcpy(afile, "ar_test.a"); - iarg = 1; - - if (argc < 2) - { - printf("usage: tiny_libmaker [lib] file...\n"); - return 1; - } - for (i=1; i<argc; i++) { - istrlen = strlen(argv[i]); - if (argv[i][istrlen-2] == '.') { - if(argv[i][istrlen-1] == 'a') - strcpy(afile, argv[i]); - else if(argv[i][istrlen-1] == 'o') { - iarg = i; - break; - } - } - } - - strcpy(tfile, "./XXXXXX"); - if (!mktemp(tfile) || (fo = fopen(tfile, "wb+")) == NULL) - { - fprintf(stderr, "Can't open temporary file %s\n", tfile); - return 2; - } - - if ((fh = fopen(afile, "wb")) == NULL) - { - fprintf(stderr, "Can't open file %s \n", afile); - remove(tfile); - return 2; - } - - funcmax = 250; - afpos = realloc(NULL, funcmax * sizeof *afpos); // 250 func - memcpy(&arhdro.ar_mode, "100666", 6); - - //iarg = 1; - while (iarg < argc) - { - if (!strcmp(argv[iarg], "rcs")) { - iarg++; - continue; - } - if ((fi = fopen(argv[iarg], "rb")) == NULL) - { - fprintf(stderr, "Can't open file %s \n", argv[iarg]); - remove(tfile); - return 2; - } - fseek(fi, 0, SEEK_END); - fsize = ftell(fi); - fseek(fi, 0, SEEK_SET); - buf = malloc(fsize + 1); - fread(buf, fsize, 1, fi); - fclose(fi); - - printf("%s:\n", argv[iarg]); - // elf header - ehdr = (Elf32_Ehdr *)buf; - shdr = (Elf32_Shdr *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize); - shstr = (char *)(buf + shdr->sh_offset); - for (i = 0; i < ehdr->e_shnum; i++) - { - shdr = (Elf32_Shdr *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize); - if (!shdr->sh_offset) continue; - if (shdr->sh_type == SHT_SYMTAB) - { - symtab = (char *)(buf + shdr->sh_offset); - symtabsize = shdr->sh_size; - } - if (shdr->sh_type == SHT_STRTAB) - { - if (!strcmp(shstr + shdr->sh_name, ".strtab")) - { - strtab = (char *)(buf + shdr->sh_offset); - strtabsize = shdr->sh_size; - } - } - } - - if (symtab && symtabsize) - { - int nsym = symtabsize / sizeof(Elf32_Sym); - //printf("symtab: info size shndx name\n"); - for (i = 1; i < nsym; i++) - { - sym = (Elf32_Sym *) (symtab + i * sizeof(Elf32_Sym)); - if (sym->st_shndx && (sym->st_info == 0x11 || sym->st_info == 0x12)) { - //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name); - istrlen = strlen(strtab + sym->st_name)+1; - anames = realloc(anames, strpos+istrlen); - strcpy(anames + strpos, strtab + sym->st_name); - strpos += istrlen; - if (++funccnt >= funcmax) { - funcmax += 250; - afpos = realloc(afpos, funcmax * sizeof *afpos); // 250 func more - } - afpos[funccnt] = fpos; - } - } - } - memset(&arhdro.ar_name, ' ', sizeof(arhdr.ar_name)); - strcpy(arhdro.ar_name, argv[iarg]); - arhdro.ar_name[strlen(argv[iarg])] = '/'; - sprintf(stmp, "%-10d", fsize); - memcpy(&arhdro.ar_size, stmp, 10); - fwrite(&arhdro, sizeof(arhdro), 1, fo); - fwrite(buf, fsize, 1, fo); - free(buf); - iarg++; - fpos += (fsize + sizeof(arhdro)); - } - hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int); - if ((hofs & 1)) { // align - hofs++; - fpos = 1; - } else fpos = 0; - // write header - fwrite("!<arch>\n", 8, 1, fh); - sprintf(stmp, "%-10d", strpos + (funccnt+1) * sizeof(int)); - memcpy(&arhdr.ar_size, stmp, 10); - fwrite(&arhdr, sizeof(arhdr), 1, fh); - afpos[0] = le2belong(funccnt); - for (i=1; i<=funccnt; i++) { - afpos[i] = le2belong(afpos[i] + hofs); - } - fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh); - fwrite(anames, strpos, 1, fh); - if (fpos) fwrite("", 1, 1, fh); - // write objects - fseek(fo, 0, SEEK_END); - fsize = ftell(fo); - fseek(fo, 0, SEEK_SET); - buf = malloc(fsize + 1); - fread(buf, fsize, 1, fo); - fclose(fo); - fwrite(buf, fsize, 1, fh); - fclose(fh); - free(buf); - if (anames) - free(anames); - if (afpos) - free(afpos); - remove(tfile); - return 0; -} diff --git a/tinyc/x86_64-asm.h b/tinyc/x86_64-asm.h new file mode 100644 index 000000000..cb9eb16c8 --- /dev/null +++ b/tinyc/x86_64-asm.h @@ -0,0 +1,525 @@ + DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */ + DEF_ASM_OP0(cld, 0xfc) + DEF_ASM_OP0(cli, 0xfa) + DEF_ASM_OP0(clts, 0x0f06) + DEF_ASM_OP0(cmc, 0xf5) + DEF_ASM_OP0(lahf, 0x9f) + DEF_ASM_OP0(sahf, 0x9e) + DEF_ASM_OP0(pushfq, 0x9c) + DEF_ASM_OP0(popfq, 0x9d) + DEF_ASM_OP0(pushf, 0x9c) + DEF_ASM_OP0(popf, 0x9d) + DEF_ASM_OP0(stc, 0xf9) + DEF_ASM_OP0(std, 0xfd) + DEF_ASM_OP0(sti, 0xfb) + DEF_ASM_OP0(aaa, 0x37) + DEF_ASM_OP0(aas, 0x3f) + DEF_ASM_OP0(daa, 0x27) + DEF_ASM_OP0(das, 0x2f) + DEF_ASM_OP0(aad, 0xd50a) + DEF_ASM_OP0(aam, 0xd40a) + DEF_ASM_OP0(cbw, 0x6698) + DEF_ASM_OP0(cwd, 0x6699) + DEF_ASM_OP0(cwde, 0x98) + DEF_ASM_OP0(cdq, 0x99) + DEF_ASM_OP0(cbtw, 0x6698) + DEF_ASM_OP0(cwtl, 0x98) + DEF_ASM_OP0(cwtd, 0x6699) + DEF_ASM_OP0(cltd, 0x99) + DEF_ASM_OP0(cqto, 0x4899) + DEF_ASM_OP0(int3, 0xcc) + DEF_ASM_OP0(into, 0xce) + DEF_ASM_OP0(iret, 0xcf) + DEF_ASM_OP0(rsm, 0x0faa) + DEF_ASM_OP0(hlt, 0xf4) + DEF_ASM_OP0(wait, 0x9b) + DEF_ASM_OP0(nop, 0x90) + DEF_ASM_OP0(pause, 0xf390) + DEF_ASM_OP0(xlat, 0xd7) + + /* strings */ +ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX)) + +ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) +ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) + +ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX)) + +ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX)) + +ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX)) + +ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX)) +ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX)) + + /* bits */ + +ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW)) + +ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA)) + +ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA)) + +ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA)) + +ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA)) + + /* prefixes */ + DEF_ASM_OP0(lock, 0xf0) + DEF_ASM_OP0(rep, 0xf3) + DEF_ASM_OP0(repe, 0xf3) + DEF_ASM_OP0(repz, 0xf3) + DEF_ASM_OP0(repne, 0xf2) + DEF_ASM_OP0(repnz, 0xf2) + + DEF_ASM_OP0(invd, 0x0f08) + DEF_ASM_OP0(wbinvd, 0x0f09) + DEF_ASM_OP0(cpuid, 0x0fa2) + DEF_ASM_OP0(wrmsr, 0x0f30) + DEF_ASM_OP0(rdtsc, 0x0f31) + DEF_ASM_OP0(rdmsr, 0x0f32) + DEF_ASM_OP0(rdpmc, 0x0f33) + + DEF_ASM_OP0(syscall, 0x0f05) + DEF_ASM_OP0(sysret, 0x0f07) + DEF_ASM_OP0L(sysretq, 0x480f07, 0, 0) + DEF_ASM_OP0(ud2, 0x0f0b) + + /* NOTE: we took the same order as gas opcode definition order */ +/* Right now we can't express the fact that 0xa1/0xa3 can't use $eax and a + 32 bit moffset as operands. +ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX)) +ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR)) */ +ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG)) +/* The moves are special: the 0xb8 form supports IM64 (the only insn that + does) with REG64. It doesn't support IM32 with REG64, it would use + the full movabs form (64bit immediate). For IM32->REG64 we prefer + the 0xc7 opcode. So disallow all 64bit forms and code the rest by hand. */ +ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG)) +ALT(DEF_ASM_OP2(mov, 0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64)) +ALT(DEF_ASM_OP2(movq, 0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64)) +ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA)) + +ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG)) + +ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG64)) +ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG64)) +ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_CR)) +ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_DB)) + +ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16)) +ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) +ALT(DEF_ASM_OP2(movsbq, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) +ALT(DEF_ASM_OP2(movswq, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG)) +ALT(DEF_ASM_OP2(movslq, 0x63, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG)) +ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) +ALT(DEF_ASM_OP2(movzwq, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG)) + +ALT(DEF_ASM_OP1(pushq, 0x6a, 0, 0, OPT_IM8S)) +ALT(DEF_ASM_OP1(push, 0x6a, 0, 0, OPT_IM8S)) +ALT(DEF_ASM_OP1(pushw, 0x666a, 0, 0, OPT_IM8S)) +ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG64)) +ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG16)) +ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REG64 | OPT_EA)) +ALT(DEF_ASM_OP1(pushw, 0x6668, 0, 0, OPT_IM16)) +ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32)) +ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG)) + +ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG64)) +ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG16)) +ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA)) +ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG)) + +ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX)) +ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW)) +ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG)) + +ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) +ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) +ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) +ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) + +ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) +ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) +ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) +ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) + +ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG)) + +ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) +ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) +ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) +ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) +ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) + + /* arith */ +ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ +ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG)) +ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX)) +ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG)) + +ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG)) +ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX)) +ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG)) + +ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) + +ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) + +ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) + +ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG)) +ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW)) +ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) +ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW)) + +ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX)) +ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA)) +ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX)) + + /* shifts */ +ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) +ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG)) + +ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) +ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) + +ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) +ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP)) +ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) +ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8)) + +ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA)) +ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA)) + DEF_ASM_OP1(ljmpw, 0x66ff, 5, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(ljmpl, 0xff, 5, OPC_MODRM, OPT_EA) + +ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) +ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) +ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) + DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) + DEF_ASM_OP0(leave, 0xc9) + DEF_ASM_OP0(ret, 0xc3) + DEF_ASM_OP0(retq, 0xc3) +ALT(DEF_ASM_OP1(retq, 0xc2, 0, 0, OPT_IM16)) +ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) + DEF_ASM_OP0(lret, 0xcb) +ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) + +ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8)) + DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8) + DEF_ASM_OP1(jecxz, 0x67e3, 0, 0, OPT_DISP8) + + /* float */ + /* specific fcomp handling */ +ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) + +ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) +ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) +ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) +ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) +ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) +ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) +ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) +ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) +ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) +ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) +ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) +ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) +ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) + + DEF_ASM_OP0(fucompp, 0xdae9) + DEF_ASM_OP0(ftst, 0xd9e4) + DEF_ASM_OP0(fxam, 0xd9e5) + DEF_ASM_OP0(fld1, 0xd9e8) + DEF_ASM_OP0(fldl2t, 0xd9e9) + DEF_ASM_OP0(fldl2e, 0xd9ea) + DEF_ASM_OP0(fldpi, 0xd9eb) + DEF_ASM_OP0(fldlg2, 0xd9ec) + DEF_ASM_OP0(fldln2, 0xd9ed) + DEF_ASM_OP0(fldz, 0xd9ee) + + DEF_ASM_OP0(f2xm1, 0xd9f0) + DEF_ASM_OP0(fyl2x, 0xd9f1) + DEF_ASM_OP0(fptan, 0xd9f2) + DEF_ASM_OP0(fpatan, 0xd9f3) + DEF_ASM_OP0(fxtract, 0xd9f4) + DEF_ASM_OP0(fprem1, 0xd9f5) + DEF_ASM_OP0(fdecstp, 0xd9f6) + DEF_ASM_OP0(fincstp, 0xd9f7) + DEF_ASM_OP0(fprem, 0xd9f8) + DEF_ASM_OP0(fyl2xp1, 0xd9f9) + DEF_ASM_OP0(fsqrt, 0xd9fa) + DEF_ASM_OP0(fsincos, 0xd9fb) + DEF_ASM_OP0(frndint, 0xd9fc) + DEF_ASM_OP0(fscale, 0xd9fd) + DEF_ASM_OP0(fsin, 0xd9fe) + DEF_ASM_OP0(fcos, 0xd9ff) + DEF_ASM_OP0(fchs, 0xd9e0) + DEF_ASM_OP0(fabs, 0xd9e1) + DEF_ASM_OP0(fninit, 0xdbe3) + DEF_ASM_OP0(fnclex, 0xdbe2) + DEF_ASM_OP0(fnop, 0xd9d0) + DEF_ASM_OP0(fwait, 0x9b) + + /* fp load */ + DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) + DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) + DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) +ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) + DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) + DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) + + /* fp store */ + DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) + DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) + DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) +ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) + DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) + + DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) + DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) + + /* exchange */ + DEF_ASM_OP0(fxch, 0xd9c9) +ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) + + /* misc FPU */ + DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) + DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) + + DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) + DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) + DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) + DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) + DEF_ASM_OP0(fnstsw, 0xdfe0) +ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) +ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) + DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) +ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) +ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) + DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) + DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) + DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) + DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) + DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) + DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) + DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) + DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) + DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) + DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) + DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) + /* The *q forms of fxrstor/fxsave use a REX prefix. + If the operand would use extended registers we would have to modify + it instead of generating a second one. Currently that's no + problem with TCC, we don't use extended registers. */ + DEF_ASM_OP1(fxsaveq, 0x0fae, 0, OPC_MODRM | OPC_48, OPT_EA ) + DEF_ASM_OP1(fxrstorq, 0x0fae, 1, OPC_MODRM | OPC_48, OPT_EA ) + + /* segments */ + DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) +ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG)) + DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(lgdtq, 0x0f01, 2, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(lidtq, 0x0f01, 3, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) + DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) +ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG)) + DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG16) + DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(sgdtq, 0x0f01, 0, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(sidtq, 0x0f01, 1, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) + DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) + DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG32 | OPT_EA) +ALT(DEF_ASM_OP1(str, 0x660f00, 1, OPC_MODRM, OPT_REG16)) +ALT(DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM | OPC_48, OPT_REG64)) + DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) + DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) + DEF_ASM_OP0L(swapgs, 0x0f01, 7, OPC_MODRM) + + /* 486 */ + /* bswap can't be applied to 16bit regs */ + DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) + DEF_ASM_OP1(bswapl, 0x0fc8, 0, OPC_REG, OPT_REG32 ) + DEF_ASM_OP1(bswapq, 0x0fc8, 0, OPC_REG | OPC_48, OPT_REG64 ) + +ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA )) +ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA )) + DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) + + /* pentium */ + DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) + + /* AMD 64 */ + DEF_ASM_OP1(cmpxchg16b, 0x0fc7, 1, OPC_MODRM | OPC_48, OPT_EA ) + + /* pentium pro */ +ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW)) + + DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) + + DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) + DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) + + /* mmx */ + DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ + DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE ) + /* movd shouldn't accept REG64, but AMD64 spec uses it for 32 and 64 bit + moves, so let's be compatible. */ +ALT(DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG64, OPT_MMXSSE )) +ALT(DEF_ASM_OP2(movq, 0x0f6e, 0, OPC_MODRM | OPC_48, OPT_REG64, OPT_MMXSSE )) +ALT(DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )) +ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 )) +ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 )) +ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) +ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE )) +ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )) +ALT(DEF_ASM_OP2(movq, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 )) + + DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) +ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE )) + DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + + /* sse */ + DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) +ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) + DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) +ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) + DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE ) +ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 )) + DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE ) + DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX ) + DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX ) + DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE ) + DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ) + + DEF_ASM_OP1(prefetchnta, 0x0f18, 0, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(prefetcht0, 0x0f18, 1, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(prefetcht1, 0x0f18, 2, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(prefetcht2, 0x0f18, 3, OPC_MODRM, OPT_EA) + DEF_ASM_OP1(prefetchw, 0x0f0d, 1, OPC_MODRM, OPT_EA) + DEF_ASM_OP0L(lfence, 0x0fae, 5, OPC_MODRM) + DEF_ASM_OP0L(mfence, 0x0fae, 6, OPC_MODRM) + DEF_ASM_OP0L(sfence, 0x0fae, 7, OPC_MODRM) + DEF_ASM_OP1(clflush, 0x0fae, 7, OPC_MODRM, OPT_EA) +#undef ALT +#undef DEF_ASM_OP0 +#undef DEF_ASM_OP0L +#undef DEF_ASM_OP1 +#undef DEF_ASM_OP2 +#undef DEF_ASM_OP3 diff --git a/tinyc/x86_64-gen.c b/tinyc/x86_64-gen.c index 1227f41f0..f4d86e1b7 100644 --- a/tinyc/x86_64-gen.c +++ b/tinyc/x86_64-gen.c @@ -20,10 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <assert.h> +#ifdef TARGET_DEFS_ONLY /* number of available registers */ -#define NB_REGS 5 +#define NB_REGS 25 +#define NB_ASM_REGS 16 +#define CONFIG_TCC_ASM /* a register can belong to several classes. The classes must be sorted from more general to more precise (see gv2() code which does @@ -33,45 +35,60 @@ #define RC_RAX 0x0004 #define RC_RCX 0x0008 #define RC_RDX 0x0010 -#define RC_XMM0 0x0020 -#define RC_ST0 0x0040 /* only for long double */ +#define RC_ST0 0x0080 /* only for long double */ +#define RC_R8 0x0100 +#define RC_R9 0x0200 +#define RC_R10 0x0400 +#define RC_R11 0x0800 +#define RC_XMM0 0x1000 +#define RC_XMM1 0x2000 +#define RC_XMM2 0x4000 +#define RC_XMM3 0x8000 +#define RC_XMM4 0x10000 +#define RC_XMM5 0x20000 +#define RC_XMM6 0x40000 +#define RC_XMM7 0x80000 #define RC_IRET RC_RAX /* function return: integer register */ #define RC_LRET RC_RDX /* function return: second integer register */ #define RC_FRET RC_XMM0 /* function return: float register */ +#define RC_QRET RC_XMM1 /* function return: second float register */ /* pretty names for the registers */ enum { TREG_RAX = 0, TREG_RCX = 1, TREG_RDX = 2, + TREG_RSP = 4, TREG_RSI = 6, TREG_RDI = 7, + TREG_R8 = 8, TREG_R9 = 9, TREG_R10 = 10, TREG_R11 = 11, - TREG_XMM0 = 3, - TREG_ST0 = 4, + TREG_XMM0 = 16, + TREG_XMM1 = 17, + TREG_XMM2 = 18, + TREG_XMM3 = 19, + TREG_XMM4 = 20, + TREG_XMM5 = 21, + TREG_XMM6 = 22, + TREG_XMM7 = 23, - TREG_MEM = 0x10, + TREG_ST0 = 24, + + TREG_MEM = 0x20 }; #define REX_BASE(reg) (((reg) >> 3) & 1) #define REG_VALUE(reg) ((reg) & 7) -int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_RAX, - /* ecx */ RC_INT | RC_RCX, - /* edx */ RC_INT | RC_RDX, - /* xmm0 */ RC_FLOAT | RC_XMM0, - /* st0 */ RC_ST0, -}; - /* return registers for function */ #define REG_IRET TREG_RAX /* single word int return register */ #define REG_LRET TREG_RDX /* second word return register (for long long) */ #define REG_FRET TREG_XMM0 /* float return register */ +#define REG_QRET TREG_XMM1 /* second float return register */ /* defined if function parameters must be evaluated in reverse order */ #define INVERT_FUNC_PARAMS @@ -81,32 +98,56 @@ int reg_classes[NB_REGS] = { /* long double size and alignment, in bytes */ #define LDOUBLE_SIZE 16 -#define LDOUBLE_ALIGN 8 +#define LDOUBLE_ALIGN 16 /* maximum alignment (for aligned attribute support) */ -#define MAX_ALIGN 8 +#define MAX_ALIGN 16 /******************************************************/ -/* ELF defines */ - -#define EM_TCC_TARGET EM_X86_64 - -/* relocation type for 32 bit data relocation */ -#define R_DATA_32 R_X86_64_64 -#define R_JMP_SLOT R_X86_64_JUMP_SLOT -#define R_COPY R_X86_64_COPY - -#define ELF_START_ADDR 0x08048000 -#define ELF_PAGE_SIZE 0x1000 - +#else /* ! TARGET_DEFS_ONLY */ /******************************************************/ +#include "tcc.h" +#include <assert.h> + +ST_DATA const int reg_classes[NB_REGS] = { + /* eax */ RC_INT | RC_RAX, + /* ecx */ RC_INT | RC_RCX, + /* edx */ RC_INT | RC_RDX, + 0, + 0, + 0, + 0, + 0, + RC_R8, + RC_R9, + RC_R10, + RC_R11, + 0, + 0, + 0, + 0, + /* xmm0 */ RC_FLOAT | RC_XMM0, + /* xmm1 */ RC_FLOAT | RC_XMM1, + /* xmm2 */ RC_FLOAT | RC_XMM2, + /* xmm3 */ RC_FLOAT | RC_XMM3, + /* xmm4 */ RC_FLOAT | RC_XMM4, + /* xmm5 */ RC_FLOAT | RC_XMM5, + /* xmm6 an xmm7 are included so gv() can be used on them, + but they are not tagged with RC_FLOAT because they are + callee saved on Windows */ + RC_XMM6, + RC_XMM7, + /* st0 */ RC_ST0 +}; static unsigned long func_sub_sp_offset; static int func_ret_sub; /* XXX: make it faster ? */ -void g(int c) +ST_FUNC void g(int c) { int ind1; + if (nocode_wanted) + return; ind1 = ind + 1; if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); @@ -114,7 +155,7 @@ void g(int c) ind = ind1; } -void o(unsigned int c) +ST_FUNC void o(unsigned int c) { while (c) { g(c); @@ -122,7 +163,13 @@ void o(unsigned int c) } } -void gen_le32(int c) +ST_FUNC void gen_le16(int v) +{ + g(v); + g(v >> 8); +} + +ST_FUNC void gen_le32(int c) { g(c); g(c >> 8); @@ -130,7 +177,7 @@ void gen_le32(int c) g(c >> 24); } -void gen_le64(int64_t c) +ST_FUNC void gen_le64(int64_t c) { g(c); g(c >> 8); @@ -142,14 +189,24 @@ void gen_le64(int64_t c) g(c >> 56); } +static void orex(int ll, int r, int r2, int b) +{ + if ((r & VT_VALMASK) >= VT_CONST) + r = 0; + if ((r2 & VT_VALMASK) >= VT_CONST) + r2 = 0; + if (ll || REX_BASE(r) || REX_BASE(r2)) + o(0x40 | REX_BASE(r) | (REX_BASE(r2) << 2) | (ll << 3)); + o(b); +} + /* output a symbol and patch all calls to it */ -void gsym_addr(int t, int a) +ST_FUNC void gsym_addr(int t, int a) { - int n, *ptr; while (t) { - ptr = (int *)(cur_text_section->data + t); - n = *ptr; /* next value */ - *ptr = a - t - 4; + unsigned char *ptr = cur_text_section->data + t; + uint32_t n = read32le(ptr); /* next value */ + write32le(ptr, a - t - 4); t = n; } } @@ -159,9 +216,6 @@ void gsym(int t) gsym_addr(t, ind); } -/* psym is used to put an instruction with a data field which is a - reference to a symbol. It is in fact the same as oad ! */ -#define psym oad static int is64_type(int t) { @@ -170,58 +224,59 @@ static int is64_type(int t) (t & VT_BTYPE) == VT_LLONG); } -static int is_sse_float(int t) { - int bt; - bt = t & VT_BTYPE; - return bt == VT_DOUBLE || bt == VT_FLOAT; -} - /* instruction + 4 bytes data. Return the address of the data */ static int oad(int c, int s) { - int ind1; - + int t; + if (nocode_wanted) + return s; o(c); - ind1 = ind + 4; - if (ind1 > cur_text_section->data_allocated) - section_realloc(cur_text_section, ind1); - *(int *)(cur_text_section->data + ind) = s; - s = ind; - ind = ind1; - return s; + t = ind; + gen_le32(s); + return t; +} + +/* generate jmp to a label */ +#define gjmp2(instr,lbl) oad(instr,lbl) + +ST_FUNC void gen_addr32(int r, Sym *sym, int c) +{ + if (r & VT_SYM) + greloca(cur_text_section, sym, ind, R_X86_64_32S, c), c=0; + gen_le32(c); } /* output constant with relocation if 'r & VT_SYM' is true */ -static void gen_addr64(int r, Sym *sym, int64_t c) +ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c) { if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_X86_64_64); + greloca(cur_text_section, sym, ind, R_X86_64_64, c), c=0; gen_le64(c); } /* output constant with relocation if 'r & VT_SYM' is true */ -static void gen_addrpc32(int r, Sym *sym, int c) +ST_FUNC void gen_addrpc32(int r, Sym *sym, int c) { - if (r & VT_SYM) - greloc(cur_text_section, sym, ind, R_X86_64_PC32); + greloca(cur_text_section, sym, ind, R_X86_64_PC32, 0); gen_le32(c-4); } /* output got address with relocation */ static void gen_gotpcrel(int r, Sym *sym, int c) { - Section *sr; - ElfW(Rela) *rel; - greloc(cur_text_section, sym, ind, R_X86_64_GOTPCREL); - sr = cur_text_section->reloc; - rel = (ElfW(Rela) *)(sr->data + sr->data_offset - sizeof(ElfW(Rela))); - rel->r_addend = -4; +#ifdef TCC_TARGET_PE + tcc_error("internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n", + get_tok_str(sym->v, NULL), c, r, + cur_text_section->data[ind-3], + cur_text_section->data[ind-2], + cur_text_section->data[ind-1] + ); +#endif + greloca(cur_text_section, sym, ind, R_X86_64_GOTPCREL, -4); gen_le32(0); - if (c) { /* we use add c, %xxx for displacement */ - o(0x48 + REX_BASE(r)); - o(0x81); + orex(1, r, 0, 0x81); o(0xc0 + REG_VALUE(r)); gen_le32(c); } @@ -255,30 +310,24 @@ static void gen_modrm_impl(int op_reg, int r, Sym *sym, int c, int is_got) g(0x00 | op_reg | REG_VALUE(r)); } } else { - g(0x00 | op_reg | (r & VT_VALMASK)); + g(0x00 | op_reg | REG_VALUE(r)); } } -/* generate a modrm reference. 'op_reg' contains the addtionnal 3 +/* generate a modrm reference. 'op_reg' contains the additional 3 opcode bits */ static void gen_modrm(int op_reg, int r, Sym *sym, int c) { gen_modrm_impl(op_reg, r, sym, c, 0); } -/* generate a modrm reference. 'op_reg' contains the addtionnal 3 +/* generate a modrm reference. 'op_reg' contains the additional 3 opcode bits */ static void gen_modrm64(int opcode, int op_reg, int r, Sym *sym, int c) { int is_got; - int rex = 0x48 | (REX_BASE(op_reg) << 2); - if ((r & VT_VALMASK) != VT_CONST && - (r & VT_VALMASK) != VT_LOCAL) { - rex |= REX_BASE(VT_VALMASK & r); - } - o(rex); - o(opcode); is_got = (op_reg & TREG_MEM) && !(sym->type.t & VT_STATIC); + orex(1, r, op_reg, opcode); gen_modrm_impl(op_reg, r, sym, c, is_got); } @@ -289,10 +338,20 @@ void load(int r, SValue *sv) int v, t, ft, fc, fr; SValue v1; +#ifdef TCC_TARGET_PE + SValue v2; + sv = pe_getimport(sv, &v2); +#endif + fr = sv->r; - ft = sv->type.t; - fc = sv->c.ul; + ft = sv->type.t & ~VT_DEFSIGN; + fc = sv->c.i; + if (fc != sv->c.i && (fr & VT_SYM)) + tcc_error("64 bit addend in load"); + ft &= ~(VT_VOLATILE | VT_CONSTANT); + +#ifndef TCC_TARGET_PE /* we use indirect access via got */ if ((fr & VT_VALMASK) == VT_CONST && (fr & VT_SYM) && (fr & VT_LVAL) && !(sv->sym->type.t & VT_STATIC)) { @@ -307,97 +366,151 @@ void load(int r, SValue *sv) /* load from the temporal register */ fr = tr | VT_LVAL; } +#endif v = fr & VT_VALMASK; if (fr & VT_LVAL) { + int b, ll; if (v == VT_LLOCAL) { v1.type.t = VT_PTR; v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; - load(r, &v1); + v1.c.i = fc; fr = r; + if (!(reg_classes[fr] & (RC_INT|RC_R11))) + fr = get_reg(RC_INT); + load(fr, &v1); } + ll = 0; + /* Like GCC we can load from small enough properly sized + structs and unions as well. + XXX maybe move to generic operand handling, but should + occur only with asm, so tccasm.c might also be a better place */ + if ((ft & VT_BTYPE) == VT_STRUCT) { + int align; + switch (type_size(&sv->type, &align)) { + case 1: ft = VT_BYTE; break; + case 2: ft = VT_SHORT; break; + case 4: ft = VT_INT; break; + case 8: ft = VT_LLONG; break; + default: + tcc_error("invalid aggregate type for register load"); + break; + } + } if ((ft & VT_BTYPE) == VT_FLOAT) { - o(0x6e0f66); /* movd */ - r = 0; + b = 0x6e0f66; + r = REG_VALUE(r); /* movd */ } else if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0x7e0ff3); /* movq */ - r = 0; + b = 0x7e0ff3; /* movq */ + r = REG_VALUE(r); } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - o(0xdb); /* fldt */ - r = 5; - } else if ((ft & VT_TYPE) == VT_BYTE) { - o(0xbe0f); /* movsbl */ + b = 0xdb, r = 5; /* fldt */ + } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) { + b = 0xbe0f; /* movsbl */ } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { - o(0xb60f); /* movzbl */ + b = 0xb60f; /* movzbl */ } else if ((ft & VT_TYPE) == VT_SHORT) { - o(0xbf0f); /* movswl */ + b = 0xbf0f; /* movswl */ } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { - o(0xb70f); /* movzwl */ - } else if (is64_type(ft)) { - gen_modrm64(0x8b, r, fr, sv->sym, fc); - return; + b = 0xb70f; /* movzwl */ + } else { + assert(((ft & VT_BTYPE) == VT_INT) + || ((ft & VT_BTYPE) == VT_LLONG) + || ((ft & VT_BTYPE) == VT_PTR) + || ((ft & VT_BTYPE) == VT_FUNC) + ); + ll = is64_type(ft); + b = 0x8b; + } + if (ll) { + gen_modrm64(b, r, fr, sv->sym, fc); } else { - o(0x8b); /* movl */ + orex(ll, fr, r, b); + gen_modrm(r, fr, sv->sym, fc); } - gen_modrm(r, fr, sv->sym, fc); } else { if (v == VT_CONST) { - if ((ft & VT_BTYPE) == VT_LLONG) { - assert(!(fr & VT_SYM)); - o(0x48); - o(0xb8 + REG_VALUE(r)); /* mov $xx, r */ - gen_addr64(fr, sv->sym, sv->c.ull); - } else { - if (fr & VT_SYM) { - if (sv->sym->type.t & VT_STATIC) { - o(0x8d48); - o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */ - gen_addrpc32(fr, sv->sym, fc); - } else { - o(0x8b48); - o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */ - gen_gotpcrel(r, sv->sym, fc); - } + if (fr & VT_SYM) { +#ifdef TCC_TARGET_PE + orex(1,0,r,0x8d); + o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */ + gen_addrpc32(fr, sv->sym, fc); +#else + if (sv->sym->type.t & VT_STATIC) { + orex(1,0,r,0x8d); + o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */ + gen_addrpc32(fr, sv->sym, fc); } else { - o(0xb8 + REG_VALUE(r)); /* mov $xx, r */ - gen_le32(fc); + orex(1,0,r,0x8b); + o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */ + gen_gotpcrel(r, sv->sym, fc); } +#endif + } else if (is64_type(ft)) { + orex(1,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */ + gen_le64(sv->c.i); + } else { + orex(0,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */ + gen_le32(fc); } } else if (v == VT_LOCAL) { - o(0x48 | REX_BASE(r)); - o(0x8d); /* lea xxx(%ebp), r */ + orex(1,0,r,0x8d); /* lea xxx(%ebp), r */ gen_modrm(r, VT_LOCAL, sv->sym, fc); } else if (v == VT_CMP) { - oad(0xb8 + r, 0); /* mov $0, r */ - o(0x0f); /* setxx %br */ + orex(0,r,0,0); + if ((fc & ~0x100) != TOK_NE) + oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */ + else + oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */ + if (fc & 0x100) + { + /* This was a float compare. If the parity bit is + set the result was unordered, meaning false for everything + except TOK_NE, and true for TOK_NE. */ + fc &= ~0x100; + o(0x037a + (REX_BASE(r) << 8)); + } + orex(0,r,0, 0x0f); /* setxx %br */ o(fc); - o(0xc0 + r); + o(0xc0 + REG_VALUE(r)); } else if (v == VT_JMP || v == VT_JMPI) { t = v & 1; - oad(0xb8 + r, t); /* mov $1, r */ - o(0x05eb); /* jmp after */ + orex(0,r,0,0); + oad(0xb8 + REG_VALUE(r), t); /* mov $1, r */ + o(0x05eb + (REX_BASE(r) << 8)); /* jmp after */ gsym(fc); - oad(0xb8 + r, t ^ 1); /* mov $0, r */ + orex(0,r,0,0); + oad(0xb8 + REG_VALUE(r), t ^ 1); /* mov $0, r */ } else if (v != r) { - if (r == TREG_XMM0) { - assert(v == TREG_ST0); - /* gen_cvt_ftof(VT_DOUBLE); */ - o(0xf0245cdd); /* fstpl -0x10(%rsp) */ - /* movsd -0x10(%rsp),%xmm0 */ - o(0x44100ff2); - o(0xf024); + if ((r >= TREG_XMM0) && (r <= TREG_XMM7)) { + if (v == TREG_ST0) { + /* gen_cvt_ftof(VT_DOUBLE); */ + o(0xf0245cdd); /* fstpl -0x10(%rsp) */ + /* movsd -0x10(%rsp),%xmmN */ + o(0x100ff2); + o(0x44 + REG_VALUE(r)*8); /* %xmmN */ + o(0xf024); + } else { + assert((v >= TREG_XMM0) && (v <= TREG_XMM7)); + if ((ft & VT_BTYPE) == VT_FLOAT) { + o(0x100ff3); + } else { + assert((ft & VT_BTYPE) == VT_DOUBLE); + o(0x100ff2); + } + o(0xc0 + REG_VALUE(v) + REG_VALUE(r)*8); + } } else if (r == TREG_ST0) { - assert(v == TREG_XMM0); + assert((v >= TREG_XMM0) && (v <= TREG_XMM7)); /* gen_cvt_ftof(VT_LDOUBLE); */ - /* movsd %xmm0,-0x10(%rsp) */ - o(0x44110ff2); + /* movsd %xmmN,-0x10(%rsp) */ + o(0x110ff2); + o(0x44 + REG_VALUE(r)*8); /* %xmmN */ o(0xf024); o(0xf02444dd); /* fldl -0x10(%rsp) */ } else { - o(0x48 | REX_BASE(r) | (REX_BASE(v) << 2)); - o(0x89); - o(0xc0 + r + v * 8); /* mov v, r */ + orex(1,r,v, 0x89); + o(0xc0 + REG_VALUE(r) + REG_VALUE(v) * 8); /* mov v, r */ } } } @@ -411,30 +524,40 @@ void store(int r, SValue *v) /* store the REX prefix in this variable when PIC is enabled */ int pic = 0; - ft = v->type.t; - fc = v->c.ul; +#ifdef TCC_TARGET_PE + SValue v2; + v = pe_getimport(v, &v2); +#endif + fr = v->r & VT_VALMASK; + ft = v->type.t; + fc = v->c.i; + if (fc != v->c.i && (fr & VT_SYM)) + tcc_error("64 bit addend in store"); + ft &= ~(VT_VOLATILE | VT_CONSTANT); bt = ft & VT_BTYPE; +#ifndef TCC_TARGET_PE /* we need to access the variable via got */ if (fr == VT_CONST && (v->r & VT_SYM)) { /* mov xx(%rip), %r11 */ o(0x1d8b4c); - gen_gotpcrel(TREG_R11, v->sym, v->c.ul); + gen_gotpcrel(TREG_R11, v->sym, v->c.i); pic = is64_type(bt) ? 0x49 : 0x41; } +#endif /* XXX: incorrect if float reg to reg */ if (bt == VT_FLOAT) { o(0x66); o(pic); o(0x7e0f); /* movd */ - r = 0; + r = REG_VALUE(r); } else if (bt == VT_DOUBLE) { o(0x66); o(pic); o(0xd60f); /* movq */ - r = 0; + r = REG_VALUE(r); } else if (bt == VT_LDOUBLE) { o(0xc0d9); /* fld %st(0) */ o(pic); @@ -445,11 +568,11 @@ void store(int r, SValue *v) o(0x66); o(pic); if (bt == VT_BYTE || bt == VT_BOOL) - o(0x88); + orex(0, 0, r, 0x88); else if (is64_type(bt)) op64 = 0x89; else - o(0x89); + orex(0, 0, r, 0x89); } if (pic) { /* xxx r, (%r11) where xxx is mov, movq, fld, or etc */ @@ -457,9 +580,7 @@ void store(int r, SValue *v) o(op64); o(3 + (r << 3)); } else if (op64) { - if (fr == VT_CONST || - fr == VT_LOCAL || - (v->r & VT_LVAL)) { + if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) { gen_modrm64(op64, r, v->r, v->sym, fc); } else if (fr != r) { /* XXX: don't we really come here? */ @@ -467,9 +588,7 @@ void store(int r, SValue *v) o(0xc0 + fr + r * 8); /* mov r, fr */ } } else { - if (fr == VT_CONST || - fr == VT_LOCAL || - (v->r & VT_LVAL)) { + if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) { gen_modrm(r, v->r, v->sym, fc); } else if (fr != r) { /* XXX: don't we really come here? */ @@ -479,32 +598,26 @@ void store(int r, SValue *v) } } -static void gadd_sp(int val) -{ - if (val == (char)val) { - o(0xc48348); - g(val); - } else { - oad(0xc48148, val); /* add $xxx, %rsp */ - } -} - /* 'is_jmp' is '1' if it is a jump */ static void gcall_or_jmp(int is_jmp) { int r; - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { + if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && + ((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) { /* constant case */ if (vtop->r & VT_SYM) { /* relocation case */ - greloc(cur_text_section, vtop->sym, - ind + 1, R_X86_64_PC32); +#ifdef TCC_TARGET_PE + greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4)); +#else + greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4)); +#endif } else { /* put an empty PC32 relocation */ - put_elf_reloc(symtab_section, cur_text_section, - ind + 1, R_X86_64_PC32, 0); + put_elf_reloca(symtab_section, cur_text_section, + ind + 1, R_X86_64_PC32, 0, (int)(vtop->c.i-4)); } - oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */ + oad(0xe8 + is_jmp, 0); /* call/jmp im */ } else { /* otherwise, indirect call */ r = TREG_R11; @@ -515,142 +628,763 @@ static void gcall_or_jmp(int is_jmp) } } -static uint8_t arg_regs[6] = { - TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9 +#if defined(CONFIG_TCC_BCHECK) +#ifndef TCC_TARGET_PE +static addr_t func_bound_offset; +static unsigned long func_bound_ind; +#endif + +static void gen_static_call(int v) +{ + Sym *sym = external_global_sym(v, &func_old_type, 0); + oad(0xe8, 0); + greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4); +} + +/* generate a bounded pointer addition */ +ST_FUNC void gen_bounded_ptr_add(void) +{ + /* save all temporary registers */ + save_regs(0); + + /* prepare fast x86_64 function call */ + gv(RC_RAX); + o(0xc68948); // mov %rax,%rsi ## second arg in %rsi, this must be size + vtop--; + + gv(RC_RAX); + o(0xc78948); // mov %rax,%rdi ## first arg in %rdi, this must be ptr + vtop--; + + /* do a fast function call */ + gen_static_call(TOK___bound_ptr_add); + + /* returned pointer is in rax */ + vtop++; + vtop->r = TREG_RAX | VT_BOUNDED; + + + /* relocation offset of the bounding function call point */ + vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela))); +} + +/* patch pointer addition in vtop so that pointer dereferencing is + also tested */ +ST_FUNC void gen_bounded_ptr_deref(void) +{ + addr_t func; + int size, align; + ElfW(Rela) *rel; + Sym *sym; + + size = 0; + /* XXX: put that code in generic part of tcc */ + if (!is_float(vtop->type.t)) { + if (vtop->r & VT_LVAL_BYTE) + size = 1; + else if (vtop->r & VT_LVAL_SHORT) + size = 2; + } + if (!size) + size = type_size(&vtop->type, &align); + switch(size) { + case 1: func = TOK___bound_ptr_indir1; break; + case 2: func = TOK___bound_ptr_indir2; break; + case 4: func = TOK___bound_ptr_indir4; break; + case 8: func = TOK___bound_ptr_indir8; break; + case 12: func = TOK___bound_ptr_indir12; break; + case 16: func = TOK___bound_ptr_indir16; break; + default: + tcc_error("unhandled size when dereferencing bounded pointer"); + func = 0; + break; + } + + sym = external_global_sym(func, &func_old_type, 0); + if (!sym->c) + put_extern_sym(sym, NULL, 0, 0); + + /* patch relocation */ + /* XXX: find a better solution ? */ + + rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i); + rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info)); +} +#endif + +#ifdef TCC_TARGET_PE + +#define REGN 4 +static const uint8_t arg_regs[REGN] = { + TREG_RCX, TREG_RDX, TREG_R8, TREG_R9 }; + +/* Prepare arguments in R10 and R11 rather than RCX and RDX + because gv() will not ever use these */ +static int arg_prepare_reg(int idx) { + if (idx == 0 || idx == 1) + /* idx=0: r10, idx=1: r11 */ + return idx + 10; + else + return arg_regs[idx]; +} + +static int func_scratch, func_alloca; + /* Generate function call. The function address is pushed first, then all the parameters in call order. This functions pops all the parameters and the function address. */ + +static void gen_offs_sp(int b, int r, int d) +{ + orex(1,0,r & 0x100 ? 0 : r, b); + if (d == (char)d) { + o(0x2444 | (REG_VALUE(r) << 3)); + g(d); + } else { + o(0x2484 | (REG_VALUE(r) << 3)); + gen_le32(d); + } +} + +static int using_regs(int size) +{ + return !(size > 8 || (size & (size - 1))); +} + +/* Return the number of registers needed to return the struct, or 0 if + returning via struct pointer. */ +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) +{ + int size, align; + *ret_align = 1; // Never have to re-align return values for x86-64 + *regsize = 8; + size = type_size(vt, &align); + if (!using_regs(size)) + return 0; + if (size == 8) + ret->t = VT_LLONG; + else if (size == 4) + ret->t = VT_INT; + else if (size == 2) + ret->t = VT_SHORT; + else + ret->t = VT_BYTE; + ret->ref = NULL; + return 1; +} + +static int is_sse_float(int t) { + int bt; + bt = t & VT_BTYPE; + return bt == VT_DOUBLE || bt == VT_FLOAT; +} + +static int gfunc_arg_size(CType *type) { + int align; + if (type->t & (VT_ARRAY|VT_BITFIELD)) + return 8; + return type_size(type, &align); +} + void gfunc_call(int nb_args) { - int size, align, r, args_size, i, func_call; - Sym *func_sym; - SValue *orig_vtop; - int nb_reg_args = 0; - int nb_sse_args = 0; - int sse_reg, gen_reg; + int size, r, args_size, i, d, bt, struct_size; + int arg; - /* calculate the number of integer/float arguments */ - args_size = 0; - for(i = 0; i < nb_args; i++) { - if ((vtop[-i].type.t & VT_BTYPE) == VT_STRUCT) { - args_size += type_size(&vtop->type, &align); - } else if ((vtop[-i].type.t & VT_BTYPE) == VT_LDOUBLE) { - args_size += 16; - } else if (is_sse_float(vtop[-i].type.t)) { - nb_sse_args++; - if (nb_sse_args > 8) args_size += 8; - } else { - nb_reg_args++; - if (nb_reg_args > 6) args_size += 8; - } - } + args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE; + arg = nb_args; /* for struct arguments, we need to call memcpy and the function call breaks register passing arguments we are preparing. So, we process arguments which will be passed by stack first. */ - orig_vtop = vtop; - gen_reg = nb_reg_args; - sse_reg = nb_sse_args; - /* adjust stack to align SSE boundary */ - if (args_size &= 8) { - o(0x50); /* push $rax */ - } + struct_size = args_size; for(i = 0; i < nb_args; i++) { - if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { - size = type_size(&vtop->type, &align); + SValue *sv; + + --arg; + sv = &vtop[-i]; + bt = (sv->type.t & VT_BTYPE); + size = gfunc_arg_size(&sv->type); + + if (using_regs(size)) + continue; /* arguments smaller than 8 bytes passed in registers or on stack */ + + if (bt == VT_STRUCT) { /* align to stack align size */ - size = (size + 3) & ~3; - /* allocate the necessary size on stack */ - o(0x48); - oad(0xec81, size); /* sub $xxx, %rsp */ + size = (size + 15) & ~15; /* generate structure store */ r = get_reg(RC_INT); - o(0x48 + REX_BASE(r)); - o(0x89); /* mov %rsp, r */ - o(0xe0 + r); - { - /* following code breaks vtop[1] */ - SValue tmp = vtop[1]; - vset(&vtop->type, r | VT_LVAL, 0); - vswap(); - vstore(); - vtop[1] = tmp; - } - args_size += size; - } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { + gen_offs_sp(0x8d, r, struct_size); + struct_size += size; + + /* generate memcpy call */ + vset(&sv->type, r | VT_LVAL, 0); + vpushv(sv); + vstore(); + --vtop; + } else if (bt == VT_LDOUBLE) { gv(RC_ST0); - size = LDOUBLE_SIZE; - oad(0xec8148, size); /* sub $xxx, %rsp */ - o(0x7cdb); /* fstpt 0(%rsp) */ - g(0x24); - g(0x00); - args_size += size; - } else if (is_sse_float(vtop->type.t)) { - int j = --sse_reg; - if (j >= 8) { - gv(RC_FLOAT); - o(0x50); /* push $rax */ - /* movq %xmm0, (%rsp) */ - o(0x04d60f66); - o(0x24); - args_size += 8; + gen_offs_sp(0xdb, 0x107, struct_size); + struct_size += 16; + } + } + + if (func_scratch < struct_size) + func_scratch = struct_size; + + arg = nb_args; + struct_size = args_size; + + for(i = 0; i < nb_args; i++) { + --arg; + bt = (vtop->type.t & VT_BTYPE); + + size = gfunc_arg_size(&vtop->type); + if (!using_regs(size)) { + /* align to stack align size */ + size = (size + 15) & ~15; + if (arg >= REGN) { + d = get_reg(RC_INT); + gen_offs_sp(0x8d, d, struct_size); + gen_offs_sp(0x89, d, arg*8); + } else { + d = arg_prepare_reg(arg); + gen_offs_sp(0x8d, d, struct_size); } + struct_size += size; } else { - int j = --gen_reg; - /* simple type */ - /* XXX: implicit cast ? */ - if (j >= 6) { + if (is_sse_float(vtop->type.t)) { + if (tcc_state->nosse) + tcc_error("SSE disabled"); + gv(RC_XMM0); /* only use one float register */ + if (arg >= REGN) { + /* movq %xmm0, j*8(%rsp) */ + gen_offs_sp(0xd60f66, 0x100, arg*8); + } else { + /* movaps %xmm0, %xmmN */ + o(0x280f); + o(0xc0 + (arg << 3)); + d = arg_prepare_reg(arg); + /* mov %xmm0, %rxx */ + o(0x66); + orex(1,d,0, 0x7e0f); + o(0xc0 + REG_VALUE(d)); + } + } else { + if (bt == VT_STRUCT) { + vtop->type.ref = NULL; + vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT + : size > 1 ? VT_SHORT : VT_BYTE; + } + r = gv(RC_INT); - o(0x50 + r); /* push r */ - args_size += 8; + if (arg >= REGN) { + gen_offs_sp(0x89, r, arg*8); + } else { + d = arg_prepare_reg(arg); + orex(1,d,r,0x89); /* mov */ + o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d)); + } } } vtop--; } - vtop = orig_vtop; + save_regs(0); + + /* Copy R10 and R11 into RCX and RDX, respectively */ + if (nb_args > 0) { + o(0xd1894c); /* mov %r10, %rcx */ + if (nb_args > 1) { + o(0xda894c); /* mov %r11, %rdx */ + } + } + + gcall_or_jmp(0); + + if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) { + /* need to add the "func_scratch" area after alloca */ + o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4; + } + + /* other compilers don't clear the upper bits when returning char/short */ + bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED); + if (bt == (VT_BYTE | VT_UNSIGNED)) + o(0xc0b60f); /* movzbl %al, %eax */ + else if (bt == VT_BYTE) + o(0xc0be0f); /* movsbl %al, %eax */ + else if (bt == VT_SHORT) + o(0x98); /* cwtl */ + else if (bt == (VT_SHORT | VT_UNSIGNED)) + o(0xc0b70f); /* movzbl %al, %eax */ +#if 0 /* handled in gen_cast() */ + else if (bt == VT_INT) + o(0x9848); /* cltq */ + else if (bt == (VT_INT | VT_UNSIGNED)) + o(0xc089); /* mov %eax,%eax */ +#endif + vtop--; +} + + +#define FUNC_PROLOG_SIZE 11 + +/* generate function prolog of type 't' */ +void gfunc_prolog(CType *func_type) +{ + int addr, reg_param_index, bt, size; + Sym *sym; + CType *type; + + func_ret_sub = 0; + func_scratch = 0; + func_alloca = 0; + loc = 0; + + addr = PTR_SIZE * 2; + ind += FUNC_PROLOG_SIZE; + func_sub_sp_offset = ind; + reg_param_index = 0; + + sym = func_type->ref; + + /* if the function returns a structure, then add an + implicit pointer parameter */ + func_vt = sym->type; + func_var = (sym->f.func_type == FUNC_ELLIPSIS); + size = gfunc_arg_size(&func_vt); + if (!using_regs(size)) { + gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr); + func_vc = addr; + reg_param_index++; + addr += 8; + } + + /* define parameters */ + while ((sym = sym->next) != NULL) { + type = &sym->type; + bt = type->t & VT_BTYPE; + size = gfunc_arg_size(type); + if (!using_regs(size)) { + if (reg_param_index < REGN) { + gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr); + } + sym_push(sym->v & ~SYM_FIELD, type, VT_LLOCAL | VT_LVAL, addr); + } else { + if (reg_param_index < REGN) { + /* save arguments passed by register */ + if ((bt == VT_FLOAT) || (bt == VT_DOUBLE)) { + if (tcc_state->nosse) + tcc_error("SSE disabled"); + o(0xd60f66); /* movq */ + gen_modrm(reg_param_index, VT_LOCAL, NULL, addr); + } else { + gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr); + } + } + sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr); + } + addr += 8; + reg_param_index++; + } + + while (reg_param_index < REGN) { + if (func_type->ref->f.func_type == FUNC_ELLIPSIS) { + gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr); + addr += 8; + } + reg_param_index++; + } +} + +/* generate function epilog */ +void gfunc_epilog(void) +{ + int v, saved_ind; + + o(0xc9); /* leave */ + if (func_ret_sub == 0) { + o(0xc3); /* ret */ + } else { + o(0xc2); /* ret n */ + g(func_ret_sub); + g(func_ret_sub >> 8); + } + + saved_ind = ind; + ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; + /* align local size to word & save local variables */ + v = (func_scratch + -loc + 15) & -16; + + if (v >= 4096) { + Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); + oad(0xb8, v); /* mov stacksize, %eax */ + oad(0xe8, 0); /* call __chkstk, (does the stackframe too) */ + greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4); + o(0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */ + } else { + o(0xe5894855); /* push %rbp, mov %rsp, %rbp */ + o(0xec8148); /* sub rsp, stacksize */ + gen_le32(v); + } + + /* add the "func_scratch" area after each alloca seen */ + while (func_alloca) { + unsigned char *ptr = cur_text_section->data + func_alloca; + func_alloca = read32le(ptr); + write32le(ptr, func_scratch); + } + + cur_text_section->data_offset = saved_ind; + pe_add_unwind_data(ind, saved_ind, v); + ind = cur_text_section->data_offset; +} + +#else + +static void gadd_sp(int val) +{ + if (val == (char)val) { + o(0xc48348); + g(val); + } else { + oad(0xc48148, val); /* add $xxx, %rsp */ + } +} + +typedef enum X86_64_Mode { + x86_64_mode_none, + x86_64_mode_memory, + x86_64_mode_integer, + x86_64_mode_sse, + x86_64_mode_x87 +} X86_64_Mode; + +static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b) +{ + if (a == b) + return a; + else if (a == x86_64_mode_none) + return b; + else if (b == x86_64_mode_none) + return a; + else if ((a == x86_64_mode_memory) || (b == x86_64_mode_memory)) + return x86_64_mode_memory; + else if ((a == x86_64_mode_integer) || (b == x86_64_mode_integer)) + return x86_64_mode_integer; + else if ((a == x86_64_mode_x87) || (b == x86_64_mode_x87)) + return x86_64_mode_memory; + else + return x86_64_mode_sse; +} + +static X86_64_Mode classify_x86_64_inner(CType *ty) +{ + X86_64_Mode mode; + Sym *f; + + switch (ty->t & VT_BTYPE) { + case VT_VOID: return x86_64_mode_none; + + case VT_INT: + case VT_BYTE: + case VT_SHORT: + case VT_LLONG: + case VT_BOOL: + case VT_PTR: + case VT_FUNC: + return x86_64_mode_integer; + + case VT_FLOAT: + case VT_DOUBLE: return x86_64_mode_sse; + + case VT_LDOUBLE: return x86_64_mode_x87; + + case VT_STRUCT: + f = ty->ref; + + mode = x86_64_mode_none; + for (f = f->next; f; f = f->next) + mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type)); + + return mode; + } + assert(0); + return 0; +} + +static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count) +{ + X86_64_Mode mode; + int size, align, ret_t = 0; + + if (ty->t & (VT_BITFIELD|VT_ARRAY)) { + *psize = 8; + *palign = 8; + *reg_count = 1; + ret_t = ty->t; + mode = x86_64_mode_integer; + } else { + size = type_size(ty, &align); + *psize = (size + 7) & ~7; + *palign = (align + 7) & ~7; + + if (size > 16) { + mode = x86_64_mode_memory; + } else { + mode = classify_x86_64_inner(ty); + switch (mode) { + case x86_64_mode_integer: + if (size > 8) { + *reg_count = 2; + ret_t = VT_QLONG; + } else { + *reg_count = 1; + ret_t = (size > 4) ? VT_LLONG : VT_INT; + } + break; + + case x86_64_mode_x87: + *reg_count = 1; + ret_t = VT_LDOUBLE; + break; + + case x86_64_mode_sse: + if (size > 8) { + *reg_count = 2; + ret_t = VT_QFLOAT; + } else { + *reg_count = 1; + ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT; + } + break; + default: break; /* nothing to be done for x86_64_mode_memory and x86_64_mode_none*/ + } + } + } + + if (ret) { + ret->ref = NULL; + ret->t = ret_t; + } + + return mode; +} + +ST_FUNC int classify_x86_64_va_arg(CType *ty) +{ + /* This definition must be synced with stdarg.h */ + enum __va_arg_type { + __va_gen_reg, __va_float_reg, __va_stack + }; + int size, align, reg_count; + X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, ®_count); + switch (mode) { + default: return __va_stack; + case x86_64_mode_integer: return __va_gen_reg; + case x86_64_mode_sse: return __va_float_reg; + } +} + +/* Return the number of registers needed to return the struct, or 0 if + returning via struct pointer. */ +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) +{ + int size, align, reg_count; + *ret_align = 1; // Never have to re-align return values for x86-64 + *regsize = 8; + return (classify_x86_64_arg(vt, ret, &size, &align, ®_count) != x86_64_mode_memory); +} + +#define REGN 6 +static const uint8_t arg_regs[REGN] = { + TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9 +}; + +static int arg_prepare_reg(int idx) { + if (idx == 2 || idx == 3) + /* idx=2: r10, idx=3: r11 */ + return idx + 8; + else + return arg_regs[idx]; +} + +/* Generate function call. The function address is pushed first, then + all the parameters in call order. This functions pops all the + parameters and the function address. */ +void gfunc_call(int nb_args) +{ + X86_64_Mode mode; + CType type; + int size, align, r, args_size, stack_adjust, i, reg_count; + int nb_reg_args = 0; + int nb_sse_args = 0; + int sse_reg, gen_reg; + char _onstack[nb_args], *onstack = _onstack; + + /* calculate the number of integer/float register arguments, remember + arguments to be passed via stack (in onstack[]), and also remember + if we have to align the stack pointer to 16 (onstack[i] == 2). Needs + to be done in a left-to-right pass over arguments. */ + stack_adjust = 0; + for(i = nb_args - 1; i >= 0; i--) { + mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, ®_count); + if (mode == x86_64_mode_sse && nb_sse_args + reg_count <= 8) { + nb_sse_args += reg_count; + onstack[i] = 0; + } else if (mode == x86_64_mode_integer && nb_reg_args + reg_count <= REGN) { + nb_reg_args += reg_count; + onstack[i] = 0; + } else if (mode == x86_64_mode_none) { + onstack[i] = 0; + } else { + if (align == 16 && (stack_adjust &= 15)) { + onstack[i] = 2; + stack_adjust = 0; + } else + onstack[i] = 1; + stack_adjust += size; + } + } + + if (nb_sse_args && tcc_state->nosse) + tcc_error("SSE disabled but floating point arguments passed"); + + /* fetch cpu flag before generating any code */ + if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP) + gv(RC_INT); + + /* for struct arguments, we need to call memcpy and the function + call breaks register passing arguments we are preparing. + So, we process arguments which will be passed by stack first. */ + gen_reg = nb_reg_args; + sse_reg = nb_sse_args; + args_size = 0; + stack_adjust &= 15; + for (i = 0; i < nb_args;) { + mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, ®_count); + if (!onstack[i]) { + ++i; + continue; + } + /* Possibly adjust stack to align SSE boundary. We're processing + args from right to left while allocating happens left to right + (stack grows down), so the adjustment needs to happen _after_ + an argument that requires it. */ + if (stack_adjust) { + o(0x50); /* push %rax; aka sub $8,%rsp */ + args_size += 8; + stack_adjust = 0; + } + if (onstack[i] == 2) + stack_adjust = 1; + + vrotb(i+1); + + switch (vtop->type.t & VT_BTYPE) { + case VT_STRUCT: + /* allocate the necessary size on stack */ + o(0x48); + oad(0xec81, size); /* sub $xxx, %rsp */ + /* generate structure store */ + r = get_reg(RC_INT); + orex(1, r, 0, 0x89); /* mov %rsp, r */ + o(0xe0 + REG_VALUE(r)); + vset(&vtop->type, r | VT_LVAL, 0); + vswap(); + vstore(); + break; + + case VT_LDOUBLE: + gv(RC_ST0); + oad(0xec8148, size); /* sub $xxx, %rsp */ + o(0x7cdb); /* fstpt 0(%rsp) */ + g(0x24); + g(0x00); + break; + + case VT_FLOAT: + case VT_DOUBLE: + assert(mode == x86_64_mode_sse); + r = gv(RC_FLOAT); + o(0x50); /* push $rax */ + /* movq %xmmN, (%rsp) */ + o(0xd60f66); + o(0x04 + REG_VALUE(r)*8); + o(0x24); + break; + + default: + assert(mode == x86_64_mode_integer); + /* simple type */ + /* XXX: implicit cast ? */ + r = gv(RC_INT); + orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */ + break; + } + args_size += size; + + vpop(); + --nb_args; + onstack++; + } + + /* XXX This should be superfluous. */ + save_regs(0); /* save used temporary registers */ /* then, we prepare register passing arguments. Note that we cannot set RDX and RCX in this loop because gv() may break these temporary registers. Let's use R10 and R11 instead of them */ - gen_reg = nb_reg_args; - sse_reg = nb_sse_args; + assert(gen_reg <= REGN); + assert(sse_reg <= 8); for(i = 0; i < nb_args; i++) { - if ((vtop->type.t & VT_BTYPE) == VT_STRUCT || - (vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - } else if (is_sse_float(vtop->type.t)) { - int j = --sse_reg; - if (j < 8) { - gv(RC_FLOAT); /* only one float register */ - /* movaps %xmm0, %xmmN */ - o(0x280f); - o(0xc0 + (sse_reg << 3)); + mode = classify_x86_64_arg(&vtop->type, &type, &size, &align, ®_count); + /* Alter stack entry type so that gv() knows how to treat it */ + vtop->type = type; + if (mode == x86_64_mode_sse) { + if (reg_count == 2) { + sse_reg -= 2; + gv(RC_FRET); /* Use pair load into xmm0 & xmm1 */ + if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */ + /* movaps %xmm0, %xmmN */ + o(0x280f); + o(0xc0 + (sse_reg << 3)); + /* movaps %xmm1, %xmmN */ + o(0x280f); + o(0xc1 + ((sse_reg+1) << 3)); + } + } else { + assert(reg_count == 1); + --sse_reg; + /* Load directly to register */ + gv(RC_XMM0 << sse_reg); } - } else { - int j = --gen_reg; + } else if (mode == x86_64_mode_integer) { /* simple type */ /* XXX: implicit cast ? */ - if (j < 6) { - r = gv(RC_INT); - if (j < 2) { - o(0x8948); /* mov */ - o(0xc0 + r * 8 + arg_regs[j]); - } else if (j < 4) { - o(0x8949); /* mov */ - /* j=2: r10, j=3: r11 */ - o(0xc0 + r * 8 + j); - } else { - o(0x8949); /* mov */ - /* j=4: r8, j=5: r9 */ - o(0xc0 + r * 8 + j - 4); - } + int d; + gen_reg -= reg_count; + r = gv(RC_INT); + d = arg_prepare_reg(gen_reg); + orex(1,d,r,0x89); /* mov */ + o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d)); + if (reg_count == 2) { + d = arg_prepare_reg(gen_reg+1); + orex(1,d,vtop->r2,0x89); /* mov */ + o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d)); } } vtop--; } + assert(gen_reg == 0); + assert(sse_reg == 0); - save_regs(0); /* save used temporary registers */ + /* We shouldn't have many operands on the stack anymore, but the + call address itself is still there, and it might be in %eax + (or edx/ecx) currently, which the below writes would clobber. + So evict all remaining operands here. */ + save_regs(0); /* Copy R10 and R11 into RDX and RCX, respectively */ if (nb_reg_args > 2) { @@ -660,22 +1394,16 @@ void gfunc_call(int nb_args) } } - func_sym = vtop->type.ref; - func_call = FUNC_CALL(func_sym->r); - oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */ + if (vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */ + oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */ gcall_or_jmp(0); if (args_size) gadd_sp(args_size); vtop--; } -#ifdef TCC_TARGET_PE -/* XXX: support PE? */ -#warning "PE isn't tested at all" -#define FUNC_PROLOG_SIZE 12 -#else + #define FUNC_PROLOG_SIZE 11 -#endif static void push_arg_reg(int i) { loc -= 8; @@ -685,21 +1413,20 @@ static void push_arg_reg(int i) { /* generate function prolog of type 't' */ void gfunc_prolog(CType *func_type) { - int i, addr, align, size, func_call; - int param_index, param_addr, reg_param_index, sse_param_index; + X86_64_Mode mode; + int i, addr, align, size, reg_count; + int param_addr = 0, reg_param_index, sse_param_index; Sym *sym; CType *type; - func_ret_sub = 0; - sym = func_type->ref; - func_call = FUNC_CALL(sym->r); addr = PTR_SIZE * 2; loc = 0; ind += FUNC_PROLOG_SIZE; func_sub_sp_offset = ind; + func_ret_sub = 0; - if (func_type->ref->c == FUNC_ELLIPSIS) { + if (sym->f.func_type == FUNC_ELLIPSIS) { int seen_reg_num, seen_sse_num, seen_stack_size; seen_reg_num = seen_sse_num = 0; /* frame pointer and return address */ @@ -708,24 +1435,24 @@ void gfunc_prolog(CType *func_type) sym = func_type->ref; while ((sym = sym->next) != NULL) { type = &sym->type; - if (is_sse_float(type->t)) { - if (seen_sse_num < 8) { - seen_sse_num++; - } else { - seen_stack_size += 8; - } - } else if ((type->t & VT_BTYPE) == VT_STRUCT) { - size = type_size(type, &align); - size = (size + 3) & ~3; - seen_stack_size += size; - } else if ((type->t & VT_BTYPE) == VT_LDOUBLE) { - seen_stack_size += LDOUBLE_SIZE; - } else { - if (seen_reg_num < 6) { - seen_reg_num++; - } else { - seen_stack_size += 8; - } + mode = classify_x86_64_arg(type, NULL, &size, &align, ®_count); + switch (mode) { + default: + stack_arg: + seen_stack_size = ((seen_stack_size + align - 1) & -align) + size; + break; + + case x86_64_mode_integer: + if (seen_reg_num + reg_count > REGN) + goto stack_arg; + seen_reg_num += reg_count; + break; + + case x86_64_mode_sse: + if (seen_sse_num + reg_count > 8) + goto stack_arg; + seen_sse_num += reg_count; + break; } } @@ -743,70 +1470,96 @@ void gfunc_prolog(CType *func_type) /* save all register passing arguments */ for (i = 0; i < 8; i++) { loc -= 16; - o(0xd60f66); /* movq */ - gen_modrm(7 - i, VT_LOCAL, NULL, loc); + if (!tcc_state->nosse) { + o(0xd60f66); /* movq */ + gen_modrm(7 - i, VT_LOCAL, NULL, loc); + } /* movq $0, loc+8(%rbp) */ o(0x85c748); gen_le32(loc + 8); gen_le32(0); } - for (i = 0; i < 6; i++) { - push_arg_reg(5 - i); + for (i = 0; i < REGN; i++) { + push_arg_reg(REGN-1-i); } } sym = func_type->ref; - param_index = 0; reg_param_index = 0; sse_param_index = 0; /* if the function returns a structure, then add an implicit pointer parameter */ func_vt = sym->type; - if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { + mode = classify_x86_64_arg(&func_vt, NULL, &size, &align, ®_count); + if (mode == x86_64_mode_memory) { push_arg_reg(reg_param_index); - param_addr = loc; - func_vc = loc; - param_index++; reg_param_index++; } /* define parameters */ while ((sym = sym->next) != NULL) { type = &sym->type; - size = type_size(type, &align); - size = (size + 3) & ~3; - if (is_sse_float(type->t)) { - if (sse_param_index < 8) { + mode = classify_x86_64_arg(type, NULL, &size, &align, ®_count); + switch (mode) { + case x86_64_mode_sse: + if (tcc_state->nosse) + tcc_error("SSE disabled but floating point arguments used"); + if (sse_param_index + reg_count <= 8) { /* save arguments passed by register */ - loc -= 8; - o(0xd60f66); /* movq */ - gen_modrm(sse_param_index, VT_LOCAL, NULL, loc); + loc -= reg_count * 8; param_addr = loc; + for (i = 0; i < reg_count; ++i) { + o(0xd60f66); /* movq */ + gen_modrm(sse_param_index, VT_LOCAL, NULL, param_addr + i*8); + ++sse_param_index; + } } else { + addr = (addr + align - 1) & -align; param_addr = addr; addr += size; } - sse_param_index++; - } else if ((type->t & VT_BTYPE) == VT_STRUCT || - (type->t & VT_BTYPE) == VT_LDOUBLE) { + break; + + case x86_64_mode_memory: + case x86_64_mode_x87: + addr = (addr + align - 1) & -align; param_addr = addr; addr += size; - } else { - if (reg_param_index < 6) { + break; + + case x86_64_mode_integer: { + if (reg_param_index + reg_count <= REGN) { /* save arguments passed by register */ - push_arg_reg(reg_param_index); + loc -= reg_count * 8; param_addr = loc; + for (i = 0; i < reg_count; ++i) { + gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, param_addr + i*8); + ++reg_param_index; + } } else { + addr = (addr + align - 1) & -align; param_addr = addr; - addr += 8; + addr += size; } - reg_param_index++; + break; + } + default: break; /* nothing to be done for x86_64_mode_none */ } sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, param_addr); - param_index++; } + +#ifdef CONFIG_TCC_BCHECK + /* leave some room for bound checking code */ + if (tcc_state->do_bounds_check) { + func_bound_offset = lbounds_section->data_offset; + func_bound_ind = ind; + oad(0xb8, 0); /* lbound section pointer */ + o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ + oad(0xb8, 0); /* call to function */ + } +#endif } /* generate function epilog */ @@ -814,6 +1567,37 @@ void gfunc_epilog(void) { int v, saved_ind; +#ifdef CONFIG_TCC_BCHECK + if (tcc_state->do_bounds_check + && func_bound_offset != lbounds_section->data_offset) + { + addr_t saved_ind; + addr_t *bounds_ptr; + Sym *sym_data; + + /* add end of table info */ + bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); + *bounds_ptr = 0; + + /* generate bound local allocation */ + sym_data = get_sym_ref(&char_pointer_type, lbounds_section, + func_bound_offset, lbounds_section->data_offset); + saved_ind = ind; + ind = func_bound_ind; + greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0); + ind = ind + 5 + 3; + gen_static_call(TOK___bound_local_new); + ind = saved_ind; + + /* generate bound check local freeing */ + o(0x5250); /* save returned value, if any */ + greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0); + oad(0xb8, 0); /* mov xxx, %rax */ + o(0xc78948); /* mov %rax,%rdi # first arg in %rdi, this must be ptr */ + gen_static_call(TOK___bound_local_delete); + o(0x585a); /* restore returned value, if any */ + } +#endif o(0xc9); /* leave */ if (func_ret_sub == 0) { o(0xc3); /* ret */ @@ -826,29 +1610,18 @@ void gfunc_epilog(void) v = (-loc + 15) & -16; saved_ind = ind; ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; -#ifdef TCC_TARGET_PE - if (v >= 4096) { - Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); - oad(0xb8, v); /* mov stacksize, %eax */ - oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ - greloc(cur_text_section, sym, ind-4, R_X86_64_PC32); - } else -#endif - { - o(0xe5894855); /* push %rbp, mov %rsp, %rbp */ - o(0xec8148); /* sub rsp, stacksize */ - gen_le32(v); -#if FUNC_PROLOG_SIZE == 12 - o(0x90); /* adjust to FUNC_PROLOG_SIZE */ -#endif - } + o(0xe5894855); /* push %rbp, mov %rsp, %rbp */ + o(0xec8148); /* sub rsp, stacksize */ + gen_le32(v); ind = saved_ind; } +#endif /* not PE */ + /* generate a jump to a label */ int gjmp(int t) { - return psym(0xe9, t); + return gjmp2(0xe9, t); } /* generate a jump to a fixed address */ @@ -864,46 +1637,76 @@ void gjmp_addr(int a) } } +ST_FUNC void gtst_addr(int inv, int a) +{ + int v = vtop->r & VT_VALMASK; + if (v == VT_CMP) { + inv ^= (vtop--)->c.i; + a -= ind + 2; + if (a == (char)a) { + g(inv - 32); + g(a); + } else { + g(0x0f); + oad(inv - 16, a - 4); + } + } else if ((v & ~1) == VT_JMP) { + if ((v & 1) != inv) { + gjmp_addr(a); + gsym(vtop->c.i); + } else { + gsym(vtop->c.i); + o(0x05eb); + gjmp_addr(a); + } + vtop--; + } +} + /* generate a test. set 'inv' to invert test. Stack entry is popped */ -int gtst(int inv, int t) +ST_FUNC int gtst(int inv, int t) { - int v, *p; + int v = vtop->r & VT_VALMASK; - v = vtop->r & VT_VALMASK; - if (v == VT_CMP) { + if (nocode_wanted) { + ; + } else if (v == VT_CMP) { /* fast case : can jump directly since flags are set */ + if (vtop->c.i & 0x100) + { + /* This was a float compare. If the parity flag is set + the result was unordered. For anything except != this + means false and we don't jump (anding both conditions). + For != this means true (oring both). + Take care about inverting the test. We need to jump + to our target if the result was unordered and test wasn't NE, + otherwise if unordered we don't want to jump. */ + vtop->c.i &= ~0x100; + if (inv == (vtop->c.i == TOK_NE)) + o(0x067a); /* jp +6 */ + else + { + g(0x0f); + t = gjmp2(0x8a, t); /* jp t */ + } + } g(0x0f); - t = psym((vtop->c.i - 16) ^ inv, t); + t = gjmp2((vtop->c.i - 16) ^ inv, t); } else if (v == VT_JMP || v == VT_JMPI) { /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ - p = &vtop->c.i; - while (*p != 0) - p = (int *)(cur_text_section->data + *p); - *p = t; - t = vtop->c.i; + uint32_t n1, n = vtop->c.i; + if (n) { + while ((n1 = read32le(cur_text_section->data + n))) + n = n1; + write32le(cur_text_section->data + n, t); + t = vtop->c.i; + } } else { t = gjmp(t); gsym(vtop->c.i); } - } else { - if (is_float(vtop->type.t) || - (vtop->type.t & VT_BTYPE) == VT_LLONG) { - vpushi(0); - gen_op(TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - } else { - v = gv(RC_INT); - o(0x85); - o(0xc0 + v * 9); - g(0x0f); - t = psym(0x85 ^ inv, t); - } } vtop--; return t; @@ -913,41 +1716,37 @@ int gtst(int inv, int t) void gen_opi(int op) { int r, fr, opc, c; + int ll, uu, cc; + + ll = is64_type(vtop[-1].type.t); + uu = (vtop[-1].type.t & VT_UNSIGNED) != 0; + cc = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; switch(op) { case '+': case TOK_ADDC1: /* add with carry generation */ opc = 0; gen_op8: - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST && - !is64_type(vtop->type.t)) { + if (cc && (!ll || (int)vtop->c.i == vtop->c.i)) { /* constant case */ vswap(); r = gv(RC_INT); - if (is64_type(vtop->type.t)) { - o(0x48 | REX_BASE(r)); - } vswap(); c = vtop->c.i; if (c == (char)c) { /* XXX: generate inc and dec for smaller code ? */ - o(0x83); + orex(ll, r, 0, 0x83); o(0xc0 | (opc << 3) | REG_VALUE(r)); g(c); } else { - o(0x81); + orex(ll, r, 0, 0x81); oad(0xc0 | (opc << 3) | REG_VALUE(r), c); } } else { gv2(RC_INT, RC_INT); r = vtop[-1].r; fr = vtop[0].r; - if (opc != 7 || - is64_type(vtop[0].type.t) || (vtop[0].type.t & VT_UNSIGNED) || - is64_type(vtop[-1].type.t) || (vtop[-1].type.t & VT_UNSIGNED)) { - o(0x48 | REX_BASE(r) | (REX_BASE(fr) << 2)); - } - o((opc << 3) | 0x01); + orex(ll, r, fr, (opc << 3) | 0x01); o(0xc0 + REG_VALUE(r) + REG_VALUE(fr) * 8); } vtop--; @@ -979,13 +1778,9 @@ void gen_opi(int op) gv2(RC_INT, RC_INT); r = vtop[-1].r; fr = vtop[0].r; - if (is64_type(vtop[0].type.t) || (vtop[0].type.t & VT_UNSIGNED) || - is64_type(vtop[-1].type.t) || (vtop[-1].type.t & VT_UNSIGNED)) { - o(0x48 | REX_BASE(fr) | (REX_BASE(r) << 2)); - } + orex(ll, fr, r, 0xaf0f); /* imul fr, r */ + o(0xc0 + REG_VALUE(fr) + REG_VALUE(r) * 8); vtop--; - o(0xaf0f); /* imul fr, r */ - o(0xc0 + fr + r * 8); break; case TOK_SHL: opc = 4; @@ -997,39 +1792,32 @@ void gen_opi(int op) opc = 7; gen_shift: opc = 0xc0 | (opc << 3); - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + if (cc) { /* constant case */ vswap(); r = gv(RC_INT); - if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { - o(0x48 | REX_BASE(r)); - c = 0x3f; - } else { - c = 0x1f; - } vswap(); - c &= vtop->c.i; - o(0xc1); /* shl/shr/sar $xxx, r */ - o(opc | r); - g(c); + orex(ll, r, 0, 0xc1); /* shl/shr/sar $xxx, r */ + o(opc | REG_VALUE(r)); + g(vtop->c.i & (ll ? 63 : 31)); } else { /* we generate the shift in ecx */ gv2(RC_INT, RC_RCX); r = vtop[-1].r; - if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG) { - o(0x48 | REX_BASE(r)); - } - o(0xd3); /* shl/shr/sar %cl, r */ - o(opc | r); + orex(ll, r, 0, 0xd3); /* shl/shr/sar %cl, r */ + o(opc | REG_VALUE(r)); } vtop--; break; - case '/': case TOK_UDIV: - case TOK_PDIV: - case '%': case TOK_UMOD: - case TOK_UMULL: + uu = 1; + goto divmod; + case '/': + case '%': + case TOK_PDIV: + uu = 0; + divmod: /* first operand must be in eax */ /* XXX: need better constraint for second operand */ gv2(RC_RAX, RC_RCX); @@ -1037,30 +1825,13 @@ void gen_opi(int op) fr = vtop[0].r; vtop--; save_reg(TREG_RDX); - if (op == TOK_UMULL) { - o(0xf7); /* mul fr */ - o(0xe0 + fr); - vtop->r2 = TREG_RDX; + orex(ll, 0, 0, uu ? 0xd231 : 0x99); /* xor %edx,%edx : cqto */ + orex(ll, fr, 0, 0xf7); /* div fr, %eax */ + o((uu ? 0xf0 : 0xf8) + REG_VALUE(fr)); + if (op == '%' || op == TOK_UMOD) + r = TREG_RDX; + else r = TREG_RAX; - } else { - if (op == TOK_UDIV || op == TOK_UMOD) { - o(0xf7d231); /* xor %edx, %edx, div fr, %eax */ - o(0xf0 + fr); - } else { - if ((vtop->type.t & VT_BTYPE) & VT_LLONG) { - o(0x9948); /* cqto */ - o(0x48 + REX_BASE(fr)); - } else { - o(0x99); /* cltd */ - } - o(0xf7); /* idiv fr, %eax */ - o(0xf8 + fr); - } - if (op == '%' || op == TOK_UMOD) - r = TREG_RDX; - else - r = TREG_RAX; - } vtop->r = r; break; default: @@ -1075,7 +1846,7 @@ void gen_opl(int op) } /* generate a floating point operation 'v = t1 op t2' instruction. The - two operands are guaranted to have the same floating point type */ + two operands are guaranteed to have the same floating point type */ /* XXX: need to use ST1 too */ void gen_opf(int op) { @@ -1117,7 +1888,10 @@ void gen_opf(int op) swapped = 0; if (swapped) o(0xc9d9); /* fxch %st(1) */ - o(0xe9da); /* fucompp */ + if (op == TOK_EQ || op == TOK_NE) + o(0xe9da); /* fucompp */ + else + o(0xd9de); /* fcompp */ o(0xe0df); /* fnstsw %ax */ if (op == TOK_EQ) { o(0x45e480); /* and $0x45, %ah */ @@ -1161,7 +1935,7 @@ void gen_opf(int op) break; } ft = vtop->type.t; - fc = vtop->c.ul; + fc = vtop->c.i; o(0xde); /* fxxxp %st, %st(1) */ o(0xc1 + (a << 3)); vtop--; @@ -1170,13 +1944,13 @@ void gen_opf(int op) if (op >= TOK_ULT && op <= TOK_GT) { /* if saved lvalue, then we must reload it */ r = vtop->r; - fc = vtop->c.ul; + fc = vtop->c.i; if ((r & VT_VALMASK) == VT_LLOCAL) { SValue v1; r = get_reg(RC_INT); - v1.type.t = VT_INT; + v1.type.t = VT_PTR; v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; + v1.c.i = fc; load(r, &v1); fc = 0; } @@ -1194,31 +1968,29 @@ void gen_opf(int op) } if (swapped) { - o(0x7e0ff3); /* movq */ - gen_modrm(1, r, vtop->sym, fc); + gv(RC_FLOAT); + vswap(); + } + assert(!(vtop[-1].r & VT_LVAL)); + + if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) + o(0x66); + if (op == TOK_EQ || op == TOK_NE) + o(0x2e0f); /* ucomisd */ + else + o(0x2f0f); /* comisd */ - if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { - o(0x66); - } - o(0x2e0f); /* ucomisd %xmm0, %xmm1 */ - o(0xc8); + if (vtop->r & VT_LVAL) { + gen_modrm(vtop[-1].r, r, vtop->sym, fc); } else { - if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { - o(0x66); - } - o(0x2e0f); /* ucomisd */ - gen_modrm(0, r, vtop->sym, fc); + o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8); } vtop--; vtop->r = VT_CMP; - vtop->c.i = op; + vtop->c.i = op | 0x100; } else { - /* no memory reference possible for long double operations */ - if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { - load(TREG_XMM0, vtop); - swapped = !swapped; - } + assert((vtop->type.t & VT_BTYPE) != VT_LDOUBLE); switch(op) { default: case '+': @@ -1235,47 +2007,42 @@ void gen_opf(int op) break; } ft = vtop->type.t; - fc = vtop->c.ul; - if ((ft & VT_BTYPE) == VT_LDOUBLE) { - o(0xde); /* fxxxp %st, %st(1) */ - o(0xc1 + (a << 3)); + fc = vtop->c.i; + assert((ft & VT_BTYPE) != VT_LDOUBLE); + + r = vtop->r; + /* if saved lvalue, then we must reload it */ + if ((vtop->r & VT_VALMASK) == VT_LLOCAL) { + SValue v1; + r = get_reg(RC_INT); + v1.type.t = VT_PTR; + v1.r = VT_LOCAL | VT_LVAL; + v1.c.i = fc; + load(r, &v1); + fc = 0; + } + + assert(!(vtop[-1].r & VT_LVAL)); + if (swapped) { + assert(vtop->r & VT_LVAL); + gv(RC_FLOAT); + vswap(); + } + + if ((ft & VT_BTYPE) == VT_DOUBLE) { + o(0xf2); } else { - /* if saved lvalue, then we must reload it */ - r = vtop->r; - if ((r & VT_VALMASK) == VT_LLOCAL) { - SValue v1; - r = get_reg(RC_INT); - v1.type.t = VT_INT; - v1.r = VT_LOCAL | VT_LVAL; - v1.c.ul = fc; - load(r, &v1); - fc = 0; - } - if (swapped) { - /* movq %xmm0,%xmm1 */ - o(0x7e0ff3); - o(0xc8); - load(TREG_XMM0, vtop); - /* subsd %xmm1,%xmm0 (f2 0f 5c c1) */ - if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0xf2); - } else { - o(0xf3); - } - o(0x0f); - o(0x58 + a); - o(0xc1); - } else { - if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0xf2); - } else { - o(0xf3); - } - o(0x0f); - o(0x58 + a); - gen_modrm(0, r, vtop->sym, fc); - } + o(0xf3); } + o(0x0f); + o(0x58 + a); + + if (vtop->r & VT_LVAL) { + gen_modrm(vtop[-1].r, r, vtop->sym, fc); + } else { + o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8); + } + vtop--; } } @@ -1310,17 +2077,17 @@ void gen_cvt_itof(int t) } vtop->r = TREG_ST0; } else { - save_reg(TREG_XMM0); + int r = get_reg(RC_FLOAT); gv(RC_INT); - o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT)); + o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT?1:0)); if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || (vtop->type.t & VT_BTYPE) == VT_LLONG) { o(0x48); /* REX */ } o(0x2a0f); - o(0xc0 + (vtop->r & VT_VALMASK)); /* cvtsi2sd */ - vtop->r = TREG_XMM0; + o(0xc0 + (vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */ + vtop->r = r; } } @@ -1332,15 +2099,19 @@ void gen_cvt_ftof(int t) ft = vtop->type.t; bt = ft & VT_BTYPE; tbt = t & VT_BTYPE; - + if (bt == VT_FLOAT) { gv(RC_FLOAT); if (tbt == VT_DOUBLE) { - o(0xc0140f); /* unpcklps */ - o(0xc05a0f); /* cvtps2pd */ + o(0x140f); /* unpcklps */ + o(0xc0 + REG_VALUE(vtop->r)*9); + o(0x5a0f); /* cvtps2pd */ + o(0xc0 + REG_VALUE(vtop->r)*9); } else if (tbt == VT_LDOUBLE) { + save_reg(RC_ST0); /* movss %xmm0,-0x10(%rsp) */ - o(0x44110ff3); + o(0x110ff3); + o(0x44 + REG_VALUE(vtop->r)*8); o(0xf024); o(0xf02444d9); /* flds -0x10(%rsp) */ vtop->r = TREG_ST0; @@ -1348,29 +2119,37 @@ void gen_cvt_ftof(int t) } else if (bt == VT_DOUBLE) { gv(RC_FLOAT); if (tbt == VT_FLOAT) { - o(0xc0140f66); /* unpcklpd */ - o(0xc05a0f66); /* cvtpd2ps */ + o(0x140f66); /* unpcklpd */ + o(0xc0 + REG_VALUE(vtop->r)*9); + o(0x5a0f66); /* cvtpd2ps */ + o(0xc0 + REG_VALUE(vtop->r)*9); } else if (tbt == VT_LDOUBLE) { + save_reg(RC_ST0); /* movsd %xmm0,-0x10(%rsp) */ - o(0x44110ff2); + o(0x110ff2); + o(0x44 + REG_VALUE(vtop->r)*8); o(0xf024); o(0xf02444dd); /* fldl -0x10(%rsp) */ vtop->r = TREG_ST0; } } else { + int r; gv(RC_ST0); + r = get_reg(RC_FLOAT); if (tbt == VT_DOUBLE) { o(0xf0245cdd); /* fstpl -0x10(%rsp) */ /* movsd -0x10(%rsp),%xmm0 */ - o(0x44100ff2); + o(0x100ff2); + o(0x44 + REG_VALUE(r)*8); o(0xf024); - vtop->r = TREG_XMM0; + vtop->r = r; } else if (tbt == VT_FLOAT) { o(0xf0245cd9); /* fstps -0x10(%rsp) */ /* movss -0x10(%rsp),%xmm0 */ - o(0x44100ff3); + o(0x100ff3); + o(0x44 + REG_VALUE(r)*8); o(0xf024); - vtop->r = TREG_XMM0; + vtop->r = r; } } } @@ -1400,11 +2179,8 @@ void gen_cvt_ftoi(int t) } else { assert(0); } - if (size == 8) { - o(0x48 + REX_BASE(r)); - } - o(0x2c0f); /* cvttss2si or cvttsd2si */ - o(0xc0 + (REG_VALUE(r) << 3)); + orex(size == 8, r, 0, 0x2c0f); /* cvttss2si or cvttsd2si */ + o(0xc0 + REG_VALUE(vtop->r) + REG_VALUE(r)*8); vtop->r = r; } @@ -1415,5 +2191,39 @@ void ggoto(void) vtop--; } +/* Save the stack pointer onto the stack and return the location of its address */ +ST_FUNC void gen_vla_sp_save(int addr) { + /* mov %rsp,addr(%rbp)*/ + gen_modrm64(0x89, TREG_RSP, VT_LOCAL, NULL, addr); +} + +/* Restore the SP from a location on the stack */ +ST_FUNC void gen_vla_sp_restore(int addr) { + gen_modrm64(0x8b, TREG_RSP, VT_LOCAL, NULL, addr); +} + +/* Subtract from the stack pointer, and push the resulting value onto the stack */ +ST_FUNC void gen_vla_alloc(CType *type, int align) { +#ifdef TCC_TARGET_PE + /* alloca does more than just adjust %rsp on Windows */ + vpush_global_sym(&func_old_type, TOK_alloca); + vswap(); /* Move alloca ref past allocation size */ + gfunc_call(1); +#else + int r; + r = gv(RC_INT); /* allocation size */ + /* sub r,%rsp */ + o(0x2b48); + o(0xe0 | REG_VALUE(r)); + /* We align to 16 bytes rather than align */ + /* and ~15, %rsp */ + o(0xf0e48348); + vpop(); +#endif +} + + /* end of x86-64 code generator */ /*************************************************************/ +#endif /* ! TARGET_DEFS_ONLY */ +/******************************************************/ diff --git a/tinyc/x86_64-link.c b/tinyc/x86_64-link.c new file mode 100644 index 000000000..c0c5e13bf --- /dev/null +++ b/tinyc/x86_64-link.c @@ -0,0 +1,295 @@ +#ifdef TARGET_DEFS_ONLY + +#define EM_TCC_TARGET EM_X86_64 + +/* relocation type for 32 bit data relocation */ +#define R_DATA_32 R_X86_64_32S +#define R_DATA_PTR R_X86_64_64 +#define R_JMP_SLOT R_X86_64_JUMP_SLOT +#define R_GLOB_DAT R_X86_64_GLOB_DAT +#define R_COPY R_X86_64_COPY +#define R_RELATIVE R_X86_64_RELATIVE + +#define R_NUM R_X86_64_NUM + +#define ELF_START_ADDR 0x400000 +#define ELF_PAGE_SIZE 0x200000 + +#define PCRELATIVE_DLLPLT 1 +#define RELOCATE_DLLPLT 1 + +#else /* !TARGET_DEFS_ONLY */ + +#include "tcc.h" + +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_X86_64_32: + case R_X86_64_32S: + case R_X86_64_64: + case R_X86_64_GOTPC32: + case R_X86_64_GOTPC64: + case R_X86_64_GOTPCREL: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: + case R_X86_64_GOTTPOFF: + case R_X86_64_GOT32: + case R_X86_64_GOT64: + case R_X86_64_GLOB_DAT: + case R_X86_64_COPY: + case R_X86_64_RELATIVE: + case R_X86_64_GOTOFF64: + return 0; + + case R_X86_64_PC32: + case R_X86_64_PC64: + case R_X86_64_PLT32: + case R_X86_64_PLTOFF64: + case R_X86_64_JUMP_SLOT: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe whether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: + case R_X86_64_COPY: + case R_X86_64_RELATIVE: + return NO_GOTPLT_ENTRY; + + /* The following relocs wouldn't normally need GOT or PLT + slots, but we need them for simplicity in the link + editor part. See our caller for comments. */ + case R_X86_64_32: + case R_X86_64_32S: + case R_X86_64_64: + case R_X86_64_PC32: + case R_X86_64_PC64: + return AUTO_GOTPLT_ENTRY; + + case R_X86_64_GOTTPOFF: + return BUILD_GOT_ONLY; + + case R_X86_64_GOT32: + case R_X86_64_GOT64: + case R_X86_64_GOTPC32: + case R_X86_64_GOTPC64: + case R_X86_64_GOTOFF64: + case R_X86_64_GOTPCREL: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: + case R_X86_64_PLT32: + case R_X86_64_PLTOFF64: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) +{ + Section *plt = s1->plt; + uint8_t *p; + int modrm; + unsigned plt_offset, relofs; + + modrm = 0x25; + + /* empty PLT: create PLT0 entry that pushes the library identifier + (GOT + PTR_SIZE) and jumps to ld.so resolution routine + (GOT + 2 * PTR_SIZE) */ + if (plt->data_offset == 0) { + p = section_ptr_add(plt, 16); + p[0] = 0xff; /* pushl got + PTR_SIZE */ + p[1] = modrm + 0x10; + write32le(p + 2, PTR_SIZE); + p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */ + p[7] = modrm; + write32le(p + 8, PTR_SIZE * 2); + } + plt_offset = plt->data_offset; + + /* The PLT slot refers to the relocation entry it needs via offset. + The reloc entry is created below, so its offset is the current + data_offset */ + relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0; + + /* Jump to GOT entry where ld.so initially put the address of ip + 4 */ + p = section_ptr_add(plt, 16); + p[0] = 0xff; /* jmp *(got + x) */ + p[1] = modrm; + write32le(p + 2, got_offset); + p[6] = 0x68; /* push $xxx */ + /* On x86-64, the relocation is referred to by _index_ */ + write32le(p + 7, relofs / sizeof (ElfW_Rel)); + p[11] = 0xe9; /* jmp plt_start */ + write32le(p + 12, -(plt->data_offset)); + return plt_offset; +} + +/* relocate the PLT: compute addresses and offsets in the PLT now that final + address for PLT and GOT are known (see fill_program_header) */ +ST_FUNC void relocate_plt(TCCState *s1) +{ + uint8_t *p, *p_end; + + if (!s1->plt) + return; + + p = s1->plt->data; + p_end = p + s1->plt->data_offset; + + if (p < p_end) { + int x = s1->got->sh_addr - s1->plt->sh_addr - 6; + add32le(p + 2, x); + add32le(p + 8, x - 6); + p += 16; + while (p < p_end) { + add32le(p + 2, x + s1->plt->data - p); + p += 16; + } + } +} + +static ElfW_Rel *qrel; /* ptr to next reloc entry reused */ + +void relocate_init(Section *sr) +{ + qrel = (ElfW_Rel *) sr->data; +} + +void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) +{ + int sym_index, esym_index; + + sym_index = ELFW(R_SYM)(rel->r_info); + + switch (type) { + case R_X86_64_64: + if (s1->output_type == TCC_OUTPUT_DLL) { + esym_index = s1->sym_attrs[sym_index].dyn_index; + qrel->r_offset = rel->r_offset; + if (esym_index) { + qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64); + qrel->r_addend = rel->r_addend; + qrel++; + break; + } else { + qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); + qrel->r_addend = read64le(ptr) + val; + qrel++; + } + } + add64le(ptr, val); + break; + case R_X86_64_32: + case R_X86_64_32S: + if (s1->output_type == TCC_OUTPUT_DLL) { + /* XXX: this logic may depend on TCC's codegen + now TCC uses R_X86_64_32 even for a 64bit pointer */ + qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); + /* Use sign extension! */ + qrel->r_addend = (int)read32le(ptr) + val; + qrel++; + } + add32le(ptr, val); + break; + + case R_X86_64_PC32: + if (s1->output_type == TCC_OUTPUT_DLL) { + /* DLL relocation */ + esym_index = s1->sym_attrs[sym_index].dyn_index; + if (esym_index) { + qrel->r_offset = rel->r_offset; + qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32); + /* Use sign extension! */ + qrel->r_addend = (int)read32le(ptr) + rel->r_addend; + qrel++; + break; + } + } + goto plt32pc32; + + case R_X86_64_PLT32: + /* fallthrough: val already holds the PLT slot address */ + + plt32pc32: + { + long long diff; + diff = (long long)val - addr; + if (diff < -2147483648LL || diff > 2147483647LL) { + tcc_error("internal error: relocation failed"); + } + add32le(ptr, diff); + } + break; + + case R_X86_64_PLTOFF64: + add64le(ptr, val - s1->got->sh_addr + rel->r_addend); + break; + + case R_X86_64_PC64: + if (s1->output_type == TCC_OUTPUT_DLL) { + /* DLL relocation */ + esym_index = s1->sym_attrs[sym_index].dyn_index; + if (esym_index) { + qrel->r_offset = rel->r_offset; + qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC64); + qrel->r_addend = read64le(ptr) + rel->r_addend; + qrel++; + break; + } + } + add64le(ptr, val - addr); + break; + + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: + /* They don't need addend */ + write64le(ptr, val - rel->r_addend); + break; + case R_X86_64_GOTPCREL: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: + add32le(ptr, s1->got->sh_addr - addr + + s1->sym_attrs[sym_index].got_offset - 4); + break; + case R_X86_64_GOTPC32: + add32le(ptr, s1->got->sh_addr - addr + rel->r_addend); + break; + case R_X86_64_GOTPC64: + add64le(ptr, s1->got->sh_addr - addr + rel->r_addend); + break; + case R_X86_64_GOTTPOFF: + add32le(ptr, val - s1->got->sh_addr); + break; + case R_X86_64_GOT32: + /* we load the got offset */ + add32le(ptr, s1->sym_attrs[sym_index].got_offset); + break; + case R_X86_64_GOT64: + /* we load the got offset */ + add64le(ptr, s1->sym_attrs[sym_index].got_offset); + break; + case R_X86_64_GOTOFF64: + add64le(ptr, val - s1->got->sh_addr); + break; + case R_X86_64_RELATIVE: + /* do nothing */ + break; + } +} + +#endif /* !TARGET_DEFS_ONLY */ diff --git a/todo.txt b/todo.txt index 87cb2b509..e06ddf555 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,7 @@ version 1.0 battle plan ======================= -- make 'not nil' the default (produce warnings instead of errors for - a smooth migration path) -- case objects needs to be safe and need to support pattern matching -- implement a way to forward object type declarations across module - boundaries; C++ style +- let 'doAssert' analyse the expressions and produce more helpful output - fix "high priority" bugs - try to fix as many compiler crashes as reasonable @@ -13,19 +9,21 @@ version 1.0 battle plan Not critical for 1.0 ==================== -- get GC:v2 stable: nim c --gc:v2 -r -d:useSysAssert -d:useGcAssert -d:smokeCycles -d:useRealtimeGc tests/gc/gctest +- introduce ``nkStmtListExpr`` for template/macro invokations to produce + better stack traces +- make 'break' not leave named blocks +- make FlowVar compatible to Futures +- make 'not nil' the default (produce warnings instead of errors for + a smooth migration path) +- case objects needs to be safe and need to support pattern matching - find a solution for the x.f[T](y) gotcha - implement ``.delegate`` for .experimental - annotation support for getType() -- ``concept`` needs to be refined, a nice name for the feature is not enough. - make '--implicitStatic:on' the default; then we can also clean up the 'static[T]' mess in the compiler! - ``not`` or ``~`` for the effects system -- document and stress test ``.partial`` object declarations - figure out why C++ bootstrapping is so much slower -- The bitwise 'not' operator cold be renamed to 'bnot' to - prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs! - make 'nil' work for 'add': - resizeString - incrSeq @@ -33,7 +31,6 @@ Not critical for 1.0 - pragmas need 'bindSym' support - pragmas need re-work: 'push' is dangerous, 'hasPragma' does not work reliably with user-defined pragmas -- memory manager: add a measure of fragmentation - we need a magic thisModule symbol - optimize 'genericReset'; 'newException' leads to code bloat @@ -54,7 +51,6 @@ Bugs GC == -- use slightly bigger blocks in the allocator - resizing of strings/sequences could take into account the memory that is allocated diff --git a/tools/finish.nim b/tools/finish.nim index 45d7dd3a8..207f15f76 100644 --- a/tools/finish.nim +++ b/tools/finish.nim @@ -32,7 +32,7 @@ proc downloadMingw(): DownloadResult = let curl = findExe"curl" var cmd: string if curl.len > 0: - cmd = curl & " --out " & "dist" / mingw & " " & url + cmd = quoteShell(curl) & " --out " & "dist" / mingw & " " & url elif fileExists"bin/nimgrab.exe": cmd = "bin/nimgrab.exe " & url & " dist" / mingw if cmd.len > 0: diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim index 8dff722ec..e9c1b26fa 100644 --- a/tools/nimgrep.nim +++ b/tools/nimgrep.nim @@ -45,6 +45,9 @@ type TOptions = set[TOption] TConfirmEnum = enum ceAbort, ceYes, ceAll, ceNo, ceNone + Pattern = Regex | Peg + +using pattern: Pattern var filenames: seq[string] = @[] @@ -118,7 +121,7 @@ proc highlight(s, match, repl: string, t: tuple[first, last: int], stdout.write("\n") stdout.flushFile() -proc processFile(filename: string) = +proc processFile(pattern; filename: string) = var filenameShown = false template beforeHighlight = if not filenameShown and optVerbose notin options: @@ -135,18 +138,8 @@ proc processFile(filename: string) = if optVerbose in options: stdout.writeLine(filename) stdout.flushFile() - var pegp: Peg - var rep: Regex var result: string - if optRegex in options: - if {optIgnoreCase, optIgnoreStyle} * options != {}: - rep = re(pattern, {reExtended, reIgnoreCase}) - else: - rep = re(pattern) - else: - pegp = peg(pattern) - if optReplace in options: result = newStringOfCap(buffer.len) @@ -156,11 +149,7 @@ proc processFile(filename: string) = for j in 0..high(matches): matches[j] = "" var reallyReplace = true while i < buffer.len: - var t: tuple[first, last: int] - if optRegex notin options: - t = findBounds(buffer, pegp, matches, i) - else: - t = findBounds(buffer, rep, matches, i) + let t = findBounds(buffer, pattern, matches, i) if t.first < 0: break inc(line, countLines(buffer, i, t.first-1)) @@ -170,11 +159,7 @@ proc processFile(filename: string) = if optReplace notin options: highlight(buffer, wholeMatch, "", t, line, showRepl=false) else: - var r: string - if optRegex notin options: - r = replace(wholeMatch, pegp, replacement % matches) - else: - r = replace(wholeMatch, rep, replacement % matches) + let r = replace(wholeMatch, pattern, replacement % matches) if optConfirm in options: highlight(buffer, wholeMatch, r, t, line, showRepl=true) case confirm() @@ -246,17 +231,17 @@ proc styleInsensitive(s: string): string = addx() else: addx() -proc walker(dir: string) = +proc walker(pattern; dir: string) = for kind, path in walkDir(dir): case kind of pcFile: if extensions.len == 0 or path.hasRightExt(extensions): - processFile(path) + processFile(pattern, path) of pcDir: if optRecursive in options: - walker(path) + walker(pattern, path) else: discard - if existsFile(dir): processFile(dir) + if existsFile(dir): processFile(pattern, dir) proc writeHelp() = stdout.write(Usage) @@ -332,11 +317,18 @@ else: pattern = "\\y " & pattern elif optIgnoreCase in options: pattern = "\\i " & pattern + let pegp = peg(pattern) + for f in items(filenames): + walker(pegp, f) else: + var reflags = {reStudy, reExtended} if optIgnoreStyle in options: pattern = styleInsensitive(pattern) if optWord in options: pattern = r"\b (:?" & pattern & r") \b" - for f in items(filenames): - walker(f) + if {optIgnoreCase, optIgnoreStyle} * options != {}: + reflags.incl reIgnoreCase + let rep = re(pattern, reflags) + for f in items(filenames): + walker(rep, f) diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl index ec20566ac..3e7d8ae6e 100644 --- a/tools/niminst/buildsh.tmpl +++ b/tools/niminst/buildsh.tmpl @@ -144,6 +144,8 @@ case $ucpu in mycpu="sparc64" fi ;; + *ppc64le* ) + mycpu="powerpc64el" ;; *ppc64* ) if [ "$myos" = "linux" ] ; then COMP_FLAGS="$COMP_FLAGS -m64" diff --git a/tools/niminst/makefile.tmpl b/tools/niminst/makefile.tmpl index 4a20680e0..891333251 100644 --- a/tools/niminst/makefile.tmpl +++ b/tools/niminst/makefile.tmpl @@ -4,10 +4,10 @@ # "# Template is in tools/niminst/makefile.tmpl\n" & # "# To regenerate run ``niminst csource`` or ``koch csource``\n" -CC = gcc -LINKER = gcc -COMP_FLAGS = $(CPPFLAGS) $(CFLAGS) ?{c.ccompiler.flags} -LINK_FLAGS = $(LDFLAGS) ?{c.linker.flags} +CC ??= gcc +LD ??= gcc +CFLAGS += -Ic_code ?{c.ccompiler.flags} +LDFLAGS += ?{c.linker.flags} binDir = ?{firstBinPath(c).toUnix} koch := $(shell sh -c 'test -s ../koch.nim && echo "yes"') @@ -17,63 +17,57 @@ endif ucpu := $(shell sh -c 'uname -m | tr "[:upper:]" "[:lower:]"') uos := $(shell sh -c 'uname | tr "[:upper:]" "[:lower:]"') -uosname := $(shell sh -c 'uname -o | tr "[:upper:]" "[:lower:]"') ifeq ($(uos),linux) myos = linux - LINK_FLAGS += -ldl -lm + LDFLAGS += -ldl -lm endif ifeq ($(uos),dragonfly) myos = freebsd - LINK_FLAGS += -lm + LDFLAGS += -lm endif ifeq ($(uos),freebsd) myos= freebsd CC = clang - LINKER = clang - LINK_FLAGS += -lm + LD = clang + LDFLAGS += -lm endif ifeq ($(uos),openbsd) myos = openbsd - LINK_FLAGS += -lm + LDFLAGS += -lm endif ifeq ($(uos),netbsd) myos = netbsd - LINK_FLAGS += -lm + LDFLAGS += -lm endif ifeq ($(uos),darwin) myos = macosx CC = clang - LINKER = clang - LINK_FLAGS += -ldl -lm + LD = clang + LDFLAGS += -ldl -lm ifeq ($(HOSTTYPE),x86_64) ucpu = amd64 endif endif ifeq ($(uos),aix) myos = aix - LINK_FLAGS += -dl -lm + LDFLAGS += -dl -lm endif ifeq ($(uos),solaris) myos = solaris - LINK_FLAGS += -ldl -lm -lsocket -lnsl + LDFLAGS += -ldl -lm -lsocket -lnsl endif ifeq ($(uos),sun) myos = solaris - LINK_FLAGS += -ldl -lm -lsocket -lnsl + LDFLAGS += -ldl -lm -lsocket -lnsl endif ifeq ($(uos),haiku) myos = haiku endif -ifndef uos +ifndef myos $(error unknown operating system: $(uos)) endif -ifeq ($(uosname),android) - myos = android - LINK_FLAGS += -landroid-glob -endif - ifeq ($(ucpu),i386) mycpu = i386 endif @@ -107,11 +101,14 @@ endif ifeq ($(ucpu),sun) mycpu = sparc endif +ifeq ($(ucpu),ppc64le) + mycpu = powerpc64el +endif ifeq ($(ucpu),ppc64) mycpu = powerpc64 ifeq ($(myos),linux) - COMP_FLAGS += -m64 - LINK_FLAGS += -m64 + CFLAGS += -m64 + LDFLAGS += -m64 endif endif ifeq ($(ucpu),powerpc) @@ -138,7 +135,16 @@ endif ifeq ($(ucpu),armv6l) mycpu = arm endif -ifndef ucpu +ifeq ($(ucpu),armv7l) + mycpu = arm +endif +ifeq ($(ucpu),armv7hl) + mycpu = arm +endif +ifeq ($(ucpu),aarch64) + mycpu = arm64 +endif +ifndef mycpu $(error unknown processor: $(ucpu)) endif @@ -160,12 +166,9 @@ ifeq ($(strip $(oFiles)),) $(error no C code generated for: [$(myos): $(mycpu)]) endif -%.o: %.c - $(CC) $(COMP_FLAGS) -Ic_code -c $< -o $@ - ?{"$(binDir)/" & toLowerAscii(c.name)}: $(oFiles) @mkdir -p $(binDir) - $(LINKER) -o $@ $^ $(LINK_FLAGS) + $(LD) -o $@ $^ $(LDFLAGS) @echo "SUCCESS" .PHONY: clean diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index e4568dc3a..9c15326b0 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -283,7 +283,7 @@ proc yesno(p: var CfgParser, v: string): bool = else: quit(errorStr(p, "unknown value; use: yes|no")) proc incl(s: var seq[string], x: string): int = - for i in 0.. <s.len: + for i in 0 ..< s.len: if cmpIgnoreStyle(s[i], x) == 0: return i s.add(x) result = s.len-1 diff --git a/tools/nimpretty.nim b/tools/nimpretty.nim index 2c967b1e8..36d1382cf 100644 --- a/tools/nimpretty.nim +++ b/tools/nimpretty.nim @@ -42,7 +42,8 @@ proc writeVersion() = proc prettyPrint(infile: string) = let fileIdx = fileInfoIdx(infile) let tree = parseFile(fileIdx, newIdentCache()) - renderModule(tree, infile, {}) + let outfile = changeFileExt(infile, ".pretty.nim") + renderModule(tree, infile, outfile, {}) proc main = var infile: string @@ -50,7 +51,7 @@ proc main = for kind, key, val in getopt(): case kind of cmdArgument: - infile = key + infile = key.addFileExt(".nim") of cmdLongoption, cmdShortOption: case normalize(key) of "help", "h": writeHelp() diff --git a/tools/nimresolve.nim b/tools/nimresolve.nim deleted file mode 100644 index 9af24df5a..000000000 --- a/tools/nimresolve.nim +++ /dev/null @@ -1,158 +0,0 @@ -# -# -# The Nim Compiler -# (c) Copyright 2017 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## Standard tool that resolves import paths. - -import - os, strutils, parseopt - -import "../compiler/nimblecmd" - -# You can change these constants to build you own adapted resolver. -const - considerParentDirs = not defined(noParentProjects) - considerNimbleDirs = not defined(noNimbleDirs) - -const - Version = "1.0" - Usage = "nimresolve - Nim Resolve Package Path Version " & Version & """ - - (c) 2017 Andreas Rumpf -Usage: - nimresolve [options] package -Options: - --source:FILE the file that requests to resolve 'package' - --stdlib:PATH the path to use for the standard library - --project:FILE the main '.nim' file that was passed to the Nim compiler - --subdir:EXPR the subdir part in: 'import $pkg / subdir' - --noNimblePath do not search the Nimble path to resolve the package -""" - -proc writeHelp() = - stdout.write(Usage) - stdout.flushFile() - quit(0) - -proc writeVersion() = - stdout.write(Version & "\n") - stdout.flushFile() - quit(0) - -type - Task = object - source, stdlib, subdir, project, pkg: string - noNimblePath: bool - -proc findInNimbleDir(t: Task; dir: string): bool = - var best = "" - var bestv = "" - for k, p in os.walkDir(dir, relative=true): - if k == pcDir and p.len > t.pkg.len+1 and - p[t.pkg.len] == '-' and p.startsWith(t.pkg): - let (_, a) = getPathVersion(p) - if bestv.len == 0 or bestv < a: - bestv = a - best = dir / p - - if best.len > 0: - var f: File - if open(f, best / changeFileExt(t.pkg, ".nimble-link")): - # the second line contains what we're interested in, see: - # https://github.com/nim-lang/nimble#nimble-link - var override = "" - discard readLine(f, override) - discard readLine(f, override) - close(f) - if not override.isAbsolute(): - best = best / override - else: - best = override - let f = if t.subdir.len == 0: t.pkg else: t.subdir - let res = addFileExt(best / f, "nim") - if best.len > 0 and fileExists(res): - echo res - result = true - -const stdlibDirs = [ - "pure", "core", "arch", - "pure/collections", - "pure/concurrency", "impure", - "wrappers", "wrappers/linenoise", - "windows", "posix", "js"] - -proc resolve(t: Task) = - template attempt(a) = - let x = addFileExt(a, "nim") - if fileExists(x): - echo x - return - - case t.pkg - of "stdlib": - if t.subdir.len == 0: - echo t.stdlib - return - else: - for candidate in stdlibDirs: - attempt(t.stdlib / candidate / t.subdir) - of "root": - let root = t.project.splitFile.dir - if t.subdir.len == 0: - echo root - return - else: - attempt(root / t.subdir) - else: - when considerParentDirs: - var p = parentDir(t.source.splitFile.dir) - # support 'import $karax': - let f = if t.subdir.len == 0: t.pkg else: t.subdir - - while p.len > 0: - let dir = p / t.pkg - if dirExists(dir): - attempt(dir / f) - # 2nd attempt: try to use 'karax/karax' - attempt(dir / t.pkg / f) - # 3rd attempt: try to use 'karax/src/karax' - attempt(dir / "src" / f) - attempt(dir / "src" / t.pkg / f) - p = parentDir(p) - - when considerNimbleDirs: - if not t.noNimblePath: - if findInNimbleDir(t, getHomeDir() / ".nimble" / "pkgs"): return - when not defined(windows): - if findInNimbleDir(t, "/opt/nimble/pkgs"): return - - quit "cannot resolve: " & (t.pkg / t.subdir) - -proc main = - var t: Task - t.subdir = "" - for kind, key, val in getopt(): - case kind - of cmdArgument: - t.pkg = key - of cmdLongoption, cmdShortOption: - case normalize(key) - of "source": t.source = val - of "stdlib": t.stdlib = val - of "project": t.project = val - of "subdir": t.subdir = val - of "nonimblepath": t.noNimblePath = true - of "help", "h": writeHelp() - of "version", "v": writeVersion() - else: writeHelp() - of cmdEnd: assert(false) # cannot happen - if t.pkg.len == 0: - quit "[Error] no package to resolve." - resolve(t) - -main() diff --git a/tools/nimweb.nim b/tools/nimweb.nim index a082520e0..c8b87c1f2 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -52,7 +52,7 @@ proc initConfigData(c: var TConfigData) = c.pdf = @[] c.infile = "" c.outdir = "" - c.nimArgs = "--hint[Conf]:off --hint[Path]:off --hint[Processing]:off " + c.nimArgs = "--hint[Conf]:off --hint[Path]:off --hint[Processing]:off -d:boot " c.authors = "" c.projectTitle = "" c.projectName = "" @@ -307,7 +307,7 @@ proc buildDoc(c: var TConfigData, destPath: string) = destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc): - commands[i] = findNim() & " doc $# --git.url:$# -o:$# --index:on $#" % + commands[i] = findNim() & " doc0 $# --git.url:$# -o:$# --index:on $#" % [c.nimArgs, gitRepo, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc diff --git a/web/website.ini b/web/website.ini index 13e9b97e8..273c3223d 100644 --- a/web/website.ini +++ b/web/website.ini @@ -35,7 +35,7 @@ doc: "nimfix.rst;nimsuggest.rst;nep1.rst;nims.rst;contributing.rst" pdf: "manual.rst;lib.rst;tut1.rst;tut2.rst;nimc.rst;niminst.rst;gc.rst" srcdoc2: "system.nim;system/nimscript;pure/ospaths" srcdoc2: "core/macros;pure/marshal;core/typeinfo" -srcdoc2: "impure/re;impure/nre;pure/typetraits" +srcdoc2: "impure/re;impure/nre;pure/typetraits;../nimsuggest/sexp.nim" srcdoc2: "pure/concurrency/threadpool.nim;pure/concurrency/cpuinfo.nim" srcdoc: "system/threads.nim;system/channels.nim;js/dom" srcdoc2: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm" @@ -44,13 +44,14 @@ srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib;pure/strscan srcdoc2: "pure/parseopt;pure/parseopt2;pure/hashes;pure/strtabs;pure/lexbase" srcdoc2: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql" srcdoc2: "pure/streams;pure/terminal;pure/cgi;pure/unicode;pure/strmisc" -srcdoc2: "pure/htmlgen;pure/parseutils;pure/browsers" +srcdoc2: "pure/htmlgen;pure/parseutils;pure/browsers;js/jsconsole" srcdoc2: "impure/db_postgres;impure/db_mysql;impure/db_sqlite;pure/db_common" srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl" srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser" srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes" srcdoc2: "pure/json;pure/base64;pure/scgi" srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists" +srcdoc2: "pure/collections/sharedlist;pure/collections/sharedtables" srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/collections/deques;pure/encodings" srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies" srcdoc2: "pure/memfiles;pure/subexes;pure/collections/critbits" @@ -59,12 +60,15 @@ srcdoc2: "pure/nimprof;pure/unittest;packages/docutils/highlite" srcdoc2: "packages/docutils/rst;packages/docutils/rstast" srcdoc2: "packages/docutils/rstgen;pure/logging;pure/options;pure/asyncdispatch;pure/asyncnet" srcdoc2: "pure/nativesockets;pure/asynchttpserver;pure/net;pure/selectors;pure/future" -srcdoc2: "deprecated/pure/ftpclient" -srcdoc2: "pure/asyncfile;pure/asyncftpclient" +srcdoc2: "deprecated/pure/ftpclient;pure/collections/chains" +srcdoc2: "pure/asyncfile;pure/asyncftpclient;pure/lenientops" srcdoc2: "pure/md5;pure/rationals" -srcdoc2: "posix/posix;pure/distros" -srcdoc2: "pure/fenv;pure/securehash;impure/rdstdin" +srcdoc2: "posix/posix;pure/distros;pure/oswalkdir" +srcdoc2: "pure/collections/heapqueue" +srcdoc2: "pure/fenv;pure/securehash;impure/rdstdin;pure/strformat" +srcdoc2: "pure/segfaults" srcdoc2: "pure/basic2d;pure/basic3d;pure/mersenne;pure/coro;pure/httpcore" +srcdoc2: "pure/bitops;pure/nimtracker;pure/punycode;pure/volatile;js/asyncjs" ; Note: everything under 'webdoc' doesn't get listed in the index, so wrappers ; should live here @@ -73,7 +77,7 @@ webdoc: "wrappers/mysql;wrappers/iup" webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc;wrappers/odbcsql" webdoc: "wrappers/pcre" webdoc: "wrappers/openssl" -webdoc: "wrappers/libuv;wrappers/joyent_http_parser" +webdoc: "wrappers/joyent_http_parser" webdoc: "posix/posix;wrappers/odbcsql" webdoc: "wrappers/libsvm.nim" |