Ejemplo n.º 1
0
        bool _ExternConst(bool isJustConst = false)
        {
            if (!(_TokIsIdent(_i) && _TokIsIdent(_i + 1)))
            {
                return(false);                                                      //must be TYPE name
            }
            int what = 0;

            if (_TokIsChar(_i + 2, ';'))
            {
                what = 1;
            }
            else if (isJustConst && _TokIsChar(_i + 2, '='))
            {
                what = 2;
            }
            else
            {
                return(false);
            }

            //get type
            _Symbol x;

            if (!_TryFindSymbol(_i, out x, false))
            {
                return(false);
            }
            if (0 != _Unalias(_i, ref x))
            {
                return(false);
            }
            _i++;

            if (what == 1)
            {
                //we need only GUID
                if (x.csTypename != "GUID")
                {
                    return(false);
                }

                string name = _TokToString(_i), data;
                if (!_guids.TryGetValue(name, out data))
                {
                    //AOutput.Write(name);
                    return(false);
                }

                if (name.Ends("A") && char.IsLower(name[name.Length - 2]))
                {
                    //AOutput.Write(name);
                    return(false);
                }
                else if (name.Ends("W") && char.IsLower(name[name.Length - 2]))
                {
                    //AOutput.Write(name);
                    name = name.Remove(name.Length - 1);
                }

                if (!_guidsAdded.Add(name))
                {
                    return(false);                                       //prevent duplicates
                }
                _sbVar.AppendFormat("\r\ninternal static Guid {0} = new Guid({1});\r\n", name, data);

                _i++;
            }
            else                 //C++ const constant
            {
                var ct = x as _CppType;
                if (ct == null)
                {
                    //_Err(_i, "example");
                    return(false);
                }

                int iName = _i++, iValue = ++_i;
                while (!_TokIsChar(_i, ';'))
                {
                    _i++;
                }
                string name = _TokToString(iName);

                _ExpressionResult r = _Expression(iValue, _i, name);
                //OutList(ct.csTypename, r.typeS, r.valueS);
                if (r.typeS == null)
                {
                    return(false);
                }

                _enumValues[_tok[iName]] = r.valueI;

                __sbDef.Clear();
                __sbDef.AppendFormat("internal const {0} {1} = {2};", ct.csTypename, name, r.valueS);
                //AOutput.Write(__sbDef);
                _cppConst.Add(__sbDef.ToString());
            }
            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Converts C-style fixed-size array to C#. Gets MarshalAs attribute, appends "[]" to typeName etc.
        /// Supports "[y][x]" etc.
        /// _i must be at '['. Finally it will be after ']'.
        /// If empty array (like TYPE x[] or TYPE x[0]), attributes receives "//...". If 1-element array, receives "/*...*/".
        /// </summary>
        /// <param name="typeName">This function appends "[]" if need, or convertes "char" to "string".</param>
        /// <param name="memberName">If less than 8 elements, and memberName looks like a "Reserved" etc, splits into multiple members like "Reserved_0, Reserved_1, ...".</param>
        /// <param name="attributes">If !isParameter, receives attribute like "[MarshalAs(UnmanagedType.ByValArray, SizeConst = {x})]". If already is MarshalAs attribute, uses it as ArraySubType.</param>
        /// <param name="isParameter">Just skip [..] or [...][...] and append "[]" to typeName. Used for parameters, because the attribute can be used only with struct fields; C++ arguments for parameters 'TYPE param[n]' are passed like 'TYPE* param', and n is ignored, can be empty.</param>
        void _ConvertCArray(ref string typeName, ref string memberName, ref string attributes, bool isParameter = false)
        {
            uint elemCount = 1;

            for (; _TokIsChar(_i, '['); _i++)              //support [a][b]
            {
                int i0 = _i + 1;
                _SkipEnclosed();
                if (isParameter)
                {
                    continue;
                }
                uint ec = 0;
                if (_i > i0)                  //else TYPE x[]
                {
                    _ExpressionResult r = _Expression(i0, _i, "[]");
                    switch (r.typeS)
                    {
                    case "int":
                    case "uint": break;

                    default: _Err(i0, "cannot calculate"); break;
                    }
                    ec = r.valueI;
                }
                elemCount *= ec;
            }

            if (isParameter)
            {
                typeName += "[]";
                return;
            }

            if (typeName.Ends("[]"))
            {
                typeName = typeName.Remove(typeName.Length - 2);                                 //'TYPE a[n], b[m]'
            }
            string marshalAs = "ByValArray", comment = null, comment2 = null;

            if (elemCount == 0)                  //variable-length array of >= 0 elements
            {
                comment = "//";                  //disable the attribute together with member, and let the member be not array
            }
            else if (elemCount == 1)             //variable-length array of >= 1 elements
            {
                comment = "/*"; comment2 = "*/"; //disable the attribute, and let the member be not array
            }
            else if (typeName == "char")
            {
                typeName  = "string";
                marshalAs = "ByValTStr";
            }
            else
            {
                if (elemCount < 8 && (memberName.Find("Reserved", true) >= 0 || memberName.Find("pad", true) >= 0 || memberName.Starts("Spare", true)))
                {
                    //AOutput.Write(memberName);
                    var sb = new StringBuilder();
                    for (int i = 0; i < elemCount; i++)
                    {
                        if (i > 0)
                        {
                            sb.Append(", ");
                        }
                        sb.Append(memberName);
                        sb.Append('_');
                        sb.Append(i);
                    }
                    memberName = sb.ToString();
                    comment    = "/*"; comment2 = "*/";
                }
                else
                {
                    //if(elemCount<8) AOutput.Write(memberName);
                    typeName += "[]";
                }
            }

            if (attributes != null)
            {
                _Err(_i, "TODO");                                //0 in SDK. Should extract its type from [MarshalAs(UnmanagedType.(\w+) and insert in the new attributes.
            }
            attributes = $"{comment}[MarshalAs(UnmanagedType.{marshalAs}, SizeConst = {elemCount})]{comment2}";
        }
Ejemplo n.º 3
0
        void _DefineUndef()
        {
            char *s = T(++_i);
            char  c = *s;            //was like `d$$$_REALNAME, now s is without `

            if (c == 'c')            //`cx "C# code converted by the preprocessor script", where x tells what it is
            {
                if (!_TokIsChar(++_i, '\x2'))
                {
                    _Err(_i, "unexpected 1");
                }
                _tok[_i] = new _Token(T(_i) + 1, _tok[_i].len - 2);
                if (s[1] == 'p')
                {
                    _sbVar.AppendLine(_TokToString(_i));
                }
                else
                {
                    _Err(_i - 1, "unexpected 2");
                }
                return;
            }

            s       += 5; int lenName = _tok[_i].len - 5;       //skip prefix 'd$$$_' that was added to avoid unexpanding names
            _tok[_i] = new _Token(s, lenName);
            int iName = _i;

            //is function-style?
            char *s2     = T(++_i);
            bool  isFunc = c == 'd' && *s2 == '(' && s2 == s + lenName;

            //find value
            int iValue = _i, iParamOrValue = _i;

            if (isFunc)
            {
                iValue = _SkipEnclosed(_i) + 1;                    //name(parameters)[ value]
            }
            //find next line
            int iNext = iValue;

            for (; ; iNext++)
            {
                char k = *T(iNext);
                if (k == '`' || k == '\x0')
                {
                    break;
                }
            }

            string name = new string(s, 0, lenName);

            if (c == 'u')              //#undef
            {
                if (!_defineConst.Remove(name) && !_defineOther.Remove(name))
                {
                    _defineW.Remove(name);
                }
                //AOutput.Write($"#undef {name}");
            }
            else if (iValue < iNext)         //preprocessor removes some #define values, it's ok
            {
                if (isFunc)                  //info: for func-style get parameters as part of value
                {
                    __DefineAddToOther(iName, name, _TokToString(iParamOrValue, iNext));
                }
                else if (*s2 == '\x2')                    //ANSI string constant, when tokenizing replaced the first '\"' to '\x2'
                {
                    *s2 = '\"';
                    __DefineAddToOther(iName, name, " " + _TokToString(iParamOrValue, iNext) + " //ANSI string");
                }
                else
                {
                    _ExpressionResult r = _Expression(iParamOrValue, iNext, name);
                    if (r.typeS == null)
                    {
                        bool isFuncWA = (iNext - iValue == 1) && __DefineWA(name, r.valueS);
                        if (!isFuncWA)
                        {
                            //don't add '#define NAME1 NAME2'
                            if (iNext - iValue == 1 && _TokIsIdent(iValue))
                            {
                                //OutList(name, r.valueS);
                            }
                            else
                            {
                                //OutList(name, iNext-iValue);
                                __DefineAddToOther(iName, name, " " + r.valueS);
                            }
                        }
                    }
                    else
                    {
                        __sbDef.Clear();
                        __sbDef.AppendFormat("internal {2} {3} {0} = {1};", name, r.valueS, r.notConst ? "readonly" : "const", r.typeS);
                        _defineConst[name] = __sbDef.ToString();
                    }
                }
            }

            _i = iNext - 1;
        }