static void IFNextChar (CharSource* S) /* Read the next character from the input file */ { /* Check for end of line, read the next line if needed */ while (S->V.File.Line [S->V.File.Pos.Col] == '\0') { unsigned Len, Removed; /* End of current line reached, read next line */ if (fgets (S->V.File.Line, sizeof (S->V.File.Line), S->V.File.F) == 0) { /* End of file. Add an empty line to the listing. This is a * small hack needed to keep the PC output in sync. */ NewListingLine ("", S->V.File.Pos.Name, FCount); C = EOF; return; } /* For better handling of files with unusual line endings (DOS * files that are accidently translated on Unix for example), * first remove all whitespace at the end, then add a single * newline. */ Len = strlen (S->V.File.Line); Removed = 0; while (Len > 0 && IsSpace (S->V.File.Line[Len-1])) { ++Removed; --Len; } if (Removed) { S->V.File.Line[Len+0] = '\n'; S->V.File.Line[Len+1] = '\0'; } /* One more line */ S->V.File.Pos.Line++; S->V.File.Pos.Col = 0; /* Remember the new line for the listing */ NewListingLine (S->V.File.Line, S->V.File.Pos.Name, FCount); } /* Return the next character from the file */ C = S->V.File.Line [S->V.File.Pos.Col++]; }
static void IFNextChar (CharSource* S) /* Read the next character from the input file */ { /* Check for end of line, read the next line if needed */ while (SB_GetIndex (&S->V.File.Line) >= SB_GetLen (&S->V.File.Line)) { unsigned Len; /* End of current line reached, read next line */ SB_Clear (&S->V.File.Line); while (1) { int N = fgetc (S->V.File.F); if (N == EOF) { /* End of file. Accept files without a newline at the end */ if (SB_NotEmpty (&S->V.File.Line)) { break; } /* No more data - add an empty line to the listing. This ** is a small hack needed to keep the PC output in sync. */ NewListingLine (&EmptyStrBuf, S->V.File.Pos.Name, FCount); C = EOF; return; /* Check for end of line */ } else if (N == '\n') { /* End of line */ break; /* Collect other stuff */ } else { /* Append data to line */ SB_AppendChar (&S->V.File.Line, N); } } /* If we come here, we have a new input line. To avoid problems ** with strange line terminators, remove all whitespace from the ** end of the line, then add a single newline. */ Len = SB_GetLen (&S->V.File.Line); while (Len > 0 && IsSpace (SB_AtUnchecked (&S->V.File.Line, Len-1))) { --Len; } SB_Drop (&S->V.File.Line, SB_GetLen (&S->V.File.Line) - Len); SB_AppendChar (&S->V.File.Line, '\n'); /* Terminate the string buffer */ SB_Terminate (&S->V.File.Line); /* One more line */ S->V.File.Pos.Line++; /* Remember the new line for the listing */ NewListingLine (&S->V.File.Line, S->V.File.Pos.Name, FCount); } /* Set the column pointer */ S->V.File.Pos.Col = SB_GetIndex (&S->V.File.Line); /* Return the next character from the buffer */ C = SB_Get (&S->V.File.Line); }