From 755daff8bcab9866f9622f53db1eea5ee95e6e9a Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:00:08 +0100 Subject: [PATCH 01/32] Test script: detecting code block without associated project. --- frontend/tests/compile_blocks.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index a60441103..d39e7c841 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -100,7 +100,10 @@ def is_empty(line): i + 1, lang_re.match(line).groups()[0] ) - project = project_re.match(line).groups()[0] + project = project_re.match(line) + if project is not None: + project = project.groups()[0] + main_file = main_re.match(line) if main_file is not None: # Retrieve actual main filename @@ -344,6 +347,11 @@ def extract_diagnostics(lines): projects = dict() for (i, b) in code_blocks: + if b.project is None: + print ("Error: project not set in {} at line {}".format( + rst_file, str(b.line_start))) + exit(1) + if not b.project in projects: projects[b.project] = list() projects[b.project].append((i, b)) From ab7ea0dec45c6654bda7e4cb54c59100c186e6f4 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:00:44 +0100 Subject: [PATCH 02/32] Test script: fixing call to remove-tree. --- frontend/tests/compile_blocks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index d39e7c841..5bd86d59b 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -365,7 +365,7 @@ def init_project_dir(project): project_dir = base_project_dir + "/" + project.replace(".", "/") if os.path.exists(project_dir): - shutil.rmtree(args.build_dir) + shutil.rmtree(project_dir) try: os.makedirs(project_dir) From 818d6582fcc1aa580abdd3a6413c450b3c752f96 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:03:46 +0100 Subject: [PATCH 03/32] Test script: storing runtime output in "out" variable. --- frontend/tests/compile_blocks.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index 5bd86d59b..18f997c02 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -480,6 +480,7 @@ def get_main_filename(block): print_error(loc, "Failed to compile example") print(e.output) has_error = True + out = str(e.output.decode("utf-8")) elif block.language == "c": try: out = run("gcc", "-c", main_file) @@ -490,11 +491,12 @@ def get_main_filename(block): print_error(loc, "Failed to compile example") print(e.output) has_error = True + out = str(e.output.decode("utf-8")) if not compile_error and not has_error: if block.language == "ada": try: - run("./{}".format(P.splitext(main_file)[0])) + out = run("./{}".format(P.splitext(main_file)[0])) if 'ada-run-expect-failure' in block.classes: print_error( @@ -502,7 +504,7 @@ def get_main_filename(block): ) has_error = True - except S.CalledProcessError: + except S.CalledProcessError as e: if 'ada-run-expect-failure' in block.classes: if args.verbose: print("Running of example expectedly failed") @@ -510,19 +512,21 @@ def get_main_filename(block): print_error(loc, "Running of example failed") has_error = True + out = str(e.output.decode("utf-8")) if 'compile' in block.buttons: for source_file in source_files: if block.language == "ada": try: - run("gcc", "-c", "-gnatc", "-gnatyg0-s", - source_file.basename) - except S.CalledProcessError: + out = run("gcc", "-c", "-gnatc", "-gnatyg0-s", + source_file.basename) + except S.CalledProcessError as e: if 'ada-expect-compile-error' in block.classes: compile_error = True else: print_error(loc, "Failed to compile example") has_error = True + out = str(e.output.decode("utf-8")) if any(b in prove_buttons for b in block.buttons): From 9f7da80aae6ddc7cc7a3b711ca3247063391914f Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:05:49 +0100 Subject: [PATCH 04/32] Test script: adding support for storing build / runtime output. --- frontend/tests/compile_blocks.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index 18f997c02..c166c79bb 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -462,6 +462,12 @@ def get_main_filename(block): main_file = source_files[-1].basename return main_file + def make_project_block_dir(): + project_block_dir = str(block.line_start) + os.makedirs(project_block_dir) + + return project_block_dir + if (('ada-run' in block.classes or 'ada-run-expect-failure' in block.classes or 'run' in block.buttons) @@ -469,6 +475,8 @@ def get_main_filename(block): ): main_file = get_main_filename(block) + project_block_dir = make_project_block_dir() + if block.language == "ada": try: out = run("gprbuild", "-gnata", "-gnatyg0-s", "-f", @@ -481,6 +489,8 @@ def get_main_filename(block): print(e.output) has_error = True out = str(e.output.decode("utf-8")) + with open(project_block_dir + "/build.log", u"w") as logfile: + logfile.write(out) elif block.language == "c": try: out = run("gcc", "-c", main_file) @@ -492,6 +502,8 @@ def get_main_filename(block): print(e.output) has_error = True out = str(e.output.decode("utf-8")) + with open(project_block_dir + "/build.log", u"w") as logfile: + logfile.write(out) if not compile_error and not has_error: if block.language == "ada": @@ -513,8 +525,13 @@ def get_main_filename(block): has_error = True out = str(e.output.decode("utf-8")) + + with open(project_block_dir + "/run.log", u"w") as logfile: + logfile.write(out) if 'compile' in block.buttons: + project_block_dir = make_project_block_dir() + for source_file in source_files: if block.language == "ada": try: @@ -528,6 +545,8 @@ def get_main_filename(block): has_error = True out = str(e.output.decode("utf-8")) + with open(project_block_dir + "/compile.log", u"w+") as logfile: + logfile.write(out) if any(b in prove_buttons for b in block.buttons): if block.language == "ada": From 698b32d62359db7ac268d47867d12b82b2652e35 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:09:48 +0100 Subject: [PATCH 05/32] Test script: adding handling of C code blocks. --- frontend/tests/compile_blocks.py | 40 +++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index c166c79bb..43bd85927 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -495,7 +495,7 @@ def make_project_block_dir(): try: out = run("gcc", "-c", main_file) except S.CalledProcessError as e: - if 'ada-expect-compile-error' in block.classes: + if 'c-expect-compile-error' in block.classes: compile_error = True else: print_error(loc, "Failed to compile example") @@ -528,6 +528,29 @@ def make_project_block_dir(): with open(project_block_dir + "/run.log", u"w") as logfile: logfile.write(out) + + elif block.language == "c": + try: + out = run("./{}".format(P.splitext(main_file)[0])) + + if 'c-run-expect-failure' in block.classes: + print_error( + loc, "Running of example should have failed" + ) + has_error = True + + except S.CalledProcessError as e: + if 'c-run-expect-failure' in block.classes: + if args.verbose: + print("Running of example expectedly failed") + else: + print_error(loc, "Running of example failed") + has_error = True + out = str(e.output.decode("utf-8")) + + with open(project_block_dir + "/run.log", u"w") as logfile: + logfile.write(out) + if 'compile' in block.buttons: project_block_dir = make_project_block_dir() @@ -547,6 +570,21 @@ def make_project_block_dir(): with open(project_block_dir + "/compile.log", u"w+") as logfile: logfile.write(out) + + elif block.language == "c": + try: + out = run("gcc", "-c", source_file.basename) + except S.CalledProcessError as e: + if 'c-expect-compile-error' in block.classes: + compile_error = True + else: + print_error(loc, "Failed to compile example") + has_error = True + out = str(e.output.decode("utf-8")) + + with open(project_block_dir + "/compile.log", u"w+") as logfile: + logfile.write(out) + if any(b in prove_buttons for b in block.buttons): if block.language == "ada": From 5f1ba9d5b06134617e7ea59aedd5a93ceafecca4 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:11:08 +0100 Subject: [PATCH 06/32] Test script: removing "ada-run" from list of classes that require "run_button." --- frontend/tests/compile_blocks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index 43bd85927..38c71ee3a 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -648,7 +648,7 @@ def make_project_block_dir(): print_error(loc, "Expected prove error, got none!") has_error = True - if (any (c in ['ada-run','ada-run-expect-failure','ada-norun'] for + if (any (c in ['ada-run-expect-failure','ada-norun'] for c in block.classes) and not 'run' in block.buttons): print_error(loc, "Expected run button, got none!") From cd36550868a265f50ed94d29f29c81c8f282e3b2 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:11:43 +0100 Subject: [PATCH 07/32] Test script: adding support for keeping all files generated by the script. --- frontend/tests/compile_blocks.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index 38c71ee3a..252d104c5 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -214,6 +214,8 @@ def __repr__(self): parser.add_argument('--verbose', '-v', type=bool, default=False, help='Show more information') +parser.add_argument('--keep_files', '-k', action='store_true', + help='Keep files generated in the test') parser.add_argument('--code-block', '-b', type=str, default=0) parser.add_argument('--all-diagnostics', '-A', action='store_true') parser.add_argument('--code-block-at', type=int, default=0) @@ -491,6 +493,7 @@ def make_project_block_dir(): out = str(e.output.decode("utf-8")) with open(project_block_dir + "/build.log", u"w") as logfile: logfile.write(out) + elif block.language == "c": try: out = run("gcc", "-c", main_file) @@ -664,7 +667,7 @@ def make_project_block_dir(): os.chdir(work_dir) - if os.path.exists(base_project_dir): + if os.path.exists(base_project_dir) and not args.keep_files: shutil.rmtree(base_project_dir) return analysis_error From 95832152a979ac551e8af93916d8c0706bb6f041 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:14:01 +0100 Subject: [PATCH 08/32] Sphinx: adding Python class for build / runtime output files. --- frontend/sphinx/code_block_info.py | 59 +++++++++++++++++++++++++++++ frontend/sphinx/widget_extension.py | 8 +++- 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 frontend/sphinx/code_block_info.py diff --git a/frontend/sphinx/code_block_info.py b/frontend/sphinx/code_block_info.py new file mode 100644 index 000000000..95a85ef12 --- /dev/null +++ b/frontend/sphinx/code_block_info.py @@ -0,0 +1,59 @@ +"""Provide compiler/runtime information for code block. +""" + +from typing import List, Dict +import glob + +import os + +class CodeBlockInfo(): + """Code block info class + """ + + # Hard-coding directories: + # - build directory + # - base project directory + base_project_dir = "projects" + + def __init__(self, + project_name : str, + filename : str, + line_number: int): + """Widget constructor + """ + self.__project_name: str = project_name + self.__filename: str = filename + self.__line_number: int = line_number + self.__src_test_data_dir = "" + self.__data_available = False + + if 'SRC_TEST_DIR' in os.environ: + self.__src_test_data_dir = os.environ['SRC_TEST_DIR'] + self.__data_available = True + + def __get_project_dir(self) -> str: + return self.__project_name.replace(".", "/") + + def __get_code_block_dir(self) -> str: + return (self.__src_test_data_dir + "/" + + self.base_project_dir + "/" + + self.__get_project_dir() + "/" + + str(self.__line_number)) + + def get_info(self) -> Dict[str, str]: + """ + """ + info : Dict[str, str] = {} + + if not self.__data_available: + return info + + code_block_dir = self.__get_code_block_dir() + + for logfile in glob.glob(code_block_dir + "/*.log"): + with open(logfile) as f: + content = f.read() + log_type = os.path.splitext(os.path.basename(logfile))[0] + info[log_type] = content + + return info diff --git a/frontend/sphinx/widget_extension.py b/frontend/sphinx/widget_extension.py index f1ae1b60e..eb211dc76 100644 --- a/frontend/sphinx/widget_extension.py +++ b/frontend/sphinx/widget_extension.py @@ -55,6 +55,7 @@ # Widget lib from widget.widget import Widget +from code_block_info import CodeBlockInfo # specifies the server address to set on the widgets WIDGETS_SERVER_URL = os.environ.get( @@ -77,7 +78,7 @@ class WidgetCodeDirective(Directive): 'name': directives.unchanged, } - def latex(self, widget: Widget): + def latex(self, widget: Widget, code_block_info : CodeBlockInfo): """Performs Latex parsing on nodes Used to create the PDF builds of the site. @@ -147,7 +148,10 @@ def run(self): # Attemping to detect HTML or Latex output by checking for 'html' in tags if 'html' not in self.state.state_machine.document.settings.env.app.tags.tags: - nodes_latex = self.latex(widget) + code_block_info = CodeBlockInfo(project_name=widget.name, + filename=self.content.items[0][0], + line_number=self.content.items[0][1] - 1) + nodes_latex = self.latex(widget, code_block_info) # insert widget into the template template = jinja_env.get_template('widget.html') From 77cc430d59649d3fea3055e5233a6fc8330e4937 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:15:32 +0100 Subject: [PATCH 09/32] Sphinx: integrating build / runtime output into LaTeX file (for PDF books). --- frontend/sphinx/widget_extension.py | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/frontend/sphinx/widget_extension.py b/frontend/sphinx/widget_extension.py index eb211dc76..7fcd3efa8 100644 --- a/frontend/sphinx/widget_extension.py +++ b/frontend/sphinx/widget_extension.py @@ -114,6 +114,55 @@ def latex(self, widget: Widget, code_block_info : CodeBlockInfo): nodes_latex.append(container_node) + def get_info_preamble(info_type : str) -> str: + known_info_type : Dict[str, str] = { + 'build' : '\\textbf{Build output}', + 'run' : '\\textbf{Runtime output}', + 'compile' : '\\textbf{Compilation output}' + } + if info_type in known_info_type: + return known_info_type[info_type] + else: + return "Let's " + info_type + " the example:" + + block_info : Dict[str, str] = code_block_info.get_info() + + for info_type in sorted(block_info): + + if block_info[info_type] == "": + # Do not show empty boxes + continue + + preamble_node = nodes.container( + '', literal_block=False, + classes=[]) + + preamble_raw = nodes.raw('', + get_info_preamble(info_type), + format='latex') + + preamble_node += preamble_raw + + container_node = nodes.container( + '', literal_block=True, + classes=['literal-block-wrapper']) + + literal = nodes.literal_block('', + block_info[info_type], + format='latex') + literal['language'] = 'none' + literal['source'] = info_type + + caption = nodes.caption('', info_type) + caption.source = literal.source + caption.line = literal.line + + # container_node += caption + container_node += literal + + nodes_latex.append(preamble_node) + nodes_latex.append(container_node) + return nodes_latex def run(self): From b1f3f8389e553d5955cf0b0feac4cdbe916574a5 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:17:02 +0100 Subject: [PATCH 10/32] Makefile: adding support for build / runtime output for PDF books. --- frontend/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/Makefile b/frontend/Makefile index c0dbbb69e..9bf705992 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -4,7 +4,8 @@ SPHINXBUILD = sphinx-build SPHINXPROJ = learnadacorecom SPHINXCONF = sphinx BUILDDIR = dist -TEST_DRIVER = PYTHONPATH="$PYTHONPATH:sphinx" python3 tests/compile_blocks.py -B $(BUILDDIR)/test_output +SRC_TEST_DIR = $(BUILDDIR)/test_output +TEST_DRIVER = PYTHONPATH="$PYTHONPATH:sphinx:../backend" python3 tests/compile_blocks.py --keep_files -B $(SRC_TEST_DIR) MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) MKFILE_DIR := $(dir $(MKFILE_PATH)) @@ -162,6 +163,7 @@ $(BOOKS): @mkdir -p $(BUILDDIR)/pdf_books/$(SPHINX_DIR) @export SPHINX_TITLE="$(SPHINX_TITLE)"; \ export SPHINX_AUTHOR="$(SPHINX_AUTHOR)"; \ + export SRC_TEST_DIR="$(SRC_TEST_DIR)"; \ $(SPHINXBUILD) -M latexpdf $@ \ "$(BUILDDIR)" $(SPHINXOPTS) $(O) -v -c "$(SPHINXCONF)" @mv $(BUILDDIR)/latex/learnadacorecom.pdf $(BUILDDIR)/pdf_books/$(SPHINX_DIR)/$(SPHINX_PDF) From 5b0009f058ee46568f2417648cab1895ae020bef Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:20:03 +0100 Subject: [PATCH 11/32] Editorial changes: removing unneeded instances of "ada-run" class. --- content/courses/intro-to-ada/chapters/arrays.rst | 8 +------- .../courses/intro-to-ada/chapters/modular_programming.rst | 6 ------ .../courses/intro-to-ada/chapters/more_about_types.rst | 2 -- .../intro-to-ada/chapters/object_oriented_programming.rst | 2 -- content/courses/intro-to-ada/chapters/records.rst | 2 -- .../intro-to-ada/chapters/strongly_typed_language.rst | 4 +--- 6 files changed, 2 insertions(+), 22 deletions(-) diff --git a/content/courses/intro-to-ada/chapters/arrays.rst b/content/courses/intro-to-ada/chapters/arrays.rst index 26ec01cad..c54fe163f 100644 --- a/content/courses/intro-to-ada/chapters/arrays.rst +++ b/content/courses/intro-to-ada/chapters/arrays.rst @@ -12,7 +12,6 @@ Arrays in Ada are used to define contiguous collections of elements that can be selected by indexing. Here's a simple example: .. code:: ada run_button project=Courses.Intro_To_Ada.Arrays.Greet - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -72,7 +71,6 @@ to index into the array. equivalence between an array and a pointer to its initial element. .. code:: ada run_button project=Courses.Intro_To_Ada.Arrays.Array_Bounds_Example - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -113,7 +111,6 @@ Since you can use any discrete type to index an array, enumeration types are permitted. .. code:: ada run_button project=Courses.Intro_To_Ada.Arrays.Month_Example - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -192,7 +189,7 @@ an element outside of the bounds of the array, you will get a run-time error instead of accessing random memory as in unsafe languages. .. code:: ada run_button project=Courses.Intro_To_Ada.Arrays.Greet_3 - :class: ada-run, ada-run-expect-failure + :class: ada-run-expect-failure with Ada.Text_IO; use Ada.Text_IO; @@ -317,7 +314,6 @@ in that case, the bounds will need to be provided when creating instances of the type. .. code:: ada run_button project=Courses.Intro_To_Ada.Arrays.Unconstrained_Array_Example - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -414,7 +410,6 @@ literals, as we can see in the example below. end String_Literals; .. code:: ada run_button project=Courses.Intro_To_Ada.Arrays.Greet_4 - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -439,7 +434,6 @@ type if you supply an initialization, since the bounds can be deduced from the initialization expression. .. code:: ada run_button project=Courses.Intro_To_Ada.Arrays.Greet_5 - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; diff --git a/content/courses/intro-to-ada/chapters/modular_programming.rst b/content/courses/intro-to-ada/chapters/modular_programming.rst index 379fd7853..0d073bbf7 100644 --- a/content/courses/intro-to-ada/chapters/modular_programming.rst +++ b/content/courses/intro-to-ada/chapters/modular_programming.rst @@ -38,7 +38,6 @@ Here is an example of a package declaration in Ada: And here is how you use it: .. code:: ada run_button project=Courses.Intro_To_Ada.Modular_Programming.Week - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; with Week; @@ -121,7 +120,6 @@ In fact, we have been using the :ada:`use` clause since almost the beginning of this tutorial. .. code:: ada run_button project=Courses.Intro_To_Ada.Modular_Programming.Week - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; -- ^ Make every entity of the Ada.Text_IO package @@ -306,7 +304,6 @@ we can use elements from this child package in a subprogram by simply writing we write :ada:`use Week.Child` in addition. For example: .. code:: ada run_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; with Week.Child; use Week.Child; @@ -348,7 +345,6 @@ same way as before: we can reuse the previous test application and adapt the :ada:`with` and :ada:`use`, and the function call. This is the updated code: .. code:: ada run_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; with Week.Child.Grandchild; use Week.Child.Grandchild; @@ -397,7 +393,6 @@ This is the corresponding package body of :ada:`Week.Child_2`: We can now reference both children in our test application: .. code:: ada run_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; with Week.Child; use Week.Child; @@ -510,7 +505,6 @@ string. Likewise, we can use this strategy to implement the This is a simple test application for the packages above: .. code:: ada run_button project=Courses.Intro_To_Ada.Modular_Programming.Visibility - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; with Book.Additional_Operations; use Book.Additional_Operations; diff --git a/content/courses/intro-to-ada/chapters/more_about_types.rst b/content/courses/intro-to-ada/chapters/more_about_types.rst index 234ddbc58..5b0ae1cdd 100644 --- a/content/courses/intro-to-ada/chapters/more_about_types.rst +++ b/content/courses/intro-to-ada/chapters/more_about_types.rst @@ -534,7 +534,6 @@ specify their values in aggregates, as seen above, and you can access their values via the dot notation. .. code:: ada run_button project=Courses.Intro_To_Ada.More_About_Types.Var_Size_Record_2 - :class: ada-run with Var_Size_Record_2; use Var_Size_Record_2; with Ada.Text_IO; use Ada.Text_IO; @@ -617,7 +616,6 @@ If you try to access a field that is not valid for your record, a Here is how you could write an evaluator for expressions: .. code:: ada run_button project=Courses.Intro_To_Ada.More_About_Types.Variant_Record - :class: ada-run with Variant_Record; use Variant_Record; with Ada.Text_IO; use Ada.Text_IO; diff --git a/content/courses/intro-to-ada/chapters/object_oriented_programming.rst b/content/courses/intro-to-ada/chapters/object_oriented_programming.rst index b68412d02..d0103fd71 100644 --- a/content/courses/intro-to-ada/chapters/object_oriented_programming.rst +++ b/content/courses/intro-to-ada/chapters/object_oriented_programming.rst @@ -341,7 +341,6 @@ type, namely an object of a classwide type. affect the original one. .. code:: ada run_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Tagged_Types - :class: ada-run with P; use P; @@ -400,7 +399,6 @@ the dot notation. Any remaining parameter are passed normally: .. code:: ada run_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Tagged_Types - :class: ada-run with P; use P; diff --git a/content/courses/intro-to-ada/chapters/records.rst b/content/courses/intro-to-ada/chapters/records.rst index edc873f8f..f9ee2b143 100644 --- a/content/courses/intro-to-ada/chapters/records.rst +++ b/content/courses/intro-to-ada/chapters/records.rst @@ -79,7 +79,6 @@ type mentioned above, we can access the :ada:`Year` component by writing Let's look at an example: .. code:: ada run_button project=Courses.Intro_To_Ada.Records.Record_Selection - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -147,7 +146,6 @@ using the :ada:`Year` component of :ada:`Some_Day`. Let's look at a complete example: .. code:: ada run_button project=Courses.Intro_To_Ada.Arrays.Record_Component_Renaming - :class: ada-run package Dates is diff --git a/content/courses/intro-to-ada/chapters/strongly_typed_language.rst b/content/courses/intro-to-ada/chapters/strongly_typed_language.rst index 81c31cbb0..339566d29 100644 --- a/content/courses/intro-to-ada/chapters/strongly_typed_language.rst +++ b/content/courses/intro-to-ada/chapters/strongly_typed_language.rst @@ -296,7 +296,6 @@ The compiler will choose a floating-point representation that supports the required precision. For example: .. code:: ada run_button project=Courses.Intro_To_Ada.Strongly_Typed_Language.Custom_Floating_Types - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -600,7 +599,6 @@ some values while staying within a single type. This is where subtypes come into play. A subtype does not introduce a new type. .. code:: ada run_button project=Courses.Intro_To_Ada.Strongly_Typed_Language.Days_Subtype - :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -642,7 +640,7 @@ constraints are enforced at run time: if you violate a subtype constraint, an exception will be raised. .. code:: ada run_button project=Courses.Intro_To_Ada.Strongly_Typed_Language.Days_Subtype_Error - :class: ada-run, ada-run-expect-failure + :class: ada-run-expect-failure with Ada.Text_IO; use Ada.Text_IO; From 9d56419d6d6889c0175bfd499d0dff1e359ab08c Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:21:50 +0100 Subject: [PATCH 12/32] Editorial changes: adding compile button to source-code blocks. --- .../intro-to-ada/chapters/exceptions.rst | 2 +- .../intro-to-ada/chapters/generics.rst | 8 +++--- .../chapters/imperative_language.rst | 12 ++++---- .../chapters/modular_programming.rst | 22 +++++++-------- .../chapters/more_about_types.rst | 28 +++++++++---------- .../chapters/object_oriented_programming.rst | 13 ++++----- .../courses/intro-to-ada/chapters/privacy.rst | 2 +- .../chapters/standard_library_containers.rst | 2 +- .../chapters/standard_library_numerics.rst | 2 +- .../intro-to-ada/chapters/subprograms.rst | 10 +++---- .../courses/intro-to-ada/chapters/tasking.rst | 8 +++--- 11 files changed, 53 insertions(+), 56 deletions(-) diff --git a/content/courses/intro-to-ada/chapters/exceptions.rst b/content/courses/intro-to-ada/chapters/exceptions.rst index 6e5e32611..bd901cc5b 100644 --- a/content/courses/intro-to-ada/chapters/exceptions.rst +++ b/content/courses/intro-to-ada/chapters/exceptions.rst @@ -14,7 +14,7 @@ Ada exceptions are not types, but instead objects, which may be peculiar to you if you're used to the way Java or Python support exceptions. Here's how you declare an exception: -.. code:: ada no_button project=Courses.Intro_To_Ada.Exceptions.Show_Exception +.. code:: ada compile_button project=Courses.Intro_To_Ada.Exceptions.Show_Exception package Exceptions is My_Except : exception; diff --git a/content/courses/intro-to-ada/chapters/generics.rst b/content/courses/intro-to-ada/chapters/generics.rst index a649e3123..84759f80c 100644 --- a/content/courses/intro-to-ada/chapters/generics.rst +++ b/content/courses/intro-to-ada/chapters/generics.rst @@ -15,7 +15,7 @@ by using the keyword :ada:`generic`. For example: .. raph-amiard: We are lacking a definition/link of metaprogramming. -.. code:: ada no_button project=Courses.Intro_To_Ada.Generics.Show_Simple_Generic +.. code:: ada compile_button project=Courses.Intro_To_Ada.Generics.Show_Simple_Generic generic type T is private; @@ -37,7 +37,7 @@ want to create an algorithm that works on any integer type, or even on any type at all, whether a numeric type or not. The following example declares a formal type :ada:`T` for the :ada:`Set` procedure. -.. code:: ada no_button project=Courses.Intro_To_Ada.Generics.Show_Formal_Type_Declaration +.. code:: ada compile_button project=Courses.Intro_To_Ada.Generics.Show_Formal_Type_Declaration generic type T is private; @@ -71,7 +71,7 @@ Formal object declaration Formal objects are similar to subprogram parameters. They can reference formal types declared in the formal specification. For example: -.. code:: ada no_button project=Courses.Intro_To_Ada.Generics.Show_Formal_Object_Declaration +.. code:: ada compile_button project=Courses.Intro_To_Ada.Generics.Show_Formal_Object_Declaration generic type T is private; @@ -95,7 +95,7 @@ We don't repeat the :ada:`generic` keyword for the body declaration of a generic subprogram or package. Instead, we start with the actual declaration and use the generic types and objects we declared. For example: -.. code:: ada no_button project=Courses.Intro_To_Ada.Generics.Show_Generic_Body_Definition +.. code:: ada compile_button project=Courses.Intro_To_Ada.Generics.Show_Generic_Body_Definition generic type T is private; diff --git a/content/courses/intro-to-ada/chapters/imperative_language.rst b/content/courses/intro-to-ada/chapters/imperative_language.rst index 827db9cca..0f2534dd6 100644 --- a/content/courses/intro-to-ada/chapters/imperative_language.rst +++ b/content/courses/intro-to-ada/chapters/imperative_language.rst @@ -118,7 +118,7 @@ and subprogram parameter modes. Ada's :ada:`if` statement is pretty unsurprising in form and function: -.. code:: ada no_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Positive +.. code:: ada compile_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Positive with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; @@ -156,7 +156,7 @@ integer value). Here's a slight variation on the example, which illustrates an :ada:`if` statement with an :ada:`else` part: -.. code:: ada no_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Positive_2 +.. code:: ada compile_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Positive_2 with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; @@ -180,7 +180,7 @@ displays the value followed by the String " is not a positive number". Our final variation illustrates an :ada:`if` statement with :ada:`elsif` sections: -.. code:: ada no_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Direction +.. code:: ada compile_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Direction with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; @@ -418,7 +418,7 @@ but with some important differences. Here's an example, a variation of a program that was shown earlier with an :ada:`if` statement: -.. code:: ada no_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Direction_2 +.. code:: ada compile_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Direction_2 with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; @@ -542,7 +542,7 @@ A declaration cannot appear as a statement. If you need to declare a local variable amidst the statements, you can introduce a new declarative region with a block statement: -.. code:: ada no_button project=Courses.Intro_To_Ada.Imperative_Language.Greet_6 +.. code:: ada compile_button project=Courses.Intro_To_Ada.Imperative_Language.Greet_6 with Ada.Text_IO; use Ada.Text_IO; @@ -589,7 +589,7 @@ If expressions Here's an alternative version of an example we saw earlier; the :ada:`if` statement has been replaced by an :ada:`if` expression: -.. code:: ada no_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Positive +.. code:: ada compile_button project=Courses.Intro_To_Ada.Imperative_Language.Check_Positive with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; diff --git a/content/courses/intro-to-ada/chapters/modular_programming.rst b/content/courses/intro-to-ada/chapters/modular_programming.rst index 0d073bbf7..99ba340e0 100644 --- a/content/courses/intro-to-ada/chapters/modular_programming.rst +++ b/content/courses/intro-to-ada/chapters/modular_programming.rst @@ -21,7 +21,7 @@ Packages Here is an example of a package declaration in Ada: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Week +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Week package Week is @@ -151,7 +151,7 @@ declarations and no body. That's not a mistake: in a package specification, which is what is illustrated above, you cannot declare bodies. Those have to be in the package body. -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Operations +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Operations package Operations is @@ -253,7 +253,7 @@ is called :ada:`Text_IO`. In the previous examples, we've been using the Let's begin our discussion on child packages by taking our previous :ada:`Week` package: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages package Week is @@ -269,7 +269,7 @@ Let's begin our discussion on child packages by taking our previous If we want to create a child package for :ada:`Week`, we may write: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages package Week.Child is @@ -280,7 +280,7 @@ If we want to create a child package for :ada:`Week`, we may write: Here, :ada:`Week` is the parent package and :ada:`Child` is the child package. This is the corresponding package body of :ada:`Week.Child`: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages package body Week.Child is @@ -323,7 +323,7 @@ the hierarchy of the previous source-code example by declaring a be the parent of the :ada:`Grandchild` package. Let's consider this implementation: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages package Week.Child.Grandchild is @@ -365,7 +365,7 @@ So far, we've seen a single child package of a parent package. However, a parent package can also have multiple children. We could extend the example above and implement a :ada:`Week.Child_2` package. For example: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages package Week.Child_2 is @@ -379,7 +379,7 @@ but it's also the parent of the :ada:`Child_2` package. In the same way, This is the corresponding package body of :ada:`Week.Child_2`: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Child_Packages package body Week.Child_2 is @@ -414,7 +414,7 @@ for elements declared in the package body of a parent package. Let's consider the package :ada:`Book` and its child :ada:`Additional_Operations`: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Visibility +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Visibility package Book is @@ -436,7 +436,7 @@ Let's consider the package :ada:`Book` and its child This is the body of both packages: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Visibility +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Visibility package body Book is @@ -486,7 +486,7 @@ implementation of the :ada:`Get_Extended_Author` function to retrieve this string. Likewise, we can use this strategy to implement the :ada:`Get_Extended_Title` function. This is the adapted code: -.. code:: ada no_button project=Courses.Intro_To_Ada.Modular_Programming.Visibility +.. code:: ada compile_button project=Courses.Intro_To_Ada.Modular_Programming.Visibility package body Book.Additional_Operations is diff --git a/content/courses/intro-to-ada/chapters/more_about_types.rst b/content/courses/intro-to-ada/chapters/more_about_types.rst index 5b0ae1cdd..8fa9fdc62 100644 --- a/content/courses/intro-to-ada/chapters/more_about_types.rst +++ b/content/courses/intro-to-ada/chapters/more_about_types.rst @@ -48,7 +48,7 @@ convenient: However, note that as soon as you used a named association, all subsequent components likewise need to be specified with names associations. -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Points +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Points package Points is type Point is record @@ -73,7 +73,7 @@ in the section on :ref:`enumeration types `. Let's take a simple example: it is possible in Ada to have functions that have the same name, but different types for their parameters. -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Overloading +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Overloading package Pkg is function F (A : Integer) return Integer; @@ -87,7 +87,7 @@ overloading. One of the novel aspects of Ada's overloading facility is the ability to resolve overloading based on the return type of a function. -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Overloading +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Overloading package Pkg is type SSID is new Integer; @@ -150,7 +150,7 @@ This is where a qualified expression becomes useful. Syntactically the target of a qualified expression can be either any expression in parentheses, or an aggregate: -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Qual_Expr +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Qual_Expr package Qual_Expr is type Point is record @@ -211,7 +211,7 @@ pointers: Here is how you declare a simple pointer type, or access type, in Ada: -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types package Dates is type Months is (January, February, March, April, May, June, July, @@ -295,7 +295,7 @@ Once we have declared an access type, we need a way to give variables of the types a meaningful value! You can allocate a value of an access type with the :ada:`new` keyword in Ada. -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types with Dates; use Dates; @@ -309,7 +309,7 @@ with the :ada:`new` keyword in Ada. If the type you want to allocate needs constraints, you can put them in the subtype indication, just as you would do in a variable declaration: -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types with Dates; use Dates; @@ -327,7 +327,7 @@ In some cases, though, allocating just by specifying the type is not ideal, so Ada also allows you to initialize along with the allocation. This is done via the qualified expression syntax: -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types with Dates; use Dates; @@ -348,7 +348,7 @@ pointer. Dereferencing a pointer uses the :ada:`.all` syntax in Ada, but is often not needed - in many cases, the access value will be implicitly dereferenced for you: -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Access_Types with Dates; use Dates; @@ -417,7 +417,7 @@ naturally defined through two types, a record type and an access type, that are mutually dependent. To declare mutually dependent types, you can use an incomplete type declaration: -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Simple_List +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Simple_List package Simple_List is type Node; @@ -448,7 +448,7 @@ known at compile time. This is illustrated in the example below: .. ?? an elaboration pragma is used. .. ?? Consider simplifying or restructuring the example to avoid this issue -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Var_Size_Record +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Var_Size_Record package Runtime_Length is function Compute_Max_Len return Natural; @@ -487,7 +487,7 @@ different sizes. You can get analogous functionality for records, too, using a special kind of field that is called a discriminant: -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Var_Size_Record_2 +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Var_Size_Record_2 package Var_Size_Record_2 is type Items_Array is array (Positive range <>) of Integer; @@ -571,7 +571,7 @@ However, discriminants can also be used to obtain the functionality of what are sometimes called "variant records": records that can contain different sets of fields. -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Variant_Record +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Variant_Record package Variant_Record is type Expr; -- Forward declaration of Expr @@ -799,7 +799,7 @@ fixed-point data types |mdash| you can find more details in this discussion about the `Q format `_. We may also rewrite this code with an exact type definition: -.. code:: ada no_button project=Courses.Intro_To_Ada.More_About_Types.Normalized_Adapted_Fixed_Point_Type +.. code:: ada compile_button project=Courses.Intro_To_Ada.More_About_Types.Normalized_Adapted_Fixed_Point_Type procedure Normalized_Adapted_Fixed_Point_Type is type TQ31 is delta 2.0 ** (-31) range -1.0 .. 1.0 - 2.0 ** (-31); diff --git a/content/courses/intro-to-ada/chapters/object_oriented_programming.rst b/content/courses/intro-to-ada/chapters/object_oriented_programming.rst index d0103fd71..b6ee1ec42 100644 --- a/content/courses/intro-to-ada/chapters/object_oriented_programming.rst +++ b/content/courses/intro-to-ada/chapters/object_oriented_programming.rst @@ -76,7 +76,7 @@ brushed on, but not really covered, up to now: You can create one or more new types from every type in Ada. Type derivation is built into the language. -.. code:: ada no_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Newtypes +.. code:: ada compile_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Newtypes package Newtypes is type Point is record @@ -184,7 +184,7 @@ functionality is added: Let's see our first tagged type declarations: -.. code:: ada no_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Tagged_Types +.. code:: ada compile_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Tagged_Types package P is type My_Class is tagged null record; @@ -433,8 +433,7 @@ applied to tagged types, as we'll see in this section. This is an example of a tagged private type: -.. code:: ada no_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Tagged_Private_Types - :class: ada-syntax-only +.. code:: ada compile_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Tagged_Private_Types package P is type T is tagged private; @@ -446,8 +445,7 @@ This is an example of a tagged private type: This is an example of a tagged limited type: -.. code:: ada no_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Tagged_Limited_Types - :class: ada-syntax-only +.. code:: ada compile_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Tagged_Limited_Types package P is type T is tagged limited record @@ -512,8 +510,7 @@ In this section, we'll discuss an useful pattern for object-oriented programming in Ada: classwide access type. Let's start with an example where we declare a tagged type :ada:`T` and a derived type :ada:`T_New`: -.. code:: ada no_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Classwide_Error - :class: ada-syntax-only +.. code:: ada compile_button project=Courses.Intro_To_Ada.Object_Oriented_Programming.Classwide_Error package P is type T is tagged null record; diff --git a/content/courses/intro-to-ada/chapters/privacy.rst b/content/courses/intro-to-ada/chapters/privacy.rst index 0061d55f2..804874625 100644 --- a/content/courses/intro-to-ada/chapters/privacy.rst +++ b/content/courses/intro-to-ada/chapters/privacy.rst @@ -47,7 +47,7 @@ Abstract data types With this high-level granularity, it might not seem obvious how to hide the implementation details of a type. Here is how it can be done in Ada: -.. code:: ada no_button project=Courses.Intro_To_Ada.Privacy.Stacks +.. code:: ada compile_button project=Courses.Intro_To_Ada.Privacy.Stacks package Stacks is type Stack is private; diff --git a/content/courses/intro-to-ada/chapters/standard_library_containers.rst b/content/courses/intro-to-ada/chapters/standard_library_containers.rst index 2582971e8..6615ad04c 100644 --- a/content/courses/intro-to-ada/chapters/standard_library_containers.rst +++ b/content/courses/intro-to-ada/chapters/standard_library_containers.rst @@ -28,7 +28,7 @@ Instantiation Here's an example showing the instantiation and declaration of a vector :ada:`V`: -.. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Vector_Inst +.. code:: ada compile_button project=Courses.Intro_To_Ada.Standard_Library.Show_Vector_Inst with Ada.Containers.Vectors; diff --git a/content/courses/intro-to-ada/chapters/standard_library_numerics.rst b/content/courses/intro-to-ada/chapters/standard_library_numerics.rst index d7434f7c5..95ffeaabe 100644 --- a/content/courses/intro-to-ada/chapters/standard_library_numerics.rst +++ b/content/courses/intro-to-ada/chapters/standard_library_numerics.rst @@ -14,7 +14,7 @@ The :ada:`Ada.Numerics.Elementary_Functions` package provides common operations for floating-point types, such as square root, logarithm, and the trigonometric functions (e.g., sin, cos). For example: -.. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Elem_Math +.. code:: ada run_button project=Courses.Intro_To_Ada.Standard_Library.Show_Elem_Math with Ada.Text_IO; use Ada.Text_IO; with Ada.Numerics; use Ada.Numerics; diff --git a/content/courses/intro-to-ada/chapters/subprograms.rst b/content/courses/intro-to-ada/chapters/subprograms.rst index c92af7a59..44e7f5791 100644 --- a/content/courses/intro-to-ada/chapters/subprograms.rst +++ b/content/courses/intro-to-ada/chapters/subprograms.rst @@ -17,13 +17,13 @@ does not. This example shows the declaration and definition of a function: -.. code:: ada no_button project=Courses.Intro_To_Ada.Subprograms.Increment +.. code:: ada compile_button project=Courses.Intro_To_Ada.Subprograms.Increment function Increment (I : Integer) return Integer; -- We declare (but don't define) a function with one -- parameter, returning an integer value -.. code:: ada no_button project=Courses.Intro_To_Ada.Subprograms.Increment +.. code:: ada compile_button project=Courses.Intro_To_Ada.Subprograms.Increment -- We define the Increment function @@ -44,7 +44,7 @@ section at all, for example: Here's another variation on the previous example: -.. code:: ada no_button project=Courses.Intro_To_Ada.Subprograms.Increment_By +.. code:: ada compile_button project=Courses.Intro_To_Ada.Subprograms.Increment_By function Increment_By (I : Integer := 0; @@ -57,7 +57,7 @@ C/C++, a call to a subprogram without parameters does not include parentheses. This is the implementation of the function above: -.. code:: ada no_button project=Courses.Intro_To_Ada.Subprograms.Increment_By +.. code:: ada compile_button project=Courses.Intro_To_Ada.Subprograms.Increment_By function Increment_By (I : Integer := 0; @@ -441,7 +441,7 @@ This can be useful, for example, to improve the readability of your application when you're using code from external sources that cannot be changed in your system. Let's look at an example: -.. code:: ada no_button project=Courses.Intro_To_Ada.Subprograms.Proc_Renaming +.. code:: ada compile_button project=Courses.Intro_To_Ada.Subprograms.Proc_Renaming procedure A_Procedure_With_Very_Long_Name_That_Cannot_Be_Changed (A_Message : String); diff --git a/content/courses/intro-to-ada/chapters/tasking.rst b/content/courses/intro-to-ada/chapters/tasking.rst index f5d7a2aa9..326fc7208 100644 --- a/content/courses/intro-to-ada/chapters/tasking.rst +++ b/content/courses/intro-to-ada/chapters/tasking.rst @@ -123,7 +123,7 @@ Synchronization also occurs if we move the task to a separate package. In the example below, we declare a task :ada:`T` in the package :ada:`Simple_Sync_Pkg`. -.. code:: ada no_button project=Courses.Intro_To_Ada.Tasking.Simple_Sync_Pkg +.. code:: ada compile_button project=Courses.Intro_To_Ada.Tasking.Simple_Sync_Pkg package Simple_Sync_Pkg is task T; @@ -131,7 +131,7 @@ the example below, we declare a task :ada:`T` in the package This is the corresponding package body: -.. code:: ada no_button project=Courses.Intro_To_Ada.Tasking.Simple_Sync_Pkg +.. code:: ada compile_button project=Courses.Intro_To_Ada.Tasking.Simple_Sync_Pkg with Ada.Text_IO; use Ada.Text_IO; @@ -363,7 +363,7 @@ the elapsed time (:ada:`Show_Elapsed_Time`) and a dummy :ada:`Computational_Intensive_App` procedure which is simulated by using a simple delay. This is the package specification: -.. code:: ada no_button project=Courses.Intro_To_Ada.Tasking.Show_Time +.. code:: ada compile_button project=Courses.Intro_To_Ada.Tasking.Show_Time with Ada.Real_Time; use Ada.Real_Time; @@ -385,7 +385,7 @@ simple delay. This is the package specification: And this is the package body: -.. code:: ada no_button project=Courses.Intro_To_Ada.Tasking.Show_Time +.. code:: ada compile_button project=Courses.Intro_To_Ada.Tasking.Show_Time with Ada.Text_IO; use Ada.Text_IO; From 35a9c12857b46fee468fcb081771bb83e78cdbb6 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:23:13 +0100 Subject: [PATCH 13/32] Editorial changes: removing paragraphs from PDF version. Leaving explicit build / runtime output only in HTML version. --- .../chapters/imperative_language.rst | 63 ++++++++++--------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/content/courses/intro-to-ada/chapters/imperative_language.rst b/content/courses/intro-to-ada/chapters/imperative_language.rst index 0f2534dd6..e54526c5d 100644 --- a/content/courses/intro-to-ada/chapters/imperative_language.rst +++ b/content/courses/intro-to-ada/chapters/imperative_language.rst @@ -35,24 +35,26 @@ Here's a very simple imperative Ada program: which we'll assume is in the source file :file:`greet.adb`. -If you compile that source with the GNAT compiler and run the executable, -you will get an unsurprising result. +.. only:: builder_html -.. code-block:: sh + If you compile that source with the GNAT compiler and run the executable, + you will get an unsurprising result. - $ gprbuild greet.adb - using project file [...]_default.gpr - Compile - [Ada] greet.adb - Bind - [gprbind] greet.bexch - [Ada] greet.ali - Link - [link] greet.adb + .. code-block:: sh - $ ./greet - Hello, World! - $ + $ gprbuild greet.adb + using project file [...]_default.gpr + Compile + [Ada] greet.adb + Bind + [gprbind] greet.bexch + [Ada] greet.ali + Link + [link] greet.adb + + $ ./greet + Hello, World! + $ There are several noteworthy things in the above program: @@ -251,16 +253,17 @@ discrete range. end loop; end Greet_5a; -Executing this procedure yields the following output: +.. only:: builder_html -.. code-block:: sh + Executing this procedure yields the following output: - Hello, World! 1 - Hello, World! 2 - Hello, World! 3 - Hello, World! 4 - Hello, World! 5 + .. code-block:: sh + Hello, World! 1 + Hello, World! 2 + Hello, World! 3 + Hello, World! 4 + Hello, World! 5 A few things to note: @@ -298,15 +301,17 @@ To iterate backwards over a range, use the :ada:`reverse` keyword: end loop; end Greet_5a_Reverse; -Executing this procedure yields the following output: +.. only:: builder_html + + Executing this procedure yields the following output: -.. code-block:: sh + .. code-block:: sh - Hello, World! 5 - Hello, World! 4 - Hello, World! 3 - Hello, World! 2 - Hello, World! 1 + Hello, World! 5 + Hello, World! 4 + Hello, World! 3 + Hello, World! 2 + Hello, World! 1 The bounds of a :ada:`for` loop may be computed at run-time; they are evaluated once, before the loop body is executed. If the value of the From c20bac6a732151f30f486210e501ac7e4470836d Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 02:23:39 +0100 Subject: [PATCH 14/32] Editorial changes: adding "ada-run" class to source-code examples. --- .../chapters/standard_library_files_streams.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/content/courses/intro-to-ada/chapters/standard_library_files_streams.rst b/content/courses/intro-to-ada/chapters/standard_library_files_streams.rst index 937dd72b9..03b8d03c1 100644 --- a/content/courses/intro-to-ada/chapters/standard_library_files_streams.rst +++ b/content/courses/intro-to-ada/chapters/standard_library_files_streams.rst @@ -68,6 +68,7 @@ Let's see an example that writes information into a new text file and then reads it back from the same file: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Simple_Text_File_IO + :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -93,6 +94,7 @@ library also includes a :ada:`Reset` procedure, which, as the name implies, resets (erases) all the information from the file. For example: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Text_File_Reset + :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -127,6 +129,7 @@ that context. The following example deletes a file and then tries to open the same file for reading: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Text_File_Input_Except + :class: ada-run with Ada.Text_IO; use Ada.Text_IO; @@ -170,6 +173,7 @@ In the following example, we instantiate the :ada:`Ada.Sequential_IO` package for floating-point types: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Seq_Float_IO + :class: ada-run with Ada.Text_IO; with Ada.Sequential_IO; @@ -204,6 +208,7 @@ following example uses a record that includes a Boolean and a floating-point value: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Seq_Rec_IO + :class: ada-run with Ada.Text_IO; with Ada.Sequential_IO; @@ -265,6 +270,7 @@ the :ada:`Ada.Sequential_IO` package by the :ada:`Ada.Direct_IO` package. This is the new source code: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Dir_Float_IO + :class: ada-run with Ada.Text_IO; with Ada.Direct_IO; @@ -304,6 +310,7 @@ the new position / index. You can use the :ada:`Index` function to retrieve the current index. Let's see an example: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Dir_Float_In_Out_File + :class: ada-run with Ada.Text_IO; with Ada.Direct_IO; @@ -370,6 +377,7 @@ Let's look at a version of the :ada:`Show_Dir_Float_IO` procedure from the previous section that makes use of stream I/O instead of direct I/O: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_Float_Stream + :class: ada-run with Ada.Text_IO; with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO; @@ -421,6 +429,7 @@ The following example shows file I/O that mixes both strings of different lengths and floating-point values: .. code:: ada no_button project=Courses.Intro_To_Ada.Standard_Library.Show_String_Stream + :class: ada-run with Ada.Text_IO; with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO; From 54c2c62318155cc807d5290223de00815193f8af Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 03:24:10 +0100 Subject: [PATCH 15/32] Test script: correcting compilation of C code block. --- frontend/tests/compile_blocks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index 252d104c5..2e669cac8 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -496,7 +496,9 @@ def make_project_block_dir(): elif block.language == "c": try: - out = run("gcc", "-c", main_file) + cmd = ["gcc", "-o", + P.splitext(main_file)[0]] + glob.glob('*.c') + out = run(*cmd) except S.CalledProcessError as e: if 'c-expect-compile-error' in block.classes: compile_error = True From 927bbbdc240ab90287a6342b5939cc399ce6b8c0 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 03:30:06 +0100 Subject: [PATCH 16/32] Test script: importing glob --- frontend/tests/compile_blocks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index 2e669cac8..9bb7e0124 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -30,6 +30,7 @@ from os import path as P import colors as C import shutil +import glob import re from widget.chop import manual_chop, cheapo_gnatchop, real_gnatchop From b7405bc48a050ddfa7824cb81ce6c41a1bd430c7 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 03:30:43 +0100 Subject: [PATCH 17/32] Widget: adding C-related Sphinx classes. --- frontend/sphinx/widget/widget.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/sphinx/widget/widget.py b/frontend/sphinx/widget/widget.py index ccc063186..e23ed9e9a 100644 --- a/frontend/sphinx/widget/widget.py +++ b/frontend/sphinx/widget/widget.py @@ -272,19 +272,21 @@ def parseOpts(self, opts: List[str]): self.__no_button = True elif opt == 'ada-syntax-only': self.__no_button = True - elif opt == 'ada-expect-compile-error': + elif opt in ['ada-expect-compile-error', + 'c-expect-compile-error']: # this is for testing, nothing to do here continue elif opt == 'ada-expect-prove-error': # this is for testing, nothing to do here continue - elif opt == 'ada-run': + elif opt in ['ada-run', 'c-run']: # this is for testing, nothing to do here continue - elif opt == 'ada-norun': + elif opt in ['ada-norun', 'c-norun']: # this is for testing, nothing to do here continue - elif opt == 'ada-run-expect-failure': + elif opt in ['ada-run-expect-failure', + 'c-run-expect-failure']: # this is for testing, nothing to do here continue else: From 5b4250ba211c8e435cac1f330af602c2f3f85604 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:15:42 +0100 Subject: [PATCH 18/32] Test script: correcting creation of directory for build/runtime output. --- frontend/tests/compile_blocks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index 9bb7e0124..6db1514ae 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -467,7 +467,8 @@ def get_main_filename(block): def make_project_block_dir(): project_block_dir = str(block.line_start) - os.makedirs(project_block_dir) + if not os.path.exists(project_block_dir): + os.makedirs(project_block_dir) return project_block_dir From e31ce4d8a907dcee2093ccf00e6839c77c1a4ade Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:16:35 +0100 Subject: [PATCH 19/32] Test script: fixing call to remove-tree in case of "keep files." --- frontend/tests/compile_blocks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index 6db1514ae..bf762c10e 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -678,7 +678,8 @@ def make_project_block_dir(): # Remove the build dir, but only if the user didn't ask for a specific # subset of code_blocks -if os.path.exists(args.build_dir) and not args.code_block: +if (os.path.exists(args.build_dir) and not args.code_block + and not args.keep_files): shutil.rmtree(args.build_dir) if not os.path.exists(args.build_dir): From 49a1cc4ecf8d621d888617b1e2274e793d32c84a Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:17:00 +0100 Subject: [PATCH 20/32] Test script: adding support for storing output of the prover. --- frontend/tests/compile_blocks.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index bf762c10e..a94c5f082 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -595,6 +595,8 @@ def make_project_block_dir(): if any(b in prove_buttons for b in block.buttons): if block.language == "ada": + project_block_dir = make_project_block_dir() + main_file = get_main_filename(block) spark_mode = True project_filename = write_project_file(main_file, @@ -628,6 +630,10 @@ def make_project_block_dir(): print_error(loc, "Failed to prove example") print(e.output) has_error = True + out = str(e.output.decode("utf-8")) + + with open(project_block_dir + "/prove.log", u"w") as logfile: + logfile.write(out) else: print_error(loc, "Wrong language selected for prove button") print(e.output) From 609671e8a845118ea00330316fa3dcea71da378a Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:17:38 +0100 Subject: [PATCH 21/32] Widget: adding support for including output of the prover for PDF book. --- frontend/sphinx/widget_extension.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/sphinx/widget_extension.py b/frontend/sphinx/widget_extension.py index 7fcd3efa8..d19cb488f 100644 --- a/frontend/sphinx/widget_extension.py +++ b/frontend/sphinx/widget_extension.py @@ -90,6 +90,7 @@ def latex(self, widget: Widget, code_block_info : CodeBlockInfo): List[nodes]: Returns a list of Latex nodes """ nodes_latex = [] + for f in widget.files: # Based on sphinx/directives/code.py @@ -118,7 +119,8 @@ def get_info_preamble(info_type : str) -> str: known_info_type : Dict[str, str] = { 'build' : '\\textbf{Build output}', 'run' : '\\textbf{Runtime output}', - 'compile' : '\\textbf{Compilation output}' + 'compile' : '\\textbf{Compilation output}', + 'prove' : '\\textbf{Prover output}' } if info_type in known_info_type: return known_info_type[info_type] From 7634c2eac72b34820630d2d00ed4a3dad0bca496 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:18:52 +0100 Subject: [PATCH 22/32] Correcting function prototype. --- .../chapters/02_Perspective.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/02_Perspective.rst b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/02_Perspective.rst index 34e60df3c..cf8268557 100644 --- a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/02_Perspective.rst +++ b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/02_Perspective.rst @@ -1945,7 +1945,7 @@ values from :ada:`'a'` to :ada:`'z'`: !main.c #include - void main(void) + int main(int argc, const char * argv[]) { char Arr [26]; char C = 'a'; @@ -2656,7 +2656,7 @@ Here's a first example: #include #include "proc.h" - void main (void) + int main(int argc, const char * argv[]) { int v1, v2; From 088a708bef0f5aa3e7de27cad9e81d535c484d60 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:20:02 +0100 Subject: [PATCH 23/32] Editorial change: correcting typo in project name of code blocks. --- .../chapters/01_Introduction.rst | 4 ++-- .../chapters/02_Perspective.rst | 18 +++++++++--------- .../chapters/03_Concurrency.rst | 4 ++-- .../chapters/04_Embedded.rst | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/01_Introduction.rst b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/01_Introduction.rst index 8002c022d..cece8deca 100644 --- a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/01_Introduction.rst +++ b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/01_Introduction.rst @@ -24,7 +24,7 @@ program in Ada and C: [C] -.. code:: c cli_input run_button project=Courses.Ada_For_C_Embedded_Dev.Introduction.Add_Angles_C +.. code:: c cli_input run_button project=Courses.Ada_For_Embedded_C_Dev.Introduction.Add_Angles_C !main.c #include @@ -60,7 +60,7 @@ program in Ada and C: [Ada] -.. code:: ada cli_input run_button project=Courses.Ada_For_C_Embedded_Dev.Introduction.Add_Angles_Ada +.. code:: ada cli_input run_button project=Courses.Ada_For_Embedded_C_Dev.Introduction.Add_Angles_Ada with Ada.Command_Line; use Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; diff --git a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/02_Perspective.rst b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/02_Perspective.rst index cf8268557..efa39f3b8 100644 --- a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/02_Perspective.rst +++ b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/02_Perspective.rst @@ -119,7 +119,7 @@ program: [C] -.. code:: c run_button manual_chop project=Courses.Ada_For_C_Embedded_Dev.Perspective.Hello_World_C +.. code:: c run_button manual_chop project=Courses.Ada_For_Embedded_C_Dev.Perspective.Hello_World_C !main.c #include @@ -132,7 +132,7 @@ program: [Ada] -.. code:: ada run_button project=Courses.Ada_For_C_Embedded_Dev.Perspective.Hello_World_Ada +.. code:: ada run_button project=Courses.Ada_For_Embedded_C_Dev.Perspective.Hello_World_Ada with Ada.Text_IO; @@ -2435,7 +2435,7 @@ Pointers to scalar objects in Ada and C look like: [Ada] -.. code:: ada run_button project=Courses.Ada_For_C_Embedded_Dev.Perspective.Access_To_Scalars +.. code:: ada run_button project=Courses.Ada_For_Embedded_C_Dev.Perspective.Access_To_Scalars procedure Main is type A_Int is access Integer; @@ -2446,7 +2446,7 @@ Pointers to scalar objects in Ada and C look like: [C] -.. code:: c run_button project=Courses.Ada_For_C_Embedded_Dev.Perspective.Pointers_To_Scalars +.. code:: c run_button project=Courses.Ada_For_Embedded_C_Dev.Perspective.Pointers_To_Scalars !main.c #include @@ -2463,7 +2463,7 @@ In Ada, an initializer can be specified with the allocation by appending [Ada] -.. code:: ada run_button project=Courses.Ada_For_C_Embedded_Dev.Perspective.Access_Initialization +.. code:: ada run_button project=Courses.Ada_For_Embedded_C_Dev.Perspective.Access_Initialization procedure Main is type A_Int is access Integer; @@ -2485,7 +2485,7 @@ objects that have gone out of scope. For example: [Ada] -.. code:: ada run_button project=Courses.Ada_For_C_Embedded_Dev.Perspective.Access_All +.. code:: ada run_button project=Courses.Ada_For_Embedded_C_Dev.Perspective.Access_All procedure Main is type A_Int is access all Integer; @@ -2497,7 +2497,7 @@ objects that have gone out of scope. For example: [C] -.. code:: c run_button project=Courses.Ada_For_C_Embedded_Dev.Perspective.Access_All_C +.. code:: c run_button project=Courses.Ada_For_Embedded_C_Dev.Perspective.Access_All_C !main.c int main(int argc, const char * argv[]) @@ -2515,7 +2515,7 @@ the access type as follows: [Ada] -.. code:: ada run_button project=Courses.Ada_For_C_Embedded_Dev.Perspective.Unchecked_Deallocation +.. code:: ada run_button project=Courses.Ada_For_Embedded_C_Dev.Perspective.Unchecked_Deallocation with Ada.Unchecked_Deallocation; @@ -2529,7 +2529,7 @@ the access type as follows: [C] -.. code:: c run_button project=Courses.Ada_For_C_Embedded_Dev.Perspective.Free +.. code:: c run_button project=Courses.Ada_For_Embedded_C_Dev.Perspective.Free !main.c #include diff --git a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/03_Concurrency.rst b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/03_Concurrency.rst index 7dcb962b2..8d8b7e377 100644 --- a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/03_Concurrency.rst +++ b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/03_Concurrency.rst @@ -603,7 +603,7 @@ using the Ravenscar profile. For example: [Ada] -.. code:: ada compile_button project=Courses.Ada_For_C_Embedded_Dev.Concurrency.Ravenscar +.. code:: ada compile_button project=Courses.Ada_For_Embedded_C_Dev.Concurrency.Ravenscar :class: ada-expect-compile-error package My_Tasks is @@ -643,7 +643,7 @@ in the main application: [Ada] -.. code:: ada run_button project=Courses.Ada_For_C_Embedded_Dev.Concurrency.Ravenscar +.. code:: ada run_button project=Courses.Ada_For_Embedded_C_Dev.Concurrency.Ravenscar with My_Tasks; use My_Tasks; diff --git a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/04_Embedded.rst b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/04_Embedded.rst index 9d1e9a94c..c79f51134 100644 --- a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/04_Embedded.rst +++ b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/04_Embedded.rst @@ -169,7 +169,7 @@ assembler as well as source-level variables to be used for input and output: [Ada] -.. code:: ada no_button project=Courses.Ada_For_C_Embedded_Dev.Embedded.Assembly_Code +.. code:: ada no_button project=Courses.Ada_For_Embedded_C_Dev.Embedded.Assembly_Code with System.Machine_Code; use System.Machine_Code; with Interfaces; use Interfaces; @@ -350,7 +350,7 @@ obvious when looking at this code snippet: [Ada] -.. code:: ada run_button project=Courses.Ada_For_C_Embedded_Dev.Embedded.Fixed_Point +.. code:: ada run_button project=Courses.Ada_For_Embedded_C_Dev.Embedded.Fixed_Point package Fixed_Definitions is From 2f7fc487dd381c033060db3c276e6e259248ece3 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:20:40 +0100 Subject: [PATCH 24/32] Test: adding missing class for expected error in C code. --- .../Ada_For_The_Embedded_C_Developer/chapters/08_Performance.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/08_Performance.rst b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/08_Performance.rst index 02e52a493..659227dfb 100644 --- a/content/courses/Ada_For_The_Embedded_C_Developer/chapters/08_Performance.rst +++ b/content/courses/Ada_For_The_Embedded_C_Developer/chapters/08_Performance.rst @@ -219,6 +219,7 @@ consider the following example in C: [C] .. code:: c manual_chop run_button project=Courses.Ada_For_Embedded_C_Dev.Performance.Division_By_Zero + :class: c-run-expect-failure !main.c #include From 750e05a1bdaf8ba8a6a1a9d4cc786e076f6902bd Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:21:51 +0100 Subject: [PATCH 25/32] GitHub actions: adding test of the build of PDF books. --- .github/workflows/sphinx-content-tests.js.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/sphinx-content-tests.js.yml b/.github/workflows/sphinx-content-tests.js.yml index 6d3441890..5d45e0f60 100644 --- a/.github/workflows/sphinx-content-tests.js.yml +++ b/.github/workflows/sphinx-content-tests.js.yml @@ -47,3 +47,5 @@ jobs: run: make SPHINXOPTS="-W" test_engine - name: Run SPHINX content tests run: make -k test_content + - name: Build PDF books including build/runtime output + run: make pdf_books From b18b6896c19a1494f7eb913bc4676aa4275d8f9d Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 20 Feb 2021 04:39:28 +0100 Subject: [PATCH 26/32] GitHub actions: adding dependencies for PDF books. --- .github/workflows/sphinx-content-tests.js.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sphinx-content-tests.js.yml b/.github/workflows/sphinx-content-tests.js.yml index 5d45e0f60..0ec28335d 100644 --- a/.github/workflows/sphinx-content-tests.js.yml +++ b/.github/workflows/sphinx-content-tests.js.yml @@ -30,7 +30,17 @@ jobs: - name: Install OS Deps run: | sudo apt-get install -y \ - graphviz + graphviz \ + texlive-latex-base \ + texlive-latex-recommended \ + texlive-latex-extra \ + texlive-fonts-recommended \ + texlive-fonts-extra \ + latexmk \ + texlive-xetex \ + fonts-lmodern \ + fonts-open-sans \ + fonts-dejavu - name: Install dependencies run: yarn --frozen-lockfile - name: ada-actions/toolchain From 8bb43e47fe5bb237df72d45d14459fe829a3044d Mon Sep 17 00:00:00 2001 From: gusthoff Date: Fri, 26 Feb 2021 12:28:53 +0100 Subject: [PATCH 27/32] GitHub actions: adding support for storing PDF books in artifact. --- .github/workflows/sphinx-content-tests.js.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/sphinx-content-tests.js.yml b/.github/workflows/sphinx-content-tests.js.yml index 0ec28335d..7f1721a58 100644 --- a/.github/workflows/sphinx-content-tests.js.yml +++ b/.github/workflows/sphinx-content-tests.js.yml @@ -59,3 +59,9 @@ jobs: run: make -k test_content - name: Build PDF books including build/runtime output run: make pdf_books + - name: Archive PDF books in artifact + uses: actions/upload-artifact@v2 + with: + name: learn-pdf-books + path: | + frontend/dist/pdf_books/*.* From ec3eef2c3b3c397284c5e44675d08177c24bfe89 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Fri, 26 Feb 2021 12:50:10 +0100 Subject: [PATCH 28/32] GitHub actions: limiting retention period to one day. --- .github/workflows/sphinx-content-tests.js.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sphinx-content-tests.js.yml b/.github/workflows/sphinx-content-tests.js.yml index 7f1721a58..d33c4f84b 100644 --- a/.github/workflows/sphinx-content-tests.js.yml +++ b/.github/workflows/sphinx-content-tests.js.yml @@ -65,3 +65,4 @@ jobs: name: learn-pdf-books path: | frontend/dist/pdf_books/*.* + retention-days: 1 From 426c46181aa1f6dc950d4fd31f4f0b4e842b5350 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Fri, 26 Feb 2021 14:39:03 +0100 Subject: [PATCH 29/32] GitHub actions: correcting path to PDF books. --- .github/workflows/sphinx-content-tests.js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sphinx-content-tests.js.yml b/.github/workflows/sphinx-content-tests.js.yml index d33c4f84b..aee91441c 100644 --- a/.github/workflows/sphinx-content-tests.js.yml +++ b/.github/workflows/sphinx-content-tests.js.yml @@ -64,5 +64,5 @@ jobs: with: name: learn-pdf-books path: | - frontend/dist/pdf_books/*.* + frontend/dist/pdf_books retention-days: 1 From 0da9a614540869b5dd8bffb141849aaa20440c69 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Fri, 26 Feb 2021 15:23:14 +0100 Subject: [PATCH 30/32] Editorial changes: replacing attention block by admonition. Using admonition to fix formatting issue in PDF book. --- content/courses/intro-to-ada/chapters/arrays.rst | 3 ++- content/courses/intro-to-ada/chapters/exceptions.rst | 2 +- .../intro-to-ada/chapters/object_oriented_programming.rst | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/content/courses/intro-to-ada/chapters/arrays.rst b/content/courses/intro-to-ada/chapters/arrays.rst index c54fe163f..32387d437 100644 --- a/content/courses/intro-to-ada/chapters/arrays.rst +++ b/content/courses/intro-to-ada/chapters/arrays.rst @@ -504,7 +504,8 @@ cases like this one, it is impossible for a compiler to know in the general case if you are assigning a value of the correct length, so this violation will generally result in a run-time error. -.. attention:: +.. admonition:: Attention + While we will learn more about this later, it is important to know that arrays are not the only types whose instances might be of unknown size at compile-time. diff --git a/content/courses/intro-to-ada/chapters/exceptions.rst b/content/courses/intro-to-ada/chapters/exceptions.rst index bd901cc5b..b05b97010 100644 --- a/content/courses/intro-to-ada/chapters/exceptions.rst +++ b/content/courses/intro-to-ada/chapters/exceptions.rst @@ -99,7 +99,7 @@ can add it to the statements block of your current subprogram: Put ("Cannot open input file"); end Open_File; -.. attention:: +.. admonition:: Attention Exception handlers have an important restriction that you need to be careful about: Exceptions raised in the declarative diff --git a/content/courses/intro-to-ada/chapters/object_oriented_programming.rst b/content/courses/intro-to-ada/chapters/object_oriented_programming.rst index b6ee1ec42..5e29afccd 100644 --- a/content/courses/intro-to-ada/chapters/object_oriented_programming.rst +++ b/content/courses/intro-to-ada/chapters/object_oriented_programming.rst @@ -329,7 +329,9 @@ type, namely an object of a classwide type. -- Dispatching: Calls My_Class.Foo end Main; -.. attention:: You can convert an object of type :ada:`Derived` to an +.. admonition:: Attention + + You can convert an object of type :ada:`Derived` to an object of type :ada:`My_Class`. This is called a *view conversion* in Ada parlance and is useful, for example, if you want to call a parent method. From 1a1a445c50e3394da438f9eaf4ea7e72ee94eed8 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Fri, 26 Feb 2021 18:00:36 +0100 Subject: [PATCH 31/32] Widget: reintroducing caption for source-code blocks in PDF books. --- frontend/sphinx/widget_extension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/sphinx/widget_extension.py b/frontend/sphinx/widget_extension.py index d19cb488f..088aae432 100644 --- a/frontend/sphinx/widget_extension.py +++ b/frontend/sphinx/widget_extension.py @@ -110,7 +110,7 @@ def latex(self, widget: Widget, code_block_info : CodeBlockInfo): caption.source = literal.source caption.line = literal.line -# container_node += caption + container_node += caption container_node += literal nodes_latex.append(container_node) From 09749f74a96108a8537df4eab5d250b496da661f Mon Sep 17 00:00:00 2001 From: gusthoff Date: Fri, 26 Feb 2021 18:01:09 +0100 Subject: [PATCH 32/32] Test script: removing "using project" line from build output. --- frontend/tests/compile_blocks.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/tests/compile_blocks.py b/frontend/tests/compile_blocks.py index a94c5f082..d300a88b8 100755 --- a/frontend/tests/compile_blocks.py +++ b/frontend/tests/compile_blocks.py @@ -482,6 +482,10 @@ def make_project_block_dir(): project_block_dir = make_project_block_dir() if block.language == "ada": + + def remove_string(some_text, rem): + return re.sub(".*" + rem + ".*\n?","", some_text) + try: out = run("gprbuild", "-gnata", "-gnatyg0-s", "-f", main_file) @@ -493,6 +497,8 @@ def make_project_block_dir(): print(e.output) has_error = True out = str(e.output.decode("utf-8")) + + out = remove_string(out, "using project") with open(project_block_dir + "/build.log", u"w") as logfile: logfile.write(out)