Test timeout. Test exceeded 10 sec

I’m stuck on Stage #TZ7.

I’ve tried .. :
IDK what even to try. I have no idea what to do now.

The story is,
In the third test, we have the following contents in the test file:
() #<|TAB|>{}
@
$
+++
// Let’s Go!
+++

so when my Scanner() function consumes the ‘/’, it sees weather the next charecter is also ‘/’. If so, it will consider the whole line as a comment. Now it will call the skip_to_next_line() function.
That function will skip until the ‘\n’ charecter. Since my scanner will need to detect the ‘\n’ so that it can update the line counter, I have kept the skip_to_next_line() function like that.

But then since I did not design the skip_to_next_line() properly, I would skip the ‘\n’ and the line counter would count the lines incorrectly.

The wrong code is here:

int skip_to_next_line(int file_iterator,char* file_contents)
{
    //file_iterator points to the current charecter scanned by scanner()
    //file_contents will contain the actual data from the file that we are scaning.
    //thus we get the current element by file_contents[file_iterator]

    while(file_contents[file_iterator] != '\n' && file_contents[file_iterator] != '\0');
    {
        file_iterator += 1;
    }

    //file_iterator += 1;
    return file_iterator;
}

here the file_iterator will point to the charecter in the line next to the comment, skipping the ‘\n’. Thus I was unable to pass the 3rd test.

Now, I have changed the code. Nothing big. Just the return statement.

From this:

return file_iterator

to:

return file_iterator - 1;

Now I am struck here. The program is being timed out. What abomination have I unleashed?!?

I dont know if explaining my code flow will be usefull, but I am doing it.

→ The program starts with main() where the read_file_contents() is called first.

read_file_contents() will read the file contents, return the contents as a array named as file_contents. Until now , the functions I have mentioned are written in default, not by me

→ Now I call the Scanner() from the main. This is where my code starts. Scanner will iterate through the file_contents array, identify elements then do whatever is supposed to be done.

→ if a comment is identified, skip_to_next_line() function is called.

Here are my logs:

