From e18e65c1b9ee616b5cbbce7b7477267ea2819a69 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 10 Apr 2015 16:55:18 +0200 Subject: [PATCH] example annotated for automatic docu extraction --- docs/manual/update_listings.py | 178 ++++++++++++++++++ .../example/led_counter.c | 21 ++- 2 files changed, 192 insertions(+), 7 deletions(-) create mode 100644 docs/manual/update_listings.py diff --git a/docs/manual/update_listings.py b/docs/manual/update_listings.py new file mode 100644 index 000000000..f2a9edc4a --- /dev/null +++ b/docs/manual/update_listings.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python +import os +import re +import sys + +docs_folder = "" +appendix_file = docs_folder + "examples.tex" + +lst_header = """ +\\begin{lstlisting} +""" + +lst_ending = """ +\end{lstlisting} +""" + +example_header = """ +\documentclass[11pt, oneside]{article} +\usepackage{geometry} +\geometry{letterpaper} +%\geometry{landscape} +%\usepackage[parfill]{parskip} +\usepackage{graphicx} +\usepackage{amssymb} +\usepackage{listings} +\\begin{document} +\section{Examples} +""" + +example_ending = """ +\end{document} +""" + +example_item = """ + \item \emph{EXAMPLE_TITLE}: EXAMPLE_DESC, see Section \\ref{example:EXAMPLE_LABLE}. +""" +example_section = """ +\subsection{EXAMPLE_TITLE: EXAMPLE_DESC} +\label{example:EXAMPLE_LABLE} + +""" +example_subsection = """ +\subsubsection{LISTING_CAPTION} +""" + +listing_start = """ +\\begin{lstlisting}[float, caption= LISTING_CAPTION., label=LISTING_LABLE] +""" + +listing_ending = """ +\end{lstlisting} + +""" +msp_folder = "../../platforms/msp-exp430f5438-cc2564b/example/" +# Example group title: [folder, example file, section title] +list_of_examples = { + "UART" : [[msp_folder, "led_counter", "provides UART and timer interrupt without Bluetooth", "UART and timer interrupt without Bluetooth"]] + #"GAP" : [["", "gap_inquiry"]], + #"SPP Server" : [["", "spp_counter"], + # ["", "spp_accel"], + # ["", "spp_flowcontrol"]], +} + +class State: + SearchExampleStart = 0 + SearchSnippetStart = 2 + SearchSnippetPause = 4 + SearchSnippetResume = 5 + SearchSnippetEnd = 6 + ReachedExampleEnd = 7 + +def replacePlaceholder(template, title, lable): + snippet = template.replace("API_TITLE", title).replace("API_LABLE", lable) + return snippet + + +def writeListings(fout, infile_name): + lst_lable = "" + lst_caption = "" + searchBrief = 0 + state = State.SearchExampleStart + with open(infile_name, 'rb') as fin: + for line in fin: + if searchBrief == 1: + parts = re.match('.*(@brief)\s*(.*)\n',line) + if parts: + searchBrief = 0 + brief = parts.group(2)+"\n" + if state == State.SearchExampleStart: + aout.write(brief) + state = State.SearchSnippetStart + elif state == State.SearchSnippetStart: + aout.write(example_subsection.replace("LISTING_CAPTION", lst_caption)) + brief = brief.replace(lst_lable, "\\ref{"+lst_lable+"}") + print brief + aout.write(brief) + aout.write(listing_start.replace("LISTING_CAPTION", lst_caption).replace("LISTING_LABLE", lst_lable)) + state = State.SearchSnippetEnd + continue + + if state == State.SearchExampleStart: + parts = re.match('.*(EXAMPLE_START)\((.*)\):\s*(.*)(\*/)?\n',line) + if parts: + lable = parts.group(2) + title = parts.group(2).replace("_","\_") + desc = parts.group(3).replace("_","\_") + aout.write(example_section.replace("EXAMPLE_TITLE", title).replace("EXAMPLE_DESC", desc).replace("EXAMPLE_LABLE", lable)) + searchBrief = 1 + + if state == State.SearchSnippetStart: + parts = re.match('.*(SNIPPET_START)\((.*)\):\s*(.*)(\*/)?\n',line) + if parts: + lst_lable = parts.group(2) + lst_caption = parts.group(3).replace("_","\_") + searchBrief = 1 + + if state == State.SearchSnippetEnd: + parts_end = re.match('.*(SNIPPET_END).*',line) + parts_pause = re.match('.*(SNIPPET_PAUSE).*',line) + + if not parts_end and not parts_pause: + parts = re.match('.*(\*)/*\s*\n', line); + if parts: + continue + aout.write(line) + continue + elif parts_end: + aout.write(listing_ending) + state = State.SearchSnippetStart + continue + elif parts_pause: + aout.write("...\n") + state = State.SearchSnippetResume + continue + + if state == State.SearchSnippetResume: + parts = re.match('.*(SNIPPET_RESUME).*',line) + if parts: + state = State.SearchSnippetEnd + continue + + parts = re.match('.*(EXAMPLE_END).*',line) + if parts: + if state != State.SearchSnippetStart: + print "Formating error detected" + state = State.ReachedExampleEnd + print "Reached end of the example" + + + +# write list of examples +with open(appendix_file, 'w') as aout: + aout.write(example_header) + aout.write("\\begin{itemize}\n"); + + for group_title, examples in list_of_examples.iteritems(): + group_title = group_title + " example" + if len(examples) > 1: + group_title = group_title + "s" + group_title = group_title + ":" + + aout.write(" \item " + group_title + "\n"); + aout.write(" \\begin{itemize}\n"); + for example in examples: + lable = example[1] + title = example[1].replace("_","\_") + desc = example[2].replace("_","\_") + aout.write(example_item.replace("EXAMPLE_TITLE", title).replace("EXAMPLE_DESC", desc).replace("EXAMPLE_LABLE", lable)) + aout.write(" \\end{itemize}\n") + aout.write("\\end{itemize}\n") + + for group_title, examples in list_of_examples.iteritems(): + for example in examples: + file_name = example[0] + example[1] + ".c" + writeListings(aout, file_name) + + aout.write(example_ending) + diff --git a/platforms/msp-exp430f5438-cc2564b/example/led_counter.c b/platforms/msp-exp430f5438-cc2564b/example/led_counter.c index 09e2f0ddb..3d57c5118 100644 --- a/platforms/msp-exp430f5438-cc2564b/example/led_counter.c +++ b/platforms/msp-exp430f5438-cc2564b/example/led_counter.c @@ -1,8 +1,7 @@ -// ***************************************************************************** -// -// led_counter demo - uses the BTstack run loop to blink an LED -// -// ***************************************************************************** + +/* EXAMPLE_START(led_counter): UART and timer interrupt without Bluetooth + * @brief The example uses the BTstack run loop to blink an LED. The example demonstrates how to setup hardware, initialize BTstack without Bluetooth, provide a periodic timer to toggle an LED and print number of toggles as a minimal BTstack test. + */ #include #include @@ -30,7 +29,10 @@ static void run_loop_register_timer(timer_source_t *timer, uint16_t period){ run_loop_add_timer(timer); } -static void heartbeat_handler(timer_source_t *ts){ +/* SNIPPET_START(LEDToggler): Periodic counter + * @brief As timers in BTstack are single shot, the periodic counter is implemented by re-registering the timer source in the heartbeat handler callback function. Listing LEDToggler shows heartbeat handler adapted to periodically toggle an LED and print number of toggles. + */ + static void heartbeat_handler(timer_source_t *ts){ // increment counter char lineBuffer[30]; sprintf(lineBuffer, "BTstack counter %04u\n\r", ++counter); @@ -42,7 +44,11 @@ static void heartbeat_handler(timer_source_t *ts){ // re-register timer run_loop_register_timer(ts, HEARTBEAT_PERIOD_MS); } +/* SNIPPET_END(LEDToggler) */ +/* SNIPPET_START(RunLoopExecution): Run loop execution + * @brief Listing RunLoopExecution shows how to setup and start the run loop. For hardware and BTstack setup, please check the source code in \path{../src/main.c} + */ static void timer_setup(){ // set one-shot timer heartbeat.process = &heartbeat_handler; @@ -58,4 +64,5 @@ int btstack_main(int argc, const char * argv[]){ return 0; } - +/* SNIPPET_END(RunLoopExecution) */ +/* EXAMPLE_END */ \ No newline at end of file