diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..f19fa97a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "doxy/doxygen2jsdoc"] + path = doxy/doxygen2jsdoc + url = https://github.com/intel-iot-devkit/doxygen2jsdoc +[submodule "doxy/doxyport"] + path = doxy/doxyport + url = https://github.com/intel-iot-devkit/doxyport diff --git a/.travis.yml b/.travis.yml index b713b563..74547323 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,45 +3,6 @@ sudo: required language: cpp -compiler: - - clang - - gcc - -env: - - TARGET=doc - - TARGET=python - - TARGET=java - - TARGET=node4 - - TARGET=node5 - - TARGET=node6 - - TARGET=android - - TARGET=sonar-scan - -matrix: - exclude: - - compiler: clang - env: TARGET=java - - compiler: gcc - env: TARGET=android - - compiler: clang - env: TARGET=sonar-scan - include: - - compiler: gcc - env: GCC_VERSION=6 TARGET=doc - - compiler: gcc - env: GCC_VERSION=6 TARGET=python - - compiler: gcc - env: GCC_VERSION=6 TARGET=java - - compiler: gcc - env: GCC_VERSION=6 TARGET=node4 - - compiler: gcc - env: GCC_VERSION=6 TARGET=node5 - - compiler: gcc - env: GCC_VERSION=6 TARGET=node6 - allow_failures: - - compiler: gcc - env: TARGET=sonar-scan - services: - docker @@ -51,14 +12,71 @@ before_install: - chmod +x docker-compose - sudo mv docker-compose /usr/local/bin -before_script: - - if [ "$CC" == "gcc" ]; then export CC=gcc-${GCC_VERSION:-5}; fi - - if [ "$CXX" == "g++" ]; then export CXX=g++-${GCC_VERSION:-5}; fi - - if [ "$CC" == "clang" ]; then export CC=clang-3.8; fi - - if [ "$CXX" == "clang++" ]; then export CXX=clang++-3.8; fi - - docker-compose build base - - if [ "$TARGET" == "android" ]; then docker-compose build java; fi - - docker-compose build ${TARGET} - -script: - - docker-compose run ${TARGET} +jobs: + fast_finish: true + allow_failures: + - env: TARGET=sonar-scan + - env: TARGET=ipk + include: + - &run-with-clang + stage: Clang 3.8 + env: TARGET=python + before_script: docker-compose pull ${TARGET} + script: + - export CC=clang-3.8 CXX=clang++-3.8 + - docker-compose run ${TARGET} + - <<: *run-with-clang + env: TARGET=node4 + - <<: *run-with-clang + env: TARGET=node5 + - <<: *run-with-clang + env: TARGET=node6 + - <<: *run-with-clang + env: TARGET=java + - &run-with-gcc-5 + stage: Gcc 5 + env: TARGET=python + before_script: docker-compose pull ${TARGET} + script: + - export CC=gcc-5 CXX=g++-5 + - docker-compose run ${TARGET} + - <<: *run-with-gcc-5 + env: TARGET=node4 + - <<: *run-with-gcc-5 + env: TARGET=node5 + - <<: *run-with-gcc-5 + env: TARGET=node6 + - <<: *run-with-gcc-5 + env: TARGET=java + - &run-with-gcc-6 + stage: Gcc 6 + env: TARGET=python + before_script: docker-compose pull ${TARGET} + script: + - export CC=gcc-6 CXX=g++-6 + - docker-compose run ${TARGET} + - <<: *run-with-gcc-6 + env: TARGET=node4 + - <<: *run-with-gcc-6 + env: TARGET=node5 + - <<: *run-with-gcc-6 + env: TARGET=node6 + - <<: *run-with-gcc-6 + env: TARGET=java + - &run-additional-jobs + stage: Additional Jobs + env: TARGET=doc + before_script: docker-compose pull ${TARGET} + script: + - export CC=clang-3.8 CXX=clang++-3.8 + - docker-compose run ${TARGET} + - <<: *run-additional-jobs + env: TARGET=android + - <<: *run-additional-jobs + env: TARGET=sonar-scan + - <<: *run-additional-jobs + env: TARGET=ipk + - <<: *run-additional-jobs + env: TARGET=rpm + - <<: *run-additional-jobs + env: TARGET=npm diff --git a/CMakeLists.txt b/CMakeLists.txt index 70c14a15..3a6098cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,7 +318,7 @@ if (BUILDDOC) COMMENT "Generating API documentation with Doxygen" VERBATIM ) - # Check if Sphinx is installed and add target to generate API documentationa + # Check if Sphinx is installed and add target to generate API documentation # Currently, the per-module documentation for python is generated from the # python2 modules. if(BUILDSWIGPYTHON) @@ -343,14 +343,10 @@ if (BUILDDOC) # Check if Yuidoc is installed and add target for API documentation if(BUILDSWIGNODE) find_package(Yuidoc REQUIRED) - file(GLOB_RECURSE JSDOC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/doxy/node doxy/node/*) - foreach(JSDOC_FILE ${JSDOC_FILES}) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxy/node/${JSDOC_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${JSDOC_FILE} COPYONLY) - endforeach() add_custom_target(jsdoc ALL - COMMAND ${NODEJS_EXECUTABLE} docgen -m upm -i xml -t ${CMAKE_CURRENT_SOURCE_DIR}/src -g ../../ - COMMAND ${YUIDOC_EXECUTABLE} -C --no-sort --helpers generators/yuidoc/helper.js --themedir generators/yuidoc/tmpl -o html/node jsdoc/yuidoc/upm - COMMAND ${NODEJS_EXECUTABLE} tolower -i html/node + COMMAND ${CMAKE_SOURCE_DIR}/doxy/doxygen2jsdoc/docgen.js -m upm -i xml -o jsdoc -t ${CMAKE_CURRENT_SOURCE_DIR}/src -g ../../ + COMMAND ${YUIDOC_EXECUTABLE} -C --no-sort --helpers ${CMAKE_SOURCE_DIR}/doxy/node/generators/yuidoc/helper.js --themedir ${CMAKE_SOURCE_DIR}/doxy/node/generators/yuidoc/tmpl -o html/node jsdoc/yuidoc/upm + COMMAND ${CMAKE_SOURCE_DIR}/doxy/doxygen2jsdoc/tolower.js -i html/node DEPENDS doc WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating API documentation with Yuidoc" VERBATIM diff --git a/docker-compose.yaml b/docker-compose.yaml index 779d3464..edcacbbe 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,14 +3,7 @@ version: '2.1' services: base: - image: upm-base - build: - context: . - dockerfile: docker/Dockerfile.base - args: - - http_proxy - - https_proxy - - no_proxy + image: dnoliver/upm-base environment: - http_proxy - https_proxy @@ -35,17 +28,38 @@ services: doc: extends: base + image: dnoliver/upm-all environment: + - BUILDSWIGPYTHON=ON + - BUILDSWIGJAVA=ON + - BUILDSWIGNODE=ON - BUILDDOC=ON - command: bash -c "./scripts/run-cmake.sh && make -j8 -Cbuild doc" + command: bash -c "./scripts/run-cmake.sh && ./scripts/build-doc.sh" + + ipk: + extends: base + environment: + - IPK=ON + - BUILDDOC=OFF + command: bash -c "./scripts/run-cmake.sh && make -Cbuild -j8 package" + + rpm: + extends: doc + environment: + - RPM=ON + - BUILDDOC=OFF + command: bash -c "./scripts/run-cmake.sh && make -Cbuild -j8 package" + + npm: + extends: doc + environment: + - NPM=ON + - BUILDDOC=OFF + command: bash -c "./scripts/run-cmake.sh && make -Cbuild -j8 npmpkg" sonar-scan: extends: base - image: upm-sonar - build: - dockerfile: docker/Dockerfile.sonar - args: - - NODE_VERSION=v5.12.0 + image: dnoliver/upm-all environment: - BUILDSWIGPYTHON=ON - BUILDSWIGNODE=ON @@ -63,52 +77,36 @@ services: python: extends: base - image: upm-python - build: - dockerfile: docker/Dockerfile.python + image: dnoliver/upm-python environment: - BUILDSWIGPYTHON=ON command: bash -c "./scripts/run-cmake.sh && cd build && make -j8 && make -j8 install && ldconfig && ctest --output-on-failure" java: extends: base - image: upm-java - build: - dockerfile: docker/Dockerfile.java + image: dnoliver/upm-java environment: - BUILDSWIGJAVA=ON command: bash -c "./scripts/run-cmake.sh && cd build && make -j8 && make -j8 install && ldconfig && ctest --output-on-failure" android: extends: java - image: upm-android - build: - dockerfile: docker/Dockerfile.android + image: dnoliver/upm-android environment: - BUILDTESTS=OFF command: bash -c "./scripts/build-android.sh" node4: extends: base - image: upm-node4 - build: - dockerfile: docker/Dockerfile.node - args: - - NODE_VERSION=v4.4.7 + image: dnoliver/upm-node4 environment: - BUILDSWIGNODE=ON command: bash -c "./scripts/run-cmake.sh && cd build && make -j8 && make -j8 install && ldconfig && ctest --output-on-failure -E examplenames_js" node5: extends: node4 - image: upm-node5 - build: - args: - - NODE_VERSION=v5.12.0 + image: dnoliver/upm-node5 node6: extends: node4 - image: upm-node6 - build: - args: - - NODE_VERSION=v6.11.0 + image: dnoliver/upm-node6 diff --git a/docker/Dockerfile.android b/docker/Dockerfile.android deleted file mode 100644 index e0864c75..00000000 --- a/docker/Dockerfile.android +++ /dev/null @@ -1,67 +0,0 @@ -FROM upm-java - -WORKDIR /opt - -# Install CMake 3.6.2 -RUN wget -q https://cmake.org/files/v3.6/cmake-3.6.2-Linux-x86_64.sh && \ - mkdir /opt/cmake && \ - sh /opt/cmake-3.6.2-Linux-x86_64.sh --prefix=/opt/cmake --skip-license && \ - ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake && \ - cmake --version && \ - rm -fr /opt/cmake-3.6.2-Linux-x86_64.sh - -# Android NDK build Dependencies -RUN wget -q https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip && \ - unzip -qq android-ndk-r14b-linux-x86_64.zip && \ - rm -fr android-ndk-r14b-linux-x86_64.zip -ENV NDK_HOME /opt/android-ndk-r14b -ENV NDK_MODULE_PATH /opt/android-ndk-r14b - -# Android Things library -RUN wget -q https://github.com/androidthings/native-libandroidthings/archive/0.4.1-devpreview.tar.gz && \ - tar xf 0.4.1-devpreview.tar.gz && \ - rm -fr /opt/0.4.1-devpreview.tar.gz -ENV ANDROIDTHINGS_NATIVE_LIB /opt/native-libandroidthings-0.4.1-devpreview - -# Build Mraa For Android Things -RUN git clone --depth 1 https://github.com/intel-iot-devkit/mraa.git && \ - cd mraa && \ - cmake \ - -DANDROID_COMPILER_FLAGS_CXX='-std=c++11' \ - -DANDROID_PIE=1 \ - -DANDROID_PLATFORM=android-24 \ - -DANDROID_STL_FORCE_FEATURES=on \ - -DANDROID_STL=c++_shared \ - -DANDROID_TOOLCHAIN_NAME=x86-i686 \ - -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \ - -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \ - -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=BOTH \ - -DCMAKE_FIND_ROOT_PATH=$NDK_HOME/platforms/android-24/arch-x86/ \ - -DCMAKE_MODULE_PATH=$ANDROIDTHINGS_NATIVE_LIB \ - -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ - -DCMAKE_INSTALL_PREFIX=/opt/mraa/install \ - -DJAVA_AWT_INCLUDE_PATH=$JAVA_HOME/include \ - -DJAVA_AWT_LIBRARY=$JAVA_HOME/jre/lib/amd64/libjawt.so \ - -DJAVA_INCLUDE_PATH=$JAVA_HOME/include \ - -DJAVA_INCLUDE_PATH2=$JAVA_HOME/include/linux \ - -DJAVA_JVM_LIBRARY=$JAVA_HOME/jre/lib/amd64/server/libjvm.so \ - -DBUILDARCH=PERIPHERALMAN \ - -DJSONPLAT=OFF \ - -DBUILDDOC=OFF \ - -DBUILDSWIG=ON \ - -DBUILDSWIGPYTHON=OFF \ - -DBUILDSWIGNODE=OFF \ - -DBUILDSWIGJAVA=ON \ - -DENABLEEXAMPLES=OFF \ - -DINSTALLGPIOTOOL=OFF \ - -DINSTALLTOOLS=OFF \ - -DBUILDTESTS=OFF \ - -H. \ - -Bbuild && \ - make -j8 -Cbuild install -ENV MRAA_INSTALL_DIR /opt/mraa/install - -# Set Workdir -WORKDIR $UPM_SRC_DIR - -CMD bash diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base deleted file mode 100644 index 89872254..00000000 --- a/docker/Dockerfile.base +++ /dev/null @@ -1,68 +0,0 @@ -FROM ubuntu:16.04 - -ENV DEBIAN_FRONTEND noninteractive - -# Prepare apt-get -RUN apt-get update && apt-get -y --no-install-recommends install software-properties-common - -# Add Mraa Repository -RUN add-apt-repository ppa:mraa/mraa && \ - # Update apt-get - apt-get -y update && \ - # Install apt-utils - apt-get -y --no-install-recommends install apt-utils && \ - # Main Build Dependencies - apt-get -y --no-install-recommends install git build-essential cmake swig clang-3.8 gcc-5 g++-5 libpthread-stubs0-dev pkg-config wget unzip \ - # Mraa Build Dependencies - libmraa1 libmraa-dev mraa-tools \ - # Docs Build Dependencies - python-sphinx doxygen graphviz \ - # Sensor Specific Build Dependencies - libjpeg-dev - -# Test Build Dependencies -RUN apt-get -y --no-install-recommends install python python-dev python-pip && \ - pip install chardet - -# Install gcc-6 g++-6 -RUN add-apt-repository ppa:ubuntu-toolchain-r/test && \ - apt-get update && \ - apt-get -y --no-install-recommends install gcc-6 g++-6 - -WORKDIR /opt - -# Install libbacnet 0.3.12 -RUN wget https://downloads.sourceforge.net/project/bacnet/bacnet-stack/bacnet-stack-0.8.3/bacnet-stack-0.8.3.zip && \ - unzip -qq bacnet-stack-0.8.3.zip && cd bacnet-stack-0.8.3 && \ - BACDL_DEFINE=-DBACDL_MSTP=1 MAKE_DEFINE=-fPIC make clean all && \ - cp /opt/bacnet-stack-0.8.3/lib/libbacnet.a /usr/lib/libbacnet.a && \ - echo "prefix=/usr" >> /usr/lib/pkgconfig/libbacnet.pc && \ - echo "exec_prefix=\${prefix}" >> /usr/lib/pkgconfig/libbacnet.pc && \ - echo "libdir=\${exec_prefix}/lib" >> /usr/lib/pkgconfig/libbacnet.pc && \ - echo "includedir=\${exec_prefix}/include" >> /usr/lib/pkgconfig/libbacnet.pc && \ - echo "Name: bacnet" >> /usr/lib/pkgconfig/libbacnet.pc && \ - echo "Description: BACnet library" >> /usr/lib/pkgconfig/libbacnet.pc && \ - echo "Version: 0.8.3" >> /usr/lib/pkgconfig/libbacnet.pc && \ - echo "Libs: -L\${libdir} -lbacnet" >> /usr/lib/pkgconfig/libbacnet.pc && \ - echo "Cflags: -I\${includedir}/bacnet" >> /usr/lib/pkgconfig/libbacnet.pc && \ - mkdir /usr/include/bacnet && \ - cp /opt/bacnet-stack-0.8.3/include/* /usr/include/bacnet/ && \ - rm -fr /opt/bacnet-stack-0.8.3.zip - -# Install libmodbus 3.1.4 -RUN wget http://libmodbus.org/releases/libmodbus-3.1.4.tar.gz && \ - tar xf libmodbus-3.1.4.tar.gz && cd libmodbus-3.1.4 && \ - ./configure && make -j8 && make install && \ - rm -fr /opt/libmodbus-3.1.4.tar.gz - -# Install openzwave -RUN apt-get update && apt-get -y --no-install-recommends install libudev-dev && \ - git clone --depth 1 https://github.com/OpenZWave/open-zwave.git && cd open-zwave && make -j8 install && \ - echo "/usr/local/lib64" >> /etc/ld.so.conf.d/openzwave.conf - -# Set Workdir -ARG UPM_SRC_DIR=/usr/src/app -ENV UPM_SRC_DIR $UPM_SRC_DIR -WORKDIR $UPM_SRC_DIR - -CMD bash diff --git a/docker/Dockerfile.java b/docker/Dockerfile.java deleted file mode 100644 index 7f88493e..00000000 --- a/docker/Dockerfile.java +++ /dev/null @@ -1,15 +0,0 @@ -FROM upm-base - -# Update apt-get -RUN apt-get -y update && \ - # Java Build Dependencies - apt-get -y --no-install-recommends install libmraa-java \ - default-jre default-jdk - -# Configure Java Home -ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/ - -# Set Workdir -WORKDIR $UPM_SRC_DIR - -CMD bash diff --git a/docker/Dockerfile.node b/docker/Dockerfile.node deleted file mode 100644 index 833eebc5..00000000 --- a/docker/Dockerfile.node +++ /dev/null @@ -1,17 +0,0 @@ -FROM upm-base - -WORKDIR /opt - -# Node.js Build Dependencies -RUN wget -q -O - https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash -ENV NVM_DIR /root/.nvm -ARG NODE_VERSION -RUN . $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm use $NODE_VERSION && \ - npm install -g node-gyp && node-gyp install -ENV PATH $NVM_DIR/versions/node/$NODE_VERSION/bin:$PATH - -# Set Workdir -WORKDIR $UPM_SRC_DIR - -CMD bash - diff --git a/docker/Dockerfile.python b/docker/Dockerfile.python deleted file mode 100644 index aaa99808..00000000 --- a/docker/Dockerfile.python +++ /dev/null @@ -1,16 +0,0 @@ -FROM upm-base - -# Update apt-get -RUN apt-get -y update && \ - # Python Build Dependencies - apt-get -y --no-install-recommends install python-mraa python3-mraa \ - python python-dev python3 python3-dev python-pip python3-pip - -# Install Python Test Dependencies -RUN pip install chardet && pip3 install chardet - -# Set Workdir -WORKDIR $UPM_SRC_DIR - -CMD bash - diff --git a/docker/Dockerfile.sonar b/docker/Dockerfile.sonar deleted file mode 100644 index 44ac71ec..00000000 --- a/docker/Dockerfile.sonar +++ /dev/null @@ -1,41 +0,0 @@ -FROM upm-base - -# Update apt-get -RUN apt-get -y update && \ - # Python Build Dependencies - apt-get -y --no-install-recommends install python-mraa python3-mraa \ - python python-dev python3 python3-dev python-pip python3-pip \ - # Java Build Dependencies - libmraa-java default-jre default-jdk - -# Set JAVA_HOME -ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/ - -WORKDIR /opt - -# Install Python Test Dependencies -RUN pip install chardet && pip3 install chardet - -# Node.js Build Dependencies -RUN wget -q -O - https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash -ENV NVM_DIR /root/.nvm -ARG NODE_VERSION -RUN . $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm use $NODE_VERSION && \ - npm install -g node-gyp && node-gyp install -ENV PATH $NVM_DIR/versions/node/$NODE_VERSION/bin:$PATH - -# Static Code Analysis Scanner -ENV SONAR_DIR /opt/sonar -ENV SONAR_VER "3.0.3.778" -WORKDIR $SONAR_DIR -RUN wget https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_VER}-linux.zip && \ - wget https://sonarqube.com/static/cpp/build-wrapper-linux-x86.zip && \ - unzip sonar-scanner-cli-${SONAR_VER}-linux.zip && \ - unzip build-wrapper-linux-x86.zip && \ - rm sonar-scanner-cli-${SONAR_VER}-linux.zip build-wrapper-linux-x86.zip -ENV PATH $SONAR_DIR/sonar-scanner-${SONAR_VER}-linux/bin:$SONAR_DIR/build-wrapper-linux-x86:$PATH - -# Set Workdir -WORKDIR $UPM_SRC_DIR - -CMD bash diff --git a/docs/building.md b/docs/building.md index dc939427..5817f954 100644 --- a/docs/building.md +++ b/docs/building.md @@ -139,61 +139,6 @@ Requirements: **NOTE:** docker-compose is an optional requirement. It actually make running complex docker build and run command easier. But you can just use docker to build and run. -### Docker Images Hierarchy - -To improve build times and images sizes, upm use a build hierarchy to incrementally -create a build environment. Find below a brief description of them: - -1. **upm-base:** Provides the basic infrastructure and tools to compile C/C++ code and documentation. -2. **upm-python:** Provides the python2/python3 build tools. Depends on `upm-base`. -3. **upm-java:** Provides the Java build tools. Depends on `upm-base`. -4. **upm-android:** Provides the Android Things build tools. Depends on `upm-java`. -5. **upm-node4:** Provides the Node.js v4.4.7 build tools. Depends on `upm-base`. -6. **upm-node5:** Same as `upm-node4`, but using Node.js v5.12.0. -7. **upm-node6:** Same as `upm-node4`, but using Node.js v6.11.0. - -**NOTE:** If you want to know which tools are installed for each of the upm targets, -just take a look at the `docker/` folder. All the related Dockerfiles are stored there! - -### Building Docker Images - -**tl;dr:** Just use this commands to build the hierarchy: - -```sh -# Build the base image -$ docker-compose build base -# Build python image -$ docker-compose build python -# Build java image -$ docker-compose build java -# Build node4 image -$ docker-compose build node4 -# Build node5 image -$ docker-compose build node5 -# Build node6 image -$ docker-compose build node6 -# Build android things image -$ docker-compose build android -``` - -**docker-compose** will take a look at the `docker-compose.yaml` file in the repository -root directory, and build the requested target for you. At the end, docker-compose will -tag the image built with an `upm-` prefix. You can check them by running `docker images`. - -If you don't want to use docker-compose, you can also use `docker build` to generate every image. -For example, to create the base image, you can do: - -```sh -# From the repository root folder -$ docker build -d docker/Dockerfile.base -t upm-base . -``` - -Now, you don't actually need to build every image to start working. Let's say you -are a Python developer, and has no idea what Node.js is, just build the base and -python image! - -**NOTE:** If you work on Android Things, you will need the base, java, and android image. - ### Using Docker Images to build Upm **tl;dr:** Just use this commands to build upm: @@ -242,7 +187,7 @@ $ docker run \ --env BUILDSWIGPYTHON=ON \ --env BUILDSWIGJAVA=OFF \ --env BUILDSWIGNODE=OFF \ - upm-python \ + dnoliver/upm-python \ bash -c "./scripts/run-cmake.sh && make -Cbuild" ``` @@ -256,25 +201,6 @@ to proxy settings: Visit [this link](https://docs.docker.com/engine/admin/systemd/#httphttps-proxy) to configure docker daemon behind a proxy. -**docker build fails to fetch packages from internet** - -docker-compose will automatically take `http_proxy`, `https_proxy`, and `no_proxy` -environment variables and use it as build arguments. Be sure to properly configure -this variables before building. - -docker, unlinke docker-compose, do not take the proxy settings from the environment -automatically. You need to send them as build arguments: - -```sh -# From the repository root folder -$ docker build \ - -d docker/Dockerfile.base \ - --build-arg http_proxy=$http_proxy \ - --build-arg https_proxy=$https_proxy \ - --build-arg no_proxy=$no_proxy \ - -t upm-base . -``` - **docker run fails to access the internet** docker-compose will automatically take `http_proxy`, `https_proxy`, and `no_proxy` @@ -295,6 +221,6 @@ $ docker run \ --env http_proxy=$http_proxy \ --env https_proxy=$https_proxy \ --env no_proxy=$no_proxy \ - upm-python \ + dnoliver/upm-python \ bash -c "./scripts/run-cmake.sh && make -Cbuild" ``` diff --git a/doxy/Doxyfile.in b/doxy/Doxyfile.in index a7ef8a55..36af3228 100644 --- a/doxy/Doxyfile.in +++ b/doxy/Doxyfile.in @@ -129,8 +129,6 @@ ABBREVIATE_BRIEF = "The $name class" \ ALWAYS_DETAILED_SEC = NO -DETAILS_AT_TOP = YES - # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment @@ -1861,18 +1859,6 @@ GENERATE_XML = YES XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size diff --git a/doxy/Doxyfile.java.in b/doxy/Doxyfile.java.in index 58eee576..b0d6a6a6 100644 --- a/doxy/Doxyfile.java.in +++ b/doxy/Doxyfile.java.in @@ -129,8 +129,6 @@ ABBREVIATE_BRIEF = "The $name class" \ ALWAYS_DETAILED_SEC = NO -DETAILS_AT_TOP = YES - # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment @@ -1818,18 +1816,6 @@ GENERATE_XML = YES XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size diff --git a/doxy/doxygen2jsdoc b/doxy/doxygen2jsdoc new file mode 160000 index 00000000..67cad692 --- /dev/null +++ b/doxy/doxygen2jsdoc @@ -0,0 +1 @@ +Subproject commit 67cad692720982ac3cbd99bf1c3421edc69b08f9 diff --git a/doxy/doxyport b/doxy/doxyport new file mode 160000 index 00000000..db3e1a6e --- /dev/null +++ b/doxy/doxyport @@ -0,0 +1 @@ +Subproject commit db3e1a6eb8677d3166d90d82c3068689803ce547 diff --git a/doxy/node/docgen.js b/doxy/node/docgen.js deleted file mode 100644 index 305cec39..00000000 --- a/doxy/node/docgen.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Author: Heidi Pan - * Copyright (c) 2015 Intel Corporation. - * - * 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. - */ - -// dependencies -var xml2js = require('./xml2js') - , fs = require('fs') - , Promise = require('bluebird') - , opts = require('commander') - , _ = require('lodash') - , mkdirp = require('mkdirp'); - - -// parse command line arguments -_.extend(opts, { addOptions: function(module) { return module.addOptions(opts); } }); -opts - .option('-m, --module [module]', 'module name for which to build documentation', 'mraa') - .option('-f, --formats [formats]', 'format for js comments', 'yuidoc,ternjs') - .option('-o, --outdir [directory]', 'top directory to build documentation', __dirname + '/jsdoc') - .addOptions(xml2js) - .parse(process.argv); - - -// use promise-style programming rather than spaghetti callbacks -Promise.promisifyAll(fs); -Promise.promisifyAll(mkdirp); - - -// main -xml2js.parse().then(function(specjs) { - var formats = opts.formats.split(','); - Promise.all(_.map(formats, function(format) { - var generateDocs = require(__dirname + '/generators/' + format + '/generator'); - var dir = opts.outdir + '/' + format + '/' + specjs.MODULE; - return mkdirp.mkdirpAsync(dir).then(function() { - return fs.writeFileAsync(dir + '/doc.js', generateDocs(specjs)); - }); - })); -}); diff --git a/doxy/node/generators/jsdoc/conf.json b/doxy/node/generators/jsdoc/conf.json deleted file mode 100644 index a2f37cca..00000000 --- a/doxy/node/generators/jsdoc/conf.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "templates": { - "default": { - "outputSourceFiles": false - } - } -} \ No newline at end of file diff --git a/doxy/node/generators/jsdoc/generator.js b/doxy/node/generators/jsdoc/generator.js deleted file mode 100644 index 6dd3d7dc..00000000 --- a/doxy/node/generators/jsdoc/generator.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Author: Heidi Pan - * Copyright (c) 2015 Intel Corporation. - * - * 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. - */ - -// dependencies -var _ = require('lodash'); - - -// generate JSDoc-style documentation -function generateDocs(specjs) { - var docs = GENERATE_MODULE(specjs.MODULE); - docs = _.reduce(specjs.METHODS, function(memo, methodSpec, methodName) { - return memo += GENERATE_METHOD(methodName, methodSpec); - }, docs); - docs = _.reduce(specjs.ENUMS, function(memo, enumSpec, enumName) { - return memo += GENERATE_ENUM(enumName, enumSpec); - }, docs); - docs = _.reduce(specjs.CLASSES, function(memo, classSpec, parentClass) { - return _.reduce(classSpec.methods, function(memo, methodSpec, methodName) { - return memo += GENERATE_METHOD(methodName, methodSpec, parentClass); - }, memo); - }, docs); - return docs; -} - - -// comment wrapper around entire spec -function GENERATE_DOC(text) { - return '/**\n' + text + ' */\n'; -} - - -// generate module spec -function GENERATE_MODULE(module) { - return GENERATE_DOC('@module ' + module + '\n'); -} - - -// generate method spec with parent module/class -function GENERATE_METHOD(name, spec, parent) { - name = name.replace(/!+$/, ''); - return GENERATE_DOC(spec.description + '\n' - + '@method ' + name + '\n' - + '@instance\n' - + (parent ? ('@memberof ' + parent + '\n') : '') - + _.reduce(spec.params, function(memo, paramSpec, paramName) { - return '@param {' + paramSpec.type + '} ' + paramName + ' ' + paramSpec.description + '\n'; - }, '') - + ( !_.isEmpty(spec.return) ? ('@return {' + spec.return.type + '} ' + spec.return.description + '\n') : '')); -} - - -// generate enum spec -function GENERATE_ENUM(name, spec) { - return GENERATE_DOC(spec.description + '\n\n' - + '@var ' + name + '\n' - + '@type Enum(' + spec.type + ')\n' - + '@instance\n'); -} - - -// TODO -// generate link spec -function GENERATE_LINK(text) { - return '{@link ' + text + '}'; -} - - -module.exports = generateDocs; diff --git a/doxy/node/generators/ternjs/generator.js b/doxy/node/generators/ternjs/generator.js deleted file mode 100644 index 2378fe1f..00000000 --- a/doxy/node/generators/ternjs/generator.js +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Author: Heidi Pan - * Copyright (c) 2015 Intel Corporation. - * - * 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. - */ - -// dependencies -var _ = require('lodash'); - - -// generate json for ternjs input -function generateDocs(specjs) { - GENERATE_TYPE = (function(enums) { - return function(type) { - return (_.contains(enums, type) ? ('Enum ' + type) : type); - } - })(_.keys(specjs.ENUMS_BY_GROUP)); - var docs = { '!name': specjs.MODULE + 'library' }; - _.extend(docs, GENERATE_MODULE(specjs.MODULE)); - _.each(specjs.ENUMS, function(enumSpec, enumName) { - _.extend(docs[specjs.MODULE], GENERATE_ENUM(enumName, enumSpec)); - }); - _.each(specjs.METHODS, function(methodSpec, methodName) { - _.extend(docs[specjs.MODULE], GENERATE_METHOD(methodName, methodSpec)); - }); - - if (_.isEmpty(specjs.CLASSGROUPS)) { - _.extend(docs[specjs.MODULE], GENERATE_CLASSES(specjs.CLASSES)); - } else { - var grouped = _.flatten(_.pluck(_.values(specjs.CLASSGROUPS), 'classes')); - var ungrouped = _.difference(_.keys(specjs.CLASSES), grouped); - _.extend(docs[specjs.MODULE], GENERATE_CLASSES(_.pick(specjs.CLASSES, ungrouped))); - _.each(specjs.CLASSGROUPS, function(groupSpec, groupName) { - _.extend(docs, GENERATE_MODULE(groupName)); - _.extend(docs[groupName], GENERATE_CLASSES(_.pick(specjs.CLASSES, groupSpec.classes), groupName)); - }); - } - return JSON.stringify(docs, null, 2); -} - - -// generate module spec -function GENERATE_MODULE(module) { - var docs = {}; - docs[module] = {}; - return docs; -} - - -// generate the spec for the given list of classes -function GENERATE_CLASSES(classes) { - var docs = {}; - _.each(classes, function(classSpec, parentClass) { - var constructor = classSpec.methods[parentClass]; - _.extend(docs, GENERATE_METHOD(parentClass, constructor ? constructor : { params: {}, return: {}, description: '' } )); - if (_.has(docs, parentClass)) { - _.each(classSpec.enums, function(enumSpec, enumName) { - _.extend(docs[parentClass], GENERATE_ENUM(enumName, enumSpec)); - }); - docs[parentClass].prototype = {}; - _.each(_.omit(classSpec.methods, parentClass), function(methodSpec, methodName) { - _.extend(docs[parentClass].prototype, GENERATE_METHOD(methodName, methodSpec)); - }); - _.each(classSpec.variables, function(variableSpec, variableName) { - _.extend(docs[parentClass].prototype, GENERATE_VARIABLE(variableName, variableSpec)); - }); - } - }); - return docs; -} - - -// generate method spec -function GENERATE_METHOD(name, spec) { - var doc = {}; - doc[name] = { - '!type': 'fn(' + GENERATE_PARAMS(spec.params) + ')' + GENERATE_RETURN(spec.return), - '!doc': spec.description - } - return doc; -} - - -// generate parameter signatures for method -function GENERATE_PARAMS(spec) { - return _.map(spec, function(paramSpec, paramName) { - return paramName + ': ' + paramSpec.type; - }).join(', '); -} - - -// generate return signature for method -function GENERATE_RETURN(spec) { - return (_.isEmpty(spec) ? '' : (' -> ' + spec.type)); -} - - -// generate enum spec -function GENERATE_ENUM(name, spec) { - var doc = {}; - doc[name] = 'Enum ' + spec.type ; - return doc; -} - - -// generate variable spec -function GENERATE_VARIABLE(name, spec) { - var doc = {}; - doc[name]= spec.type ; - return doc; -} - - -module.exports = generateDocs; diff --git a/doxy/node/generators/yuidoc/generator.js b/doxy/node/generators/yuidoc/generator.js deleted file mode 100644 index fb5fe2ab..00000000 --- a/doxy/node/generators/yuidoc/generator.js +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Author: Heidi Pan - * Copyright (c) 2015 Intel Corporation. - * - * 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. - */ - -// dependencies -var _ = require('lodash'); - - -// generate YuiDocs-style documentation -function generateDocs(specjs) { - var docs = GENERATE_MODULE(specjs.MODULE, ''); - GENERATE_TYPE = (function(enums) { - return function(type) { - return (_.contains(enums, type) ? ('Enum ' + type) : type); - } - })(_.keys(specjs.ENUMS_BY_GROUP)); - docs = _.reduce(specjs.METHODS, function(memo, methodSpec, methodName) { - return memo += GENERATE_METHOD(methodName, methodSpec); - }, docs); - docs = _.reduce(specjs.ENUMS, function(memo, enumSpec, enumName) { - return memo += GENERATE_ENUM(enumName, enumSpec); - }, docs); - if (_.isEmpty(specjs.CLASSGROUPS)) { - docs += GENERATE_CLASSES(specjs.CLASSES); - } else { - docs += GENERATE_MODULE('common', ''); - var grouped = _.flatten(_.pluck(_.values(specjs.CLASSGROUPS), 'classes')); - var ungrouped = _.difference(_.keys(specjs.CLASSES), grouped); - docs += GENERATE_CLASSES(_.pick(specjs.CLASSES, ungrouped), 'common'); - _.each(specjs.CLASSGROUPS, function(groupSpec, groupName) { - docs += GENERATE_CLASSES(_.pick(specjs.CLASSES, groupSpec.classes), groupName); - }); - // TODO: figure out why yuidoc won't associate the class with the right module if module definitions are interspersed - _.each(specjs.CLASSGROUPS, function(groupSpec, groupName) { - docs += GENERATE_MODULE(groupName, groupSpec.description); - }); - } - return docs; -} - - -// comment wrapper around entire spec -function GENERATE_DOC(text) { - return '/**\n' + text + ' */\n'; -} - - -// generate module spec -function GENERATE_MODULE(name, description) { - return GENERATE_DOC(description + '\n' - + '@module ' + name + '\n'); -} - - -// generate spec for the given list of classes -function GENERATE_CLASSES(classes, parent) { - return _.reduce(classes, function(memo, classSpec, className) { - return memo - + GENERATE_CLASS(className, classSpec.description, parent, classSpec.parent) - + _.reduce(classSpec.methods, function(memo, methodSpec, methodName) { - return memo += GENERATE_METHOD(methodName, methodSpec, className); - }, '') - + _.reduce(classSpec.variables, function(memo, variableSpec, variableName) { - return memo += GENERATE_VAR(variableName, variableSpec, className); - }, '') - + _.reduce(classSpec.enums, function(memo, enumSpec, enumName) { - return memo += GENERATE_ENUM(enumName, enumSpec, className); - }, ''); - }, ''); -} - - -// generate class spec -function GENERATE_CLASS(name, description, namespace, parent) { - return GENERATE_DOC(description + '\n' - + '@class ' + name + '\n' - + (namespace ? ('@module ' + namespace + '\n') : '') - /* - TODO: leave out until figure out what swig does with inheritance - + (parent ? ('@extends ' + parent + '\n') : '') - */ - ); -} - - -// generate method spec with parent module/class -function GENERATE_METHOD(name, spec, parent) { - name = name.replace(/!+$/, ''); - return GENERATE_DOC(spec.description + '\n' - + '@method ' + name + '\n' - + (parent ? ('@for ' + parent + '\n') : '@for common\n') - + _.reduce(spec.params, function(memo, paramSpec, paramName) { - return memo + '@param {' + GENERATE_TYPE(paramSpec.type) + '} ' + paramName + ' ' + paramSpec.description + '\n'; - }, '') - + ( !_.isEmpty(spec.return) ? ('@return {' + GENERATE_TYPE(spec.return.type) + '} ' + spec.return.description + '\n') : '')); -} - - -// generate enum spec -function GENERATE_ENUM(name, spec, parent) { - return GENERATE_DOC(spec.description + '\n' - + '@property ' + name + '\n' - + '@type Enum ' + spec.type + '\n' - + '@for ' + (parent ? parent : 'common') + '\n'); -} - - -// generate variable specs -function GENERATE_VAR(name, spec, parent) { - return GENERATE_DOC(spec.description + '\n' - + '@property ' + name + '\n' - + '@type ' + spec.type + '\n' - + '@for ' + parent + '\n'); -} - - -// TODO -// generate link spec -function GENERATE_LINK(text) { - return '{{#crossLink "' + text + '"}}{{/crossLink}}'; -} - - -module.exports = generateDocs; \ No newline at end of file diff --git a/doxy/node/grammars/xml.peg b/doxy/node/grammars/xml.peg deleted file mode 100644 index bca96d51..00000000 --- a/doxy/node/grammars/xml.peg +++ /dev/null @@ -1,45 +0,0 @@ -document - = _ ignore* _ "" body:elements _ "" _ { return body; } - - -elements - = element* - -element - = _ "<" startTag:id _ attr:attr* _ ">" _ children:elements _ "" _ { - if (startTag != endTag) { - throw new Error("Expected but found."); - } - return {name: startTag, attr: attr, children: children } - } - / "<" tag:id _ attr:attr* _ "/>" _ { - return {name: tag, attr: attr } - } - / _ text:text _ { return text } - -ignore - = "" { return } - -attr - = name:id _ "=" _ value:string { return { name:name, value:value } } - -string - = '"' '"' _ { return ""; } - / "'" "'" _ { return ""; } - / '"' text:quoted '"' _ { return text; } - / "'" text:quoted "'" _ { return text; } - -quoted - = chars:[^<>'" \t\n\r]+ { return chars.join(""); } - -text - = chars:[^<> \t\n\r]+ { return chars.join(""); } - -id - = chars:[^<>/'"=? \t\n\r]+ { return chars.join(""); } - -_ "whitespace" - = whitespace* - -whitespace - = [ \t\n\r] diff --git a/doxy/node/tolower.js b/doxy/node/tolower.js deleted file mode 100644 index c9c24217..00000000 --- a/doxy/node/tolower.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Author: Dina M Suehiro - * Copyright (c) 2015 Intel Corporation. - * - * 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. - */ - -// dependencies -var opts = require('commander'), // for command line args - fs = require('fs'), // for file system access - path = require('path'); // for file path parsing - -// parse command line arguments -opts - .option('-i, --inputdir [directory]', 'product documents directory', __dirname + '/docs/yuidoc/upm') - .parse(process.argv); - -// Set to true for console output -var debug = true; - -// Global arrays tracking the files that have been renamed -var originalFiles = []; -var renamedFiles = []; - -// Filter to get html files from different directories -var rootFiles = getHtmlFilenames(opts.inputdir); -var classesFiles = getHtmlFilenames(opts.inputdir + "/classes"); -var modulesFiles = getHtmlFilenames(opts.inputdir + "/modules"); - -// Rename files in the classes directory to have lower-cased file names. -renameFiles(classesFiles); - -classesFiles = getHtmlFilenames(opts.inputdir + "/classes"); - -// Go through the html files and update links to reflect the file names that we changed. -renameLinks(rootFiles); -renameLinks(classesFiles); -renameLinks(modulesFiles); - -// Helper function that returns paths to the html files in the specified directory -function getHtmlFilenames (directory) -{ - return fs.readdirSync(directory).map(function (file) { - return path.join(directory, file); - }).filter(function (file) { - return fs.statSync(file).isFile(); - }).filter(function (file) { - return path.extname(file).toLowerCase() == ".html"; - }); -} - -// Goes through the files and renames them to be lower-cased and tracks them the -// renamed files in the originalFiles[] and renamedFiles[] arrays. -function renameFiles(files) -{ - files.forEach(function (file) - { - var originalName = path.basename(file); - var newFileName = originalName.toLowerCase(); - var directory = path.dirname(file); - if (originalName != newFileName) - { - fs.renameSync(file, directory + "/" + newFileName); //, function(err) - - if (debug) - console.log('Renamed: %s --> %s', originalName, newFileName); - - originalFiles.push(originalName); - renamedFiles.push(newFileName); - } - }); -} - -// Helper function goes through the specified files and does a file/replace of the -// originalFiles to the renamedFiles so that the .html links match what has been renamed. -function renameLinks (files) -{ - if (originalFiles.length <= 0) - { - if (debug) - console.log("No links to rename."); - return; - } - - files.forEach(function (file) - { - // Read the file - data = fs.readFileSync(file, 'ascii'); - - // Find/replace the file names that were renamed - for (var i = 0; i < originalFiles.length; i++) - { - var findString = '/' + originalFiles[i] + '\"'; - var replaceString = '/' + renamedFiles[i] + '\"'; - - data = data.replace(findString, replaceString); - } - - // Write back - fs.writeFile(file, data, 'ascii', function (err) { - if (err) - throw err; - }); - - if (debug) - console.log('Renamed links in: %s', file); - }); -} diff --git a/doxy/node/xml2js.js b/doxy/node/xml2js.js deleted file mode 100644 index 95af7617..00000000 --- a/doxy/node/xml2js.js +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Author: Heidi Pan - * Copyright (c) 2015 Intel Corporation. - * - * 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. - */ - -// dependencies -var peg = require('pegjs') - , fs = require('fs') - , path = require('path') - , Promise = require('bluebird') - , _ = require('lodash') - , util = require('util'); - - -// use promise-style programming rather than spaghetti callbacks -Promise.promisifyAll(fs); - - -var xml2js = { - - // js-format specs - // MODULE: - // ENUMS: { - // : { - // type: , - // description: - // }, ... - // } - // ENUMS_BY_GROUP: { - // : { - // description: - // members: [ , ... ] - // }, ... - // } - // METHODS: { - // : { - // description: , - // params: { - // : { - // type: , - // description: - // }, ... - // }, - // return: { - // type: , - // description: - // } - // }, ... - // } - // CLASSES: { - // : { - // description: , - // parent: , - // group: , - // methods: { ... }, - // variables: { - // : { - // type: , - // description: - // } - // }, - // enums: { ... }, - // enums_by_group: { ... } - // }, ... - // } - // CLASSGROUPS: { - // : { - // description: , - // classes: [ , ... ], - // enums: { ... }, - // enums_by_group: { ... } - // }, ... - // } - MODULE: '', - ENUMS: {}, - ENUMS_BY_GROUP: {}, - METHODS: {}, - CLASSES: {}, - CLASSGROUPS: {}, - - - // baseline c -> js type mapping - TYPEMAPS: { - '^(const)?\\s*(unsigned|signed)?\\s*(int|short|long|float|double|size_t|u?int\\d{1,2}_t)?$': 'Number', - '^bool$': 'Boolean', - '^(const)?\\s*(unsigned|signed)?\\s*(char|char\\s*\\*|std::string)$': 'String', // TODO: verify that swig does this mapping - '^void\\s*\\(\\s*\\*\\s*\\)\\s*\\(\\s*void\\s*\\*\\)\\s*$': 'Function' - }, - - - // custom c -> js type mapping for pointers - // ARRAY_TYPEMAPS: { - // : { - // arrayType: , - // classes: [ , ... ] - // }, ... - // } - // POINTER_TYPEMAPS: { - // : { - // : , ... - // }, ... - // } - ARRAY_TYPEMAPS: {}, - POINTER_TYPEMAPS: {}, - - - // add command line options for this module - addOptions: function(opts) { - xml2js.opts = opts; - return opts - .option('-i, --inputdir [directory]', 'directory for xml files', __dirname + '/xml/mraa') - .option('-c, --custom [file]', 'json for customizations') - .option('-t, --typemaps [directory]', 'directory for custom pointer type maps') - .option('-g, --imagedir [directory]', 'directory to link to where the images will be kept', '') - .option('-s, --strict', 'leave out methods/variables if unknown type') - }, - - - // parse doxygen xml -> js-format specs - // TODO: figure out whether we need to document any protected methods/variables - parse: function() { - var XML_GRAMMAR_SPEC = 'grammars/xml.peg'; - var NAMESPACE_SPEC = xml2js.opts.inputdir + '/namespace' + xml2js.opts.module + '.xml'; - var CLASS_SPEC = function(c) { return xml2js.opts.inputdir + '/' + c + '.xml'; } - var TYPES_SPEC = xml2js.opts.inputdir + '/types_8h.xml'; - xml2js.MODULE = xml2js.opts.module; - return Promise.join(createXmlParser(XML_GRAMMAR_SPEC), - xml2js.opts.typemaps ? initCustomPointerTypemaps(xml2js.opts.typemaps) : Promise.resolve(), - fs.readFileAsync(NAMESPACE_SPEC, 'utf8'), - fs.existsSync(TYPES_SPEC) ? fs.readFileAsync(TYPES_SPEC, 'utf8') : Promise.resolve(null), - function(xmlparser, ignore, xml, xml_types) { - if (xml_types != null) { - _.extend(xml2js.ENUMS, getEnums(xmlparser.parse(xml_types)[0], false)); - _.extend(xml2js.ENUMS_BY_GROUP, getEnums(xmlparser.parse(xml_types)[0], true)); - } - var spec_c = xmlparser.parse(xml)[0]; - _.extend(xml2js.ENUMS, getEnums(spec_c, false)); - _.extend(xml2js.ENUMS_BY_GROUP, getEnums(spec_c, true)); - _.extend(xml2js.METHODS, getMethods(spec_c)); - _.each(getSubclassNames(spec_c), function(className) { xml2js.CLASSES[className] = {} }); - var parseClasses = _.map(getSubclasses(spec_c), function(c) { - return fs.readFileAsync(CLASS_SPEC(c), 'utf8').then(function(xml) { - try { - var spec_c = xmlparser.parse(xml)[0]; - var className = getName(spec_c); - _.extend(xml2js.CLASSES[className], { - description: getDescription(spec_c), - parent: getParent(spec_c, className), - enums: getEnums(spec_c, false, className), - enums_by_group: getEnums(spec_c, true, className), - variables: getVariables(spec_c, className), - methods: getMethods(spec_c, className) - }); - } catch(e) { - console.log(e.toString() + ': class ' + className + ' was not parsed correctly.'); - } - }); - }); - var parseGroups = fs.readdirAsync(xml2js.opts.inputdir).then(function(files) { - var groupxmlfiles = _.filter(files, function(fn) { - return ((path.extname(fn) == '.xml') && (path.basename(fn).search(/^group/) != -1)); - }); - return Promise.all(_.map(groupxmlfiles, function(fn) { - return fs.readFileAsync(xml2js.opts.inputdir + '/' + fn, 'utf8').then(function(xml) { - var spec_c = xmlparser.parse(xml)[0]; - if (_.isEmpty(getSubmodules(spec_c))) { - var group = getName(spec_c); - var classes = getSubclassNames(spec_c); - xml2js.CLASSGROUPS[group] = { - description: getDescription(spec_c), - classes: classes - }; - _.each(classes, function(c) { - if (_.has(xml2js.CLASSES, c)) { - xml2js.CLASSES[c].group = group; - } else { - console.log('Warning: Group ' + group + ' has unknown class ' + c); - } - }); - } - }); - })); - }); - return Promise.all(parseClasses.concat(parseGroups)); - }).then(function() { - if (!_.isEmpty(xml2js.CLASSGROUPS)) { - // try to categorize ungrouped classes, if any - var grouped = _.flatten(_.pluck(_.values(xml2js.CLASSGROUPS), 'classes')); - var ungrouped = _.difference(_.keys(xml2js.CLASSES), grouped); - _.each(ungrouped, function(c) { - _.each(findUsage(c), function(group) { - xml2js.CLASSGROUPS[group].classes.push(c); - }); - }); - grouped = _.flatten(_.pluck(_.values(xml2js.CLASSGROUPS), 'classes')); - ungrouped = _.difference(_.keys(xml2js.CLASSES), grouped); - // try to categorize ungrouped enums, if any - _.each(xml2js.ENUMS_BY_GROUP, function(enumGroupSpec, enumGroupName) { - _.each(findUsage(enumGroupName, true), function(c) { - xml2js.CLASSES[c].enums_by_group[enumGroupName] = enumGroupSpec; - _.each(enumGroupSpec.members, function(enumName) { - xml2js.CLASSES[c].enums[enumName] = xml2js.ENUMS[enumName]; - delete xml2js.ENUMS[enumName]; - }); - delete xml2js.ENUMS_BY_GROUP[enumGroupName]; - }); - }); - } - }).then(function() { - if (xml2js.opts.custom && fs.existsSync(xml2js.opts.custom)) { - return fs.readFileAsync(xml2js.opts.custom, 'utf8').then(function(custom) { - try { - customizeMethods(JSON.parse(custom)); - } catch(e) { - console.log('invalid custom.json, ignored. ' + e.toString()); - } - }); - } else { - console.log(xml2js.opts.custom ? ('Error: No such customization file exists: ' + xml2js.opts.custom) : 'No customizations given.'); - } - }).then(function() { - generateCustomPointerClasses(); - validateMethods(); - validateVars(); - return _.pick(xml2js, 'MODULE', 'ENUMS', 'ENUMS_BY_GROUP', 'METHODS', 'CLASSES', 'CLASSGROUPS'); - }); - } -}; - - -// create an xml parser -function createXmlParser(XML_GRAMMAR_SPEC) { - return fs.readFileAsync(XML_GRAMMAR_SPEC, 'utf8').then(function(xmlgrammar) { - return peg.buildParser(xmlgrammar); - }); -} - - -// configure c->js typemaps from custom swig directives -// TODO: many built in assumptions based on current upm file structures & .i customizations -function initCustomPointerTypemaps(typemapsdir) { - return fs.readdirAsync(typemapsdir).then(function(dirs) { - return Promise.all(_.map(dirs, function(dir) { - // get all js*.i directives from class-specific subdirectories, to be parsed below for %typemaps directives - return fs.readdirAsync(typemapsdir + '/' + dir).then(function(files) { - var directive = _.find(files, function(fn) { - return ((path.extname(fn) == '.i') && (path.basename(fn).search(/^js/) != -1)); - }); - var data = {}; - if (directive) { - data[dir] = typemapsdir + '/' + dir + '/' + directive; - } - return data; - }).catch(function(e) { - // get all .i directives from top level directory, and parse for %array_class directives - if (e.code == 'ENOTDIR') { - var fn = dir; - if (path.extname(fn) == '.i') { - return fs.readFileAsync(typemapsdir + '/' + fn, 'utf8').then(function(directives) { - var arraytypes = _.filter(directives.split(/\n/), function(line) { - return (line.search(/^%array_class/) != -1); - }); - _.each(arraytypes, function(arraytype) { - var parsed = arraytype.match(/%array_class\(([A-Za-z0-9_]+)[\s]*,[\s]*([A-Za-z0-9_]+)\)/); - if (parsed) { - var from = parsed[1]; - var to = parsed[2]; - xml2js.ARRAY_TYPEMAPS[from] = { arrayType: to, classes: [] }; - } else { - console.log('Incorrectly parsed array_class from ' + fn + ': ' + arraytype); - } - }); - }); - } - } else { - throw e; - } - }); - })); - }).then(function(__directivesFiles) { - // parse for %typemaps & %pointer_functions directives - var _directivesFiles = _.filter(__directivesFiles, function(data) { return !_.isEmpty(data); }); - var directivesFiles = _.object(_.map(_directivesFiles, _.keys), _.flatten(_.map(_directivesFiles, _.values))); - return Promise.all(_.map(directivesFiles, function(directivesFn, className) { - return fs.readFileAsync(directivesFn, 'utf8').then(function(directives) { - var typemaps = _.filter(directives.split(/\n/), function(line) { - return (line.search(/^%typemap/) != -1); - }); - _.each(typemaps, function(typemap) { - var parsed = typemap.match(/%typemap\((in|out)\)[\s]+([A-Za-z0-9_]+[\s]*[\*])/); - if (parsed) { - var dir = parsed[1]; // TODO: ignored for now - var type = normalizePointer(parsed[2]); - var datatype = getPointerDataType(type); - if (_.has(xml2js.ARRAY_TYPEMAPS, datatype)) { - xml2js.ARRAY_TYPEMAPS[datatype].classes.push(className); - } else { - console.log('Ignored typemap from ' + directivesFn + ': ' + typemap.replace('{', '') + ' (no %array_class directive found for ' + datatype + ')'); - } - } else { - console.log('Ignored typemap from ' + directivesFn + ': ' + typemap.replace('{', '') + ' (only considering in/out typemaps of pointer types)'); - } - }); - var ptrfns = _.filter(directives.split(/\n/), function(line) { - return (line.search(/^%pointer_functions/) != -1); - }); - _.each(ptrfns, function(ptrfn) { - var parsed = ptrfn.match(/%pointer_functions\(([A-Za-z0-9_]+)[\s]*,[\s]*([A-Za-z0-9_]+)\)/); - if (parsed) { - var from = parsed[1]; - var to = parsed[2]; - if (!_.has(xml2js.POINTER_TYPEMAPS, className)) { - xml2js.POINTER_TYPEMAPS[className] = {}; - } - xml2js.POINTER_TYPEMAPS[className][from] = to; - } - }); - }); - })); - }); -} - - -// generate class specs for custom pointer types -function generateCustomPointerClasses() { - var arrayTypes = _.pluck(_.values(xml2js.ARRAY_TYPEMAPS), 'arrayType'); - var pointerTypes = _.uniq(_.flatten(_.map(_.values(xml2js.POINTER_TYPEMAPS), _.values))); - _.each(arrayTypes, function(arrayType) { - var dataType = _.findKey(xml2js.ARRAY_TYPEMAPS, function(to) { return to.arrayType == arrayType; }); - xml2js.CLASSES[arrayType] = { - description: 'Array of type ' + dataType + '.', - enums: {}, - enums_by_group: {}, - variables: {}, - methods: {} - }; - xml2js.CLASSES[arrayType].methods[arrayType] = { - description: 'Instantiates the array.', - params: { - nelements: { - type: 'Number', - description: 'number of elements in the array' - } - }, - return: {} - }; - xml2js.CLASSES[arrayType].methods.getitem = { - description: 'Access a particular element in the array.', - params: { - index: { - type: 'Number', - description: 'index of array to read from' - }, - }, - return: { - type: getType(dataType), - description: 'the value of the element found at the given index of the array' - } - }; - xml2js.CLASSES[arrayType].methods.setitem = { - description: 'Modify a particular element in the array.', - params: { - index: { - type: 'Number', - description: 'index of array to write to' - }, - value: { - type: getType(dataType), - description: 'the value to set the element found at the given index of the array' - } - }, - return: {} - }; - }); - var pointerDataTypeMap = _.reduce(_.map(_.values(xml2js.POINTER_TYPEMAPS), _.invert), function(memo, typemap) { - return _.extend(memo, typemap); - }, {}); - _.each(pointerTypes, function(pointerType) { - var dataType = pointerDataTypeMap[pointerType]; - xml2js.CLASSES[pointerType] = { - description: 'Proxy object to data of type ' + dataType + '.', - enums: {}, - enums_by_group: {}, - variables: {}, - methods: {} - }; - xml2js.CLASSES[pointerType].methods[pointerType] = { - description: 'Instantiates the proxy object.', - params: {}, - return: {} - }; - xml2js.CLASSES[pointerType].methods.value = { - description: 'Get the value of the object.', - params: {}, - return: { - type: getType(dataType), - description: 'the value of the object' - } - }; - xml2js.CLASSES[pointerType].methods.assign = { - description: 'Set the value of the object.', - params: { - value: { - type: getType(dataType), - description: 'the value to set the object to' - } - }, - return: {} - }; - }); -} - - -// search for usage of a type -function findUsage(type, classOnly) { - var filterClasses = function(fn) { return _.without(_.map(xml2js.CLASSES, fn), undefined); }; - var usesType = function(classSpec, className) { - var methodsOfType = (_.find(classSpec.methods, function(methodSpec, methodName) { - return ((!_.isEmpty(methodSpec.return) && methodSpec.return.type == type) || - (_.contains(_.pluck(methodSpec.params, 'type'), type))); - }) != undefined); - var variablesOfType = _.contains(_.pluck(classSpec.variable, 'type'), type); - return ((methodsOfType || variablesOfType) ? className : undefined); - }; - var extendsType = function(classSpec, className) { - return ((classSpec.parent == type) ? className : undefined); - }; - var classes = _.union(filterClasses(usesType), filterClasses(extendsType)); - if (classOnly) { - return classes; - } else { - return _.without(_.uniq(_.pluck(_.pick(xml2js.CLASSES, classes), 'group')), undefined); - } -} - - -// override autogenerated methods with custom configuration -function customizeMethods(custom) { - _.each(custom, function(classMethods, className) { - _.extend(xml2js.CLASSES[className].methods, _.pick(classMethods, function(methodSpec, methodName) { - return isValidMethodSpec(methodSpec, className + '.' + methodName); - })); - }); -} - - -// make sure methods have valid types, otherwise warn (& don't include if strict) -function validateMethods() { - xml2js.METHODS = _.pick(xml2js.METHODS, function(methodSpec, methodName) { - return hasValidTypes(methodSpec, methodName); - }); - _.each(xml2js.CLASSES, function(classSpec, className) { - var valid = _.pick(classSpec.methods, function(methodSpec, methodName) { - return hasValidTypes(methodSpec, className + '.' + methodName, className); - }); - if (xml2js.opts.strict) { - xml2js.CLASSES[className].methods = valid; - } - }); -} - - -// make sure variables have valid types, otherwise warn (& don't include if strict) -function validateVars() { - _.each(xml2js.CLASSES, function(classSpec, className) { - var valid = _.pick(classSpec.variables, function(varSpec, varName) { - return ofValidType(varSpec, className + '.' + varName, className); - }); - if (xml2js.opts.strict) { - xml2js.CLASSES[className].variables = valid; - } - }); -} - - -// verify that the json spec is well formatted -function isValidMethodSpec(methodSpec, methodName) { - var valid = true; - var printIgnoredMethodOnce = _.once(function() { console.log(methodName + ' from ' + path.basename(xml2js.opts.custom) + ' is omitted from JS documentation.'); }); - function checkRule(rule, errMsg) { - if (!rule) { - printIgnoredMethodOnce(); - console.log(' ' + errMsg); - valid = false; - } - } - checkRule(_.has(methodSpec, 'description'), 'no description given'); - checkRule(_.has(methodSpec, 'params'), 'no params given (specify "params": {} for no params)'); - _.each(methodSpec.params, function(paramSpec, paramName) { - checkRule(_.has(paramSpec, 'type'), 'no type given for param ' + paramName); - checkRule(_.has(paramSpec, 'description'), 'no description given for param ' + paramName); - }); - checkRule(_.has(methodSpec, 'return'), 'no return given (specify "return": {} for no return value)'); - checkRule(_.has(methodSpec.return, 'type'), 'no type given for return value'); - checkRule(_.has(methodSpec.return, 'description'), 'no description given for return value'); - return valid; -} - - -// get enum specifications -function getEnums(spec_c, bygroup, parent) { - var spec_js = {}; - var enumGroups = _.find(getChildren(spec_c, 'sectiondef'), function(section) { - var kind = getAttr(section, 'kind'); - return ((kind == 'enum') || (kind == 'public-type')); - }); - if (enumGroups) { - _.each(enumGroups.children, function(enumGroup) { - var enumGroupName = getText(getChild(enumGroup, 'name'), 'name'); - var enumGroupDescription = getText(getChild(enumGroup, 'detaileddescription'), 'description'); - var enumGroupVals = getChildren(enumGroup, 'enumvalue'); - if (bygroup) { - spec_js[enumGroupName] = { - description: enumGroupDescription, - members: [] - }; - } - _.each(enumGroupVals, function(e) { - // TODO: get prefix as option - var enumName = getText(getChild(e, 'name'), 'name').replace(/^MRAA_/, ''); - var enumDescription = getText(getChild(e, 'detaileddescription'), 'description'); - if (!bygroup) { - spec_js[enumName] = { - type: enumGroupName, - description: enumDescription - }; - } else { - spec_js[enumGroupName].members.push(enumName); - } - }); - }); - } - return spec_js; -} - - -// get the name for the module/group/class -function getName(spec_c) { - return getText(getChild(spec_c, 'compoundname'), 'name').replace(xml2js.opts.module + '::', ''); -} - - -// get the description for the module/group/class -function getDescription(spec_c) { - return getText(getChild(spec_c, 'detaileddescription'), 'description'); -} - - -// get the classes (xml file names) for the given module -function getSubclasses(spec_c) { - return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) { - return getAttr(innerclass, 'refid'); - }); -} - - -// get the classes (class names) for the given module -function getSubclassNames(spec_c) { - return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) { - return getText(innerclass).replace(xml2js.opts.module + '::', ''); - }); -} - - -// get the submodules (xml file names) for the given module -function getSubmodules(spec_c) { - return _.map(getChildren(spec_c, 'innergroup'), function(innergroup) { - return getAttr(innergroup, 'refid'); - }); -} - - -// get parent class, if any -function getParent(spec_c, className) { - var parent = getChild(spec_c, 'basecompoundref'); - if (parent) { - parent = getText(parent); - if (!_.has(xml2js.CLASSES, parent)) { - console.log('WARNING: Class ' + className + ' has unknown parent class ' + parent); - } - } - return parent; -} - - -function hasParams(paramsSpec) { - return !(_.isEmpty(paramsSpec) || - ((_.size(paramsSpec) == 1) && getText(getChild(paramsSpec[0], 'type')) == 'void')); -} - - -// get method specifications for top-level module or a given class -// TODO: overloaded functions -// TODO: functions w/ invalid parameter(s)/return -function getMethods(spec_c, parent) { - var spec_js = {}; - var methods = _.find(getChildren(spec_c, 'sectiondef'), function(section) { - var kind = getAttr(section, 'kind'); - return ((kind == 'public-func') || (kind == 'func')); - }); - if (methods) { - _.each(methods.children, function(method) { - var methodName = getText(getChild(method, 'name'), 'name'); - if (methodName[0] != '~') { // filter out destructors - try { - var description = getChild(method, 'detaileddescription'); - var methodDescription = getText(description, 'description'); - var paramsSpec = getChildren(method, 'param'); - var params = {}; - if (hasParams(paramsSpec)) { - params = getParams(paramsSpec, getParamsDetails(description), methodName, parent); - } - var returnSpec = getChild(method, 'type'); - var retval = {}; - if (!_.isEmpty(returnSpec)) { - retval = getReturn(returnSpec, getReturnDetails(description), methodName, parent); - } - methodName = getUniqueMethodName(methodName, spec_js, parent); - spec_js[methodName] = { - description: methodDescription, - params: params, - return: retval - }; - } catch(e) { - console.log((parent ? (parent + '.') : '') + methodName + ' is omitted from JS documentation.'); - console.log(' ' + e.toString()); - } - } - }); - } - return spec_js; -} - - -// get a unique string to represent the name of an overloaded method -function getUniqueMethodName(methodName, module, parent) { - if (methodName in module) { - do { - methodName += '!'; - } while (methodName in module); - } - return methodName; -} - - -// get variable specifications for a class -function getVariables(spec_c, parent) { - var spec_js = {}; - var vars = _.find(getChildren(spec_c, 'sectiondef'), function(section) { - var kind = getAttr(section, 'kind'); - return (kind == 'public-attrib'); - }); - if (vars) { - _.each(_.filter(vars.children, function(variable) { - return (getAttr(variable, 'kind') == 'variable'); - }), function(variable) { - var varName = getText(getChild(variable, 'name'), 'name'); - var varType = getType(getText(getChild(variable, 'type')), parent); - var varDescription = getText(getChild(variable, 'detaileddescription')); - spec_js[varName] = { - type: varType, - description: varDescription - } - }); - } - return spec_js; -} - - -// get return value specs of a method -function getReturn(spec_c, details, method, parent) { - var retType = getType(getText(spec_c, 'type'), parent); - var retDescription = (details ? getText(details, 'description') : ''); - return ((retType == 'void') ? {} : { - type: retType, - description: retDescription - }); -} - - -// get paramater specs of a method -function getParams(spec_c, details, method, parent) { - var spec_js = {}; - _.each(spec_c, function(param) { - try { - var paramType = getType(getText(getChild(param, 'type'), 'type'), parent); - var paramName = getText(getChild(param, 'declname'), 'name'); - spec_js[paramName] = { type: paramType }; - } catch(e) { - if (paramType == '...') { - spec_js['arguments'] = { type: paramType }; - } else { - throw e; - } - } - }); - _.each(details, function(param) { - var getParamName = function(p) { return getText(getChild(getChild(p, 'parameternamelist'), 'parametername'), 'name'); } - var paramName = getParamName(param); - var paramDescription = getText(getChild(param, 'parameterdescription'), 'description'); - if (_.has(spec_js, paramName)) { - spec_js[paramName].description = paramDescription; - } else { - var msg = ' has documentation for an unknown parameter: ' + paramName + '. '; - var suggestions = _.difference(_.keys(spec_js), _.map(details, getParamName)); - var msgAddendum = (!_.isEmpty(suggestions) ? ('Did you mean ' + suggestions.join(', or ') + '?') : ''); - console.log('Warning: ' + (parent ? (parent + '.') : '') + method + msg + msgAddendum); - } - }); - return spec_js; -} - - -// get the equivalent javascript type from the given c type -function getType(type_c, parent) { - var type_js = type_c; - _.find(xml2js.TYPEMAPS, function(to, from) { - var pattern = new RegExp(from, 'i'); - if (type_c.search(pattern) == 0) { - type_js = to; - return true; - } - }); - if (isPointer(type_js)) { - var dataType = getPointerDataType(type_js); - var className = parent.toLowerCase(); - if (_.has(xml2js.ARRAY_TYPEMAPS, dataType) && _.contains(xml2js.ARRAY_TYPEMAPS[dataType].classes, className)) { - type_js = xml2js.ARRAY_TYPEMAPS[dataType].arrayType; - } else if (_.has(xml2js.POINTER_TYPEMAPS, className) && _.has(xml2js.POINTER_TYPEMAPS[className], dataType)) { - type_js = xml2js.POINTER_TYPEMAPS[className][dataType]; - } else if (_.has(xml2js.CLASSES, dataType)) { // TODO: verify that swig does this mapping - type_js = dataType; - } else { - type_js = dataType + ' *' - } - } - return type_js; -} - - -// verify that all types associated with the method are valid -function hasValidTypes(methodSpec, methodName, parent) { - var valid = true; - var msg = (xml2js.opts.strict ? ' is omitted from JS documentation.' : ' has invalid type(s).'); - var printIgnoredMethodOnce = _.once(function() { console.log(methodName + msg); }); - _.each(methodSpec.params, function(paramSpec, paramName) { - if (!isValidType(paramSpec.type, parent)) { - valid = false; - printIgnoredMethodOnce(); - console.log(' Error: parameter ' + paramName + ' has invalid type ' + typeToString(paramSpec.type)); - } - }); - if (!_.isEmpty(methodSpec.return) && !isValidType(methodSpec.return.type, parent)) { - valid = false; - printIgnoredMethodOnce(); - console.log(' Error: returns invalid type ' + typeToString(methodSpec.return.type)); - } - return valid; -} - - -// verify that type of variable is valid -function ofValidType(varSpec, varName, parent) { - if (isValidType(varSpec.type, parent)) { - return true; - } else { - var msgAddendum = (xml2js.opts.strict ? ' Omitted from JS documentation.' : ''); - console.log('Error: ' + varName + ' is of invalid type ' + typeToString(varSpec.type) + '.' + msgAddendum); - return false; - } -} - - -// verify whether the given type is valid JS -function isValidType(type, parent) { - return (_.contains(_.values(xml2js.TYPEMAPS), type) || - _.has(xml2js.CLASSES, type) || - _.has(xml2js.ENUMS_BY_GROUP, type) || - _.contains(['Buffer', 'Function', 'mraa_result_t'], type) || - _.has((parent ? xml2js.CLASSES[parent].enums_by_group : []), type) || - isValidPointerType(type, parent)); -} - - -function isValidPointerType(type, parent) { - var className = parent.toLowerCase(); - var arrayTypemap = _.find(xml2js.ARRAY_TYPEMAPS, function(to) { return to.arrayType == type; }); - var valid = ((arrayTypemap && _.contains(arrayTypemap.classes, className)) || - (_.has(xml2js.POINTER_TYPEMAPS, className) && (_.contains(_.values(xml2js.POINTER_TYPEMAPS[className]), type)))); - return valid; -} - - -// determines whether a type looks like a c pointer -function isPointer(type) { - return (type.search(/\w+\s*(\*|&)$/) != -1); -} - - -// remove extraneous whitespace from pointer types as canonical representation -function normalizePointer(ptr) { - return ptr.replace(/\s*$/, ''); -} - - -// get the data type of a pointer (e.g. int is the data type of int*) -function getPointerDataType(ptr) { - return ptr.replace(/\s*(\*|&)$/, ''); -} - - -// print more human friendly type for error messages -function typeToString(type) { - return type.replace('*', '*'); -} - - -// get the detailed description of a method's parameters -function getParamsDetails(spec_c) { - var paras = getChildren(spec_c, 'para'); - var details = _.find(_.map(paras, function(para) { - return getChild(para, 'parameterlist'); - }), function(obj) { return (obj != undefined); }); - return (details ? details.children : undefined); -} - - -// get the detailed description of a method's return value -function getReturnDetails(spec_c) { - var paras = getChildren(spec_c, 'para'); - return _.find(_.map(paras, function(para) { - return getChild(para, 'simplesect'); - }), function(obj) { return ((obj != undefined) && (getAttr(obj, 'kind') == 'return')); }); -} - - -// get (and flatten) the text of the given object -function getText(obj, why) { - // TODO: links ignored for now, patched for types for - var GENERATE_LINK = function(x) { return x + ' '; } - return _.reduce(obj.children, function(text, elem) { - if (_.isString(elem)) { - return text += elem.trim() + ' '; - } else if (_.isPlainObject(elem)) { - switch(elem.name) { - case 'para': - return text += getText(elem, why) + ' \n'; - case 'ref': - return text += GENERATE_LINK(getText(elem, why)); - case 'parameterlist': - case 'simplesect': - return text; // to be handled elsewhere - case 'programlisting': - case 'htmlonly': - return text; // ignored - // TODO: html doesn't seem to work for yuidoc, using markdown for now - case 'itemizedlist': - return text += '\n' + getText(elem, why) + ' \n \n'; - case 'listitem': - return text += '+ ' + getText(elem, why) + '\n'; - case 'bold': - return text += '__' + getText(elem, why).trim() + '__ '; - case 'ulink': - return text += '[' + getText(elem, why).trim() + '](' + getAttr(elem, 'url').trim() + ') '; - case 'image': - // TODO: copy images over; hard coded for now - var fn = getAttr(elem, 'name'); - return text += ' \n \n![' + fn + '](' + xml2js.opts.imagedir + '/' + fn + ') '; - case 'linebreak': - return text += ' \n'; - case 'ndash': - return text += '– '; - default: - // TODO: incomplete list of doxygen xsd implemented - console.warn('NYI Unknown Object Type: ' + elem.name); - return text; - //throw new Error('NYI Unknown Object Type: ' + elem.name); - } - } else { - throw new Error('NYI Unknown Type: ' + (typeof elem)); - } - }, '').trim(); -} - - -// get the value of attribute with the given name of the given object -function getAttr(obj, name) { - return _.find(obj.attr, function(item) { - return item.name == name; - }).value; -} - - -// get the child object with the given name of the given object -function getChild(obj, name) { - return _.find(obj.children, function(child) { - return child.name == name; - }); -} - - -// get all children objects with the given name of the given object -function getChildren(obj, name) { - return _.filter(obj.children, function(child) { - return child.name == name; - }); -} - - -// debug helper: print untruncated object -function printObj(obj) { - console.log(util.inspect(obj, false, null)); -} - - -module.exports = xml2js; \ No newline at end of file diff --git a/scripts/build-doc.sh b/scripts/build-doc.sh new file mode 100755 index 00000000..cae39d36 --- /dev/null +++ b/scripts/build-doc.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -x +set -e + +# Folders Location +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT_DIR="${DIR}/.." +BUILD_DIR="${ROOT_DIR}/build" +BUILD_LOGS_DIR="${BUILD_DIR}/logs" + +# Install doxygen2jsdoc dependencies +cd ${ROOT_DIR}/doxy/doxygen2jsdoc && npm install + +# Install doxyport dependencies +cd ${ROOT_DIR}/doxy/doxyport && make setup + +# Create logs folder if not exists +mkdir -p ${BUILD_LOGS_DIR} + +# Make Documentation +cd ${ROOT_DIR} && make -j8 -Cbuild 2> ${BUILD_LOGS_DIR}/build-doc.log + +# Make Java Documentation +cd ${BUILD_DIR} && find ../src/ -name "javaupm_*.i" > upm.i.list && \ +../doxy/doxyport/doxyport upm.i.list \ + --cmake ./compile_commands.json \ + --source ../src/interfaces/,../src/bacnetmstp \ + --destination src/ \ + --convert-protected-to-private \ + --output upm-java-files.txt \ + --mapping ../doxy/samples.mapping.txt 1> ${BUILD_LOGS_DIR}/doxyport.log && \ +rm -fr java && mkdir java && cd java && \ +doxygen ../Doxyfile-java 2> ${BUILD_LOGS_DIR}/doxygen-java.log + diff --git a/scripts/run-cmake.sh b/scripts/run-cmake.sh index 05f1e438..66c65bf1 100755 --- a/scripts/run-cmake.sh +++ b/scripts/run-cmake.sh @@ -15,6 +15,6 @@ cmake \ -DNPM=$NPM \ -DBUILDTESTS=$BUILDTESTS \ -DWERROR=$WERROR \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -H. \ -Bbuild -