src/Edit.c
void EditDetectEOLMode(LPCSTR lpData, size_t cbData, EditFileIOStatus* const status)
{
  if (!lpData || (cbData == 0)) { return; }

  /* '\r' and '\n' is not reused (e.g. as trailing byte in DBCS) by any known encoding,
  it's safe to check whole data byte by byte.*/

  DocLn lineCountCRLF = 0;
  DocLn lineCountCR = 0;
  DocLn lineCountLF = 0;

  // tools/GenerateTable.py
  static const uint8_t eol_table[16] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, // 00 - 0F
  };

  const uint8_t* ptr = (const uint8_t*)lpData;
  // No NULL-terminated requirement for *ptr == '\n'
  const uint8_t* const end = (const uint8_t*)lpData + cbData - 1;

  do {
    // skip to line end
    uint8_t ch;
    uint8_t type = 0;
    while (ptr < end && ((ch = *ptr++) > '\r' || (type = eol_table[ch]) == 0)) {} // nop
    switch (type) {
      case 1: //'\n'
        ++lineCountLF;
        break;
      case 2: //'\r'
        if (*ptr == '\n') {
          ++ptr;
          ++lineCountCRLF;
        }
        else {
          ++lineCountCR;
        }
        break;
    }
  } while (ptr < end);

  if (ptr == end) {
    switch (*ptr) {
      case '\n':
        ++lineCountLF;
        break;
      case '\r':
        ++lineCountCR;
        break;
    }
  }

  // values must kept in same order as SC_EOL_CRLF(0), SC_EOL_CR(1), SC_EOL_LF(2)
  DocLn const linesMax = max_ln(max_ln(lineCountCRLF, lineCountCR), lineCountLF);
  DocLn linesCount[3] = { 0, 0, 0 };
  linesCount[SC_EOL_CRLF] = lineCountCRLF;
  linesCount[SC_EOL_CR] = lineCountCR;
  linesCount[SC_EOL_LF] = lineCountLF;

  int iEOLMode = status->iEOLMode;
  if (linesMax != linesCount[iEOLMode])
  {
    if (linesMax == linesCount[SC_EOL_CRLF]) {
      iEOLMode = SC_EOL_CRLF;
    }
    else if (linesMax == linesCount[SC_EOL_CR]) {
      iEOLMode = SC_EOL_CR;
    }
    else {
      iEOLMode = SC_EOL_LF;
    }
  }
  status->iEOLMode = iEOLMode;

  status->bInconsistentEOLs = 1 < ((!!lineCountCRLF) + (!!lineCountCR) + (!!lineCountLF));
  status->eolCount[SC_EOL_CRLF] = lineCountCRLF;
  status->eolCount[SC_EOL_CR] = lineCountCR;
  status->eolCount[SC_EOL_LF] = lineCountLF;
}
//=============================================================================
//
// EditDetectEOLMode() - moved here to handle Unicode files correctly
// by zufuliu (https://github.com/zufuliu/notepad2)
//

