From 50eed92d74ff9302b3902a90ac3e219d694b7409 Mon Sep 17 00:00:00 2001 From: Betsalel Williamson Date: Fri, 1 Jan 2021 23:14:41 -0500 Subject: [PATCH 01/23] Added docs files that include m4 scripts to generate files from source. --- .gitignore | 2 +- Generate-Wiki/Home.md | 3 + Generate-Wiki/Tutorial 1/T1-00.md | 5 +- Generate-Wiki/Tutorial 1/T1-01.md | 3 +- Generate-Wiki/Tutorial 1/T1-02.md | 27 +--- Generate-Wiki/Tutorial 1/T1-04.md | 139 +++++------------- Generate-Wiki/Tutorial 2/T2-00.md | 3 + Generate-Wiki/Tutorial 2/T2-01.md | 5 +- Generate-Wiki/Tutorial 2/T2-02.md | 3 + Generate-Wiki/Tutorial 3/T1-03.md | 11 +- Generate-Wiki/Tutorial 3/T3-00.md | 5 +- Generate-Wiki/_Footer.md | 3 + Generate-Wiki/_Sidebar.md | 8 + Generate-Wiki/definitions.m4 | 7 +- Generate-Wiki/generate_docs.sh | 2 + .../hello-world-fixed.tcl | 31 ++++ T1/step-2-command-line-101/hello-world.tcl | 20 --- .../2-Test-Hello-World/main-fixed.c | 59 ++++++++ .../2-Test-Hello-World/main.c | 59 +------- .../3-Makefile-Hello-World/main-fixed.c | 67 +++++++++ .../3-Makefile-Hello-World/main.c | 2 - 21 files changed, 255 insertions(+), 209 deletions(-) create mode 100644 Generate-Wiki/_Footer.md create mode 100644 Generate-Wiki/_Sidebar.md create mode 100755 Generate-Wiki/generate_docs.sh create mode 100755 T1/step-2-command-line-101/hello-world-fixed.tcl create mode 100644 T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c create mode 100644 T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c diff --git a/.gitignore b/.gitignore index 4c94a4c..bfed150 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,8 @@ *.exe *.out *.log -**_** *.tclPreview +*.DS_Store **~** ~* *.o diff --git a/Generate-Wiki/Home.md b/Generate-Wiki/Home.md index 6184463..c36a7b7 100644 --- a/Generate-Wiki/Home.md +++ b/Generate-Wiki/Home.md @@ -89,4 +89,7 @@ Lastly, I would like to thank my father Tsuri and my dear friend Jordan H. for t 1. Keeping things simple is harder than it looks, and 1. If you only use a hammer everything looks like a nail +# Updates +* Jan 1, 2021 - Generated from m4 template + [[Previous Page]] | [[Next Page|T1-00]] diff --git a/Generate-Wiki/Tutorial 1/T1-00.md b/Generate-Wiki/Tutorial 1/T1-00.md index 6a84632..821735f 100644 --- a/Generate-Wiki/Tutorial 1/T1-00.md +++ b/Generate-Wiki/Tutorial 1/T1-00.md @@ -1,6 +1,6 @@ # Tutorial 1: “Hello World!” -The first step in any computer language has historically been the “Hello World!” example. The purpose of this exercise to focus on a simple task when setting the system up before getting into the programming complexities. Unlike traditional programming tutorials, we are going to be adding an additional step to this, so bear with us. This step provides a framework to automate the actions of compiling, running, and testing your program. This will set you up in the long run for best practices in programming. To download a complete working version of this program visit this GitHub URL . This tutorial will not get into the details of why different coding languages look different, what variables are and so on. See the later tutorials for more details about programming in C or Python. +The first step in any computer language has historically been the “Hello World!” example. The purpose of this exercise to focus on a simple task when setting the system up before getting into the programming complexities. Unlike traditional programming tutorials, we are going to be adding an additional step to this, so bear with us. This step provides a framework to automate the actions of compiling, running, and testing your program. This will set you up in the long run for best practices in programming. To download a complete working version of this program visit this GitHub URL <{{}}__project_repo_root__{{}}/>. This tutorial will not get into the details of why different coding languages look different, what variables are and so on. See the later tutorials for more details about programming in C or Python. Now before we get into all of this I would like to share a little bit about learning in general. @@ -23,4 +23,7 @@ We will be able to work with this guide and all of the tutorials whether you are One last note, it is often useful to install an Integrated Development Environment (IDE), like CLion, Visual Studio, NetBeans, or Emacs, but it is best to use only a text editor for this tutorial. If learning to program was learning to ride a bike, using an IDE is like adding gears to a bicycle. We first take the harder path, so that you understand the basics and can get along when you don’t have access or a budget to buy the fancy software. +# Updates +* Jan 1, 2021 - Generated from m4 template + [[Previous Page|Home]] | [[Next Page|T1-01]] \ No newline at end of file diff --git a/Generate-Wiki/Tutorial 1/T1-01.md b/Generate-Wiki/Tutorial 1/T1-01.md index 355060a..ae861ae 100644 --- a/Generate-Wiki/Tutorial 1/T1-01.md +++ b/Generate-Wiki/Tutorial 1/T1-01.md @@ -89,6 +89,7 @@ At this point you will have equivalent software for building programs that can b 1. Installing GCC on Windows - http://preshing.com/20141108/how-to-install-the-latest-gcc-on-windows/ # Updates -* Nov 11. 2020 - Added python +* Jan 1, 2021 - Generated from m4 template +* Nov 11, 2020 - Added python [[Previous Page|T1-00]] | [[Next Page|T1-02]] \ No newline at end of file diff --git a/Generate-Wiki/Tutorial 1/T1-02.md b/Generate-Wiki/Tutorial 1/T1-02.md index e1f5744..fc6a60a 100644 --- a/Generate-Wiki/Tutorial 1/T1-02.md +++ b/Generate-Wiki/Tutorial 1/T1-02.md @@ -78,19 +78,7 @@ We will output "Hello from TCL!" and use TCL/Expect to verify this from the term ``` 1. Open the file `hello-world.tcl` in a plain text editor (Notepad, Sublime, Nano, etc.) and copy-paste the following. Again, it is very important to keep the white space exactly as is shown in the code: ``` - #!/usr/bin/env expect - spawn echo "Hello World from TCL/Expect!" - - expect { - "Hello world." { - puts "Success!" - exit 0 - } - default { - puts "Error!" - exit 1 - } - } +esyscmd({{sed -n 24,33p ../T1/step-2-command-line-101/hello-world.tcl | sed 's/^/ /g' | ghead -c -1}}) ``` 1. To run this program open up a shell and change directories to the saved file. To do this you should type: ``` @@ -104,9 +92,7 @@ We will output "Hello from TCL!" and use TCL/Expect to verify this from the term You should see the following displayed on your command line screen: ``` -$ spawn echo Hello World from TCL/Expect! -Hello World from TCL/Expect! -Error! +$ esyscmd({{../T1/step-2-command-line-101/hello-world.tcl | sed -n 1,3p | ghead -c -1}}) ``` ## Troubleshooting Errors @@ -124,9 +110,7 @@ If it doesn't see the text after a default amount of time, then print that we ha What can we do to modify the program to have the following output without changing the code on the line with `"Error!"` to `"Success!"` (change what Expect is expecting)? ``` -$ spawn echo Hello World from TCL/Expect! -Hello World from TCL/Expect! -Success! +$ esyscmd({{../T1/step-2-command-line-101/hello-world-fixed.tcl | ghead -c -1}}) ``` ## Summary @@ -141,9 +125,10 @@ Congrats on modifying your first program and fixing a bug! With the TCL/Expect t 1. Additional Windows Shell CMDs - https://ss64.com/nt/ 1. TCL/Expect main wiki - http://wiki.tcl.tk/ 1. Expect tutorials - https://wiki.tcl.tk/11584 -1. Answer - +1. Answer - <{{}}__project_repo_root__{{}}/blob/develop/T1/step-2-command-line-101/hello-world.tcl> # Updates -* Nov 11. 2020 - Added good command line reference to ss64. +* Jan 1, 2021 - Generated from m4 template +* Nov 11, 2020 - Added good command line reference to ss64. [[Previous Page|T1-01]] | [[Next Page|T1-04]] \ No newline at end of file diff --git a/Generate-Wiki/Tutorial 1/T1-04.md b/Generate-Wiki/Tutorial 1/T1-04.md index e1bb21b..0801500 100644 --- a/Generate-Wiki/Tutorial 1/T1-04.md +++ b/Generate-Wiki/Tutorial 1/T1-04.md @@ -3,8 +3,8 @@ We will move quickly through this next step, but will show you how to download the Git repository with the answers. Open your Shell and navigate to a good location to store the code and run the following: -``` -$ git clone https://github.com/betsalel-williamson/Programming-Tutorial.git +```Bash +$ git clone __project_repo__ $ cd Programming-Tutorial $ ls ``` @@ -20,11 +20,10 @@ This step has the following parts: ## Part 1 Hello World Create a file named `main.c` in the directory `tutorials/step-3-hello-world/1-Hello-World` and copy the following code to it. -``` -int main ( ) { - write(1, "Hello World", 12); - return 0; -} +```C +esyscmd({{sed -n '21p' ../T1/step-4-hello-world/1-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) +esyscmd({{sed -n '42p' ../T1/step-4-hello-world/1-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) +esyscmd({{sed -n '65,66p' ../T1/step-4-hello-world/1-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) ``` Open up a shell and change directories so that when you list the files you see the file `main.c`. Type the following command to compile your code: @@ -80,14 +79,8 @@ We can run these using the `exec` function in TCL and the programs `rm` and `gcc Next is the code to run our program `main`. For our first test we will `spawn` our program with the argument `"Hello World"`. We can use the `expect` command like in the first step to see that we output the text "Hello World". Finally, we get the exit code of our program with the following code: -``` -expect eof -catch wait result -if {[lindex $result 3] == 0} { - puts "Exited successfully.\n" -} else { - puts "Test failed with code [lindex $result 3].\n" -} +```Tcl +esyscmd({{sed -n '26,32p' ../T1/step-4-hello-world/2-Test-Hello-World/test.tcl | sed 's/^/ /g' | ghead -c -1}}) ``` For our second test we only need to test that the exit code is 1. @@ -96,65 +89,15 @@ Once your tests are complete, see that when you run them that they both fail. If Here is a version of the `test.tcl` file you can base your code off of: -``` -#!/bin/env expect - -exec rm main -exec gcc -w main.c -o main - -### Test 1 ### - -spawn ./main "Hello World" -expect { - -nocase "hello world" { - puts "\nFound output of: Hello World\n" - } - default { - puts "\nTest failed. Expected Hello world\n" - } -} - -expect eof -catch wait result -if {[lindex $result 3] == 0} { - puts "Exited successfully.\n" -} else { - puts "Test failed with code [lindex $result 3].\n" -} - -### Test 2 ### - -spawn ./main -expect eof -catch wait result - -if {[lindex $result 3] == 1} { - puts "Exited successfully.\n" -} else { - puts "Test failed with code [lindex $result 3].\n" -} +```Tcl +esyscmd({{sed -n '1,51p' ../T1/step-4-hello-world/2-Test-Hello-World/test.tcl | sed 's/^/ /g' | ghead -c -1}}) ``` Now that we have failing tests, we will now modify the main function to accept what is called an input argument and to output this to the Shell. Modify your `main.c` file with the following: -``` -int main ( int argc, const char* argv[] ) { - int exit_value = -1; - - if ( argc == 2 ) { - - while(argv[1][i] != '\0'){ - i = i+1; - } - - exit_value = 0 - } else { - exit_value = 1; - } - - return exit_value; -} +```C +esyscmd({{cat ../T1/step-4-hello-world/2-Test-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) ``` We've left an error in the code for you to fix. Once it is correct, you should see that your tests now all pass! @@ -173,11 +116,9 @@ With `int exit_value = -1;` we next declare a variable to hold our exit code and Next, we check with `if ( argc == 2 )` that we only have 2 arguments. __We'll come back to this point of 2 arguments in a bit.__ If we have two arguments, then we find the length of the text passed in with the following lines. First we create a variable to hold our place, then while the current character in the string passed in isn't the null character or `\0` (this is how C lets you know that you've reached the end of your string) we increment `i`: -``` -int i = 0; -while(argv[1][i] != '\0'){ - i = i+1; -} +```C +esyscmd({{sed -n '6,8p' ../T1/step-4-hello-world/2-Test-Hello-World/main.c | sed 's/^ / /g' | ghead -c -1}}) + ``` Next we can output the string in `argv` to the Shell with `write(1, argv[1], i);`. @@ -199,55 +140,44 @@ Welcome to GNU make or the makefile! There is a scripting language called `makef ### Makefile introduction -``` -CC=gcc -OBJ=main.o - -%.o: %.c $(DEPS) - $(CC) -g -c -o $@ $< - -main: $(OBJ) - gcc -o $@ $^ $(CFLAGS) - -clean: - -rm *.o main main.exe +```Makefile +esyscmd({{sed -n '7,28p' ../T1/step-4-hello-world/3-Makefile-Hello-World/makefile | sed 's/^ / /g' | ghead -c -1}}) ``` Notice that we are now failing the build process as is shown: ``` $ make -gcc -g -c -o main.o main.c -main.c: In function 'main': -main.c:35:3: warning: implicit declaration of function 'write' [-Wimplicit-function-declaration] - write(1, argv[1], i); - ^~~~~ -gcc -o main main.o -Wall -Werror -Wextra +esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && make clean > /dev/null 2>&1 && make > temp-output.log 2>&1 && popd > /dev/null 2>&1}})dnl +esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log && popd > /dev/null 2>&1}})dnl ``` Lets walk through this step by step: 1. `$ make` is the command we typed in the Shell -1. `gcc -g -c -o main.o main.c` is the command that make will run to compile our program +1. `esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '1p' | ghead -c -1 && popd > /dev/null 2>&1}})` is the command that make will run to compile our program 1. The following is a chunk that tells us there's something up with the `main` function. ``` - main.c: In function 'main': - main.c:35:3: warning: implicit declaration of function 'write' [-Wimplicit-function-declaration] +esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '2p' | sed 's/^/ /g' && popd > /dev/null 2>&1}})dnl ``` - The file that we need to look at is `main.c`, we then need to look at `main.c:35:3` that means the file `main.c`, line 35, column 3. `warning` means that if we wanted to compile, it will work, but this is not recommended by the compiler. `implicit declaration of function 'write'` means that it found a function that we didn't explicitly tell the compiler where to find it. System functions like `printf`, `write`, are assumed to be available if you don't list them with an `include` directive. Lastly the part `[-Wimplicit-function-declaration]` is the computer code for the type of error. -1. The next few lines are the pretty version of what is at line 35, column 3. +pushdef({{__err_line_num__}}, {{esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /main[.]c:(\d+):\d+/' | tr -d '\n' && popd > /dev/null 2>&1}})}})dnl +pushdef({{__err_col_num__}}, {{esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /main[.]c:\d+:(\d+)/' | tr -d '\n' && popd > /dev/null 2>&1}})}})dnl + + The file that we need to look at is `main.c`, we then need to look at `esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /(main[.]c:\d+:\d+)/' | tr -d '\n' && popd > /dev/null 2>&1}})` that means the file `main.c`, line `{{}}__err_line_num__{{}}`, column `{{}}__err_col_num__{{}}`. + + `implicit declaration of function 'write'` means that it found a function that we didn't explicitly tell the compiler where to find it. System functions like `printf`, `write`, are assumed to be available if you don't list them with an `include` directive. Lastly the part `[-Werror,-Wimplicit-function-declaration]` is the computer code for the type of error. +1. The next few lines are the pretty version of what is at line `{{}}__err_line_num__{{}}`, column `{{}}__err_col_num__{{}}`. ``` - write(1, argv[1], i); - ^~~~~ +esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '3,4p' && popd > /dev/null 2>&1}})dnl ``` -1. We then see that as the last step gcc will be compiling the program to make sure any warnings are treated as compile errors and should stop any further compilation progress. + We now need to add the information in our code for where the compiler should find the write function. In the next part we will get into more detail about C functions. For now, we can tell gcc where to explicitly find the `write` function with an include statement at the head of our `main.c` file. The include statement will tell the compiler that there are additional code files that we want to include when we make our executable. ``` -#include +esyscmd({{sed -n '18p' ../T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c | ghead -c -1}}) ``` @@ -289,6 +219,9 @@ Congrats on finishing this last step and for completing the first tutorial! You' 1. About the write function - https://linux.die.net/man/2/write 1. StackOverflow about makefiles - https://stackoverflow.com/questions/2481269/how-to-make-a-simple-c-makefile#2481326 1. StackOverflow about makefiles 2 - https://stackoverflow.com/questions/1079832/how-can-i-configure-my-makefile-for-debug-and-release-builds#1080180 -1. Answers - +1. Answers - <{{}}__project_repo_root__{{}}/tree/develop/T1/step-4-hello-world> + +# Updates +* Jan 1, 2021 - Generated from m4 template [[Previous Page|T1-02]] | [[Next Page|T2-00]] \ No newline at end of file diff --git a/Generate-Wiki/Tutorial 2/T2-00.md b/Generate-Wiki/Tutorial 2/T2-00.md index 557e0f7..48fc756 100644 --- a/Generate-Wiki/Tutorial 2/T2-00.md +++ b/Generate-Wiki/Tutorial 2/T2-00.md @@ -41,4 +41,7 @@ We will now be teaching more of the basics in C basic other basic programming in 1. http://aelinik.free.fr/c/ 1. Good additional tutorial - http://archive.oreilly.com/oreillyschool/courses/c/Introduction%20to%20C%20Programming%20v1.pdf +# Updates +* Jan 1, 2021 - Generated from m4 template + [[Previous Page|T1-04]] | [[Next Page|T2-01]] \ No newline at end of file diff --git a/Generate-Wiki/Tutorial 2/T2-01.md b/Generate-Wiki/Tutorial 2/T2-01.md index 3b93b4d..3fff3a9 100644 --- a/Generate-Wiki/Tutorial 2/T2-01.md +++ b/Generate-Wiki/Tutorial 2/T2-01.md @@ -518,8 +518,11 @@ Congratulations! You've made it through to understanding how the `secretProgram` ## References -1. Code - +1. Code - <{{}}__project_repo_root__{{}}/tree/develop/T2/step-1-code-gen> 1. Google style guide - 1. Stackoverflow discussion on malloc and strings - +# Updates +* Jan 1, 2021 - Generated from m4 template + [[Previous Page|T2-00]] | [[Next Page|T2-02]] \ No newline at end of file diff --git a/Generate-Wiki/Tutorial 2/T2-02.md b/Generate-Wiki/Tutorial 2/T2-02.md index 7881727..b1f3d05 100644 --- a/Generate-Wiki/Tutorial 2/T2-02.md +++ b/Generate-Wiki/Tutorial 2/T2-02.md @@ -23,4 +23,7 @@ You may want to copy the makefile to compile your code that is in the solutions Again, the way the `secretProgram` works is that it takes the current date and time down to the minute, `XOR`s this number with a hash and then that is the password. If the correct password was entered then it outputs success message and exits with the code `0`. If not, then the program displays exits with the code `1`. You can try and work out the hash and compute things manually, but in this case it will be easier to build a C program that will run the program as long as it takes to get the correct answer. +# Updates +* Jan 1, 2021 - Generated from m4 template + [[Previous Page|T2-01]] | [[Next Page|T2-03]] \ No newline at end of file diff --git a/Generate-Wiki/Tutorial 3/T1-03.md b/Generate-Wiki/Tutorial 3/T1-03.md index 0fb5c8e..43c58c8 100644 --- a/Generate-Wiki/Tutorial 3/T1-03.md +++ b/Generate-Wiki/Tutorial 3/T1-03.md @@ -15,10 +15,10 @@ _Had I not been using version control software, they would have had to cancel th Open up your shell and navigate to your code directory created in the previous step. Change directories (cd) into `Code` and execute the following command: ``` -$ git clone https://github.com/bhw7/SERC-Pitt-Programming-Tutorial.git +$ git clone __project_repo__ ``` -You should see the shell telling you that it is cloning into ‘SERC-Pitt-Programming-Tutorial’. When it has finished, cd into `SERC-Pitt-Programming-Tutorial`. +You should see the shell telling you that it is cloning into ‘{{}}__project_repo_name__{{}}’. When it has finished, cd into `{{}}__project_repo_name__{{}}`. As a quick tip, you can press the TAB key after typing in SERC to auto-complete the rest of the folder. Most shells will have this auto-completion feature (if the Shell auto-complete feature is not working, use the internet to search your specific shell and find out how to enable it) . @@ -36,7 +36,7 @@ You should now see the `.gitignore` and `.gitattributes` file in addition to a ` ## Part 3 Branch -Because sometimes you want to go down a rabbit hole and try something out, or share your project with other people, we will introduce you to the concept of code branches. This topic will be covered more in detail later on. For now know that Git will store the information by default in the branch with the name `master`. It is a best practice after you finish the initial steps in setting up your repository to start a branch named `develop` and work from it. +Because sometimes you want to go down a rabbit hole and try something out, or share your project with other people, we will introduce you to the concept of code branches. This topic will be covered more in detail later on. For now know that Git will store the information by default in the branch with the name `main`. It is a best practice after you finish the initial steps in setting up your repository to start a branch named `develop` and work from it. In a professional environment, all work should be done in a specific `features` branch, and then merged to the `develop` branch only when you have finished a feature and tested that it works. A merge will synchronize the changes between these two branches. We will wait to cover merging in the later Git tutorial. @@ -143,6 +143,9 @@ If you are already familiar with Git you may have noticed that we did not tell y 1. Git main website - https://git-scm.com/ 1. Highly recommended GUI version of Git - https://www.gitkraken.com/ 1. StackOverflow on Git reverting - https://stackoverflow.com/questions/927358/how-to-undo-the-most-recent-commits-in-git#927386 -1. Answer - https://github.com/bhw7/SERC-Pitt-Programming-Tutorial/blob/master/T1/step-3-version-control-101 +1. Answer - __project_repo_root__{{}}/blob/main/T1/step-3-version-control-101 + +# Updates +* Jan 1, 2021 - Generated from m4 template [[Previous Page|T1-02]] | [[Next Page|T1-04]] \ No newline at end of file diff --git a/Generate-Wiki/Tutorial 3/T3-00.md b/Generate-Wiki/Tutorial 3/T3-00.md index 138d252..f1e1ff5 100644 --- a/Generate-Wiki/Tutorial 3/T3-00.md +++ b/Generate-Wiki/Tutorial 3/T3-00.md @@ -4,4 +4,7 @@ The information in this tutorial was other information that was moved outside th The topics include: Git - Dicussion on using ethical use of code \ No newline at end of file + Dicussion on using ethical use of code + +# Updates +* Jan 1, 2021 - Generated from m4 template \ No newline at end of file diff --git a/Generate-Wiki/_Footer.md b/Generate-Wiki/_Footer.md new file mode 100644 index 0000000..c54bf10 --- /dev/null +++ b/Generate-Wiki/_Footer.md @@ -0,0 +1,3 @@ +Authored by __author__ [{{}}__author_email__{{}}](mailto:{{}}__author_email__{{}}). + +For more information about SERC visit [sercpitt.weebly.com](https://sercpitt.weebly.com/) \ No newline at end of file diff --git a/Generate-Wiki/_Sidebar.md b/Generate-Wiki/_Sidebar.md new file mode 100644 index 0000000..a91d930 --- /dev/null +++ b/Generate-Wiki/_Sidebar.md @@ -0,0 +1,8 @@ +* [[Home]] +* [[Tutorial 1: Introduction|T1-00]] + 1. [[Setup|T1-01]] + 1. [[Command Line 101|T1-02]] + 1. [[Your First C Program|T1-04]] +* [[Tutorial 2: Crash Course|T2-00]] + 1. [[Walkthrough of secretProgram|T2-01]] + 1. [[Crack the Code|T2-02]] diff --git a/Generate-Wiki/definitions.m4 b/Generate-Wiki/definitions.m4 index c60aa1e..11cd61d 100644 --- a/Generate-Wiki/definitions.m4 +++ b/Generate-Wiki/definitions.m4 @@ -2,12 +2,12 @@ changequote({{,}}) dnl# root definitions import first dnl#syscmd(echo "Author: " | tr -d '\n')dnl dnl#pushdef({{__author__}}, esyscmd(read AUTHOR && echo $AUTHOR | tr -d '\n'))dnl -pushdef({{__author__}}, {{Betsalel (Saul) Williamson}}))dnl +pushdef({{__author__}}, {{Betsalel (Saul) Williamson}})dnl dnl dnl dnl#syscmd(echo "Author Email: " | tr -d '\n')dnl dnl#pushdef({{__author_email__}}, esyscmd(read AUTHOR_EMAIL && echo $AUTHOR_EMAIL | tr -d '\n'))dnl -pushdef({{__author_email__}}, {{saul.williamson@ieee.org}}))dnl +pushdef({{__author_email__}}, {{saul.williamson@ieee.org}})dnl dnl dnl pushdef({{__wiki_licence__}}, {{CC BY 4.0 license}})dnl @@ -15,5 +15,6 @@ pushdef({{__wiki_licence_full__}}, {{Creative Commons 4.0 Attribution License}}) pushdef({{__wiki_licence_web_address__}}, {{https://creativecommons.org/licenses/by/4.0/}})dnl dnl dnl -pushdef({{__project_repo__}}, {{https://github.com/betsalel-williamson/Programming-Tutorial.git}})dnl +pushdef({{__project_repo_root__}}, {{https://github.com/betsalel-williamson/Programming-Tutorial}})dnl +pushdef({{__project_repo__}}, {{__project_repo_root__{{}}.git}})dnl pushdef({{__project_repo_name__}}, {{Programming-Tutorial}})dnl diff --git a/Generate-Wiki/generate_docs.sh b/Generate-Wiki/generate_docs.sh new file mode 100755 index 0000000..95377d2 --- /dev/null +++ b/Generate-Wiki/generate_docs.sh @@ -0,0 +1,2 @@ +#! env sh +find . -name "*.md" -exec sh -c 'm4 definitions.m4 "$0" > "../../Programming-Tutorial.wiki/$0"' {} \; \ No newline at end of file diff --git a/T1/step-2-command-line-101/hello-world-fixed.tcl b/T1/step-2-command-line-101/hello-world-fixed.tcl new file mode 100755 index 0000000..9a5b0a9 --- /dev/null +++ b/T1/step-2-command-line-101/hello-world-fixed.tcl @@ -0,0 +1,31 @@ +#!/usr/bin/env expect +# This first line is called a shebang (pronounced Sha-Bang) and +# will tell the shell what program to use for the following text. + +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. + +spawn echo "Hello World from TCL/Expect!" + +# What can we do to make this command exit with success? +# There are multiple ways to go about this. +# Method one, is to simply change the text in the expect +# command from "Hello world." to "Hello World from TCL/Expect!" +# Method two is to change the text to be more flexible +# and replace "Hello world." with the text between the +# `` characters `-nocase "hello world"`. + +# Method two: +expect { + -nocase "hello world" { + puts "Success!" + exit 0 + } + default { + puts "Error!" + exit 1 + } +} diff --git a/T1/step-2-command-line-101/hello-world.tcl b/T1/step-2-command-line-101/hello-world.tcl index 2f070db..62f83b9 100755 --- a/T1/step-2-command-line-101/hello-world.tcl +++ b/T1/step-2-command-line-101/hello-world.tcl @@ -31,23 +31,3 @@ expect { exit 1 } } - -# What can we do to make this command exit with success? -# There are multiple ways to go about this. -# Method one, is to simply change the text in the expect -# command from "Hello world." to "Hello World from TCL/Expect!" -# Method two is to change the text to be more flexible -# and replace "Hello world." with the text between the -# `` characters `-nocase "hello world"`. - -# Method two: -# expect { -# -nocase "hello world" { -# puts "Success!" -# exit 0 -# } -# default { -# puts "Error!" -# exit 1 -# } -# } diff --git a/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c b/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c new file mode 100644 index 0000000..c3ef0da --- /dev/null +++ b/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c @@ -0,0 +1,59 @@ +/* + * Welcome to your second program in C. + * + * In this program you will modify the code from your first program + * to accept a parameter or argument as input from the Shell. + * + */ + +int main ( int argc, const char* argv[] ) { + + // argc is the number of arguments passed into the program + // argv is the array (think a list) of arguments + // We access the items in the array by putting a number between + // the square brackets. In C, we call this number an index. + // This is very important because indexes will always start + // with 0. You can think of this in terms of number types. + // In math, the natural numbers start with 1 and increase. + // Indexes start at 0 and will increase until the number of + // items in the array minus 1. + + int exit_value = -1; + // we set this exit value to be -1 so we can know if the + // program exits unexpectedly before being able to set + // the value 0, or 1 as will be shown later on. + + // ensure the correct number of parameters are used. + if ( argc == 2 ) { + int i = 0; // declare a variable to count the length + // of the text passed in as an argument + + // In C, all properly formmated strings end with + // the character '\0'. To get the length of the text, + // or string, we start at the first index value 0. + while( argv[1][i] != '\0' ) { + i = i + 1; + } + + write( 1, argv[1], i ); + + // What do you think the zeroth item or element + // in argv is? + + // i = 0; // reset i to be 0 + + // while(argv[0][i] != '\0') { + // i = i+1; + // } + + // write(1, argv[0], i); + + exit_value = 0; + } else { + // if the incorrect number of parameters are used + // then report that there was an error + exit_value = 1; + } + + return exit_value; +} diff --git a/T1/step-4-hello-world/2-Test-Hello-World/main.c b/T1/step-4-hello-world/2-Test-Hello-World/main.c index c3ef0da..880d2b5 100644 --- a/T1/step-4-hello-world/2-Test-Hello-World/main.c +++ b/T1/step-4-hello-world/2-Test-Hello-World/main.c @@ -1,59 +1,16 @@ -/* - * Welcome to your second program in C. - * - * In this program you will modify the code from your first program - * to accept a parameter or argument as input from the Shell. - * - */ - int main ( int argc, const char* argv[] ) { - - // argc is the number of arguments passed into the program - // argv is the array (think a list) of arguments - // We access the items in the array by putting a number between - // the square brackets. In C, we call this number an index. - // This is very important because indexes will always start - // with 0. You can think of this in terms of number types. - // In math, the natural numbers start with 1 and increase. - // Indexes start at 0 and will increase until the number of - // items in the array minus 1. - int exit_value = -1; - // we set this exit value to be -1 so we can know if the - // program exits unexpectedly before being able to set - // the value 0, or 1 as will be shown later on. - // ensure the correct number of parameters are used. if ( argc == 2 ) { - int i = 0; // declare a variable to count the length - // of the text passed in as an argument - - // In C, all properly formmated strings end with - // the character '\0'. To get the length of the text, - // or string, we start at the first index value 0. - while( argv[1][i] != '\0' ) { - i = i + 1; - } - - write( 1, argv[1], i ); - - // What do you think the zeroth item or element - // in argv is? - - // i = 0; // reset i to be 0 - - // while(argv[0][i] != '\0') { - // i = i+1; - // } - - // write(1, argv[0], i); - - exit_value = 0; + + while(argv[1][i] != '\0'){ + i = i+1; + } + + exit_value = 0 } else { - // if the incorrect number of parameters are used - // then report that there was an error - exit_value = 1; + exit_value = 1; } return exit_value; -} +} \ No newline at end of file diff --git a/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c b/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c new file mode 100644 index 0000000..f157f83 --- /dev/null +++ b/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c @@ -0,0 +1,67 @@ +/* +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +*/ + +/* + * Welcome to your second program in C. + * + * In this program you will modify the code from your first program + * to accept a parameter or argument as input from the Shell. + * + */ + +#include + +int main ( int argc, const char* argv[] ) { + + // argc is the number of arguments passed into the program + // argv is the array (think a list) of arguments + // We access the items in the array by putting a number between + // the square brackets. In C, we call this number an index. + // This is very important because indexes will always start + // with 0. You can think of this in terms of number types. + // In math, the natural numbers start with 1 and increase. + // Indexes start at 0 and will increase until the number of + // items in the array minus 1. + int exit_value; + + // ensure the correct number of parameters are used. + if ( argc == 2 ) + { + int i = 0; // declare a variable to count the length + // of the text passed in as an argument + + // In C, all text ends with the character '\0'. + // To get the length of the text, or string, we + // start at the first index + while( argv[1][i] != '\0' ) { + i = i + 1; + } + + write( 1, argv[1], i ); + + // What do you think the zeroth item or element + // in argv is? + + // i = 0; // reset i to be 0 + + // while(argv[0][i] != '\0') { + // i = i+1; + // } + + // write(1, argv[0], i); + + exit_value = 0; + } else { + // if the incorrect number of parameters are used + // then report that there was an error + exit_value = 1; + } + + return exit_value; +} diff --git a/T1/step-4-hello-world/3-Makefile-Hello-World/main.c b/T1/step-4-hello-world/3-Makefile-Hello-World/main.c index f157f83..68f9fe0 100644 --- a/T1/step-4-hello-world/3-Makefile-Hello-World/main.c +++ b/T1/step-4-hello-world/3-Makefile-Hello-World/main.c @@ -15,8 +15,6 @@ * */ -#include - int main ( int argc, const char* argv[] ) { // argc is the number of arguments passed into the program From e8307596686489cba3b727561d6e8c445eda0c86 Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Fri, 1 Jan 2021 23:26:53 -0500 Subject: [PATCH 02/23] Changed file extension for md files to m4 --- Generate-Wiki/{Home.md => Home.md.m4} | 0 Generate-Wiki/Tutorial 1/{T1-00.md => T1-00.md.m4} | 0 Generate-Wiki/Tutorial 1/{T1-01.md => T1-01.md.m4} | 0 Generate-Wiki/Tutorial 1/{T1-02.md => T1-02.md.m4} | 0 Generate-Wiki/Tutorial 1/{T1-04.md => T1-04.md.m4} | 0 Generate-Wiki/Tutorial 2/{T2-00.md => T2-00.md.m4} | 0 Generate-Wiki/Tutorial 2/{T2-01.md => T2-01.md.m4} | 0 Generate-Wiki/Tutorial 2/{T2-02.md => T2-02.md.m4} | 0 Generate-Wiki/Tutorial 3/{T1-03.md => T1-03.md.m4} | 0 Generate-Wiki/Tutorial 3/{T3-00.md => T3-00.md.m4} | 0 Generate-Wiki/{_Footer.md => _Footer.md.m4} | 0 Generate-Wiki/{_Sidebar.md => _Sidebar.md.m4} | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename Generate-Wiki/{Home.md => Home.md.m4} (100%) rename Generate-Wiki/Tutorial 1/{T1-00.md => T1-00.md.m4} (100%) rename Generate-Wiki/Tutorial 1/{T1-01.md => T1-01.md.m4} (100%) rename Generate-Wiki/Tutorial 1/{T1-02.md => T1-02.md.m4} (100%) rename Generate-Wiki/Tutorial 1/{T1-04.md => T1-04.md.m4} (100%) rename Generate-Wiki/Tutorial 2/{T2-00.md => T2-00.md.m4} (100%) rename Generate-Wiki/Tutorial 2/{T2-01.md => T2-01.md.m4} (100%) rename Generate-Wiki/Tutorial 2/{T2-02.md => T2-02.md.m4} (100%) rename Generate-Wiki/Tutorial 3/{T1-03.md => T1-03.md.m4} (100%) rename Generate-Wiki/Tutorial 3/{T3-00.md => T3-00.md.m4} (100%) rename Generate-Wiki/{_Footer.md => _Footer.md.m4} (100%) rename Generate-Wiki/{_Sidebar.md => _Sidebar.md.m4} (100%) diff --git a/Generate-Wiki/Home.md b/Generate-Wiki/Home.md.m4 similarity index 100% rename from Generate-Wiki/Home.md rename to Generate-Wiki/Home.md.m4 diff --git a/Generate-Wiki/Tutorial 1/T1-00.md b/Generate-Wiki/Tutorial 1/T1-00.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 1/T1-00.md rename to Generate-Wiki/Tutorial 1/T1-00.md.m4 diff --git a/Generate-Wiki/Tutorial 1/T1-01.md b/Generate-Wiki/Tutorial 1/T1-01.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 1/T1-01.md rename to Generate-Wiki/Tutorial 1/T1-01.md.m4 diff --git a/Generate-Wiki/Tutorial 1/T1-02.md b/Generate-Wiki/Tutorial 1/T1-02.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 1/T1-02.md rename to Generate-Wiki/Tutorial 1/T1-02.md.m4 diff --git a/Generate-Wiki/Tutorial 1/T1-04.md b/Generate-Wiki/Tutorial 1/T1-04.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 1/T1-04.md rename to Generate-Wiki/Tutorial 1/T1-04.md.m4 diff --git a/Generate-Wiki/Tutorial 2/T2-00.md b/Generate-Wiki/Tutorial 2/T2-00.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 2/T2-00.md rename to Generate-Wiki/Tutorial 2/T2-00.md.m4 diff --git a/Generate-Wiki/Tutorial 2/T2-01.md b/Generate-Wiki/Tutorial 2/T2-01.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 2/T2-01.md rename to Generate-Wiki/Tutorial 2/T2-01.md.m4 diff --git a/Generate-Wiki/Tutorial 2/T2-02.md b/Generate-Wiki/Tutorial 2/T2-02.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 2/T2-02.md rename to Generate-Wiki/Tutorial 2/T2-02.md.m4 diff --git a/Generate-Wiki/Tutorial 3/T1-03.md b/Generate-Wiki/Tutorial 3/T1-03.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 3/T1-03.md rename to Generate-Wiki/Tutorial 3/T1-03.md.m4 diff --git a/Generate-Wiki/Tutorial 3/T3-00.md b/Generate-Wiki/Tutorial 3/T3-00.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 3/T3-00.md rename to Generate-Wiki/Tutorial 3/T3-00.md.m4 diff --git a/Generate-Wiki/_Footer.md b/Generate-Wiki/_Footer.md.m4 similarity index 100% rename from Generate-Wiki/_Footer.md rename to Generate-Wiki/_Footer.md.m4 diff --git a/Generate-Wiki/_Sidebar.md b/Generate-Wiki/_Sidebar.md.m4 similarity index 100% rename from Generate-Wiki/_Sidebar.md rename to Generate-Wiki/_Sidebar.md.m4 From 9fc1de135e38ad10294ca6e7b13eabd8b8e78291 Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Sat, 2 Jan 2021 00:05:23 -0500 Subject: [PATCH 03/23] Updated the generate docs command to output to the proper directory --- Generate-Wiki/generate_docs.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Generate-Wiki/generate_docs.sh b/Generate-Wiki/generate_docs.sh index 95377d2..24027e0 100755 --- a/Generate-Wiki/generate_docs.sh +++ b/Generate-Wiki/generate_docs.sh @@ -1,2 +1,23 @@ #! env sh -find . -name "*.md" -exec sh -c 'm4 definitions.m4 "$0" > "../../Programming-Tutorial.wiki/$0"' {} \; \ No newline at end of file +# filename: generate_docs.sh + +# This command must be executed with the following: +# 1. run inside the "Generate-Wiki" directory +# 2. have the wiki repository cloned at ../../Programming-Tutorial.wiki +# + +# TODO: validate assumptions here... + +# version 1 of the command: +# find . -name "*.md" -exec sh -c 'm4 definitions.m4 "$0" > "../../Programming-Tutorial.wiki/$0"' {} \; + +# find the md.m4 files +# for each one, +# run the m4 command +# to do this we need to rename the files from *.md.m4 to *.md +# and place these files in the wiki directory + +# we call the realpath command here so that it fails fast +# if the wiki directory does not exist + +find . -name "*.md.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); echo "m4 definitions.m4 \"$(realpath $0)\" > \"$(realpath ../../Programming-Tutorial.wiki/$rename)\""' {} \; \ No newline at end of file From f70c5879702a027e78f5bf73f05ed283a74e935e Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Sat, 2 Jan 2021 00:14:56 -0500 Subject: [PATCH 04/23] Fixed bug in generation script; Fixed formatting in T1-04 --- Generate-Wiki/Tutorial 1/T1-04.md.m4 | 2 +- Generate-Wiki/generate_docs.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Generate-Wiki/Tutorial 1/T1-04.md.m4 b/Generate-Wiki/Tutorial 1/T1-04.md.m4 index 0801500..38787f9 100644 --- a/Generate-Wiki/Tutorial 1/T1-04.md.m4 +++ b/Generate-Wiki/Tutorial 1/T1-04.md.m4 @@ -116,9 +116,9 @@ With `int exit_value = -1;` we next declare a variable to hold our exit code and Next, we check with `if ( argc == 2 )` that we only have 2 arguments. __We'll come back to this point of 2 arguments in a bit.__ If we have two arguments, then we find the length of the text passed in with the following lines. First we create a variable to hold our place, then while the current character in the string passed in isn't the null character or `\0` (this is how C lets you know that you've reached the end of your string) we increment `i`: + ```C esyscmd({{sed -n '6,8p' ../T1/step-4-hello-world/2-Test-Hello-World/main.c | sed 's/^ / /g' | ghead -c -1}}) - ``` Next we can output the string in `argv` to the Shell with `write(1, argv[1], i);`. diff --git a/Generate-Wiki/generate_docs.sh b/Generate-Wiki/generate_docs.sh index 24027e0..0480cd3 100755 --- a/Generate-Wiki/generate_docs.sh +++ b/Generate-Wiki/generate_docs.sh @@ -12,7 +12,7 @@ # find . -name "*.md" -exec sh -c 'm4 definitions.m4 "$0" > "../../Programming-Tutorial.wiki/$0"' {} \; # find the md.m4 files -# for each one, +# for each file, # run the m4 command # to do this we need to rename the files from *.md.m4 to *.md # and place these files in the wiki directory @@ -20,4 +20,4 @@ # we call the realpath command here so that it fails fast # if the wiki directory does not exist -find . -name "*.md.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); echo "m4 definitions.m4 \"$(realpath $0)\" > \"$(realpath ../../Programming-Tutorial.wiki/$rename)\""' {} \; \ No newline at end of file +find . -name "*.md.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); echo "m4 definitions.m4 \"$(realpath "$0")\" > \"$(realpath "../../Programming-Tutorial.wiki/$rename")\""' {} \; \ No newline at end of file From 6218add7509488566e904ccb68903ed85a623784 Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Sat, 2 Jan 2021 00:19:02 -0500 Subject: [PATCH 05/23] Fixed bug with generation command. --- Generate-Wiki/generate_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Generate-Wiki/generate_docs.sh b/Generate-Wiki/generate_docs.sh index 0480cd3..831b986 100755 --- a/Generate-Wiki/generate_docs.sh +++ b/Generate-Wiki/generate_docs.sh @@ -20,4 +20,4 @@ # we call the realpath command here so that it fails fast # if the wiki directory does not exist -find . -name "*.md.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); echo "m4 definitions.m4 \"$(realpath "$0")\" > \"$(realpath "../../Programming-Tutorial.wiki/$rename")\""' {} \; \ No newline at end of file +find . -name "*.md.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); m4 definitions.m4 "$(realpath "$0")" > "$(realpath "../../Programming-Tutorial.wiki/$rename")"' {} \; \ No newline at end of file From 995fbe78c2ddae99442a034a983808458a4a0810 Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Sat, 2 Jan 2021 10:44:28 -0500 Subject: [PATCH 06/23] Moved src to template directory. Added code headers to templates. --- .gitignore | 5 +- Generate-Wiki/definitions.m4 | 20 --- Generate-Wiki/generate_docs.sh | 23 ---- Notes.md | 4 + build.sh | 32 +++++ definitions.m4 | 42 ++++++ {T1 => src/T1}/step-1-setup/windows-setup.cmd | 17 ++- .../hello-world-fixed.tcl | 6 +- .../step-2-command-line-101/hello-world.tcl | 0 .../download-repository.tcl | 0 .../hello-world.tcl | 0 .../step-4-hello-world/1-Hello-World/main.c | 19 +-- .../2-Test-Hello-World/main-fixed.c | 68 ++++++++++ .../2-Test-Hello-World/main.c | 25 ++++ .../2-Test-Hello-World/test.tcl | 63 +++++++++ .../3-Makefile-Hello-World/main-fixed.c | 16 +-- .../3-Makefile-Hello-World/main.c | 16 +-- .../3-Makefile-Hello-World/makefile | 0 .../3-Makefile-Hello-World/test.tcl | 0 {T2 => src/T2}/step-1-code-gen/.gitignore | 0 {T2 => src/T2}/step-1-code-gen/lib.c | 0 {T2 => src/T2}/step-1-code-gen/lib.h | 0 {T2 => src/T2}/step-1-code-gen/macrologger.h | 2 +- {T2 => src/T2}/step-1-code-gen/main.c | 2 + {T2 => src/T2}/step-1-code-gen/makefile | 0 {T2 => src/T2}/step-1-code-gen/test.tcl | 1 + {T2 => src/T2}/step-1-pointers/.gitignore | 0 {T2 => src/T2}/step-1-pointers/main.c | 0 {T2 => src/T2}/step-1-pointers/makefile | 0 {T2 => src/T2}/step-2-brute-force/.gitignore | 0 {T2 => src/T2}/step-2-brute-force/main.c | 0 {T2 => src/T2}/step-2-brute-force/makefile | 0 src/test.tcl | 95 ++++++++++++++ templates-code/README.md.m4 | 22 ++++ .../T1/step-1-setup/windows-setup.cmd.m4 | 72 ++++++++++ .../hello-world-fixed.tcl.m4 | 29 +++++ .../hello-world.tcl.m4 | 29 +++++ .../download-repository.tcl.m4 | 64 +++++++++ .../hello-world.tcl.m4 | 49 +++++++ .../1-Hello-World/main.c.m4 | 60 +++++++++ .../2-Test-Hello-World/main-fixed.c.m4 | 2 + .../2-Test-Hello-World/main.c.m4 | 2 + .../2-Test-Hello-World/test.tcl.m4 | 4 +- .../3-Makefile-Hello-World/main-fixed.c.m4 | 60 +++++++++ .../3-Makefile-Hello-World/main.c.m4 | 58 +++++++++ .../3-Makefile-Hello-World/makefile.m4 | 24 ++++ .../3-Makefile-Hello-World/test.tcl.m4 | 59 +++++++++ .../T2/step-1-code-gen/.gitignore.m4 | 7 + templates-code/T2/step-1-code-gen/lib.c.m4 | 95 ++++++++++++++ templates-code/T2/step-1-code-gen/lib.h.m4 | 32 +++++ .../T2/step-1-code-gen/macrologger.h.m4 | 123 ++++++++++++++++++ templates-code/T2/step-1-code-gen/main.c.m4 | 48 +++++++ templates-code/T2/step-1-code-gen/makefile.m4 | 69 ++++++++++ templates-code/T2/step-1-code-gen/test.tcl.m4 | 88 +++++++++++++ .../T2/step-1-pointers/.gitignore.m4 | 5 + templates-code/T2/step-1-pointers/main.c.m4 | 120 +++++++++++++++++ templates-code/T2/step-1-pointers/makefile.m4 | 24 ++++ .../T2/step-2-brute-force/.gitignore.m4 | 5 + .../T2/step-2-brute-force/main.c.m4 | 35 +++++ .../T2/step-2-brute-force/makefile.m4 | 24 ++++ test.tcl => templates-code/test.tcl.m4 | 3 +- {Generate-Wiki => templates-wiki}/Home.md.m4 | 0 .../Tutorial 1/T1-00.md.m4 | 0 .../Tutorial 1/T1-01.md.m4 | 0 .../Tutorial 1/T1-02.md.m4 | 6 +- .../Tutorial 1/T1-04.md.m4 | 37 +++--- .../Tutorial 2/T2-00.md.m4 | 0 .../Tutorial 2/T2-01.md.m4 | 0 .../Tutorial 2/T2-02.md.m4 | 0 .../Tutorial 3/T1-03.md.m4 | 0 .../Tutorial 3/T3-00.md.m4 | 0 .../_Footer.md.m4 | 0 .../_Sidebar.md.m4 | 0 73 files changed, 1614 insertions(+), 97 deletions(-) delete mode 100644 Generate-Wiki/definitions.m4 delete mode 100755 Generate-Wiki/generate_docs.sh create mode 100644 Notes.md create mode 100755 build.sh create mode 100644 definitions.m4 rename {T1 => src/T1}/step-1-setup/windows-setup.cmd (83%) rename {T1 => src/T1}/step-2-command-line-101/hello-world-fixed.tcl (79%) mode change 100755 => 100644 rename {T1 => src/T1}/step-2-command-line-101/hello-world.tcl (100%) mode change 100755 => 100644 rename {T1 => src/T1}/step-3-version-control-101/download-repository.tcl (100%) rename {T1 => src/T1}/step-3-version-control-101/hello-world.tcl (100%) mode change 100755 => 100644 rename {T1 => src/T1}/step-4-hello-world/1-Hello-World/main.c (99%) create mode 100644 src/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c create mode 100644 src/T1/step-4-hello-world/2-Test-Hello-World/main.c create mode 100644 src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl rename {T1 => src/T1}/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c (100%) rename {T1 => src/T1}/step-4-hello-world/3-Makefile-Hello-World/main.c (100%) rename {T1 => src/T1}/step-4-hello-world/3-Makefile-Hello-World/makefile (100%) rename {T1 => src/T1}/step-4-hello-world/3-Makefile-Hello-World/test.tcl (100%) rename {T2 => src/T2}/step-1-code-gen/.gitignore (100%) rename {T2 => src/T2}/step-1-code-gen/lib.c (100%) rename {T2 => src/T2}/step-1-code-gen/lib.h (100%) rename {T2 => src/T2}/step-1-code-gen/macrologger.h (99%) rename {T2 => src/T2}/step-1-code-gen/main.c (97%) rename {T2 => src/T2}/step-1-code-gen/makefile (100%) rename {T2 => src/T2}/step-1-code-gen/test.tcl (99%) rename {T2 => src/T2}/step-1-pointers/.gitignore (100%) rename {T2 => src/T2}/step-1-pointers/main.c (100%) rename {T2 => src/T2}/step-1-pointers/makefile (100%) rename {T2 => src/T2}/step-2-brute-force/.gitignore (100%) rename {T2 => src/T2}/step-2-brute-force/main.c (100%) rename {T2 => src/T2}/step-2-brute-force/makefile (100%) create mode 100644 src/test.tcl create mode 100644 templates-code/README.md.m4 create mode 100644 templates-code/T1/step-1-setup/windows-setup.cmd.m4 create mode 100755 templates-code/T1/step-2-command-line-101/hello-world-fixed.tcl.m4 create mode 100755 templates-code/T1/step-2-command-line-101/hello-world.tcl.m4 create mode 100644 templates-code/T1/step-3-version-control-101/download-repository.tcl.m4 create mode 100755 templates-code/T1/step-3-version-control-101/hello-world.tcl.m4 create mode 100644 templates-code/T1/step-4-hello-world/1-Hello-World/main.c.m4 rename T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c => templates-code/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c.m4 (98%) rename T1/step-4-hello-world/2-Test-Hello-World/main.c => templates-code/T1/step-4-hello-world/2-Test-Hello-World/main.c.m4 (90%) rename T1/step-4-hello-world/2-Test-Hello-World/test.tcl => templates-code/T1/step-4-hello-world/2-Test-Hello-World/test.tcl.m4 (93%) create mode 100644 templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c.m4 create mode 100644 templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/main.c.m4 create mode 100644 templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/makefile.m4 create mode 100644 templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl.m4 create mode 100644 templates-code/T2/step-1-code-gen/.gitignore.m4 create mode 100644 templates-code/T2/step-1-code-gen/lib.c.m4 create mode 100644 templates-code/T2/step-1-code-gen/lib.h.m4 create mode 100644 templates-code/T2/step-1-code-gen/macrologger.h.m4 create mode 100644 templates-code/T2/step-1-code-gen/main.c.m4 create mode 100644 templates-code/T2/step-1-code-gen/makefile.m4 create mode 100644 templates-code/T2/step-1-code-gen/test.tcl.m4 create mode 100644 templates-code/T2/step-1-pointers/.gitignore.m4 create mode 100644 templates-code/T2/step-1-pointers/main.c.m4 create mode 100644 templates-code/T2/step-1-pointers/makefile.m4 create mode 100644 templates-code/T2/step-2-brute-force/.gitignore.m4 create mode 100644 templates-code/T2/step-2-brute-force/main.c.m4 create mode 100644 templates-code/T2/step-2-brute-force/makefile.m4 rename test.tcl => templates-code/test.tcl.m4 (96%) rename {Generate-Wiki => templates-wiki}/Home.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/Tutorial 1/T1-00.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/Tutorial 1/T1-01.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/Tutorial 1/T1-02.md.m4 (96%) rename {Generate-Wiki => templates-wiki}/Tutorial 1/T1-04.md.m4 (82%) rename {Generate-Wiki => templates-wiki}/Tutorial 2/T2-00.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/Tutorial 2/T2-01.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/Tutorial 2/T2-02.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/Tutorial 3/T1-03.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/Tutorial 3/T3-00.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/_Footer.md.m4 (100%) rename {Generate-Wiki => templates-wiki}/_Sidebar.md.m4 (100%) diff --git a/.gitignore b/.gitignore index bfed150..fe633f6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,7 @@ **~** ~* *.o -*.orig \ No newline at end of file +*.orig +**/debug/ +**/release/ +*.stackdump \ No newline at end of file diff --git a/Generate-Wiki/definitions.m4 b/Generate-Wiki/definitions.m4 deleted file mode 100644 index 11cd61d..0000000 --- a/Generate-Wiki/definitions.m4 +++ /dev/null @@ -1,20 +0,0 @@ -changequote({{,}}) -dnl# root definitions import first -dnl#syscmd(echo "Author: " | tr -d '\n')dnl -dnl#pushdef({{__author__}}, esyscmd(read AUTHOR && echo $AUTHOR | tr -d '\n'))dnl -pushdef({{__author__}}, {{Betsalel (Saul) Williamson}})dnl -dnl -dnl -dnl#syscmd(echo "Author Email: " | tr -d '\n')dnl -dnl#pushdef({{__author_email__}}, esyscmd(read AUTHOR_EMAIL && echo $AUTHOR_EMAIL | tr -d '\n'))dnl -pushdef({{__author_email__}}, {{saul.williamson@ieee.org}})dnl -dnl -dnl -pushdef({{__wiki_licence__}}, {{CC BY 4.0 license}})dnl -pushdef({{__wiki_licence_full__}}, {{Creative Commons 4.0 Attribution License}})dnl -pushdef({{__wiki_licence_web_address__}}, {{https://creativecommons.org/licenses/by/4.0/}})dnl -dnl -dnl -pushdef({{__project_repo_root__}}, {{https://github.com/betsalel-williamson/Programming-Tutorial}})dnl -pushdef({{__project_repo__}}, {{__project_repo_root__{{}}.git}})dnl -pushdef({{__project_repo_name__}}, {{Programming-Tutorial}})dnl diff --git a/Generate-Wiki/generate_docs.sh b/Generate-Wiki/generate_docs.sh deleted file mode 100755 index 831b986..0000000 --- a/Generate-Wiki/generate_docs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#! env sh -# filename: generate_docs.sh - -# This command must be executed with the following: -# 1. run inside the "Generate-Wiki" directory -# 2. have the wiki repository cloned at ../../Programming-Tutorial.wiki -# - -# TODO: validate assumptions here... - -# version 1 of the command: -# find . -name "*.md" -exec sh -c 'm4 definitions.m4 "$0" > "../../Programming-Tutorial.wiki/$0"' {} \; - -# find the md.m4 files -# for each file, -# run the m4 command -# to do this we need to rename the files from *.md.m4 to *.md -# and place these files in the wiki directory - -# we call the realpath command here so that it fails fast -# if the wiki directory does not exist - -find . -name "*.md.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); m4 definitions.m4 "$(realpath "$0")" > "$(realpath "../../Programming-Tutorial.wiki/$rename")"' {} \; \ No newline at end of file diff --git a/Notes.md b/Notes.md new file mode 100644 index 0000000..b52f0d7 --- /dev/null +++ b/Notes.md @@ -0,0 +1,4 @@ +# Notes for Programming Tutorial + +[ ] make templates to make it easier to manage in the long run +[ ] create contribution guidelines \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..5863a07 --- /dev/null +++ b/build.sh @@ -0,0 +1,32 @@ +#! env sh +# filename: generate_docs.sh + +# This command must be executed with the following: +# 1. run inside the "Generate-Wiki" directory +# 2. have the wiki repository cloned at ../../Programming-Tutorial.wiki +# + +# TODO: validate assumptions here... + +# version 1 of the command: +# find . -name "*.md" -exec sh -c 'm4 definitions.m4 "$0" > "../../Programming-Tutorial.wiki/$0"' {} \; + +# find the md.m4 files +# for each file, +# run the m4 command +# to do this we need to rename the files from *.md.m4 to *.md +# and place these files in the result directory + +# echo "Making directory for: ($(dirname $0))"; + +pushd ./templates-code > /dev/null 2>&1 +find . -name "*.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); mkdir -p $(dirname "../src/$rename"); m4 ../definitions.m4 "$(realpath "$0")" > "../src/$rename"' {} \; +mv ../src/README.md ../ +popd > /dev/null 2>&1 + +# we call the realpath command for the wiki so that it fails fast +# if the wiki directory does not exist +pushd ./templates-wiki > /dev/null 2>&1 +find . -name "*.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); m4 ../definitions.m4 "$(realpath "$0")" > "$(realpath "../../Programming-Tutorial.wiki/$rename")"' {} \; +popd > /dev/null 2>&1 + diff --git a/definitions.m4 b/definitions.m4 new file mode 100644 index 0000000..464ab03 --- /dev/null +++ b/definitions.m4 @@ -0,0 +1,42 @@ +changequote({{,}})dnl +dnl# root definitions import first +dnl#syscmd(echo "Author: " | tr -d '\n')dnl +dnl#pushdef({{__author__}}, esyscmd(read AUTHOR && echo $AUTHOR | tr -d '\n'))dnl +pushdef({{__author__}}, {{Betsalel (Saul) Williamson}})dnl +dnl +dnl +dnl#syscmd(echo "Author Email: " | tr -d '\n')dnl +dnl#pushdef({{__author_email__}}, esyscmd(read AUTHOR_EMAIL && echo $AUTHOR_EMAIL | tr -d '\n'))dnl +pushdef({{__author_email__}}, {{saul.williamson@ieee.org}})dnl +dnl +dnl +pushdef({{__wiki_licence__}}, {{CC BY 4.0 license}})dnl +pushdef({{__wiki_licence_full__}}, {{Creative Commons 4.0 Attribution License}})dnl +pushdef({{__wiki_licence_web_address__}}, {{https://creativecommons.org/licenses/by/4.0/}})dnl +dnl +dnl +pushdef({{__project_repo_root__}}, {{https://github.com/betsalel-williamson/Programming-Tutorial}})dnl +pushdef({{__project_repo__}}, {{__project_repo_root__{{}}.git}})dnl +pushdef({{__project_repo_name__}}, {{Programming-Tutorial}})dnl +pushdef({{__code_license_header__}}, {{The author disclaims copyright to this source code. In place of +a legal notice, here is a blessing: + May you do good and not evil. + May you find forgiveness for yourself and forgive others. + May you share freely, never taking more than you give.}})dnl +pushdef({{__code_license_header_hash_style__}}, {{# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give.}})dnl +pushdef({{__code_license_header_c__}}, {{/* +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +*/}})dnl +pushdef({{__code_license_header_markdown__}}, {{In place of a legal notice, here is a blessing: +- May you do good and not evil. +- May you find forgiveness for yourself and forgive others. +- May you share freely, never taking more than you give.}})dnl diff --git a/T1/step-1-setup/windows-setup.cmd b/src/T1/step-1-setup/windows-setup.cmd similarity index 83% rename from T1/step-1-setup/windows-setup.cmd rename to src/T1/step-1-setup/windows-setup.cmd index ada2c73..d5b8377 100644 --- a/T1/step-1-setup/windows-setup.cmd +++ b/src/T1/step-1-setup/windows-setup.cmd @@ -39,6 +39,20 @@ if not exist %cygwinPath% ( :: double-check that Cygwin was installed to the correct path if not exist %cygwinPath%\bin echo %cygwinPath%\bin not found. Check Cygwin installation path. && exit /B +:: TODO: Check the Path length to see if +:: adding would exceed the max length. +:: MAX_PATH, which is defined as 260 +:: If so, then alert the user to edit +:: the path first then run again. +:: +:: Possible solution from: +:: https://stackoverflow.com/questions/5837418/how-do-you-get-the-string-length-in-a-batch-file/8566001#8566001 +:: set tempPath="%USERPROFILE%\AppData\Local\Temp\win-setup-path.txt" +:: (ECHO %PATH%)> %tempPath% +:: FOR %%? IN (%tempPath%) DO ( SET /A strlength=%%~z? - 2 ) +:: del %tempPath% +:: if strlength + :: check to see that the environmental variables have the cygwin path echo %PATH% | find /i "%cygwinPath%\bin" > nul && set CYGWIN_PATH_BIN_SET=TRUE || set CYGWIN_PATH_BIN_SET= if defined CYGWIN_PATH_BIN_SET ( @@ -48,9 +62,6 @@ if defined CYGWIN_PATH_BIN_SET ( :: BUG, Does not check the Path length first to ensure that :: the Cygwin bin path can be added. -:: TODO: Check the Path length to see if -:: adding would exceed the max length. If so then -:: alert the user to edit the path first then run again. :: then install Git, TCL, Expect, GCC and other developer programs echo Updating Cygwin to latest and installing development programs... diff --git a/T1/step-2-command-line-101/hello-world-fixed.tcl b/src/T1/step-2-command-line-101/hello-world-fixed.tcl old mode 100755 new mode 100644 similarity index 79% rename from T1/step-2-command-line-101/hello-world-fixed.tcl rename to src/T1/step-2-command-line-101/hello-world-fixed.tcl index 9a5b0a9..58c1d10 --- a/T1/step-2-command-line-101/hello-world-fixed.tcl +++ b/src/T1/step-2-command-line-101/hello-world-fixed.tcl @@ -15,8 +15,10 @@ spawn echo "Hello World from TCL/Expect!" # Method one, is to simply change the text in the expect # command from "Hello world." to "Hello World from TCL/Expect!" # Method two is to change the text to be more flexible -# and replace "Hello world." with the text between the -# `` characters `-nocase "hello world"`. +# and replace "Hello world." with the text +# "Hello World from TCL/Expect!" or with `-nocase "hello world"`. +# The '-nocase' argument allows the check to ignore the +# case of the text so it could be upper or lower case. # Method two: expect { diff --git a/T1/step-2-command-line-101/hello-world.tcl b/src/T1/step-2-command-line-101/hello-world.tcl old mode 100755 new mode 100644 similarity index 100% rename from T1/step-2-command-line-101/hello-world.tcl rename to src/T1/step-2-command-line-101/hello-world.tcl diff --git a/T1/step-3-version-control-101/download-repository.tcl b/src/T1/step-3-version-control-101/download-repository.tcl similarity index 100% rename from T1/step-3-version-control-101/download-repository.tcl rename to src/T1/step-3-version-control-101/download-repository.tcl diff --git a/T1/step-3-version-control-101/hello-world.tcl b/src/T1/step-3-version-control-101/hello-world.tcl old mode 100755 new mode 100644 similarity index 100% rename from T1/step-3-version-control-101/hello-world.tcl rename to src/T1/step-3-version-control-101/hello-world.tcl diff --git a/T1/step-4-hello-world/1-Hello-World/main.c b/src/T1/step-4-hello-world/1-Hello-World/main.c similarity index 99% rename from T1/step-4-hello-world/1-Hello-World/main.c rename to src/T1/step-4-hello-world/1-Hello-World/main.c index 4395f01..16e0451 100644 --- a/T1/step-4-hello-world/1-Hello-World/main.c +++ b/src/T1/step-4-hello-world/1-Hello-World/main.c @@ -1,12 +1,3 @@ -/* -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -*/ - /* * Welcome to your first program in C. This program will output "Hello World" to * the shell when run. @@ -18,6 +9,16 @@ * * Single line comments are written after double forward slashes `//` */ + +/* +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +*/ + int main ( ) { // Programming language of C requires a function named `main` that returns diff --git a/src/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c b/src/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c new file mode 100644 index 0000000..cb966b7 --- /dev/null +++ b/src/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c @@ -0,0 +1,68 @@ +/* + * Welcome to your second program in C. + * + * In this program you will modify the code from your first program + * to accept a parameter or argument as input from the Shell. + * + */ + +/* +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +*/ + +int main ( int argc, const char* argv[] ) { + + // argc is the number of arguments passed into the program + // argv is the array (think a list) of arguments + // We access the items in the array by putting a number between + // the square brackets. In C, we call this number an index. + // This is very important because indexes will always start + // with 0. You can think of this in terms of number types. + // In math, the natural numbers start with 1 and increase. + // Indexes start at 0 and will increase until the number of + // items in the array minus 1. + + int exit_value = -1; + // we set this exit value to be -1 so we can know if the + // program exits unexpectedly before being able to set + // the value 0, or 1 as will be shown later on. + + // ensure the correct number of parameters are used. + if ( argc == 2 ) { + int i = 0; // declare a variable to count the length + // of the text passed in as an argument + + // In C, all properly formmated strings end with + // the character '\0'. To get the length of the text, + // or string, we start at the first index value 0. + while( argv[1][i] != '\0' ) { + i = i + 1; + } + + write( 1, argv[1], i ); + + // What do you think the zeroth item or element + // in argv is? + + // i = 0; // reset i to be 0 + + // while(argv[0][i] != '\0') { + // i = i+1; + // } + + // write(1, argv[0], i); + + exit_value = 0; + } else { + // if the incorrect number of parameters are used + // then report that there was an error + exit_value = 1; + } + + return exit_value; +} diff --git a/src/T1/step-4-hello-world/2-Test-Hello-World/main.c b/src/T1/step-4-hello-world/2-Test-Hello-World/main.c new file mode 100644 index 0000000..dc169d4 --- /dev/null +++ b/src/T1/step-4-hello-world/2-Test-Hello-World/main.c @@ -0,0 +1,25 @@ +/* +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +*/ + +int main ( int argc, const char* argv[] ) { + int exit_value = -1; + + if ( argc == 2 ) { + + while(argv[1][i] != '\0'){ + i = i+1; + } + + exit_value = 0 + } else { + exit_value = 1; + } + + return exit_value; +} \ No newline at end of file diff --git a/src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl b/src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl new file mode 100644 index 0000000..e8e5cf4 --- /dev/null +++ b/src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl @@ -0,0 +1,63 @@ +#!/bin/env expect + +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. + +# delete the executable file +exec rm main +# compile the file +exec gcc -w main.c -o main + +### Test 1 ### +# +# Given that we provide a single text input to our program, +# When we run it, +# Then the program will print the text to the Shell +# and exits with the value 0 +# + +spawn ./main "Hello World" +expect { + -nocase "hello world" { + puts "\nFound output of: Hello World\n" + } + default { + puts "\nTest failed. Expected Hello world\n" + } +} + +expect eof +catch wait result +if {[lindex $result 3] == 0} { + puts "Exited successfully.\n" +} else { + puts "Test failed with code [lindex $result 3].\n" +} + +### Test 2 ### +# +# Given that we don't provide a single text input to our +# program, +# When we run it, +# Then the program exits without printing the input and +# has the value 1 +# + +spawn ./main +expect eof +catch wait result + +if {[lindex $result 3] == 1} { + puts "Exited successfully.\n" +} else { + puts "Test failed with code [lindex $result 3].\n" +} + +# What happens when we try calling main +# with more than 1 parameter? +# $ ./main Hello World +# Hello world must be in quotes in order for this +# to be considered a single parameter diff --git a/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c b/src/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c similarity index 100% rename from T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c rename to src/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c index f157f83..dc524ab 100644 --- a/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c +++ b/src/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c @@ -1,3 +1,11 @@ +/* + * Welcome to your second program in C. + * + * In this program you will modify the code from your first program + * to accept a parameter or argument as input from the Shell. + * + */ + /* ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -7,14 +15,6 @@ ** May you share freely, never taking more than you give. */ -/* - * Welcome to your second program in C. - * - * In this program you will modify the code from your first program - * to accept a parameter or argument as input from the Shell. - * - */ - #include int main ( int argc, const char* argv[] ) { diff --git a/T1/step-4-hello-world/3-Makefile-Hello-World/main.c b/src/T1/step-4-hello-world/3-Makefile-Hello-World/main.c similarity index 100% rename from T1/step-4-hello-world/3-Makefile-Hello-World/main.c rename to src/T1/step-4-hello-world/3-Makefile-Hello-World/main.c index 68f9fe0..50a32f9 100644 --- a/T1/step-4-hello-world/3-Makefile-Hello-World/main.c +++ b/src/T1/step-4-hello-world/3-Makefile-Hello-World/main.c @@ -1,3 +1,11 @@ +/* + * Welcome to your second program in C. + * + * In this program you will modify the code from your first program + * to accept a parameter or argument as input from the Shell. + * + */ + /* ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -7,14 +15,6 @@ ** May you share freely, never taking more than you give. */ -/* - * Welcome to your second program in C. - * - * In this program you will modify the code from your first program - * to accept a parameter or argument as input from the Shell. - * - */ - int main ( int argc, const char* argv[] ) { // argc is the number of arguments passed into the program diff --git a/T1/step-4-hello-world/3-Makefile-Hello-World/makefile b/src/T1/step-4-hello-world/3-Makefile-Hello-World/makefile similarity index 100% rename from T1/step-4-hello-world/3-Makefile-Hello-World/makefile rename to src/T1/step-4-hello-world/3-Makefile-Hello-World/makefile diff --git a/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl b/src/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl similarity index 100% rename from T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl rename to src/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl diff --git a/T2/step-1-code-gen/.gitignore b/src/T2/step-1-code-gen/.gitignore similarity index 100% rename from T2/step-1-code-gen/.gitignore rename to src/T2/step-1-code-gen/.gitignore diff --git a/T2/step-1-code-gen/lib.c b/src/T2/step-1-code-gen/lib.c similarity index 100% rename from T2/step-1-code-gen/lib.c rename to src/T2/step-1-code-gen/lib.c diff --git a/T2/step-1-code-gen/lib.h b/src/T2/step-1-code-gen/lib.h similarity index 100% rename from T2/step-1-code-gen/lib.h rename to src/T2/step-1-code-gen/lib.h diff --git a/T2/step-1-code-gen/macrologger.h b/src/T2/step-1-code-gen/macrologger.h similarity index 99% rename from T2/step-1-code-gen/macrologger.h rename to src/T2/step-1-code-gen/macrologger.h index 7c36361..f53fa49 100644 --- a/T2/step-1-code-gen/macrologger.h +++ b/src/T2/step-1-code-gen/macrologger.h @@ -120,4 +120,4 @@ static inline void objc_print( NSString *format, ... ) { #endif -#endif \ No newline at end of file +#endif diff --git a/T2/step-1-code-gen/main.c b/src/T2/step-1-code-gen/main.c similarity index 97% rename from T2/step-1-code-gen/main.c rename to src/T2/step-1-code-gen/main.c index 2d98984..e603581 100644 --- a/T2/step-1-code-gen/main.c +++ b/src/T2/step-1-code-gen/main.c @@ -1,3 +1,5 @@ +/* Simple program to demonstrate c */ + /* ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: diff --git a/T2/step-1-code-gen/makefile b/src/T2/step-1-code-gen/makefile similarity index 100% rename from T2/step-1-code-gen/makefile rename to src/T2/step-1-code-gen/makefile diff --git a/T2/step-1-code-gen/test.tcl b/src/T2/step-1-code-gen/test.tcl similarity index 99% rename from T2/step-1-code-gen/test.tcl rename to src/T2/step-1-code-gen/test.tcl index 509d8a5..edc3f48 100644 --- a/T2/step-1-code-gen/test.tcl +++ b/src/T2/step-1-code-gen/test.tcl @@ -1,4 +1,5 @@ #!/usr/bin/env expect + # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # May you do good and not evil. diff --git a/T2/step-1-pointers/.gitignore b/src/T2/step-1-pointers/.gitignore similarity index 100% rename from T2/step-1-pointers/.gitignore rename to src/T2/step-1-pointers/.gitignore diff --git a/T2/step-1-pointers/main.c b/src/T2/step-1-pointers/main.c similarity index 100% rename from T2/step-1-pointers/main.c rename to src/T2/step-1-pointers/main.c diff --git a/T2/step-1-pointers/makefile b/src/T2/step-1-pointers/makefile similarity index 100% rename from T2/step-1-pointers/makefile rename to src/T2/step-1-pointers/makefile diff --git a/T2/step-2-brute-force/.gitignore b/src/T2/step-2-brute-force/.gitignore similarity index 100% rename from T2/step-2-brute-force/.gitignore rename to src/T2/step-2-brute-force/.gitignore diff --git a/T2/step-2-brute-force/main.c b/src/T2/step-2-brute-force/main.c similarity index 100% rename from T2/step-2-brute-force/main.c rename to src/T2/step-2-brute-force/main.c diff --git a/T2/step-2-brute-force/makefile b/src/T2/step-2-brute-force/makefile similarity index 100% rename from T2/step-2-brute-force/makefile rename to src/T2/step-2-brute-force/makefile diff --git a/src/test.tcl b/src/test.tcl new file mode 100644 index 0000000..23138aa --- /dev/null +++ b/src/test.tcl @@ -0,0 +1,95 @@ +#!/usr/bin/env expect +# Test the tutorial +# run from the 'src' directory + +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. + +# format code +astyle "./*.c" "./*.h" \ +--indent=spaces=2 \ +--indent-switches \ +--indent-after-parens \ +--break-blocks \ +--pad-oper \ +--pad-comma \ +--pad-paren-in \ +--break-one-line-headers \ +--add-braces \ +--add-one-line-braces \ +--max-code-length=80 \ +--mode=c \ +--recursive \ +--verbose + +# test files +set t1step1file "./T1/step-1-setup/windows-setup.cmd" +if {[file exists $t1step1file]} { + puts "Success! T1 Step 1 file check" +} else { + puts "Error (file $t1step1file missing)!" + exit 1 +} + +puts "\nSuccess! T1 Step 1\n" + +set t1step2file "./T1/step-2-command-line-101/hello-world.tcl" +set outputT1Step2 { "spawn echo Hello World from TCL/Expect!\n" "Hello World from TCL/Expect!\n" "Error!\n" } + +if {[file exists $t1step2file]} { + puts "Success! T1 Step 2 file check" +} else { + puts "Error (file $t1step2file missing)!" + exit 1 +} + +spawn $t1step2file + +# puts [expr [llength $outputT1Step2]] +for {set index 0} {$index < [expr [llength $outputT1Step2]]} {incr index +1} { + # puts [lindex $outputT1Step2 $index] + expect { + "\n" { + puts "Success (line $index)!" + } + default { + puts "Error (line $index)!" + puts [lindex $outputT1Step2 $index] + exit 1 + } + } +} + +puts "\nSuccess! T1 Step 2\n" + +set t1step3fileList { "./T1/step-3-version-control-101/download-repository.tcl" "./T1/step-3-version-control-101/hello-world.tcl" } +set outputT1Step3 { "spawn echo Hello World from TCL/Expect!\n" "Hello World from TCL/Expect!\n" "Error!\n" } + +for {set index 0} {$index < [expr [llength $t1step3fileList]]} {incr index +1} { + if {[file exists [lindex $t1step3fileList $index]]} { + puts "Success! T1 Step 3 file check" + } else { + puts "Error (file [lindex $t1step3fileList $index] missing)!" + exit 1 + } +} + +spawn [lindex $t1step3fileList 1] + +for {set index 0} {$index < [expr [llength $outputT1Step3]]} {incr index +1} { + expect { + "\n" { + puts "Success (line $index)!" + } + default { + puts "Error (line $index)!" + puts [lindex $outputT1Step3 $index] + exit 1 + } + } +} + +puts "\nSuccess! T1 Step 3\n" diff --git a/templates-code/README.md.m4 b/templates-code/README.md.m4 new file mode 100644 index 0000000..b40d861 --- /dev/null +++ b/templates-code/README.md.m4 @@ -0,0 +1,22 @@ +# Programming Tutorial +This project is a basic programming. The target audience is for those who may be beginning to learn programming or have already taken an introductory programming course. + +This tutorial walks through the creation of a program that generates a passcode and then a second program that is brute-force passcode cracking program! The tutorials don't assume much. Unlike other tutorials, it teaches important best practices like configuraiton control, developing build procedures, and testing your code. Lastly, you can follow this tutorial on any operating system (Windows, Linux, or Mac). + +The tutorial is located at <{{}}__project_repo_root__{{}}/wiki>. + +The author disclaims copyright to this source code and the tutorial may be freely shared with the [{{}}__wiki_licence__{{}}]({{}}__wiki_licence_web_address__{{}}). To share, please include the following in any slides or documents: + +``` +The tutorial is reproduced or modified from work created and shared by __author__ <{{}}__author_email__{{}}> and used according to terms described in the __wiki_licence_full__{{}}. +``` + +From the SQLite source code header: + +``` +__code_license_header_markdown__ +``` + +For questions, comments, or suggestions about this tutorial contact [{{}}__author__{{}}](mailto:{{}}__author_email__{{}}). + +This was developed with guidance from the founders of the University of Pittsburgh's Student Electronics Resource Center (SERC) and tested in a classroom setting with students. For other cool engineering tutorials and resources, check out SERC's website at [sercpitt.weebly.com](https://sercpitt.weebly.com/) . diff --git a/templates-code/T1/step-1-setup/windows-setup.cmd.m4 b/templates-code/T1/step-1-setup/windows-setup.cmd.m4 new file mode 100644 index 0000000..d5b8377 --- /dev/null +++ b/templates-code/T1/step-1-setup/windows-setup.cmd.m4 @@ -0,0 +1,72 @@ +@echo off +:: The `@echo off` command ensures that the commands that are run during this script are not displayed on the command console +setlocal +:: The `setLocal` command ensures that any variables that are set do not exist after the script exits. + +:: The author disclaims copyright to this source code. In place of +:: a legal notice, here is a blessing: +:: May you do good and not evil. +:: May you find forgiveness for yourself and forgive others. +:: May you share freely, never taking more than you give. + + +echo Checking system 32 or 64 bit... +reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT +if %OS%==32BIT (set cygwinUrl=https://cygwin.com/setup-x86.exe + echo 32 Bit system found + set cygwinPath=C:\cygwin) +if %OS%==64BIT (set cygwinUrl=https://cygwin.com/setup-x86_64.exe + echo 64 Bit system found + set cygwinPath=C:\cygwin64) + +echo Downloading cygwin setup... +if not exist %USERPROFILE%\Downloads mkdir %USERPROFILE%\Downloads +:: download Cygwin setup application +bitsadmin /transfer mydownloadjob /download /priority normal "%cygwinUrl%" "%USERPROFILE%\Downloads\cygwin-setup.exe" > NUL +echo Download completed. + +echo Checking if cygwin is installed... +:: if cygwin isn't installed then install it +if not exist %cygwinPath% ( + echo Will run cygwin installer after any key. Install with defaults. + pause + %USERPROFILE%\Downloads\cygwin-setup.exe + echo Wait to click any key until after setup is complete. + pause + ) + + +:: double-check that Cygwin was installed to the correct path +if not exist %cygwinPath%\bin echo %cygwinPath%\bin not found. Check Cygwin installation path. && exit /B + +:: TODO: Check the Path length to see if +:: adding would exceed the max length. +:: MAX_PATH, which is defined as 260 +:: If so, then alert the user to edit +:: the path first then run again. +:: +:: Possible solution from: +:: https://stackoverflow.com/questions/5837418/how-do-you-get-the-string-length-in-a-batch-file/8566001#8566001 +:: set tempPath="%USERPROFILE%\AppData\Local\Temp\win-setup-path.txt" +:: (ECHO %PATH%)> %tempPath% +:: FOR %%? IN (%tempPath%) DO ( SET /A strlength=%%~z? - 2 ) +:: del %tempPath% +:: if strlength + +:: check to see that the environmental variables have the cygwin path +echo %PATH% | find /i "%cygwinPath%\bin" > nul && set CYGWIN_PATH_BIN_SET=TRUE || set CYGWIN_PATH_BIN_SET= +if defined CYGWIN_PATH_BIN_SET ( + echo Cygwin\bin found in system PATH. + ) else (echo Adding '%cygwinPath%\bin' to PATH. + setx /M PATH "%PATH%;%cygwinPath%\bin") + +:: BUG, Does not check the Path length first to ensure that +:: the Cygwin bin path can be added. + +:: then install Git, TCL, Expect, GCC and other developer programs +echo Updating Cygwin to latest and installing development programs... +%USERPROFILE%\Downloads\cygwin-setup.exe -qvg -P python36 -P python36-devel -P python36-numpy -P python36-pip -P tcl -P expect -P git -P gcc-g++ -P make -P astyle -P diffutils -P libmpfr-devel -P libgmp-devel -P libmpc-devel -P cmake -P gdb + +pause + +goto :eof diff --git a/templates-code/T1/step-2-command-line-101/hello-world-fixed.tcl.m4 b/templates-code/T1/step-2-command-line-101/hello-world-fixed.tcl.m4 new file mode 100755 index 0000000..b4ec857 --- /dev/null +++ b/templates-code/T1/step-2-command-line-101/hello-world-fixed.tcl.m4 @@ -0,0 +1,29 @@ +#!/usr/bin/env expect +# This first line is called a shebang (pronounced Sha-Bang) and +# will tell the shell what program to use for the following text. + +__code_license_header_hash_style__ + +spawn echo "Hello World from TCL/Expect!" + +# What can we do to make this command exit with success? +# There are multiple ways to go about this. +# Method one, is to simply change the text in the expect +# command from "Hello world." to "Hello World from TCL/Expect!" +# Method two is to change the text to be more flexible +# and replace "Hello world." with the text +# "Hello World from TCL/Expect!" or with `-nocase "hello world"`. +# The '-nocase' argument allows the check to ignore the +# case of the text so it could be upper or lower case. + +# Method two: +expect { + -nocase "hello world" { + puts "Success!" + exit 0 + } + default { + puts "Error!" + exit 1 + } +} diff --git a/templates-code/T1/step-2-command-line-101/hello-world.tcl.m4 b/templates-code/T1/step-2-command-line-101/hello-world.tcl.m4 new file mode 100755 index 0000000..95c99ff --- /dev/null +++ b/templates-code/T1/step-2-command-line-101/hello-world.tcl.m4 @@ -0,0 +1,29 @@ +#!/usr/bin/env expect +# This first line is called a shebang (pronounced Sha-Bang) and +# will tell the shell what program to use for the following text. + +__code_license_header_hash_style__ + +# Our first line of code we tell the expect program to run a program! +# The program to run is `echo`. +# The echo program will display text to the shell, in this case +# that is "Hello World from TCL/Expect!" +spawn echo "Hello World from TCL/Expect!" + +# This next command `expect` (which is the same name as the program) +# will look at the shell and follow a command that you tell it to. +# We are looking to see the words "Hello world." and if we do +# then we output "Success!" to the shell and exit with the +# value 0. +# If we don't see the words "Hello world." then we will output +# "Error!" and exit with the value 1. +expect { + "Hello world from." { + puts "Success!" + exit 0 + } + default { + puts "Error!" + exit 1 + } +} diff --git a/templates-code/T1/step-3-version-control-101/download-repository.tcl.m4 b/templates-code/T1/step-3-version-control-101/download-repository.tcl.m4 new file mode 100644 index 0000000..6638dc8 --- /dev/null +++ b/templates-code/T1/step-3-version-control-101/download-repository.tcl.m4 @@ -0,0 +1,64 @@ +#!/usr/bin/env expect + +__code_license_header_hash_style__ + +# package require platform + +# create a repository folder in your documents directory +# If using Cygwin +switch $::tcl_platform(os) { + CYGWIN_NT-10.0 { + set homeDirectory $env(HOMEDRIVE)$env(HOMEPATH) + } + default { + set homeDirectory ~/ + } +} + +# make directory Documents/Code/ +# change to +set dir [file join $homeDirectory Documents\\Code\\] + +if {[file exists $dir]} { + puts "Directory exists!" +} else { + file mkdir $dir +} + +cd $dir +puts [pwd] + +# dangerous command to clear out the directory before download +if {[file exists SERC-Pitt-C-Programming-Tutorial]} { + puts "Do you want to clear out the directory first? (Y/N)" + gets stdin someVar + + if {[string match Y $someVar]} { + exec rm -rf SERC-Pitt-C-Programming-Tutorial + } +} + +if { [catch { spawn git clone https://github.com/betsalel-williamson/C-Programming-Tutorial.git } msg] } { + puts "Something seems to have gone wrong:" + puts "Information about it: $::errorInfo" +} + +expect { + eof { + puts "Finished downloading." + } +} + +puts [spawn ls -la SERC-Pitt-C-Programming-Tutorial] + +expect { + eof { + puts "Finished listing directory." + } +} +# git clone + +## make change to file +## git add change +## git commit with comment +## git revert commit diff --git a/templates-code/T1/step-3-version-control-101/hello-world.tcl.m4 b/templates-code/T1/step-3-version-control-101/hello-world.tcl.m4 new file mode 100755 index 0000000..24befcb --- /dev/null +++ b/templates-code/T1/step-3-version-control-101/hello-world.tcl.m4 @@ -0,0 +1,49 @@ +#!/usr/bin/env expect +# This first line is called a shebang (pronounced Sha-Bang) and +# will tell the shell what program to use for the following text. + +__code_license_header_hash_style__ + +# Our first line of code we tell the expect program to run a program! +# The program to run is `echo`. +# The echo program will display text to the shell, in this case +# that is "Hello World from TCL/Expect!" +spawn echo "Hello World from TCL/Expect!" + +# This next command `expect` (which is the same name as the program) +# will look at the shell and follow a command that you tell it to. +# We are looking to see the words "Hello world." and if we do +# then we output "Success!" to the shell and exit with the +# value 0. +# If we don't see the words "Hello world." then we will output +# "Error!" and exit with the value 1. +expect { + "Hello world from." { + puts "Success!" + exit 0 + } + default { + puts "Error!" + exit 1 + } +} + +# What can we do to make this command exit with success? +# There are multiple ways to go about this. +# Method one, is to simply change the text in the expect +# command from "Hello world." to "Hello World!" +# Method two is to change the text to be more flexible +# and replace "Hello world." with the text between the +# `` characters `-nocase "hello world"`. + +# Method two: +# expect { +# -nocase "hello world" { +# puts "Success!" +# exit 0 +# } +# default { +# puts "Error!" +# exit 1 +# } +# } diff --git a/templates-code/T1/step-4-hello-world/1-Hello-World/main.c.m4 b/templates-code/T1/step-4-hello-world/1-Hello-World/main.c.m4 new file mode 100644 index 0000000..bfc0330 --- /dev/null +++ b/templates-code/T1/step-4-hello-world/1-Hello-World/main.c.m4 @@ -0,0 +1,60 @@ +/* + * Welcome to your first program in C. This program will output "Hello World" to + * the shell when run. + * + * In this program you will see code, and comments about the code. + * + * Multi-line comments are text written between a leading `/*` and ending with + * the reverse. + * + * Single line comments are written after double forward slashes `//` + */ + +__code_license_header_c__ + +int main ( ) { + + // Programming language of C requires a function named `main` that returns + // an integer value. The reason for needing `main` is because the compiler + // that converts this program needs to know where to start. + // + // The reason for returning an integer or `int` is for you to report back to + // the person running the program how things went. It is the adopted + // practice to use the value 0 when all has gone well and to use other + // values to indicate that something went wrong. + // + // We will leave the ( ) blank for now and will come back to this later. C + // does not care about the white space or number of spaces between different + // lines of code. + // + // We could have written it like () or ( ). + // + // Finally, the code that we want this function to have is between the curly + // braces { } . The code between these two braces is also called a block of + // code. + + write( 1, "Hello World", 12 ); + + // The second function in this program will print the words Hello World to + // the shell. This function is called an implicitly declared function + // because we did not write where it comes from. + // There are a selection of implicit functions that C knows about. We will + // therefore ignore the warning with the `-w` option when we compile. + // + // This function takes 3 arguments: + // `1` - indicates that we would like to write to Standard Out or the main + // shell (in contrast with standard error, used when we output errors + // to the shell) + // `"Hello World"` - is the information that we want to print to the shell + // `12` - is the size of the information in bytes we want to print, or in + // other words the number of letters between the quotes + + // In C, all lines of code must end with the `;` character. One of the + // biggest issues that people run into during their first program is not + // paying attention to this detail and turning away in frustration. + + // Finally, the `return` keyword will tell the function that are finished + // and would like to indicate our program ran successfully by returning the + // value of 0. + return 0; +} diff --git a/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c.m4 similarity index 98% rename from T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c rename to templates-code/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c.m4 index c3ef0da..d06ef2c 100644 --- a/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c +++ b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/main-fixed.c.m4 @@ -6,6 +6,8 @@ * */ +__code_license_header_c__ + int main ( int argc, const char* argv[] ) { // argc is the number of arguments passed into the program diff --git a/T1/step-4-hello-world/2-Test-Hello-World/main.c b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/main.c.m4 similarity index 90% rename from T1/step-4-hello-world/2-Test-Hello-World/main.c rename to templates-code/T1/step-4-hello-world/2-Test-Hello-World/main.c.m4 index 880d2b5..3b07612 100644 --- a/T1/step-4-hello-world/2-Test-Hello-World/main.c +++ b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/main.c.m4 @@ -1,3 +1,5 @@ +__code_license_header_c__ + int main ( int argc, const char* argv[] ) { int exit_value = -1; diff --git a/T1/step-4-hello-world/2-Test-Hello-World/test.tcl b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/test.tcl.m4 similarity index 93% rename from T1/step-4-hello-world/2-Test-Hello-World/test.tcl rename to templates-code/T1/step-4-hello-world/2-Test-Hello-World/test.tcl.m4 index 817f9c3..6afbea9 100644 --- a/T1/step-4-hello-world/2-Test-Hello-World/test.tcl +++ b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/test.tcl.m4 @@ -1,5 +1,7 @@ #!/bin/env expect +__code_license_header_hash_style__ + # delete the executable file exec rm main # compile the file @@ -54,4 +56,4 @@ if {[lindex $result 3] == 1} { # with more than 1 parameter? # $ ./main Hello World # Hello world must be in quotes in order for this -# to be considered a single parameter \ No newline at end of file +# to be considered a single parameter diff --git a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c.m4 b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c.m4 new file mode 100644 index 0000000..82deef6 --- /dev/null +++ b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/main-fixed.c.m4 @@ -0,0 +1,60 @@ +/* + * Welcome to your second program in C. + * + * In this program you will modify the code from your first program + * to accept a parameter or argument as input from the Shell. + * + */ + +__code_license_header_c__ + +#include + +int main ( int argc, const char* argv[] ) { + + // argc is the number of arguments passed into the program + // argv is the array (think a list) of arguments + // We access the items in the array by putting a number between + // the square brackets. In C, we call this number an index. + // This is very important because indexes will always start + // with 0. You can think of this in terms of number types. + // In math, the natural numbers start with 1 and increase. + // Indexes start at 0 and will increase until the number of + // items in the array minus 1. + int exit_value; + + // ensure the correct number of parameters are used. + if ( argc == 2 ) + { + int i = 0; // declare a variable to count the length + // of the text passed in as an argument + + // In C, all text ends with the character '\0'. + // To get the length of the text, or string, we + // start at the first index + while( argv[1][i] != '\0' ) { + i = i + 1; + } + + write( 1, argv[1], i ); + + // What do you think the zeroth item or element + // in argv is? + + // i = 0; // reset i to be 0 + + // while(argv[0][i] != '\0') { + // i = i+1; + // } + + // write(1, argv[0], i); + + exit_value = 0; + } else { + // if the incorrect number of parameters are used + // then report that there was an error + exit_value = 1; + } + + return exit_value; +} diff --git a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/main.c.m4 b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/main.c.m4 new file mode 100644 index 0000000..f9134c0 --- /dev/null +++ b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/main.c.m4 @@ -0,0 +1,58 @@ +/* + * Welcome to your second program in C. + * + * In this program you will modify the code from your first program + * to accept a parameter or argument as input from the Shell. + * + */ + +__code_license_header_c__ + +int main ( int argc, const char* argv[] ) { + + // argc is the number of arguments passed into the program + // argv is the array (think a list) of arguments + // We access the items in the array by putting a number between + // the square brackets. In C, we call this number an index. + // This is very important because indexes will always start + // with 0. You can think of this in terms of number types. + // In math, the natural numbers start with 1 and increase. + // Indexes start at 0 and will increase until the number of + // items in the array minus 1. + int exit_value; + + // ensure the correct number of parameters are used. + if ( argc == 2 ) + { + int i = 0; // declare a variable to count the length + // of the text passed in as an argument + + // In C, all text ends with the character '\0'. + // To get the length of the text, or string, we + // start at the first index + while( argv[1][i] != '\0' ) { + i = i + 1; + } + + write( 1, argv[1], i ); + + // What do you think the zeroth item or element + // in argv is? + + // i = 0; // reset i to be 0 + + // while(argv[0][i] != '\0') { + // i = i+1; + // } + + // write(1, argv[0], i); + + exit_value = 0; + } else { + // if the incorrect number of parameters are used + // then report that there was an error + exit_value = 1; + } + + return exit_value; +} diff --git a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/makefile.m4 b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/makefile.m4 new file mode 100644 index 0000000..c2b460d --- /dev/null +++ b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/makefile.m4 @@ -0,0 +1,24 @@ +__code_license_header_hash_style__ + +CC = gcc +SRCS = main.c +OBJS = $(subst .c,.o,$(SRCS)) +CFLAGS = -Wall -Werror -Wextra +RM = rm -f + +all: main +debug: $(eval CFLAGS := -g -DDBUG) +debug: main + +main: $(OBJS) + $(CC) -o main $(OBJS) $(CFLAGS) + +main.o: main.c + +# We don't glob because this doesn't scale for +# large projects +# %.o: %.c $(DEPS) +# $(CC) -g -c -o $@ $< $(CFLAGS) + +clean: + $(RM) $(OBJS) main diff --git a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl.m4 b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl.m4 new file mode 100644 index 0000000..2762bba --- /dev/null +++ b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl.m4 @@ -0,0 +1,59 @@ +#!/bin/env expect + +__code_license_header_hash_style__ + +# delete the old executable and object files +exec make clean +# compile the file +exec make + +### Test 1 ### +# +# Given that we provide a single text input to our program, +# When we run it, +# Then the program will print the text to the Shell +# and exits with the value 0 +# + +spawn ./main "Hello World" +expect { + -nocase "hello world" { + puts "\nFound output of: Hello World\n" + } + default { + puts "\nTest failed. Expected Hello world\n" + } +} + +expect eof +catch wait result +if {[lindex $result 3] == 0} { + puts "Exited successfully.\n" +} else { + puts "Test failed with code [lindex $result 3].\n" +} + +### Test 2 ### +# +# Given that we don't provide a single text input to our +# program, +# When we run it, +# Then the program exits without printing the input and +# has the value 1 +# + +spawn ./main +expect eof +catch wait result + +if {[lindex $result 3] == 1} { + puts "Exited successfully.\n" +} else { + puts "Test failed with code [lindex $result 3].\n" +} + +# What happens when we try calling main +# with more than 1 parameter? +# $ ./main Hello World +# Hello world must be in quotes in order for this +# to be considered a single parameter diff --git a/templates-code/T2/step-1-code-gen/.gitignore.m4 b/templates-code/T2/step-1-code-gen/.gitignore.m4 new file mode 100644 index 0000000..2d428a4 --- /dev/null +++ b/templates-code/T2/step-1-code-gen/.gitignore.m4 @@ -0,0 +1,7 @@ +__code_license_header_hash_style__ + +debug/ +release/ +*.o +*.orig +*.stackdump diff --git a/templates-code/T2/step-1-code-gen/lib.c.m4 b/templates-code/T2/step-1-code-gen/lib.c.m4 new file mode 100644 index 0000000..fa45d7e --- /dev/null +++ b/templates-code/T2/step-1-code-gen/lib.c.m4 @@ -0,0 +1,95 @@ +__code_license_header_c__ + +#include "lib.h" + +int generateSecretCode( char * secret_key ) { + LOG_DEBUG( "Secret Key %s", secret_key ); + int secret_code = 0; + // for more info on this time functionality look atUpdated + // https://www.tutorialspoint.com/c_standard_library/time_h.htm + time_t my_time; + time ( &my_time ); + struct tm * time_info = localtime ( &my_time ); + LOG_DEBUG( "year->%d", time_info->tm_year + 1900 ); + LOG_DEBUG( "month->%d", time_info->tm_mon + 1 ); + LOG_DEBUG( "date->%d", time_info->tm_mday ); + LOG_DEBUG( "hour->%d", time_info->tm_hour ); + LOG_DEBUG( "minutes->%d", time_info->tm_min ); + LOG_DEBUG( "seconds->%d", time_info->tm_sec ); + int second_info = ( time_info->tm_sec / 20 ); + LOG_DEBUG( "seconds divide: %d", second_info ); + // this will demonstrate bit-wise operations + secret_code ^= time_info->tm_min << ( 'b' & 0b11 ); + secret_code ^= 1214 << ( 'h' & 0b11 ) ; + secret_code >>= ( 'w' & 0b11 ); + secret_code ^= second_info << ( '7' & 0b11 ); + + unsigned long i; + + for ( i = 0; i < strlen( secret_key ); i++ ) + { + secret_code = secret_key[i] ^ secret_code; + } + + secret_code &= 0b11111111; + + LOG_DEBUG( "secret_code %d", secret_code ); + return secret_code; +} + +void processInputArguments( int argc, char* const argv[], + char **user_input_attempt_s, char ** user_input_override_s ) { + static struct option long_options[] = + { + /* These options set a flag. */ + // each one of these lines is an option struct + /* These options don’t set a flag. + We distinguish them by their indices. */ + // required_argument is a macro in the getopts.h + {"code", required_argument, 0, 'c'}, + {"force", required_argument, 0, 'f'} + }; + /* getopt_long stores the option index here. */ + int option_index = 0; + + /* value to hold the short argument returned by getopt_long */ + int c; + + /* Detect the end of the options. */ + while ( ( c = getopt_long ( argc, argv, "c:f:", long_options, + &option_index ) ) != -1 ) + { + switch ( c ) + { + case 'c': + LOG_DEBUG ( "option -c with value `%s'\n", optarg ); + *user_input_attempt_s = optarg; + break; + + case 'f': + LOG_DEBUG ( "option -f with value `%s'\n", optarg ); + *user_input_override_s = optarg; + break; + + case '?': + LOG_DEBUG ( "unknown with value `%s'\n", optarg ); + break; + + default: + LOG_DEBUG ( "In default with value `%c'\n", c ); + } + } + + /* Print any remaining command line arguments (not options). */ + if ( optind < argc ) + { + LOG_DEBUG ( "non-option ARGV-elements: " ); + + while ( optind < argc ) + { LOG_DEBUG ( "%s ", argv[optind++] ); } + + LOG_DEBUG ( "\n" ); + } + + return; +} diff --git a/templates-code/T2/step-1-code-gen/lib.h.m4 b/templates-code/T2/step-1-code-gen/lib.h.m4 new file mode 100644 index 0000000..1216679 --- /dev/null +++ b/templates-code/T2/step-1-code-gen/lib.h.m4 @@ -0,0 +1,32 @@ +__code_license_header_c__ + +// basic C functions including write, and printf +#include +// includes the exit function along with others +#include +// some basic operations working with ASCII text +#include +// for processInputArguments +#include +// for use with getting the time +#include +// use a logger instead of printf everywhere to +// save you from printing everything in release mode +#include "macrologger.h" + +// note the style of UPPER_CASE_SNAKE_CASE, or SCREAMING_SNAKE +// this is to indicate that this is a macro, +// note that sometimes lower_case_snake is also used +// this is a style convention +#define STRING_NOT_SET NULL +#define INT_NOT_SET -1 +#define CORRECT_CODE EXIT_SUCCESS +#define INCORRECT_CODE EXIT_FAILURE +#define INVALID_USER_INPUT 2 +#define EXIT_CODE_NOT_SET -1 +#define ATOI_NO_NUMBER_CODE 0 + +// in a header file we declare functions in the corresponding .c file +int generateSecretCode( char * secret_key ); +void processInputArguments( int argc, char* const argv[], + char **user_input_attempt_s, char ** user_input_override_s ); diff --git a/templates-code/T2/step-1-code-gen/macrologger.h.m4 b/templates-code/T2/step-1-code-gen/macrologger.h.m4 new file mode 100644 index 0000000..f53fa49 --- /dev/null +++ b/templates-code/T2/step-1-code-gen/macrologger.h.m4 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2012 David Rodrigues + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __MACROLOGGER_H__ +#define __MACROLOGGER_H__ + +#ifdef __OBJC__ +#import +#else +#include +#include +#endif + +// === auxiliar functions +static inline char *timenow(); + +#define _FILE strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__ + +#define NO_LOG 0x00 +#define ERROR_LEVEL 0x01 +#define INFO_LEVEL 0x02 +#define DEBUG_LEVEL 0x03 + +#ifndef LOG_LEVEL +#define LOG_LEVEL DEBUG_LEVEL +#endif + +#ifdef __OBJC__ + +#if __has_feature(objc_arc) +#define AUTORELEASEPOOL_BEGIN @autoreleasepool { +#define AUTORELEASEPOOL_END } +#define RELEASE(OBJ) OBJ = nil +#else +#define AUTORELEASEPOOL_BEGIN NSAutoreleasePool *_pool = [[NSAutoreleasePool alloc] init]; +#define AUTORELEASEPOOL_END [_pool release]; +#define RELEASE(OBJ) [OBJ release]; +#endif + +#define PRINTFUNCTION(format, ...) objc_print(@format, __VA_ARGS__) +#else +#define PRINTFUNCTION(format, ...) fprintf(stderr, format, __VA_ARGS__) + +#endif + +#define LOG_FMT "%s | %-7s | %-15s | %s:%d | " +#define LOG_ARGS(LOG_TAG) timenow(), LOG_TAG, _FILE, __FUNCTION__, __LINE__ + +#define NEWLINE "\n" + +#define ERROR_TAG "ERROR" +#define INFO_TAG "INFO" +#define DEBUG_TAG "DEBUG" + +#if LOG_LEVEL >= DEBUG_LEVEL +#define LOG_DEBUG(message, args...) PRINTFUNCTION(LOG_FMT message NEWLINE, LOG_ARGS(DEBUG_TAG), ## args) +#else +#define LOG_DEBUG(message, args...) +#endif + +#if LOG_LEVEL >= INFO_LEVEL +#define LOG_INFO(message, args...) PRINTFUNCTION(LOG_FMT message NEWLINE, LOG_ARGS(INFO_TAG), ## args) +#else +#define LOG_INFO(message, args...) +#endif + +#if LOG_LEVEL >= ERROR_LEVEL +#define LOG_ERROR(message, args...) PRINTFUNCTION(LOG_FMT message NEWLINE, LOG_ARGS(ERROR_TAG), ## args) +#else +#define LOG_ERROR(message, args...) +#endif + +#if LOG_LEVEL >= NO_LOGS +#define LOG_IF_ERROR(condition, message, args...) if (condition) PRINTFUNCTION(LOG_FMT message NEWLINE, LOG_ARGS(ERROR_TAG), ## args) +#else +#define LOG_IF_ERROR(condition, message, args...) +#endif + +static inline char *timenow() { + static char buffer[64]; + time_t rawtime; + struct tm *timeinfo; + time( &rawtime ); + timeinfo = localtime( &rawtime ); + strftime( buffer, 64, "%Y-%m-%d %H:%M:%S", timeinfo ); + return buffer; +} + +#ifdef __OBJC__ + +static inline void objc_print( NSString *format, ... ) { + AUTORELEASEPOOL_BEGIN + va_list args; + va_start( args, format ); + NSString *logStr = [[NSString alloc] initWithFormat:format arguments:args]; + fprintf( stderr, "%s", [logStr UTF8String] ); + RELEASE( logStr ); + va_end( args ); + AUTORELEASEPOOL_END +} + +#endif + +#endif diff --git a/templates-code/T2/step-1-code-gen/main.c.m4 b/templates-code/T2/step-1-code-gen/main.c.m4 new file mode 100644 index 0000000..f4bbbc0 --- /dev/null +++ b/templates-code/T2/step-1-code-gen/main.c.m4 @@ -0,0 +1,48 @@ +/* Simple program to demonstrate c */ + +__code_license_header_c__ + +#include "lib.h" + +int main ( int argc, char* const argv[] ) { + int exit_code = EXIT_CODE_NOT_SET; + char *user_input_attempt_s = STRING_NOT_SET; + char *user_input_override_s = STRING_NOT_SET; + + processInputArguments( argc, argv, &user_input_attempt_s, + &user_input_override_s ); + + if( user_input_attempt_s == STRING_NOT_SET ) { + LOG_ERROR( "%s", "You must pass in a code. (e.g.'./main -c 1234') ." ); + abort(); + } + + LOG_DEBUG( "Found code %s", user_input_attempt_s ); + LOG_DEBUG( "We will set our magic sting!" ); + int secret_code = INT_NOT_SET; + + if( user_input_override_s == STRING_NOT_SET ) { + secret_code = generateSecretCode( "1214 Benedum" ); + } else { + printf( "Used Override!!\n" ); + secret_code = atoi( user_input_override_s ); + } + + int input = atoi( user_input_attempt_s ); + + if( input == 0 ) { + LOG_ERROR( "Invalid input: %s", user_input_attempt_s ); + exit_code = INVALID_USER_INPUT; + + } else if ( input == secret_code ) { + exit_code = EXIT_SUCCESS; + printf( "Congrats! You entered in the right code!\n" ); + + } else { + LOG_ERROR( "Your attempt %d was incorrect. Try again.\n", input ); + exit_code = INCORRECT_CODE; + } + + exit ( exit_code ); +} + diff --git a/templates-code/T2/step-1-code-gen/makefile.m4 b/templates-code/T2/step-1-code-gen/makefile.m4 new file mode 100644 index 0000000..1e4d03e --- /dev/null +++ b/templates-code/T2/step-1-code-gen/makefile.m4 @@ -0,0 +1,69 @@ +__code_license_header_hash_style__ + +# https://stackoverflow.com/questions/1079832/how-can-i-configure-my-makefile-for-debug-and-release-builds#1080180 +# Author: ffhaddad , https://stackoverflow.com/users/1952377/ffhaddad +# Compiler flags +# +CC = gcc +CFLAGS = -Wall -Werror -Wextra + +# +# Project files +# +SRCS = main.c lib.c +OBJS = $(SRCS:.c=.o) +EXE = secretPassword + +# +# Debug build settings +# +DBGDIR = debug +DBGEXE = $(DBGDIR)/$(EXE) +DBGOBJS = $(addprefix $(DBGDIR)/, $(OBJS)) +DBGCFLAGS = -g -O0 -DDEBUG + +# +# Release build settings +# +RELDIR = release +RELEXE = $(RELDIR)/$(EXE) +RELOBJS = $(addprefix $(RELDIR)/, $(OBJS)) +RELCFLAGS = -O3 -DNDEBUG -D LOG_LEVEL=0 + +.PHONY: all clean debug prep release remake + +# Default build +all: prep release + +# +# Debug rules +# +debug: $(DBGEXE) + +$(DBGEXE): $(DBGOBJS) + $(CC) $(CFLAGS) $(DBGCFLAGS) -o $(DBGEXE) $^ + +$(DBGDIR)/%.o: %.c + $(CC) -c $(CFLAGS) $(DBGCFLAGS) -o $@ $< + +# +# Release rules +# +release: $(RELEXE) + +$(RELEXE): $(RELOBJS) + $(CC) $(CFLAGS) $(RELCFLAGS) -o $(RELEXE) $^ + +$(RELDIR)/%.o: %.c + $(CC) -c $(CFLAGS) $(RELCFLAGS) -o $@ $< + +# +# Other rules +# +prep: + mkdir -p $(DBGDIR) $(RELDIR) + +remake: clean all + +clean: + rm -f $(RELEXE) $(RELOBJS) $(DBGEXE) $(DBGOBJS) diff --git a/templates-code/T2/step-1-code-gen/test.tcl.m4 b/templates-code/T2/step-1-code-gen/test.tcl.m4 new file mode 100644 index 0000000..215f0d2 --- /dev/null +++ b/templates-code/T2/step-1-code-gen/test.tcl.m4 @@ -0,0 +1,88 @@ +#!/usr/bin/env expect + +__code_license_header_hash_style__ + +proc testMustProvideCode args { + + spawn ./debug/secretPassword -f "Hello World" + expect { + -nocase "you must pass in a code" { + puts "\n[lindex [info level 0] 0] passed\n" + } + default { + puts "\n!! [lindex [info level 0] 0] test failed !!\n" + exit 1 + } + } +} + +proc testProvidedCode args { + + spawn ./debug/secretPassword -c 1234 + expect { + -nocase "Found code 1234" { + puts "\n[lindex [info level 0] 0] passed\n" + } + default { + puts "\n!! [lindex [info level 0] 0] test failed !!\n" + exit 1 + } + } +} + +proc testProvidedInvalideCode args { + + spawn ./debug/secretPassword -c 1234 + expect { + -nocase "was incorrect. Try again." { + puts "\n[lindex [info level 0] 0] passed\n" + } + default { + puts "\n!! [lindex [info level 0] 0] test failed !!\n" + exit 1 + } + } +} + +proc testForceCode args { + + spawn ./debug/secretPassword -c 1234 -f 1234 + expect { + -nocase "Congrats! You entered in the right code!" { + puts "\n[lindex [info level 0] 0] passed\n" + } + default { + puts "\n!! [lindex [info level 0] 0] test failed !!\n" + exit 1 + } + } +} + +proc testInvalidInput args { + + spawn ./debug/secretPassword -c foo -f 1234 + expect { + -nocase "Invalid input" { + puts "\n[lindex [info level 0] 0] passed\n" + } + default { + puts "\n!! [lindex [info level 0] 0] test failed !!\n" + exit 1 + } + } +} + +if {[catch {exec make debug} result] == 0} { + testMustProvideCode + testProvidedCode + testProvidedInvalideCode + testInvalidInput + testForceCode + + puts "\n\nAll tests passed\n\n" +} else { + puts "Error: $result" + exit 1 +} + + diff --git a/templates-code/T2/step-1-pointers/.gitignore.m4 b/templates-code/T2/step-1-pointers/.gitignore.m4 new file mode 100644 index 0000000..ea18294 --- /dev/null +++ b/templates-code/T2/step-1-pointers/.gitignore.m4 @@ -0,0 +1,5 @@ +__code_license_header_hash_style__ + +main +*.orig +*.o diff --git a/templates-code/T2/step-1-pointers/main.c.m4 b/templates-code/T2/step-1-pointers/main.c.m4 new file mode 100644 index 0000000..4382fa6 --- /dev/null +++ b/templates-code/T2/step-1-pointers/main.c.m4 @@ -0,0 +1,120 @@ +/* Simple program to demonstrate pointers and arrays */ + +__code_license_header_c__ + +#include +#include + +void myPointerFunction( int * pointer, int value ) { + *pointer = value; +} + +void myPointerToPointerFunction( char ** pointer_to_pointer, char* c_string ) { + *pointer_to_pointer = c_string; +} + +int main ( ) { + + // declare my c_string, or my pointer to point to the text "foo" + char *c_string = "foo"; + // will print the letter 'f' + printf( "%-35s%c\n", "First letter of c_string:", c_string[0] ); + // note we need a length of one more than the word we enter + char c_string_with_array[4]; + // we use index counting numbers that start from 0 and go until length minus 1 + c_string_with_array[0] = 'f'; + c_string_with_array[1] = 'o'; + c_string_with_array[2] = 'o'; + c_string_with_array[3] = '\0'; + // will print the letter 'f' + printf( "%-35s%c\n", "First letter, string as array:", c_string_with_array[0] ); + // will print the letter 'f' + printf( "%-35s%c\n", "First letter, pointer access:", *c_string_with_array ); + + // with the cubby example + // each variable will be assigned a cubby spot + int x = 1234; + // Look up the different print codes online for + printf( "%-35s%d\n", "Information in cubby:", x ); + // more detail. In short we tell `printf` how we want to display + // the variable `x` + + // We store the information `x` in a cubby. + // If we want to find out where that `x` was stored and get the + // cubby number we will dereference `x` with the `&` operator + // %x will print the cubby number or memory address using hex values. + printf( "%-35s%x\n", "Address of information:", &x ); + + long cubby_number_of_x_as_long = ( long ) &x; + // %x will print the cubby number or memory + printf( "%-35s%x\n", "Cubby number in long variable:", + cubby_number_of_x_as_long ); + + // we now declare a pointer + int* pointer = ( int* ) cubby_number_of_x_as_long; + // This variable will hold the cubby number of `x`. + printf( "%-35s%d\n", "Cubby number as a pointer:", *pointer ); + printf( "%-35s%x\n", "Cubby number of pointer:", &pointer ); + printf( "%-35s%x\n", "Cubby number of x:", pointer ); + // to see the information stored in the cubby + // we use the pointer operator `*` to access that information + // You must only use the `*` operator with a pointer or array + + // We can't use a `*x` because the `x` variable is not a pointer. + // If we want to use `*`, we must declare a pointer. + // error: invalid type argument of unary '*' (have 'int') + // printf("%u\n", *x); + + int array[2]; + *array = x; // same as array[0] = x; + *( array + 1 ) = 4321; // same as array[1] = 4321; + + printf( "%-35s%d\n", "Array index 0 with pointer access:", *array ); + // to see the information stored in the cubby + printf( "%-35s%d\n", "Array index 0 with array access:", array[0] ); + // to see the information stored in the cubby + printf( "%-35s%x\n", "Address of index 0 (as hex):", array ); + printf( "%-35s%ld\n", "Address of index 0 (as long):", &( array[0] ) ); + + printf( "%-35s%d\n", "Array index 1 with pointer access:", *( array + 1 ) ); + // to see the information stored in the cubby + printf( "%-35s%d\n", "Array index 1 with array access:", array[1] ); + // to see the information stored in the cubby + printf( "%-35s%x\n", "Address of index 1 (as hex):", ( array + 1 ) ); + printf( "%-35s%ld\n", "Address of index 1 (as long):", &( array[1] ) ); + + printf( "%-35s%d\n", "Array index 2 with pointer access:", *( array + 2 ) ); + // You will be able to access this information + // but is not guarenteed to be filled with anything, it may be zero + // it may be some other information that was in memory + printf( "%-35s%d\n", "Array index 2 with array access:", array[2] ); + // to see the information stored in the cubby + + printf( "%-35s%d\n", "Array index 80 with pointer access:", *( array + 80 ) ); + // You will be able to access this information + // but is not guarenteed to be filled with anything, it may be zero + // it may be some other information that was in memory + printf( "%-35s%d\n", "Array index 80 with array access:", array[80] ); + // to see the information stored in the cubby + + // note that C will allow you to access and overwrite + // locations that you may not understand + // this technique is used by hackers to exploit buffer overruns + + // the following line make crash the program or currupt another program + myPointerFunction( ( array + 2 ), 1217 ); + printf( "%-35s%d\n", "After changeing index 2:", *( array + 2 ) ); + + myPointerFunction( &( array[80] ), 1214 ); + printf( "%-35s%d\n", "After changeing index 80:", *( array + 80 ) ); + + myPointerToPointerFunction( &c_string, "Benedum" ); + printf( "%-35s%s\n", "New c_string:", c_string ); + + // what happens if we try to change the c_string_with_array? + // because arrays are allocated at compile time there is no way to get past the initial length + myPointerToPointerFunction( ( char** )&c_string_with_array, "SERC" ); + printf( "%-35s%s\n", "New c_string_with_array:", c_string_with_array ); + + return EXIT_SUCCESS; +} diff --git a/templates-code/T2/step-1-pointers/makefile.m4 b/templates-code/T2/step-1-pointers/makefile.m4 new file mode 100644 index 0000000..c2b460d --- /dev/null +++ b/templates-code/T2/step-1-pointers/makefile.m4 @@ -0,0 +1,24 @@ +__code_license_header_hash_style__ + +CC = gcc +SRCS = main.c +OBJS = $(subst .c,.o,$(SRCS)) +CFLAGS = -Wall -Werror -Wextra +RM = rm -f + +all: main +debug: $(eval CFLAGS := -g -DDBUG) +debug: main + +main: $(OBJS) + $(CC) -o main $(OBJS) $(CFLAGS) + +main.o: main.c + +# We don't glob because this doesn't scale for +# large projects +# %.o: %.c $(DEPS) +# $(CC) -g -c -o $@ $< $(CFLAGS) + +clean: + $(RM) $(OBJS) main diff --git a/templates-code/T2/step-2-brute-force/.gitignore.m4 b/templates-code/T2/step-2-brute-force/.gitignore.m4 new file mode 100644 index 0000000..ea18294 --- /dev/null +++ b/templates-code/T2/step-2-brute-force/.gitignore.m4 @@ -0,0 +1,5 @@ +__code_license_header_hash_style__ + +main +*.orig +*.o diff --git a/templates-code/T2/step-2-brute-force/main.c.m4 b/templates-code/T2/step-2-brute-force/main.c.m4 new file mode 100644 index 0000000..363fa93 --- /dev/null +++ b/templates-code/T2/step-2-brute-force/main.c.m4 @@ -0,0 +1,35 @@ +/* Trivial way to crack the code */ + +__code_license_header_c__ + +#include +#include + +int main ( ) { + + char str[80]; + char* debug_location = "./../step-1-code-gen/debug/"; + char* location = "./../step-1-code-gen/release/"; + char* exe_name = "secretPassword"; + char* args = "-c"; + + int i = 1; + + do { + sprintf( str, "%s%s %s %d", location, exe_name, args, i ); + int exit_code = system( str ); + + if ( exit_code == 0 ) { + printf( "The code is %d\n", i ); + + sprintf( str, "%s%s %s %d", debug_location, exe_name, args, i ); + int exit_code = system( str ); + + break; + } + + i++; + } while( i < 1000 ); + + exit( EXIT_SUCCESS ); +} diff --git a/templates-code/T2/step-2-brute-force/makefile.m4 b/templates-code/T2/step-2-brute-force/makefile.m4 new file mode 100644 index 0000000..c2b460d --- /dev/null +++ b/templates-code/T2/step-2-brute-force/makefile.m4 @@ -0,0 +1,24 @@ +__code_license_header_hash_style__ + +CC = gcc +SRCS = main.c +OBJS = $(subst .c,.o,$(SRCS)) +CFLAGS = -Wall -Werror -Wextra +RM = rm -f + +all: main +debug: $(eval CFLAGS := -g -DDBUG) +debug: main + +main: $(OBJS) + $(CC) -o main $(OBJS) $(CFLAGS) + +main.o: main.c + +# We don't glob because this doesn't scale for +# large projects +# %.o: %.c $(DEPS) +# $(CC) -g -c -o $@ $< $(CFLAGS) + +clean: + $(RM) $(OBJS) main diff --git a/test.tcl b/templates-code/test.tcl.m4 similarity index 96% rename from test.tcl rename to templates-code/test.tcl.m4 index 127491a..469aad3 100755 --- a/test.tcl +++ b/templates-code/test.tcl.m4 @@ -1,7 +1,8 @@ #!/usr/bin/env expect # Test the tutorial +# run from the 'src' directory -# run from the base directory +__code_license_header_hash_style__ # format code astyle "./*.c" "./*.h" \ diff --git a/Generate-Wiki/Home.md.m4 b/templates-wiki/Home.md.m4 similarity index 100% rename from Generate-Wiki/Home.md.m4 rename to templates-wiki/Home.md.m4 diff --git a/Generate-Wiki/Tutorial 1/T1-00.md.m4 b/templates-wiki/Tutorial 1/T1-00.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 1/T1-00.md.m4 rename to templates-wiki/Tutorial 1/T1-00.md.m4 diff --git a/Generate-Wiki/Tutorial 1/T1-01.md.m4 b/templates-wiki/Tutorial 1/T1-01.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 1/T1-01.md.m4 rename to templates-wiki/Tutorial 1/T1-01.md.m4 diff --git a/Generate-Wiki/Tutorial 1/T1-02.md.m4 b/templates-wiki/Tutorial 1/T1-02.md.m4 similarity index 96% rename from Generate-Wiki/Tutorial 1/T1-02.md.m4 rename to templates-wiki/Tutorial 1/T1-02.md.m4 index fc6a60a..f9a1736 100644 --- a/Generate-Wiki/Tutorial 1/T1-02.md.m4 +++ b/templates-wiki/Tutorial 1/T1-02.md.m4 @@ -78,7 +78,7 @@ We will output "Hello from TCL!" and use TCL/Expect to verify this from the term ``` 1. Open the file `hello-world.tcl` in a plain text editor (Notepad, Sublime, Nano, etc.) and copy-paste the following. Again, it is very important to keep the white space exactly as is shown in the code: ``` -esyscmd({{sed -n 24,33p ../T1/step-2-command-line-101/hello-world.tcl | sed 's/^/ /g' | ghead -c -1}}) +esyscmd({{sed -n 24,33p ../src/T1/step-2-command-line-101/hello-world.tcl | sed 's/^/ /g' | ghead -c -1}}) ``` 1. To run this program open up a shell and change directories to the saved file. To do this you should type: ``` @@ -92,7 +92,7 @@ esyscmd({{sed -n 24,33p ../T1/step-2-command-line-101/hello-world.tcl | sed 's/^ You should see the following displayed on your command line screen: ``` -$ esyscmd({{../T1/step-2-command-line-101/hello-world.tcl | sed -n 1,3p | ghead -c -1}}) +$ esyscmd({{expect ../src/T1/step-2-command-line-101/hello-world.tcl | sed -n 1,3p | ghead -c -1}}) ``` ## Troubleshooting Errors @@ -110,7 +110,7 @@ If it doesn't see the text after a default amount of time, then print that we ha What can we do to modify the program to have the following output without changing the code on the line with `"Error!"` to `"Success!"` (change what Expect is expecting)? ``` -$ esyscmd({{../T1/step-2-command-line-101/hello-world-fixed.tcl | ghead -c -1}}) +$ esyscmd({{expect ../src/T1/step-2-command-line-101/hello-world-fixed.tcl | ghead -c -1}}) ``` ## Summary diff --git a/Generate-Wiki/Tutorial 1/T1-04.md.m4 b/templates-wiki/Tutorial 1/T1-04.md.m4 similarity index 82% rename from Generate-Wiki/Tutorial 1/T1-04.md.m4 rename to templates-wiki/Tutorial 1/T1-04.md.m4 index 38787f9..f01e77f 100644 --- a/Generate-Wiki/Tutorial 1/T1-04.md.m4 +++ b/templates-wiki/Tutorial 1/T1-04.md.m4 @@ -21,9 +21,10 @@ This step has the following parts: Create a file named `main.c` in the directory `tutorials/step-3-hello-world/1-Hello-World` and copy the following code to it. ```C -esyscmd({{sed -n '21p' ../T1/step-4-hello-world/1-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) -esyscmd({{sed -n '42p' ../T1/step-4-hello-world/1-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) -esyscmd({{sed -n '65,66p' ../T1/step-4-hello-world/1-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) +int main ( ) { + write( 1, "Hello World", 12 ); + return 0; +} ``` Open up a shell and change directories so that when you list the files you see the file `main.c`. Type the following command to compile your code: @@ -80,7 +81,7 @@ We can run these using the `exec` function in TCL and the programs `rm` and `gcc Next is the code to run our program `main`. For our first test we will `spawn` our program with the argument `"Hello World"`. We can use the `expect` command like in the first step to see that we output the text "Hello World". Finally, we get the exit code of our program with the following code: ```Tcl -esyscmd({{sed -n '26,32p' ../T1/step-4-hello-world/2-Test-Hello-World/test.tcl | sed 's/^/ /g' | ghead -c -1}}) +esyscmd({{sed -n '26,32p' ../src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl | sed 's/^/ /g' | ghead -c -1}}) ``` For our second test we only need to test that the exit code is 1. @@ -90,14 +91,14 @@ Once your tests are complete, see that when you run them that they both fail. If Here is a version of the `test.tcl` file you can base your code off of: ```Tcl -esyscmd({{sed -n '1,51p' ../T1/step-4-hello-world/2-Test-Hello-World/test.tcl | sed 's/^/ /g' | ghead -c -1}}) +esyscmd({{sed -n '9,57p' ../src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl | sed 's/^/ /g' | ghead -c -1}}) ``` Now that we have failing tests, we will now modify the main function to accept what is called an input argument and to output this to the Shell. Modify your `main.c` file with the following: ```C -esyscmd({{cat ../T1/step-4-hello-world/2-Test-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) +esyscmd({{sed -n '10,25p' ../src/T1/step-4-hello-world/2-Test-Hello-World/main.c | sed 's/^/ /g' | ghead -c -1}}) ``` We've left an error in the code for you to fix. Once it is correct, you should see that your tests now all pass! @@ -118,7 +119,9 @@ Next, we check with `if ( argc == 2 )` that we only have 2 arguments. __We'll co If we have two arguments, then we find the length of the text passed in with the following lines. First we create a variable to hold our place, then while the current character in the string passed in isn't the null character or `\0` (this is how C lets you know that you've reached the end of your string) we increment `i`: ```C -esyscmd({{sed -n '6,8p' ../T1/step-4-hello-world/2-Test-Hello-World/main.c | sed 's/^ / /g' | ghead -c -1}}) + while( argv[1][i] != '\0' ) { + i = i + 1; + } ``` Next we can output the string in `argv` to the Shell with `write(1, argv[1], i);`. @@ -141,33 +144,33 @@ Welcome to GNU make or the makefile! There is a scripting language called `makef ### Makefile introduction ```Makefile -esyscmd({{sed -n '7,28p' ../T1/step-4-hello-world/3-Makefile-Hello-World/makefile | sed 's/^ / /g' | ghead -c -1}}) +esyscmd({{sed -n '7,28p' ../src/T1/step-4-hello-world/3-Makefile-Hello-World/makefile | sed 's/^ / /g' | ghead -c -1}}) ``` Notice that we are now failing the build process as is shown: ``` $ make -esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && make clean > /dev/null 2>&1 && make > temp-output.log 2>&1 && popd > /dev/null 2>&1}})dnl -esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log && popd > /dev/null 2>&1}})dnl +esyscmd({{pushd ../src/T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && make clean > /dev/null 2>&1 && make > temp-output.log 2>&1 && popd > /dev/null 2>&1}})dnl +esyscmd({{pushd ../src/T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log && popd > /dev/null 2>&1}})dnl ``` Lets walk through this step by step: 1. `$ make` is the command we typed in the Shell -1. `esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '1p' | ghead -c -1 && popd > /dev/null 2>&1}})` is the command that make will run to compile our program +1. `esyscmd({{pushd ../src/T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '1p' | ghead -c -1 && popd > /dev/null 2>&1}})` is the command that make will run to compile our program 1. The following is a chunk that tells us there's something up with the `main` function. ``` -esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '2p' | sed 's/^/ /g' && popd > /dev/null 2>&1}})dnl +esyscmd({{pushd ../src/T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '2p' | sed 's/^/ /g' && popd > /dev/null 2>&1}})dnl ``` -pushdef({{__err_line_num__}}, {{esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /main[.]c:(\d+):\d+/' | tr -d '\n' && popd > /dev/null 2>&1}})}})dnl -pushdef({{__err_col_num__}}, {{esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /main[.]c:\d+:(\d+)/' | tr -d '\n' && popd > /dev/null 2>&1}})}})dnl +pushdef({{__err_line_num__}}, {{esyscmd({{pushd ../src/T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /main[.]c:(\d+):\d+/' | tr -d '\n' && popd > /dev/null 2>&1}})}})dnl +pushdef({{__err_col_num__}}, {{esyscmd({{pushd ../src/T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /main[.]c:\d+:(\d+)/' | tr -d '\n' && popd > /dev/null 2>&1}})}})dnl - The file that we need to look at is `main.c`, we then need to look at `esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /(main[.]c:\d+:\d+)/' | tr -d '\n' && popd > /dev/null 2>&1}})` that means the file `main.c`, line `{{}}__err_line_num__{{}}`, column `{{}}__err_col_num__{{}}`. + The file that we need to look at is `main.c`, we then need to look at `esyscmd({{pushd ../src/T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | perl -lane 'print /(main[.]c:\d+:\d+)/' | tr -d '\n' && popd > /dev/null 2>&1}})` that means the file `main.c`, line `{{}}__err_line_num__{{}}`, column `{{}}__err_col_num__{{}}`. `implicit declaration of function 'write'` means that it found a function that we didn't explicitly tell the compiler where to find it. System functions like `printf`, `write`, are assumed to be available if you don't list them with an `include` directive. Lastly the part `[-Werror,-Wimplicit-function-declaration]` is the computer code for the type of error. 1. The next few lines are the pretty version of what is at line `{{}}__err_line_num__{{}}`, column `{{}}__err_col_num__{{}}`. ``` -esyscmd({{pushd ../T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '3,4p' && popd > /dev/null 2>&1}})dnl +esyscmd({{pushd ../src/T1/step-4-hello-world/3-Makefile-Hello-World > /dev/null 2>&1 && cat temp-output.log | sed -n '3,4p' && popd > /dev/null 2>&1}})dnl ``` diff --git a/Generate-Wiki/Tutorial 2/T2-00.md.m4 b/templates-wiki/Tutorial 2/T2-00.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 2/T2-00.md.m4 rename to templates-wiki/Tutorial 2/T2-00.md.m4 diff --git a/Generate-Wiki/Tutorial 2/T2-01.md.m4 b/templates-wiki/Tutorial 2/T2-01.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 2/T2-01.md.m4 rename to templates-wiki/Tutorial 2/T2-01.md.m4 diff --git a/Generate-Wiki/Tutorial 2/T2-02.md.m4 b/templates-wiki/Tutorial 2/T2-02.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 2/T2-02.md.m4 rename to templates-wiki/Tutorial 2/T2-02.md.m4 diff --git a/Generate-Wiki/Tutorial 3/T1-03.md.m4 b/templates-wiki/Tutorial 3/T1-03.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 3/T1-03.md.m4 rename to templates-wiki/Tutorial 3/T1-03.md.m4 diff --git a/Generate-Wiki/Tutorial 3/T3-00.md.m4 b/templates-wiki/Tutorial 3/T3-00.md.m4 similarity index 100% rename from Generate-Wiki/Tutorial 3/T3-00.md.m4 rename to templates-wiki/Tutorial 3/T3-00.md.m4 diff --git a/Generate-Wiki/_Footer.md.m4 b/templates-wiki/_Footer.md.m4 similarity index 100% rename from Generate-Wiki/_Footer.md.m4 rename to templates-wiki/_Footer.md.m4 diff --git a/Generate-Wiki/_Sidebar.md.m4 b/templates-wiki/_Sidebar.md.m4 similarity index 100% rename from Generate-Wiki/_Sidebar.md.m4 rename to templates-wiki/_Sidebar.md.m4 From eb4f075f7aa3742c2c32ea4a2549c98d87e5bb8f Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Sat, 2 Jan 2021 10:48:53 -0500 Subject: [PATCH 07/23] Updated notes --- Notes.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Notes.md b/Notes.md index b52f0d7..574753c 100644 --- a/Notes.md +++ b/Notes.md @@ -1,4 +1,5 @@ # Notes for Programming Tutorial -[ ] make templates to make it easier to manage in the long run -[ ] create contribution guidelines \ No newline at end of file +- [ ] make templates to make it easier to manage in the long run +- [ ] create contribution guidelines +- [x] invite others to contribue (1/1/2021, on linkedin) \ No newline at end of file From 3f897535bfcee7dddba8f331072c3078a8f31d56 Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Sat, 2 Jan 2021 11:13:35 -0500 Subject: [PATCH 08/23] Updated answer URLS --- Notes.md | 3 ++- definitions.m4 | 1 + templates-wiki/Tutorial 1/T1-01.md.m4 | 2 +- templates-wiki/Tutorial 1/T1-02.md.m4 | 2 +- templates-wiki/Tutorial 1/T1-04.md.m4 | 4 ++-- templates-wiki/Tutorial 2/T2-01.md.m4 | 2 +- templates-wiki/Tutorial 3/T1-03.md.m4 | 10 +++++----- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Notes.md b/Notes.md index 574753c..c8b14f6 100644 --- a/Notes.md +++ b/Notes.md @@ -2,4 +2,5 @@ - [ ] make templates to make it easier to manage in the long run - [ ] create contribution guidelines -- [x] invite others to contribue (1/1/2021, on linkedin) \ No newline at end of file +- [x] invite others to contribue (1/1/2021, on linkedin) +- [ ] replace `sed` commands with a search for first line and `n` lines afterwards to avoid needing to worry about rewriting examples \ No newline at end of file diff --git a/definitions.m4 b/definitions.m4 index 464ab03..636d431 100644 --- a/definitions.m4 +++ b/definitions.m4 @@ -17,6 +17,7 @@ dnl dnl pushdef({{__project_repo_root__}}, {{https://github.com/betsalel-williamson/Programming-Tutorial}})dnl pushdef({{__project_repo__}}, {{__project_repo_root__{{}}.git}})dnl +pushdef({{__project_repo_source_root__}}, {{__project_repo_root__{{}}/tree/main/src}})dnl pushdef({{__project_repo_name__}}, {{Programming-Tutorial}})dnl pushdef({{__code_license_header__}}, {{The author disclaims copyright to this source code. In place of a legal notice, here is a blessing: diff --git a/templates-wiki/Tutorial 1/T1-01.md.m4 b/templates-wiki/Tutorial 1/T1-01.md.m4 index ae861ae..cc5a405 100644 --- a/templates-wiki/Tutorial 1/T1-01.md.m4 +++ b/templates-wiki/Tutorial 1/T1-01.md.m4 @@ -54,7 +54,7 @@ Once you have installed Xcode run the following command (open up the terminal Ap We will be using Cygwin. You must install it, and the associated packages in order to run through this correctly. If you already have Cygwin installed you should still run this script to install the necessary software. 1. Run Install Setup Batch Script - 1. Navigate to the following URL + 1. Navigate to the following URL <{{}}__project_repo_source_root__{{}}/T1/step-1-setup> 1. Click on `windows-setup.cmd` 1. Click on the `Raw` button 1. Open up notepad and copy-and-paste the text into the empty text file. diff --git a/templates-wiki/Tutorial 1/T1-02.md.m4 b/templates-wiki/Tutorial 1/T1-02.md.m4 index f9a1736..35ccca7 100644 --- a/templates-wiki/Tutorial 1/T1-02.md.m4 +++ b/templates-wiki/Tutorial 1/T1-02.md.m4 @@ -125,7 +125,7 @@ Congrats on modifying your first program and fixing a bug! With the TCL/Expect t 1. Additional Windows Shell CMDs - https://ss64.com/nt/ 1. TCL/Expect main wiki - http://wiki.tcl.tk/ 1. Expect tutorials - https://wiki.tcl.tk/11584 -1. Answer - <{{}}__project_repo_root__{{}}/blob/develop/T1/step-2-command-line-101/hello-world.tcl> +1. Answer - <{{}}__project_repo_source_root__{{}}/T1/step-2-command-line-101> # Updates * Jan 1, 2021 - Generated from m4 template diff --git a/templates-wiki/Tutorial 1/T1-04.md.m4 b/templates-wiki/Tutorial 1/T1-04.md.m4 index f01e77f..39e3b5b 100644 --- a/templates-wiki/Tutorial 1/T1-04.md.m4 +++ b/templates-wiki/Tutorial 1/T1-04.md.m4 @@ -81,7 +81,7 @@ We can run these using the `exec` function in TCL and the programs `rm` and `gcc Next is the code to run our program `main`. For our first test we will `spawn` our program with the argument `"Hello World"`. We can use the `expect` command like in the first step to see that we output the text "Hello World". Finally, we get the exit code of our program with the following code: ```Tcl -esyscmd({{sed -n '26,32p' ../src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl | sed 's/^/ /g' | ghead -c -1}}) +esyscmd({{sed -n '33,38p' ../src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl | sed 's/^/ /g' | ghead -c -1}}) ``` For our second test we only need to test that the exit code is 1. @@ -222,7 +222,7 @@ Congrats on finishing this last step and for completing the first tutorial! You' 1. About the write function - https://linux.die.net/man/2/write 1. StackOverflow about makefiles - https://stackoverflow.com/questions/2481269/how-to-make-a-simple-c-makefile#2481326 1. StackOverflow about makefiles 2 - https://stackoverflow.com/questions/1079832/how-can-i-configure-my-makefile-for-debug-and-release-builds#1080180 -1. Answers - <{{}}__project_repo_root__{{}}/tree/develop/T1/step-4-hello-world> +1. Answers - <{{}}__project_repo_source_root__{{}}/T1/step-4-hello-world> # Updates * Jan 1, 2021 - Generated from m4 template diff --git a/templates-wiki/Tutorial 2/T2-01.md.m4 b/templates-wiki/Tutorial 2/T2-01.md.m4 index 3fff3a9..f180021 100644 --- a/templates-wiki/Tutorial 2/T2-01.md.m4 +++ b/templates-wiki/Tutorial 2/T2-01.md.m4 @@ -518,7 +518,7 @@ Congratulations! You've made it through to understanding how the `secretProgram` ## References -1. Code - <{{}}__project_repo_root__{{}}/tree/develop/T2/step-1-code-gen> +1. Code - <{{}}__project_repo_source_root__{{}}/T2/step-1-code-gen> 1. Google style guide - 1. Stackoverflow discussion on malloc and strings - diff --git a/templates-wiki/Tutorial 3/T1-03.md.m4 b/templates-wiki/Tutorial 3/T1-03.md.m4 index 43c58c8..4018331 100644 --- a/templates-wiki/Tutorial 3/T1-03.md.m4 +++ b/templates-wiki/Tutorial 3/T1-03.md.m4 @@ -139,11 +139,11 @@ Replace the text between the quotes with a short comment on what you did in this If you are already familiar with Git you may have noticed that we did not tell you about pushing the changes or saving the changes back to the cloud. We will be covering this in the later tutorial. ## References -1. Quick start guide to Git - https://rogerdudler.github.io/git-guide/ -1. Git main website - https://git-scm.com/ -1. Highly recommended GUI version of Git - https://www.gitkraken.com/ -1. StackOverflow on Git reverting - https://stackoverflow.com/questions/927358/how-to-undo-the-most-recent-commits-in-git#927386 -1. Answer - __project_repo_root__{{}}/blob/main/T1/step-3-version-control-101 +1. Quick start guide to Git - +1. Git main website - +1. Highly recommended GUI version of Git - +1. StackOverflow on Git reverting - +1. Answer - <{{}}__project_repo_source_root__{{}}/T1/step-3-version-control-101> # Updates * Jan 1, 2021 - Generated from m4 template From 41e0eeedf4fa1588375802f077c53cfeca8a006a Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Sat, 2 Jan 2021 18:07:16 -0500 Subject: [PATCH 09/23] Updated build script to run tests. Added some todo's to notes. Fixed bugs with executing tests. Removed unactive link from wiki. --- Notes.md | 4 ++- build.sh | 29 +++++++++++++++++++ .../hello-world-fixed.tcl | 0 .../step-2-command-line-101/hello-world.tcl | 0 .../download-repository.tcl | 0 .../hello-world.tcl | 0 .../2-Test-Hello-World/.gitignore | 7 +++++ .../2-Test-Hello-World/main.c | 14 ++++----- .../2-Test-Hello-World/test.tcl | 9 ++++-- .../3-Makefile-Hello-World/.gitignore | 7 +++++ .../3-Makefile-Hello-World/makefile | 4 +-- .../3-Makefile-Hello-World/test.tcl | 2 +- src/T2/step-1-code-gen/test.tcl | 2 ++ src/test.tcl | 17 ----------- .../2-Test-Hello-World/.gitignore.m4 | 3 ++ .../2-Test-Hello-World/main.c.m4 | 14 ++++----- .../2-Test-Hello-World/test.tcl.m4 | 9 ++++-- .../3-Makefile-Hello-World/.gitignore.m4 | 3 ++ .../3-Makefile-Hello-World/makefile.m4 | 4 +-- .../3-Makefile-Hello-World/test.tcl.m4 | 2 +- templates-code/T2/step-1-code-gen/test.tcl.m4 | 2 ++ templates-code/test.tcl.m4 | 17 ----------- templates-wiki/Tutorial 2/T2-00.md.m4 | 2 +- 23 files changed, 89 insertions(+), 62 deletions(-) mode change 100644 => 100755 src/T1/step-2-command-line-101/hello-world-fixed.tcl mode change 100644 => 100755 src/T1/step-2-command-line-101/hello-world.tcl mode change 100644 => 100755 src/T1/step-3-version-control-101/download-repository.tcl mode change 100644 => 100755 src/T1/step-3-version-control-101/hello-world.tcl create mode 100644 src/T1/step-4-hello-world/2-Test-Hello-World/.gitignore mode change 100644 => 100755 src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl create mode 100644 src/T1/step-4-hello-world/3-Makefile-Hello-World/.gitignore mode change 100644 => 100755 src/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl mode change 100644 => 100755 src/T2/step-1-code-gen/test.tcl mode change 100644 => 100755 src/test.tcl create mode 100644 templates-code/T1/step-4-hello-world/2-Test-Hello-World/.gitignore.m4 create mode 100644 templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/.gitignore.m4 diff --git a/Notes.md b/Notes.md index c8b14f6..b42c405 100644 --- a/Notes.md +++ b/Notes.md @@ -3,4 +3,6 @@ - [ ] make templates to make it easier to manage in the long run - [ ] create contribution guidelines - [x] invite others to contribue (1/1/2021, on linkedin) -- [ ] replace `sed` commands with a search for first line and `n` lines afterwards to avoid needing to worry about rewriting examples \ No newline at end of file +- [ ] replace `sed` commands with a search for first line and `n` lines afterwards to avoid needing to worry about rewriting examples +- [ ] need list of pre-reqs for building the source `M4`, `astyle` ... +- [ ] https://www.tcl.tk/doc/styleGuide.pdf is helpful, add it to the tutorial appendix \ No newline at end of file diff --git a/build.sh b/build.sh index 5863a07..98e54ab 100755 --- a/build.sh +++ b/build.sh @@ -20,13 +20,42 @@ # echo "Making directory for: ($(dirname $0))"; pushd ./templates-code > /dev/null 2>&1 +# format code +astyle "./*.c.m4" "./*.h.m4" \ +--indent=spaces=2 \ +--indent-switches \ +--indent-after-parens \ +--break-blocks \ +--pad-oper \ +--pad-comma \ +--pad-paren-in \ +--break-one-line-headers \ +--add-braces \ +--add-one-line-braces \ +--max-code-length=80 \ +--mode=c \ +--recursive \ +--verbose find . -name "*.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); mkdir -p $(dirname "../src/$rename"); m4 ../definitions.m4 "$(realpath "$0")" > "../src/$rename"' {} \; mv ../src/README.md ../ popd > /dev/null 2>&1 +pushd ./src > /dev/null 2>&1 +# ensure that tcl scripts can be executed +find . -name "*.tcl" -exec chmod +x {} \; +# run test files +# TODO: clean up output format of test files +find . -name "test*.tcl" -exec sh -c 'echo "Running test: ($(basename "$0")) in ($(dirname "$0"))"; pushd "$(dirname "$0")" > /dev/null 2>&1; ./$(basename "$0"); popd > /dev/null 2>&1' {} \; +popd > /dev/null 2>&1 + # we call the realpath command for the wiki so that it fails fast # if the wiki directory does not exist pushd ./templates-wiki > /dev/null 2>&1 find . -name "*.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); m4 ../definitions.m4 "$(realpath "$0")" > "$(realpath "../../Programming-Tutorial.wiki/$rename")"' {} \; popd > /dev/null 2>&1 +# TODO: check all links to see that they are valid... +# print a list of links and basic context (from file, line) +# output to MD file and save to a temp file + +# TODO: comb through and add all "todo's" to the Notes file. \ No newline at end of file diff --git a/src/T1/step-2-command-line-101/hello-world-fixed.tcl b/src/T1/step-2-command-line-101/hello-world-fixed.tcl old mode 100644 new mode 100755 diff --git a/src/T1/step-2-command-line-101/hello-world.tcl b/src/T1/step-2-command-line-101/hello-world.tcl old mode 100644 new mode 100755 diff --git a/src/T1/step-3-version-control-101/download-repository.tcl b/src/T1/step-3-version-control-101/download-repository.tcl old mode 100644 new mode 100755 diff --git a/src/T1/step-3-version-control-101/hello-world.tcl b/src/T1/step-3-version-control-101/hello-world.tcl old mode 100644 new mode 100755 diff --git a/src/T1/step-4-hello-world/2-Test-Hello-World/.gitignore b/src/T1/step-4-hello-world/2-Test-Hello-World/.gitignore new file mode 100644 index 0000000..9d780a1 --- /dev/null +++ b/src/T1/step-4-hello-world/2-Test-Hello-World/.gitignore @@ -0,0 +1,7 @@ +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. + +main \ No newline at end of file diff --git a/src/T1/step-4-hello-world/2-Test-Hello-World/main.c b/src/T1/step-4-hello-world/2-Test-Hello-World/main.c index dc169d4..a1997b0 100644 --- a/src/T1/step-4-hello-world/2-Test-Hello-World/main.c +++ b/src/T1/step-4-hello-world/2-Test-Hello-World/main.c @@ -11,14 +11,14 @@ int main ( int argc, const char* argv[] ) { int exit_value = -1; if ( argc == 2 ) { - - while(argv[1][i] != '\0'){ - i = i+1; - } - - exit_value = 0 + + while( argv[1][i] != '\0' ) { + i = i + 1; + } + + exit_value = 0 } else { - exit_value = 1; + exit_value = 1; } return exit_value; diff --git a/src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl b/src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl old mode 100644 new mode 100755 index e8e5cf4..36a5979 --- a/src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl +++ b/src/T1/step-4-hello-world/2-Test-Hello-World/test.tcl @@ -1,4 +1,4 @@ -#!/bin/env expect +#!/usr/bin/env expect # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: @@ -7,9 +7,12 @@ # May you share freely, never taking more than you give. # delete the executable file -exec rm main +if { [file exists main] == 1 } { + exec rm main +} + # compile the file -exec gcc -w main.c -o main +exec gcc -w main-fixed.c -o main ### Test 1 ### # diff --git a/src/T1/step-4-hello-world/3-Makefile-Hello-World/.gitignore b/src/T1/step-4-hello-world/3-Makefile-Hello-World/.gitignore new file mode 100644 index 0000000..9d780a1 --- /dev/null +++ b/src/T1/step-4-hello-world/3-Makefile-Hello-World/.gitignore @@ -0,0 +1,7 @@ +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. + +main \ No newline at end of file diff --git a/src/T1/step-4-hello-world/3-Makefile-Hello-World/makefile b/src/T1/step-4-hello-world/3-Makefile-Hello-World/makefile index 48da4ac..b325058 100644 --- a/src/T1/step-4-hello-world/3-Makefile-Hello-World/makefile +++ b/src/T1/step-4-hello-world/3-Makefile-Hello-World/makefile @@ -5,7 +5,7 @@ # May you share freely, never taking more than you give. CC = gcc -SRCS = main.c +SRCS = main-fixed.c OBJS = $(subst .c,.o,$(SRCS)) CFLAGS = -Wall -Werror -Wextra RM = rm -f @@ -17,7 +17,7 @@ debug: main main: $(OBJS) $(CC) -o main $(OBJS) $(CFLAGS) -main.o: main.c +main.o: main-fixed.c # We don't glob because this doesn't scale for # large projects diff --git a/src/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl b/src/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl old mode 100644 new mode 100755 index 632def8..93e0c77 --- a/src/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl +++ b/src/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl @@ -1,4 +1,4 @@ -#!/bin/env expect +#!/usr/bin/env expect # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: diff --git a/src/T2/step-1-code-gen/test.tcl b/src/T2/step-1-code-gen/test.tcl old mode 100644 new mode 100755 index edc3f48..93da2ad --- a/src/T2/step-1-code-gen/test.tcl +++ b/src/T2/step-1-code-gen/test.tcl @@ -76,6 +76,8 @@ proc testInvalidInput args { } } +exec make prep + if {[catch {exec make debug} result] == 0} { testMustProvideCode testProvidedCode diff --git a/src/test.tcl b/src/test.tcl old mode 100644 new mode 100755 index 23138aa..4f0f719 --- a/src/test.tcl +++ b/src/test.tcl @@ -8,23 +8,6 @@ # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. -# format code -astyle "./*.c" "./*.h" \ ---indent=spaces=2 \ ---indent-switches \ ---indent-after-parens \ ---break-blocks \ ---pad-oper \ ---pad-comma \ ---pad-paren-in \ ---break-one-line-headers \ ---add-braces \ ---add-one-line-braces \ ---max-code-length=80 \ ---mode=c \ ---recursive \ ---verbose - # test files set t1step1file "./T1/step-1-setup/windows-setup.cmd" if {[file exists $t1step1file]} { diff --git a/templates-code/T1/step-4-hello-world/2-Test-Hello-World/.gitignore.m4 b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/.gitignore.m4 new file mode 100644 index 0000000..b9034f7 --- /dev/null +++ b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/.gitignore.m4 @@ -0,0 +1,3 @@ +__code_license_header_hash_style__ + +main \ No newline at end of file diff --git a/templates-code/T1/step-4-hello-world/2-Test-Hello-World/main.c.m4 b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/main.c.m4 index 3b07612..5cd6702 100644 --- a/templates-code/T1/step-4-hello-world/2-Test-Hello-World/main.c.m4 +++ b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/main.c.m4 @@ -4,14 +4,14 @@ int main ( int argc, const char* argv[] ) { int exit_value = -1; if ( argc == 2 ) { - - while(argv[1][i] != '\0'){ - i = i+1; - } - - exit_value = 0 + + while( argv[1][i] != '\0' ) { + i = i + 1; + } + + exit_value = 0 } else { - exit_value = 1; + exit_value = 1; } return exit_value; diff --git a/templates-code/T1/step-4-hello-world/2-Test-Hello-World/test.tcl.m4 b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/test.tcl.m4 index 6afbea9..1f46529 100644 --- a/templates-code/T1/step-4-hello-world/2-Test-Hello-World/test.tcl.m4 +++ b/templates-code/T1/step-4-hello-world/2-Test-Hello-World/test.tcl.m4 @@ -1,11 +1,14 @@ -#!/bin/env expect +#!/usr/bin/env expect __code_license_header_hash_style__ # delete the executable file -exec rm main +if { [file exists main] == 1 } { + exec rm main +} + # compile the file -exec gcc -w main.c -o main +exec gcc -w main-fixed.c -o main ### Test 1 ### # diff --git a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/.gitignore.m4 b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/.gitignore.m4 new file mode 100644 index 0000000..b9034f7 --- /dev/null +++ b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/.gitignore.m4 @@ -0,0 +1,3 @@ +__code_license_header_hash_style__ + +main \ No newline at end of file diff --git a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/makefile.m4 b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/makefile.m4 index c2b460d..341b4d8 100644 --- a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/makefile.m4 +++ b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/makefile.m4 @@ -1,7 +1,7 @@ __code_license_header_hash_style__ CC = gcc -SRCS = main.c +SRCS = main-fixed.c OBJS = $(subst .c,.o,$(SRCS)) CFLAGS = -Wall -Werror -Wextra RM = rm -f @@ -13,7 +13,7 @@ debug: main main: $(OBJS) $(CC) -o main $(OBJS) $(CFLAGS) -main.o: main.c +main.o: main-fixed.c # We don't glob because this doesn't scale for # large projects diff --git a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl.m4 b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl.m4 index 2762bba..e72fe7b 100644 --- a/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl.m4 +++ b/templates-code/T1/step-4-hello-world/3-Makefile-Hello-World/test.tcl.m4 @@ -1,4 +1,4 @@ -#!/bin/env expect +#!/usr/bin/env expect __code_license_header_hash_style__ diff --git a/templates-code/T2/step-1-code-gen/test.tcl.m4 b/templates-code/T2/step-1-code-gen/test.tcl.m4 index 215f0d2..f97ef30 100644 --- a/templates-code/T2/step-1-code-gen/test.tcl.m4 +++ b/templates-code/T2/step-1-code-gen/test.tcl.m4 @@ -72,6 +72,8 @@ proc testInvalidInput args { } } +exec make prep + if {[catch {exec make debug} result] == 0} { testMustProvideCode testProvidedCode diff --git a/templates-code/test.tcl.m4 b/templates-code/test.tcl.m4 index 469aad3..bafb77d 100755 --- a/templates-code/test.tcl.m4 +++ b/templates-code/test.tcl.m4 @@ -4,23 +4,6 @@ __code_license_header_hash_style__ -# format code -astyle "./*.c" "./*.h" \ ---indent=spaces=2 \ ---indent-switches \ ---indent-after-parens \ ---break-blocks \ ---pad-oper \ ---pad-comma \ ---pad-paren-in \ ---break-one-line-headers \ ---add-braces \ ---add-one-line-braces \ ---max-code-length=80 \ ---mode=c \ ---recursive \ ---verbose - # test files set t1step1file "./T1/step-1-setup/windows-setup.cmd" if {[file exists $t1step1file]} { diff --git a/templates-wiki/Tutorial 2/T2-00.md.m4 b/templates-wiki/Tutorial 2/T2-00.md.m4 index 48fc756..f16940b 100644 --- a/templates-wiki/Tutorial 2/T2-00.md.m4 +++ b/templates-wiki/Tutorial 2/T2-00.md.m4 @@ -39,7 +39,7 @@ We will now be teaching more of the basics in C basic other basic programming in 1. About motivation to code - https://thenextweb.com/dd/2015/06/11/8-barriers-to-overcome-when-learning-to-code/ 1. http://aelinik.free.fr/c/ -1. Good additional tutorial - http://archive.oreilly.com/oreillyschool/courses/c/Introduction%20to%20C%20Programming%20v1.pdf + # Updates * Jan 1, 2021 - Generated from m4 template From a2f88a4c2c272fdf1fd7c5ee3e85d5d522c216c1 Mon Sep 17 00:00:00 2001 From: "Betsalel (Saul) Williamson" Date: Sat, 2 Jan 2021 22:38:55 -0500 Subject: [PATCH 10/23] Added under construction flag to wiki. Updated to include key markdowns. Updated comments in the build script. Added some items in Notes. --- Notes.md | 3 +- build.sh | 56 ++++++++++++++++++++------- definitions.m4 | 2 + templates-wiki/Home.md.m4 | 1 + templates-wiki/Tutorial 1/T1-00.md.m4 | 1 + templates-wiki/Tutorial 1/T1-01.md.m4 | 5 ++- templates-wiki/Tutorial 1/T1-02.md.m4 | 8 ++-- templates-wiki/Tutorial 1/T1-04.md.m4 | 1 + templates-wiki/Tutorial 2/T2-00.md.m4 | 1 + templates-wiki/Tutorial 2/T2-01.md.m4 | 1 + templates-wiki/Tutorial 2/T2-02.md.m4 | 1 + templates-wiki/Tutorial 3/T1-03.md.m4 | 1 + templates-wiki/Tutorial 3/T3-00.md.m4 | 1 + 13 files changed, 61 insertions(+), 21 deletions(-) diff --git a/Notes.md b/Notes.md index b42c405..f25666d 100644 --- a/Notes.md +++ b/Notes.md @@ -5,4 +5,5 @@ - [x] invite others to contribue (1/1/2021, on linkedin) - [ ] replace `sed` commands with a search for first line and `n` lines afterwards to avoid needing to worry about rewriting examples - [ ] need list of pre-reqs for building the source `M4`, `astyle` ... -- [ ] https://www.tcl.tk/doc/styleGuide.pdf is helpful, add it to the tutorial appendix \ No newline at end of file +- [ ] https://www.tcl.tk/doc/styleGuide.pdf is helpful, add it to the tutorial appendix +- [ ] implement fix for makefiles, need to have broken and fixed versions so that the wiki instructions make sense \ No newline at end of file diff --git a/build.sh b/build.sh index 98e54ab..0327a2b 100755 --- a/build.sh +++ b/build.sh @@ -1,25 +1,32 @@ #! env sh # filename: generate_docs.sh -# This command must be executed with the following: -# 1. run inside the "Generate-Wiki" directory -# 2. have the wiki repository cloned at ../../Programming-Tutorial.wiki -# - # TODO: validate assumptions here... -# version 1 of the command: -# find . -name "*.md" -exec sh -c 'm4 definitions.m4 "$0" > "../../Programming-Tutorial.wiki/$0"' {} \; +# ensure that we start executing in +# the script's location +pushd $(dirname $0) > /dev/null 2>&1 -# find the md.m4 files -# for each file, -# run the m4 command -# to do this we need to rename the files from *.md.m4 to *.md -# and place these files in the result directory +# TODO: check that there are no arguments... -# echo "Making directory for: ($(dirname $0))"; +# TODO: check for Programming-Tutorial.wiki +# find ../ -name .git +# get the different names ... +# config should download the wiki +# Possibly: basename -s .git `git config --get remote.origin.url` +# https://stackoverflow.com/questions/15715825/how-do-you-get-the-git-repositorys-name-in-some-git-repository +# +# $ find ../ -name .git -exec sh -c 'basename $(cat $0/config | perl -lane "print /= (.*)[.]git/")' {} \; +# Programming-Tutorial.wiki +# Programming-Tutorial +# + +# TODO: have the wiki repository cloned at ../../Programming-Tutorial.wiki +# we don't need to worry about the name, just that it should +# be there... pushd ./templates-code > /dev/null 2>&1 + # format code astyle "./*.c.m4" "./*.h.m4" \ --indent=spaces=2 \ @@ -36,21 +43,37 @@ astyle "./*.c.m4" "./*.h.m4" \ --mode=c \ --recursive \ --verbose + +# find the md.m4 files +# for each file, +# run the m4 command +# to do this we need to rename the files from *.md.m4 to *.md +# and place these files in the result directory + find . -name "*.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); mkdir -p $(dirname "../src/$rename"); m4 ../definitions.m4 "$(realpath "$0")" > "../src/$rename"' {} \; mv ../src/README.md ../ popd > /dev/null 2>&1 pushd ./src > /dev/null 2>&1 + # ensure that tcl scripts can be executed find . -name "*.tcl" -exec chmod +x {} \; + # run test files -# TODO: clean up output format of test files find . -name "test*.tcl" -exec sh -c 'echo "Running test: ($(basename "$0")) in ($(dirname "$0"))"; pushd "$(dirname "$0")" > /dev/null 2>&1; ./$(basename "$0"); popd > /dev/null 2>&1' {} \; + +# TODO: clean up output format of test files + popd > /dev/null 2>&1 # we call the realpath command for the wiki so that it fails fast # if the wiki directory does not exist pushd ./templates-wiki > /dev/null 2>&1 + +# TODO: replace '../../Programming-Tutorial.wiki' with location of wiki +# it may not be 'Programming-Tutorial.wiki' because the user can +# clone a repo into any folder... + find . -name "*.m4" -exec sh -c 'rename=$(echo "$0" | perl -lane "print /(.*)[.]m4/"); m4 ../definitions.m4 "$(realpath "$0")" > "$(realpath "../../Programming-Tutorial.wiki/$rename")"' {} \; popd > /dev/null 2>&1 @@ -58,4 +81,7 @@ popd > /dev/null 2>&1 # print a list of links and basic context (from file, line) # output to MD file and save to a temp file -# TODO: comb through and add all "todo's" to the Notes file. \ No newline at end of file +# TODO: comb through and add all "todo's" to the Notes file. +# TODO: remove todo's from output + +popd > /dev/null 2>&1 # go back to where ever... \ No newline at end of file diff --git a/definitions.m4 b/definitions.m4 index 636d431..b4dd92a 100644 --- a/definitions.m4 +++ b/definitions.m4 @@ -41,3 +41,5 @@ pushdef({{__code_license_header_markdown__}}, {{In place of a legal notice, here - May you do good and not evil. - May you find forgiveness for yourself and forgive others. - May you share freely, never taking more than you give.}})dnl +pushdef({{__project_under_construction_flag__}}, {{# Warning !!! This tutorial is currently under construction... Proceed at your own risk +}})dnl diff --git a/templates-wiki/Home.md.m4 b/templates-wiki/Home.md.m4 index c36a7b7..0b405ce 100644 --- a/templates-wiki/Home.md.m4 +++ b/templates-wiki/Home.md.m4 @@ -1,3 +1,4 @@ +__project_under_construction_flag__ Welcome to the Programming Tutorial wiki! # Introduction diff --git a/templates-wiki/Tutorial 1/T1-00.md.m4 b/templates-wiki/Tutorial 1/T1-00.md.m4 index 821735f..764a652 100644 --- a/templates-wiki/Tutorial 1/T1-00.md.m4 +++ b/templates-wiki/Tutorial 1/T1-00.md.m4 @@ -1,3 +1,4 @@ +__project_under_construction_flag__ # Tutorial 1: “Hello World!” The first step in any computer language has historically been the “Hello World!” example. The purpose of this exercise to focus on a simple task when setting the system up before getting into the programming complexities. Unlike traditional programming tutorials, we are going to be adding an additional step to this, so bear with us. This step provides a framework to automate the actions of compiling, running, and testing your program. This will set you up in the long run for best practices in programming. To download a complete working version of this program visit this GitHub URL <{{}}__project_repo_root__{{}}/>. This tutorial will not get into the details of why different coding languages look different, what variables are and so on. See the later tutorials for more details about programming in C or Python. diff --git a/templates-wiki/Tutorial 1/T1-01.md.m4 b/templates-wiki/Tutorial 1/T1-01.md.m4 index cc5a405..4d9ce20 100644 --- a/templates-wiki/Tutorial 1/T1-01.md.m4 +++ b/templates-wiki/Tutorial 1/T1-01.md.m4 @@ -1,3 +1,4 @@ +__project_under_construction_flag__ # Step 1: Setup In every professional computer environment the very first step is always finding the setup instructions and following them very carefully. Again, this is very important. **FOLLOW SETUP INSTRUCTIONS VERY CAREFULLY!** @@ -35,7 +36,7 @@ Finally, if you're still stuck stop by SERC and see us. We'll be happy to help y ## Mac The following instructions were tested on a clean install of MacOS 10.13. If you are running an earlier version of the Mac operating system the following may work. If it does not work see the subsequent instructions. -1. Open up `Terminal.app` in the `\Applications\Utilities` folder or use Spotlight to find it. Once it is open type `gcc` and hit the `enter` key. +1. Open up `Terminal.app` in the `\Applications\Utilities` folder or use Spotlight to find it. Once it is open type `gcc` and hit the enter key. 1. A dialog window will pop up and ask you to download and install the command line developer tools. 1. Click `Install` (estimated 10 min) Thats it! @@ -61,7 +62,7 @@ We will be using Cygwin. You must install it, and the associated packages in ord 1. Save as `setup.cmd` 1. To install the program for all uses, right-click `setup.cmd` and select `Run as administrator`. 1. Follow through the instructions that are displayed on the window that pops up. This script walks through installing Cygwin and the necessary programs for running the rest of the tutorial. -1. Open up a new command window and type `ls` and then the `Enter` key. +1. Open up a new command window and type `ls` and then the enter key. You should see a list of files in your current directory. If you get the following response: diff --git a/templates-wiki/Tutorial 1/T1-02.md.m4 b/templates-wiki/Tutorial 1/T1-02.md.m4 index 35ccca7..9964552 100644 --- a/templates-wiki/Tutorial 1/T1-02.md.m4 +++ b/templates-wiki/Tutorial 1/T1-02.md.m4 @@ -1,5 +1,7 @@ +__project_under_construction_flag__ # Step 2: Command Line 101 -We will get started by opening up a shell or terminal window. Find the `Meta` key on your keyboard as the key with the Windows logo on standard PC keyboards, or as the `command` key on Mac keyboards. We will refer to both these keys as the `Meta` key for the rest of this guide. + +We will get started by opening up a shell or terminal window. Find the meta key on your keyboard as the key with the Windows logo on standard PC keyboards, or as the command key on Mac keyboards. We will refer to both these keys as the meta key for the rest of this guide. Welcome to the command line. Things will look a little scary here if this is the first time you’ve opened up what is called a command-line interface (CLI) shell. Usually, modern systems will open a graphical user interface (GUI) shell that operates with icons, apps, clicks, swipes, etc. A CLI shell is a text-based or keyboard-only interface to your computer. Throughout the rest of this guide we will simply refer to the CLI shell as the Shell. **We will be using the word shell to mean the Windows Command Prompt and \*nix CLI shells.** The Shell is a simple text interface to your computer and will open up a new world of commands for you to run on your machine. @@ -7,9 +9,9 @@ _On the Internet you may sometimes see the *nix system. This is shorthand meanin On Linux, you open the Shell by opening up the terminal, konsole, shell or prompt (depending on your specific flavor of Linux like Red Hat, Ubuntu, SUSE, Fedora etc.). Each flavor has it's preferred name for the Shell. -On Mac, you open the Shell through the Terminal App by pressing `Meta-Space` and typing in `Terminal`. +On Mac, you open the Shell through the Terminal App by pressing meta+space and typing in `Terminal`. -On Windows operating systems, you open up the Shell through the regular command line by pressing `Meta-R` and typing in `cmd`, or the Power-Shell by pressing `Meta-R` and typing in `powershell`. +On Windows operating systems, you open up the Shell through the regular command line by pressing meta+R and typing in `cmd`, or the Power-Shell by pressing meta+R and typing in `powershell`. Your computer will know about the commands available to the Shell because there is a global variable called `PATH` that stores a list of locations for all the programs that the Shell can use. You may have noticed that in the Windows script example we modified this variable with the `setx` command to ensure that Cygwin was added. What this did was add all of the new programs that Cygwin installed so that we can more easily access them in the Shell. On Linux and Mac, these commands are by default installed in a directory ( `/usr/bin` or `/usr/local/bin` ) that is being watched by the Shell so that all new commands are added. diff --git a/templates-wiki/Tutorial 1/T1-04.md.m4 b/templates-wiki/Tutorial 1/T1-04.md.m4 index 39e3b5b..c1e7332 100644 --- a/templates-wiki/Tutorial 1/T1-04.md.m4 +++ b/templates-wiki/Tutorial 1/T1-04.md.m4 @@ -1,3 +1,4 @@ +__project_under_construction_flag__ # Step 3: Your First C Program We will move quickly through this next step, but will show you how to download the Git repository with the answers. diff --git a/templates-wiki/Tutorial 2/T2-00.md.m4 b/templates-wiki/Tutorial 2/T2-00.md.m4 index f16940b..7696f7d 100644 --- a/templates-wiki/Tutorial 2/T2-00.md.m4 +++ b/templates-wiki/Tutorial 2/T2-00.md.m4 @@ -1,3 +1,4 @@ +__project_under_construction_flag__ # Crash Course in C - Crack The Code