VirtualBox

Changeset 56976 in vbox


Ignore:
Timestamp:
Jul 18, 2015 3:32:09 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
101688
Message:

gccplugin.cpp: a little bit more.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/gccplugin.cpp

    r56975 r56976  
    2121#include <stdio.h>
    2222#include <iprt/cdefs.h>
     23#include <iprt/stdarg.h>
     24#include <iprt/string.h>
    2325
    2426#include "plugin.h"
     
    5961#define MY_LOC(a_hPreferred, a_pState) EXPR_LOC_OR_LOC(a_hPreferred, (a_pState)->hFmtLoc)
    6062
     63#define MY_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
     64
    6165
    6266/*******************************************************************************
     
    7074    long        iArgs;
    7175    location_t  hFmtLoc;
     76    const char *pszFmt;
    7277} MYCHECKSTATE;
    7378/** Pointer to my checker state. */
     
    208213#define MYSTATE_FMT_COLUMN(a_pState)    LOCATION_COLUMN((a_pState)->hFmtLoc)
    209214
     215void MyCheckWarnFmt(PMYCHECKSTATE pState, const char *pszLoc, const char *pszFormat, ...)
     216{
     217    char szTmp[1024];
     218    va_list va;
     219    va_start(va, pszFormat);
     220    vsnprintf(szTmp, sizeof(szTmp), pszFormat, va);
     221    va_end(va);
     222
     223
     224    /* Create a location for pszLoc. */
     225    location_t hLoc      = pState->hFmtLoc;
     226#if __GNUC__ >= 5 /** @todo figure this... */
     227    intptr_t   offString = pszLoc - pState->pszFmt;
     228    if (   offString > 0
     229        && !linemap_location_from_macro_expansion_p(line_table, hLoc))
     230    {
     231        unsigned            uCol    = 1 + offString;
     232        expanded_location   XLoc    = expand_location_to_spelling_point(hLoc);
     233        int                 cchLine;
     234# if __GNUC__ >= 5 /** @todo figure this... */
     235        const char         *pszLine = location_get_source_line(XLoc, &cchLine);
     236# else
     237        const char         *pszLine = location_get_source_line(XLoc);
     238        int                 cchLine = 0;
     239        if (pszLine)
     240        {
     241            const char *pszEol = strpbrk(pszLine, "\n\r");
     242            if (!pszEol)
     243                pszEol = strchr(pszLine, '\0');
     244            cchLine = (int)(pszEol - pszLine);
     245        }
     246# endif
     247        if (pszLine)
     248        {
     249            /** @todo Adjust the position by parsing the source. */
     250            pszLine += XLoc.column - 1;
     251            cchLine -= XLoc.column - 1;
     252        }
     253        location_t hNewLoc = linemap_position_for_loc_and_offset(line_table, hLoc, 0);
     254        if (hNewLoc)
     255            hLoc = hNewLoc;
     256    }
     257#endif
     258
     259    /* display the warning. */
     260    warning_at(hLoc, 0, "%s", szTmp);
     261}
     262
     263
    210264
    211265/**
     
    233287                warning_at(MY_LOC(hArg, pState), 0, "%u extra arguments not consumed by format string", cArgs - iArg);
    234288            else if (   TREE_CODE(hArg) != INTEGER_CST
    235                      || TREE_INT_CST(hArg).fits_shwi()
     289                     || !TREE_INT_CST(hArg).fits_shwi()
    236290                     || TREE_INT_CST(hArg).to_shwi() != -99) /* ignore final dummy argument: ..., -99); */
    237291                warning_at(MY_LOC(hArg, pState), 0, "one extra argument not consumed by format string");
     
    245299}
    246300
     301void MyCheckIntArg(PMYCHECKSTATE pState, const char *pszFmt, unsigned iArg, const char *pszMessage)
     302{
     303
     304}
     305
     306
    247307
    248308/**
     
    258318    dprintf("checker2: \"%s\" at %s:%d col %d\n", pszFmt,
    259319            MYSTATE_FMT_FILE(pState), MYSTATE_FMT_LINE(pState), MYSTATE_FMT_COLUMN(pState));
     320    pState->pszFmt = pszFmt;
     321
    260322    unsigned iArg = 0;
    261323    for (;;)
     
    263325        /*
    264326         * Skip to the next argument.
     327         * Quits the loop with the first char following the '%' in 'ch'.
    265328         */
    266329        char ch;
    267         while ((ch = *pszFmt++) != '%')
    268             if (ch == '\0')
     330        for (;;)
     331        {
     332            ch = *pszFmt++;
     333            if (ch == '%')
     334            {
     335                ch = *pszFmt++;
     336                if (ch != '%')
     337                    break;
     338            }
     339            else if (ch == '\0')
    269340            {
    270341                MyCheckFinalArg(pState, iArg);
    271342                return;
    272343            }
    273 
     344        }
     345
     346        /*
     347         * Flags
     348         */
     349        uint32_t fFlags = 0;
     350        for (;;)
     351        {
     352            uint32_t fFlag;
     353            switch (ch)
     354            {
     355                case '#':   fFlag = RTSTR_F_SPECIAL;      break;
     356                case '-':   fFlag = RTSTR_F_LEFT;         break;
     357                case '+':   fFlag = RTSTR_F_PLUS;         break;
     358                case ' ':   fFlag = RTSTR_F_BLANK;        break;
     359                case '0':   fFlag = RTSTR_F_ZEROPAD;      break;
     360                case '\'':  fFlag = RTSTR_F_THOUSAND_SEP; break;
     361                default:    fFlag = 0;                    break;
     362            }
     363            if (!fFlag)
     364                break;
     365            if (fFlags & fFlag)
     366                MyCheckWarnFmt(pState, pszFmt - 1, "duplicate flag '%c'", ch);
     367            fFlags |= fFlag;
     368            ch = *pszFmt++;
     369        }
     370
     371        /*
     372         * Width.
     373         */
     374        int cchWidth = -1;
     375        if (MY_ISDIGIT(ch))
     376        {
     377            cchWidth = ch - '0';
     378            while (   (ch = *pszFmt++) != '\0'
     379                   && MY_ISDIGIT(ch))
     380            {
     381                cchWidth *= 10;
     382                cchWidth += ch - '0';
     383            }
     384            fFlags |= RTSTR_F_WIDTH;
     385        }
     386        else if (ch == '*')
     387        {
     388            MyCheckIntArg(pState, pszFmt - 1, iArg, "width should be an 'int' sized argument");
     389            iArg++;
     390            cchWidth = 0;
     391            fFlags |= RTSTR_F_WIDTH;
     392        }
     393
     394        /*
     395         * Precision
     396         */
     397        int cchPrecision = -1;
     398        if (ch == '.')
     399        {
     400            ch = *pszFmt++;
     401            if (MY_ISDIGIT(ch))
     402            {
     403                cchPrecision = ch - '0';
     404                while (   (ch = *pszFmt++) != '\0'
     405                       && MY_ISDIGIT(ch))
     406                {
     407                    cchPrecision *= 10;
     408                    cchPrecision += ch - '0';
     409                }
     410            }
     411            else if (ch == '*')
     412            {
     413                MyCheckIntArg(pState, pszFmt - 1, iArg, "precision should be an 'int' sized argument");
     414                iArg++;
     415                cchWidth = 0;
     416            }
     417            else
     418                MyCheckWarnFmt(pState, pszFmt - 1, "Missing precision value, only got the '.'");
     419            if (cchPrecision < 0)
     420            {
     421                MyCheckWarnFmt(pState, pszFmt - 1, "Negative precision value: %d", cchPrecision);
     422                cchPrecision = 0;
     423            }
     424            fFlags |= RTSTR_F_PRECISION;
     425        }
     426
     427        /*
     428         * Argument size.
     429         */
     430        char chArgSize = ch;
     431        switch (ch)
     432        {
     433            default:
     434                chArgSize = '\0';
     435                break;
     436
     437            case 'z':
     438            case 'L':
     439            case 'j':
     440            case 't':
     441                ch = *pszFmt++;
     442                break;
     443
     444            case 'l':
     445                ch = *pszFmt++;
     446                if (ch == 'l')
     447                {
     448                    chArgSize = 'L';
     449                    ch = *pszFmt++;
     450                }
     451                break;
     452
     453            case 'h':
     454                ch = *pszFmt++;
     455                if (ch == 'h')
     456                {
     457                    chArgSize = 'H';
     458                    ch = *pszFmt++;
     459                }
     460                break;
     461
     462            case 'I': /* Used by Win32/64 compilers. */
     463                if (   pszFmt[0] == '6'
     464                    && pszFmt[1] == '4')
     465                {
     466                    pszFmt += 2;
     467                    chArgSize = 'L';
     468                }
     469                else if (   pszFmt[0] == '3'
     470                         && pszFmt[1] == '2')
     471                {
     472                    pszFmt += 2;
     473                    chArgSize = 0;
     474                }
     475                else
     476                    chArgSize = 'j';
     477                ch = *pszFmt++;
     478                break;
     479
     480            case 'q': /* Used on BSD platforms. */
     481                chArgSize = 'L';
     482                ch = *pszFmt++;
     483                break;
     484        }
     485
     486        /*
     487         * The type.
     488         */
    274489
    275490    }
     
    515730                    State.hStmt   = hStmt;
    516731                    State.hFmtLoc = gimple_location(hStmt);
     732                    State.pszFmt  = NULL;
    517733                    dprintf("     %s() __iprt_format__(iFmt=%ld, iArgs=%ld)\n",
    518734                            DECL_NAME(hFnDecl) ? IDENTIFIER_POINTER(DECL_NAME(hFnDecl)) : "<unamed>", State.iFmt, State.iArgs);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette