Increment the line number each time we go through.
Get a command from the commands buffer.
Match this one first, because it's the most specific - put the various bits of the command
into the various variables. Also, make sure the range modifier is one of the valid ones,
and that the not modifier is what we expect.
if(sscanf(cmd_line, "%d%c%d%c%c%s", &location, &rangeModifier, &locationB, ¬Modifier, &commandLetter, string) 6
',' || rangeModifier '~')
& notModifier
'!'){
Now check the command issued. Appends? Yeah, check the range --
For comma, make sure the line number isn't in the range specified. (Remember the '!'.)
For tilde, check that A) the line number isn't the one specified, B) the line number minux
the starting point divded by the second number has a remainder, C) the line number is less than
the starting point. If A and B or A and C are true, we'll match.
if(commandLetter
CMD_APPENDS && (
(rangeModifier
',' && (location > lineNumber || lineNumber > locationB))
|| (rangeModifier
'~' && location != lineNumber && ((lineNumber - location) % locationB > 0 || lineNumber < location))
Append, stick the string to the end of the existing buffer and attach a newline.
Append will use this same method for the rest off the programme.
Same method for matching replace.
if(commandLetter
CMD_REPLACE && (
(rangeModifier
',' && (location > lineNumber || lineNumber > locationB))
|| (rangeModifier
'~' && location != lineNumber && ((lineNumber - location) % locationB > 0 || lineNumber < location))
Just replace the buffer with the new string and add a newline to the end.
Replacement will be done the same way as this for the rest of the app.
And insert.
if(commandLetter
CMD_INSERT && (
(rangeModifier
',' && (location > lineNumber || lineNumber > locationB))
|| (rangeModifier
'~' && location != lineNumber && ((lineNumber - location) % locationB > 0 || lineNumber < location))
Add a newline to the end of the new string, stick the buffer on after that, and then
move it all in to the buffer. We'll reuse this method for insert throughout the app.
We're moving down in order of most specific matching regime to least specific. So this one's next.
}else if(sscanf(cmd_line, "%d%c%d%c%c", &location, &rangeModifier, &locationB, ¬Modifier, &commandLetter)
5
This is the next one in order, this time no !
}else if(sscanf(cmd_line, "%d%c%d%c%s", &location, &rangeModifier, &locationB, &commandLetter, string)
5
- & (rangeModifier
',' || rangeModifier
'~')){
For appends, we're checking if the range is a comma or a tilde. If it's comma, is the line number
in between the addresses specified? If it's a tilde, check A) is line number equal to the location
specified, B) does the line number minus the location, divided by the second number,
have NO remainder? and C) is the line number greater than the location specified?
If A is true, or B and C are true, we match.
if(commandLetter
CMD_APPENDS && (
(rangeModifier
',' && location <= lineNumber && lineNumber <= locationB)
|| (rangeModifier
'~' && (location
lineNumber || (((lineNumber - location) % locationB) 0 && lineNumber > location)))
if(commandLetter
CMD_REPLACE && (
(rangeModifier
',' && location
lineNumber)
|| (rangeModifier '~' && (location
lineNumber || (((lineNumber - location) % locationB) 0 && lineNumber > location)))
Using this to for the ranged replace for a comma-range only, once we've replaced the first line,
We make sure that none of the lines after it print until we're out of the range.
Ref: http://cnfolio.com/IntroComputingTutorial05#example05∞
if(commandLetter
CMD_REPLACE && (
(rangeModifier
',' && lineNumber > location && lineNumber <= locationB)
skipPrint = 1;
if(commandLetter
CMD_INSERT && (
(rangeModifier
',' && location <= lineNumber && lineNumber <= locationB)
|| (rangeModifier
'~' && (location lineNumber || (((lineNumber - location) % locationB)
0 && lineNumber > location)))
And then this one goes next.
}else if(sscanf(cmd_line, "%d%c%d%c", &location, &rangeModifier, &locationB, &commandLetter)
4
',' || rangeModifier
'~')){
Same method as before for dealing with the different ranges.
if(commandLetter
CMD_PRINT && (
(rangeModifier
',' && location <= lineNumber && lineNumber <= locationB)
|| (rangeModifier
'~' && (location lineNumber || (((lineNumber - location) % locationB)
0 && lineNumber > location)))
if(commandLetter
CMD_DELETE && (
(rangeModifier
',' && location <= lineNumber && lineNumber <= locationB)
|| (rangeModifier
'~' && (location
lineNumber || (((lineNumber - location) % locationB) 0 && lineNumber > location)))
skipPrint = 1;
This one's next but it doesn't have a range, just the not modifier.
}else if(sscanf(cmd_line, "%d%c%c%s", &location, ¬Modifier, &commandLetter, string)
4
- & notModifier
'!'){
So basically, because of the !, we only make sure that the line number DOESN'T match.
We don't have to use the range detection here.
if(commandLetter
CMD_APPENDS && location != lineNumber){
And here.
if(commandLetter CMD_REPLACE && location != lineNumber){
And here.
if(commandLetter
CMD_INSERT && location lineNumber){
We do have a not modifier here, so we need to not match everything.
}else if(sscanf(cmd_line, "%d%c%c", &location, ¬Modifier, &commandLetter)
3
Same here.
if(commandLetter
CMD_PRINT && location != lineNumber){
And here.
if(commandLetter CMD_DELETE && location != lineNumber){
skipPrint = 1;
This time we don't have the not modifier.
}else if(sscanf(cmd_line, "%d%c%s", &location, &commandLetter, string)
3){
So we check that the line numbers DO match. Again, no worry about ranges.
if(commandLetter CMD_APPENDS && location
lineNumber){
Same here.
if(commandLetter
CMD_REPLACE && location
lineNumber){
And here.
if(commandLetter CMD_INSERT && location
lineNumber){
We don't really have to make sure location > 0, but it's better to
validate as much of the input as you can, to weed out falsely-matching
input.
}else if(sscanf(cmd_line, "%d%c", &location, &commandLetter)
2
- & location > 0){
Again, it's a simple case of does the line number match?
if(commandLetter
CMD_PRINT && location
lineNumber){
Here too.
if(commandLetter
CMD_QUIT && location
lineNumber){
appState = STATE_EXIT;
This one as well.
if(commandLetter
CMD_DELETE && location
lineNumber){
skipPrint = 1;
We have a not modifier here.
}else if(sscanf(cmd_line, "%c%c", ¬Modifier, &commandLetter)
2
We're back to a simple command that effects every line, but not ! modifier.
}else if(sscanf(cmd_line, "%c%s", &commandLetter, string)
2){
So we don't need to worry about line matching.
if(commandLetter CMD_APPENDS){
Or here.
if(commandLetter
CMD_REPLACE){
Or here.
if(commandLetter CMD_INSERT){
}
Very simple one letter commands.
}else if(sscanf(cmd_line, "%c", &commandLetter)
1){
Which match every line.
if(commandLetter CMD_PRINT){
And here.
if(commandLetter
CMD_QUIT){
appState = STATE_EXIT;
Same here.
if(commandLetter CMD_DELETE){
skipPrint = 1;
If nothing's told it not to print since the beginning of the loop,
print the buffer. By this point, the buffer may have been modified
by a replace, append, or insert. Doesn't matter, print it anyway as
long as nothing set skipPrint to 1.
if(skipPrint
0){