remote: [tester::#TZ7] Running tests for Stage #TZ7 (Scanning: Multi-line errors)
remote: [tester::#TZ7] [test-1] Running test case: 1
remote: [tester::#TZ7] [test-1] Writing contents to ./test.lox:
remote: [tester::#TZ7] [test-1.lox] ()<|SPACE|><|TAB|>@
remote: [tester::#TZ7] [test-1] $ ./your_program.sh tokenize test.lox
remote: [your_program] LEFT_PAREN ( null
remote: [your_program] RIGHT_PAREN ) null
remote: [your_program] Logs from your program will appear here!
remote: [your_program] EOF  null
remote: [your_program] [line 2] Error: Unexpected character: @
remote: [your_program] return_value : 65
remote: [tester::#TZ7] [test-1] ✓ 1 line(s) match on stderr
remote: [tester::#TZ7] [test-1] ✓ 3 line(s) match on stdout
remote: [tester::#TZ7] [test-1] ✓ Received exit code 65.
remote: [tester::#TZ7] [test-2] Running test case: 2
remote: [tester::#TZ7] [test-2] Writing contents to ./test.lox:
remote: [tester::#TZ7] [test-2.lox]
remote: [tester::#TZ7] [test-2.lox] <|TAB|> @
remote: [tester::#TZ7] [test-2] $ ./your_program.sh tokenize test.lox
remote: [your_program] Logs from your program will appear here!
remote: [your_program] [line 2] Error: Unexpected character: @
remote: [your_program] return_value : 65
remote: [your_program] EOF  null
remote: [tester::#TZ7] [test-2] ✓ 1 line(s) match on stderr
remote: [tester::#TZ7] [test-2] ✓ 1 line(s) match on stdout
remote: [tester::#TZ7] [test-2] ✓ Received exit code 65.
remote: [tester::#TZ7] [test-3] Running test case: 3
remote: [tester::#TZ7] [test-3] Writing contents to ./test.lox:
remote: [tester::#TZ7] [test-3.lox] ()  #<|TAB|>{}
remote: [tester::#TZ7] [test-3.lox] @
remote: [tester::#TZ7] [test-3.lox] $
remote: [tester::#TZ7] [test-3.lox] +++
remote: [tester::#TZ7] [test-3.lox] // Let's Go!
remote: [tester::#TZ7] [test-3.lox] +++
remote: [tester::#TZ7] [test-3.lox] #
remote: [tester::#TZ7] [test-3] $ ./your_program.sh tokenize test.lox
remote: [your_program] Logs from your program will appear here!
remote: [your_program] LEFT_PAREN ( null
remote: [your_program] RIGHT_PAREN ) null
remote: [your_program] LEFT_BRACE { null
remote: [your_program] RIGHT_BRACE } null
remote: [your_program] PLUS + null
remote: [your_program] PLUS + null
remote: [your_program] PLUS + null
remote: [your_program] [line 1] Error: Unexpected character: #
remote: [your_program] [line 2] Error: Unexpected character: @
remote: [your_program] [line 3] Error: Unexpected character: $
remote: [tester::#TZ7] [test-3] timed out, test exceeded 10 seconds
remote: [tester::#TZ7] [test-3] Test failed

And here’s a snippet of my code:
As I do not know which snippet would have caused this, I am giving the whole code.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//global variables
long GLOBAL_file_size;
int GLOBAL_error_flag;

char *read_file_contents(const char *filename);
int Scanner(char *file_contents);
int skip_to_next_line(int file_iterator,char* file_contents);

int main(int argc, char *argv[]) {
    // Disable output buffering
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

    if (argc < 3) {
        fprintf(stderr, "Usage: ./your_program tokenize <filename>\n");
        return 1;
    }

    const char *command = argv[1];
    int return_value = 0;

    if (strcmp(command, "tokenize") == 0) {
        // You can use print statements as follows for debugging, they'll be visible when running tests.
        fprintf(stderr, "Logs from your program will appear here!\n");
        
        char *file_contents = read_file_contents(argv[2]);

        //testing(file_contents);

        if(strlen(file_contents) > 0)
        {
            int result = Scanner(file_contents);
            return_value = result;
        }
        printf("EOF  null\n");
        
        free(file_contents);
    } else {
        fprintf(stderr, "Unknown command: %s\n", command);
        return 1;
    }

    fprintf(stderr,"return_value : %d\n",return_value);
    return return_value;
}

char *read_file_contents(const char *filename) {
    FILE *file = fopen(filename, "r");
    //fprintf(stderr,"filename : %s\n",filename);
    if (file == NULL) {
        fprintf(stderr, "Error reading file: %s\n", filename);
        return NULL;
    }

    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    GLOBAL_file_size = file_size;
    rewind(file);

    char *file_contents = malloc(file_size + 1);
    if (file_contents == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        fclose(file);
        return NULL;
    }

    size_t bytes_read = fread(file_contents, 1, file_size, file);
    if (bytes_read < file_size) {
        fprintf(stderr, "Error reading file contents\n");
        free(file_contents);
        fclose(file);
        return NULL;
    }

    file_contents[file_size] = '\0';
    fclose(file);

    return file_contents;
}


int Scanner(char *file_contents)
{
    int file_iterator = 0; //iterate through the file_content array
    int line_number = 1; //current line context. Used to report warnings and errors. For now 1
    int returnable_value = 0; //0 if all right, 65 if something is wrong
    int comment_flag = 0; //if set true, skips line. For now, this will skip the entire file.

    while(file_contents[file_iterator] != '\0')
    {
        switch(file_contents[file_iterator])
        {
            //block and line defines
            case '(' :
            {
                printf("LEFT_PAREN ( null\n");
                break;
            }
            case ')' :
            {
                printf("RIGHT_PAREN ) null\n");
                break;
            }
            case '{' :
            {
                printf("LEFT_BRACE { null\n");
                break;
            }
            case '}' :
            {
                printf("RIGHT_BRACE } null\n");
                break;
            }
            case ';' :
            {
                printf("SEMICOLON ; null\n");
                break;
            }
            //whatever charecters
            case '.' :
            {
                printf("DOT . null\n");
                break;
            }
            case '*' :
            {
                printf("STAR * null\n");
                break;
            }
            case ',' :
            {
                printf("COMMA , null\n");
                break;
            }
            //operators
            case '+' :
            {
                printf("PLUS + null\n");
                break;
            }
            case '-' :
            {
                printf("MINUS - null\n");
                break;
            }
            case '/' :
            {
                if(file_contents[file_iterator + 1] == '/' )
                {
                    comment_flag = 1;
                    file_iterator = skip_to_next_line(file_iterator,file_contents); //skip until just before '\n'
                    //break;
                }
                else
                {
                    printf("SLASH / null\n");
                }

                break;
            }
            case '=' :
            {
                if(file_contents[file_iterator + 1] == '=')
                {
                    printf("EQUAL_EQUAL == null\n");
                    file_iterator += 1;
                }
                else
                {
                    printf("EQUAL = null\n");
                }

                break;
            }
            case '!' :
            {
                if(file_contents[file_iterator + 1] == '=')
                {
                    printf("BANG_EQUAL != null\n");
                    file_iterator += 1;
                }
                else
                {
                    printf("BANG ! null\n");
                }

                break;
            }
            case '<' :
            {
                if(file_contents[file_iterator + 1] == '=')
                {
                    printf("LESS_EQUAL <= null\n");
                    file_iterator += 1;
                }
                else
                {
                    printf("LESS < null\n");
                }

                break;
            }
            case '>' :
            {
                if(file_contents[file_iterator + 1] == '=')
                {
                    printf("GREATER_EQUAL >= null\n");
                    file_iterator += 1;
                }
                else
                {
                    printf("GREATER > null\n");
                }

                break;
            }
            //ignoring 
            case ' ' :
            {
                break;
            }
            case '\t' :
            {
                break;
            }
            case '\n' :
            {
                line_number += 1;
                break;
            }  
            //error bitching
            default :
            {
                //for error reporting
                fprintf(stderr,"[line %d] Error: Unexpected character: %c\n",line_number,file_contents[file_iterator]);
                returnable_value = 65;
            }    
        }

        file_iterator += 1;
    }

    return returnable_value;
}

int skip_to_next_line(int file_iterator,char* file_contents)
{
    //file_iterator points to the current charecter scanned by scanner()
    //file_contents will contain the actual data from the file that we are scaning.
    //thus we get the current element by file_contents[file_iterator]

    while(file_contents[file_iterator] != '\n' && file_contents[file_iterator] != '\0');
    {
        file_iterator += 1;
    }

    //file_iterator += 1;
    return file_iterator - 1;
}

Thank you.
Have a good day :slight_smile:

Hey @PSQUAREJ, could you upload your code to GitHub and share the link? It will be much easier to debug if I can run it directly.

Hello @andy1li , I have uploaded to Github. Sorry for the late response.

@PSQUAREJ, I tried running your code against the previous stages, but it’s actually no longer passing a previous stage #ML2 (Scanning: Division operator & comments).

Suggestions:

  1. Use our CLI to test against previous stages by running:
codecrafters test --previous
  1. Focus on fixing the early stages first, as later stages depend on them.

Closing this thread due to inactivity. If you still need assistance, feel free to reopen or start a new discussion!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.