)]}'
{
  "commit": "aeddbcf2878ebf8bc5a489c13922d82ae0c9a277",
  "tree": "890a988da02d3bf7166f0942cdbd3832820c7315",
  "parents": [
    "18732e35971d11d6ed44438be912116c37e2bb2c"
  ],
  "author": {
    "name": "Al Viro",
    "email": "viro@zeniv.linux.org.uk",
    "time": "Sun Mar 15 19:53:16 2026 -0400"
  },
  "committer": {
    "name": "Al Viro",
    "email": "viro@zeniv.linux.org.uk",
    "time": "Wed Apr 01 05:31:30 2026 -0400"
  },
  "message": "try to get whitespaces right\n\nPreprocessor started as a text filter - it took a stream of characters\nand produced a stream of characters, with the output fed to compiler.\nSemantics had been not _quite_ as bad as with Bourne shell, but it\nhad been full of dark corners all the same.\n\nBy C99 times it had been replaced with something far better defined.\nNow it operates on stream of tokens, and the output stream is _not_\nfed through the tokenizer again.  Operations are defined in terms of\nmanipulations with that stream of tokens, which avoids a lot of\nheadache.\n\nUnfortunately, it\u0027s not exactly a stream of tokens - it\u0027s a stream of\ntokens and whitespaces.  Which is where the things get interesting.\nWhen the standard says \"replace the tokens from \u003chere\u003e to \u003cthere\u003e with\nthe sequence of tokens obtained by \u003cthis\u003e\", the general understanding\nis that\n\t* whatever whitespaces might\u0027ve been between \u003chere\u003e and \u003cthere\u003e\nare removed\n\t* any whitespaces prior to \u003chere\u003e and past \u003cthere\u003e remain as-is\n\t* any whitespaces between the tokens of the sequence we are\ntold to substitute go into the the result.\nWhat\u0027s not agreed upon is what should be done to possible leading or\ntrailing whitespaces in the sequence.\n\nIn a lot of cases it doesn\u0027t matter - subsequent phases care only about\ntokens.  Moreover, \u0027#\u0027 operator (which does care about whitespaces) is\nexplicitly required to trim any leading and trailing whitespace.  However,\nthere are cases where it is observable and different implementations\nyield different results.\n\nCurrently sparse is prone to losing whitespace in many situations\nwhere it definitely shouldn\u0027t.  This commit attempts to fix that;\nsemantics I\u0027m going for matches what clang is doing, namely \"trim the\nleading and trailing whitespace off the sequence being substituted\".\nI would consider doing what gcc does (and it does diverge from clang in\nsome cases), but... it\u0027s full of interesting corner cases and downright\nbroken around combining __VA_OPT__() with ##.  When/if they decide what\nto do with that...\n\nWhat this commit does is\n\t* don\u0027t lose -\u003epos.{newline,whitespace} deposited on TOKEN_UNTAINT\ntokens; when scan_next() finds and skips those, have it collect their\n-\u003epos.{whitespace,newline}.  If we are not at the end of the list and\neventually get to a normal token, add the collected flags to it. Turns\nout that the comment in expand() had been too pessimistic - it\u0027s _not_\nterribly costly, provided that the slow case of scan_next() is uninlined.\n\n\t* have substitute() keep better track of pending whitespace.\nThe tricky part is the logics related to placemarkers and concatenation;\nsee the comments in front of substitute() for details.\n\nNote: gcc code generation for bitfields really, really stinks.\n\nSigned-off-by: Al Viro \u003cviro@zeniv.linux.org.uk\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "a368b9ed322aa3173713d2c8f09c696f8a3b0844",
      "old_mode": 33188,
      "old_path": "pre-process.c",
      "new_id": "dab8768a5340164ddb5f0071c642bcceeb5ec0e7",
      "new_mode": 33188,
      "new_path": "pre-process.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "f39cabadd867e29bfb385e3bc88929a2df1c277b",
      "new_mode": 33188,
      "new_path": "validation/preprocessor/va_opt-concat.c"
    },
    {
      "type": "modify",
      "old_id": "4fa387949ac450101fbb91ebd16f475ba3bca28e",
      "old_mode": 33188,
      "old_path": "validation/preprocessor/va_opt.c",
      "new_id": "afb5b00727c8dcb18892b314d920a337aca34104",
      "new_mode": 33188,
      "new_path": "validation/preprocessor/va_opt.c"
    },
    {
      "type": "modify",
      "old_id": "5523301ed6a4b69ebc9c1ef6fca1d2113682278c",
      "old_mode": 33188,
      "old_path": "validation/preprocessor/va_opt2.c",
      "new_id": "0828ce583e9d7cb6122bafa891932e4785d59c45",
      "new_mode": 33188,
      "new_path": "validation/preprocessor/va_opt2.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "27bbea14b088e60792b9fd6df29689778ed069d8",
      "new_mode": 33188,
      "new_path": "validation/preprocessor/whitespace.c"
    }
  ]
}