moved here to handle Unicode files correctly
by zufuliu
moved here to handle Unicode files correctly by zufuliu
void EditDetectEOLMode(LPCSTR lpData, size_t cbData, EditFileIOStatus* const status)
{
  if (!lpData || (cbData == 0)) { return; }
  DocLn lineCountCRLF = 0;
  DocLn lineCountCR = 0;
  DocLn lineCountLF = 0;
  static const uint8_t eol_table[16] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 
  };
  const uint8_t* ptr = (const uint8_t*)lpData;
  const uint8_t* const end = (const uint8_t*)lpData + cbData - 1;
  do {
    uint8_t ch;
    uint8_t type = 0;
    while (ptr < end && ((ch = *ptr++) > '\r' || (type = eol_table[ch]) == 0)) {} 
    switch (type) {
      case 1: 
        ++lineCountLF;
        break;
      case 2: 
        if (*ptr == '\n') {
          ++ptr;
          ++lineCountCRLF;
        }
        else {
          ++lineCountCR;
        }
        break;
    }
  } while (ptr < end);
  if (ptr == end) {
    switch (*ptr) {
      case '\n':
        ++lineCountLF;
        break;
      case '\r':
        ++lineCountCR;
        break;
    }
  }
  DocLn const linesMax = max_ln(max_ln(lineCountCRLF, lineCountCR), lineCountLF);
  DocLn linesCount[3] = { 0, 0, 0 };
  linesCount[SC_EOL_CRLF] = lineCountCRLF;
  linesCount[SC_EOL_CR] = lineCountCR;
  linesCount[SC_EOL_LF] = lineCountLF;
  int iEOLMode = status->iEOLMode;
  if (linesMax != linesCount[iEOLMode])
  {
    if (linesMax == linesCount[SC_EOL_CRLF]) {
      iEOLMode = SC_EOL_CRLF;
    }
    else if (linesMax == linesCount[SC_EOL_CR]) {
      iEOLMode = SC_EOL_CR;
    }
    else {
      iEOLMode = SC_EOL_LF;
    }
  }
  status->iEOLMode = iEOLMode;
  status->bInconsistentEOLs = 1 < ((!!lineCountCRLF) + (!!lineCountCR) + (!!lineCountLF));
  status->eolCount[SC_EOL_CRLF] = lineCountCRLF;
  status->eolCount[SC_EOL_CR] = lineCountCR;
  status->eolCount[SC_EOL_LF] = lineCountLF;
}
void EditDetectEOLMode ( LPCSTR lpData , size_t cbData , EditFileIOStatus * const status ) { if ( ! lpData || ( cbData == 0 ) ) { return ; } DocLn lineCountCRLF = 0 ; DocLn lineCountCR = 0 ; DocLn lineCountLF = 0 ; static const uint8_t eol_table [ 16 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 2 , 0 , 0 , } ; const uint8_t * ptr = ( const uint8_t * ) lpData ; const uint8_t * const end = ( const uint8_t * ) lpData + cbData - 1 ; do { uint8_t ch ; uint8_t type = 0 ; while ( ptr < end && ( ( ch = * ptr ++ ) > ' \r ' || ( type = eol_table [ ch ] ) == 0 ) ) { } switch ( type ) { case 1 : ++ lineCountLF ; break ; case 2 : if ( * ptr == ' \n ' ) { ++ ptr ; ++ lineCountCRLF ; } else { ++ lineCountCR ; } break ; } } while ( ptr < end ) ; if ( ptr == end ) { switch ( * ptr ) { case ' \n ' : ++ lineCountLF ; break ; case ' \r ' : ++ lineCountCR ; break ; } } DocLn const linesMax = max_ln ( max_ln ( lineCountCRLF , lineCountCR ) , lineCountLF ) ; DocLn linesCount [ 3 ] = { 0 , 0 , 0 } ; linesCount [ SC_EOL_CRLF ] = lineCountCRLF ; linesCount [ SC_EOL_CR ] = lineCountCR ; linesCount [ SC_EOL_LF ] = lineCountLF ; int iEOLMode = status -> iEOLMode ; if ( linesMax != linesCount [ iEOLMode ] ) { if ( linesMax == linesCount [ SC_EOL_CRLF ] ) { iEOLMode = SC_EOL_CRLF ; } else if ( linesMax == linesCount [ SC_EOL_CR ] ) { iEOLMode = SC_EOL_CR ; } else { iEOLMode = SC_EOL_LF ; } } status -> iEOLMode = iEOLMode ; status -> bInconsistentEOLs = 1 < ( ( ! ! lineCountCRLF ) + ( ! ! lineCountCR ) + ( ! ! lineCountLF ) ) ; status -> eolCount [ SC_EOL_CRLF ] = lineCountCRLF ; status -> eolCount [ SC_EOL_CR ] = lineCountCR ; status -> eolCount [ SC_EOL_LF ] = lineCountLF ; }
EditDetectEOLMode() - moved here to handle Unicode files correctly
by zufuliu (https://github.com/zufuliu/notepad2)
EditDetectEOLMode () - moved here to handle Unicode files correctly by zufuliu ( https : // github . com / zufuliu / notepad2 )
/* '\r' and '\n' is not reused (e.g. as trailing byte in DBCS) by any known encoding,
  it's safe to check whole data byte by byte.*/ // tools/GenerateTable.py
 // 00 - 0F
 // No NULL-terminated requirement for *ptr == '\n'
 // skip to line end
 // nop
 //'\n'
 //'\r'
 // values must kept in same order as SC_EOL_CRLF(0), SC_EOL_CR(1), SC_EOL_LF(2)
