diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index fc8c8de..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: CI -run-name: continuous integration -on: [push] -jobs: - test: - strategy: - matrix: - os: [ubuntu-20.04, ubuntu-22.04, ubuntu-latest] - cc: [gcc, clang] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - run: ./tests/test.sh - shell: bash - env: - CC: ${{ matrix.cc }} diff --git a/LICENSE b/LICENSE deleted file mode 100644 index dcbb365..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015-2023 Ryan Jacobs - -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. diff --git a/README.md b/README.md deleted file mode 100644 index 0619720..0000000 --- a/README.md +++ /dev/null @@ -1,185 +0,0 @@ -# c - -<!-- -[](https://travis-ci.org/ryanmjacobs/c) ---> - -> "There isn't much that's special about C. That's one of the reasons why it's -fast." - -I love C for its raw speed (although it does have its drawbacks). We should -all write more C. - -With this shell script, you can compile and execute C "scripts" in one go! - -(Oh yeah, and it works for C++ too.) - - - -Here's a simple example: -```c -#include <stdio.h> - -int main(void) { - printf("Hello World!\n"); - return 0; -} -``` - -Run it by typing: -```bash -$ c hello.c -Hello World! -``` - -Or, call it from the shebang! -```c -#!/usr/bin/c -#include <stdio.h> - -int main(void) { - printf("Hello World!\n"); - return 0; -} -``` -```bash -$ chmod +x hello.c -$ ./hello.c -Hello World! -``` - -## Hooked? Here's how to install it: -Use a package manager? [Check here](https://github.com/ryanmjacobs/c#packages). - -For the entire system: -```bash -$ wget https://raw.githubusercontent.com/ryanmjacobs/c/master/c -$ sudo install -m 755 c /usr/bin/c - -# Or... for systems that prefer /usr/local/bin (e.g. macOS) -$ sudo install -m 755 c /usr/local/bin/c -``` - -For your local user only: -```bash -$ wget https://raw.githubusercontent.com/ryanmjacobs/c/master/c -$ sudo install -Dm 755 c ~/.bin/c -$ echo 'PATH=$PATH:$HOME/.bin' >> ~/.bashrc -``` - -Note: if you install it somewhere other than `/usr/bin/c`, then your shebang -will be different. For example it may be something more similar to -`#!/home/ryan/.bin/c`. - -## Okay, how do I use it? -c will use whatever `$CC` is set to. You can change this with: -```bash -$ export CC=clang -$ export CC=tcc -$ # etc... -``` -## CLI -### Multiple Files - CLI -Anything you want passed to the compiler, put in quotes as the first argument. -Whether they're flags (`-Wall`, `-O2`, etc.) or file names (`file.c`, -`main.c`, etc.). - -```bash -$ c "main.c other.c" arg1 arg2 -$ c "main.c other.c -O3 -Wall -lncurses" arg1 arg2 -``` -### Single File - CLI -With only one file, omit the quotes: -```bash -$ c hello.c -$ c main.c arg1 arg2 -``` - -## Shebang! -After adding a shebang, just set the file to executable and it's ready to run. -```bash -$ chmod +x file.c -$ ./file.c -``` - -### Single File - Shebang -Add this to the top of your C file: -```c -#!/usr/bin/c -``` - -### Multiple Files - Shebang -Just tack on any extra flags, options, or files you want passed to the compiler. -Then be sure to add the terminating `--` characters. -```c -#!/usr/bin/c file1.c file2.c -lncurses -lm -- -``` - -## Caching -The default cache size is set to 5 MB. You can change this with: -```bash -$ export C_CACHE_SIZE=$((10*1024)) # 10 MB -``` -The default cache path is set to `$TMPDIR/c.cache`. You can change this with: -```bash -$ export C_CACHE_PATH="/tmp/the_cache" -``` - -### Clear cache -You can clear the cache with the `--clear-cache` flag: -```bash -$ c --clear-cache -``` - -# Contributing -Feel free to submit any ideas, questions, or problems by reporting an issue. -Or, if you're feeling a bit brave, submit a pull request. :grimacing: - -Just hack away and make sure that all the tests pass. -```bash -$ cd tests -$ ./test.sh -``` - -## Why? -First of all, I want to clarify why this is **not** the same as `tcc -run`. -TCC is a compiler. We all know that. TCC will perform its own set of -optimizations, just as GCC will perform its own and Clang will perform its -own. The purpose of this script is to give a simple front-end to your favorite -compiler. - -Whether it's GCC, Clang, or something else entirely, **you** get to choose -your compiler. - -Second reason: it's simply satisfying to type `c hello.c` and see it run instantly. - -Third reason: I'm a fan of speed, and C definitely offers it. Being able to -write a small, fast, and portable C "script" is great. You can pass around a -C "script" just like you would a BASH script. - -## zsh -If you're using `zsh`, then you can take advantage of `zsh`'s suffix aliases: -```bash -$ alias -s c='c' -$ alias -s cc='c' -$ alias -s cpp='c' -``` -Then you can run files with `./file.c` without `chmod +x`. - -## Packages -Use a package manager? You've come to the right place. - -AUR: https://aur.archlinux.org/packages/c/<br> -bpkg: `bpkg install ryanmjacobs/c`<br> -brew: `brew install c` -(shebang will be `#!/usr/local/bin/c` for Intel-based Macs or `#!/opt/homebrew/bin/c` for Apple Silicon)<br> - -## Todo -~~Maybe later we can implement caching.~~ Done! - -## License -[MIT License](https://raw.githubusercontent.com/ryanmjacobs/c/master/LICENSE). - -Basically, you can do whatever you want provided that you include -the LICENSE notice in any copy of the source. Also, I am not liable -if the script breaks anything. diff --git a/c b/c deleted file mode 100755 index 556df58..0000000 --- a/c +++ /dev/null @@ -1,243 +0,0 @@ -#!/usr/bin/env bash -## repository at https://github.com/ryanmjacobs/c -VERSION=v0.15-dev - -# max cachesize in kilobytes (default=5MB) -[[ -z "$C_CACHE_SIZE" ]] && C_CACHE_SIZE=$((5*1024)) -if ! [[ "$C_CACHE_SIZE" =~ ^[0-9]*$ ]]; then - C_CACHE_SIZE=$((5*1024)) - >&2 echo 'warning: $C_CACHE_SIZE should be a positive integer' -fi - -help_msg() { - >&$1 echo "Usage: $(basename "$0") <file.c ... | compiler_options ...> [program_arguments]" - >&$1 echo " $(basename "$0") --clear-cache" - >&$1 echo 'Execute C programs from the command line.' - >&$1 echo - >&$1 echo ' Ex: c main.c' - >&$1 echo ' Ex: c main.c arg1 arg2' - >&$1 echo " Ex: c 'main.c other.c' arg1 arg2" - >&$1 echo " Ex: c 'main.c -lncurses' arg1 arg2" - >&$1 echo -} - -cleanup() { - # remove temporary source directory - rm -rf "$tmpdir" - - # remove cache files until we are under $cachesize - if [ "$(uname -s)" == "SunOS" ] ; then ducmd="du -ks" ; else ducmd="du -kc" ; fi - while [[ "$($ducmd "$tmproot" | tail -1 | cut -f1)" -gt "$C_CACHE_SIZE" ]]; do - [[ -z "$(ls -A "$tmproot")" ]] && break - rm -rf "$(find "$tmproot" | tail -n1)" - done -} - -# Handle --help, -h, and zero args -[[ "$1" == "--help" || "$1" == "-h" ]] && { help_msg 1; exit 0; } -[[ "$#" -lt 1 ]] && { help_msg 2; exit 2; } - -# get cache location -if [[ -n "$C_CACHE_PATH" ]]; then - tmproot="$C_CACHE_PATH" -else - [[ -z "$TMPDIR" ]] && TMPDIR="/tmp" - tmproot="$TMPDIR/c.cache.$USER" -fi - -# Hadle --clear-cache -[[ "$1" == "--clear-cache" ]] && exec rm -rf "$tmproot" - -# ensure our $CC and $CXX variables are set -[[ -z "$CC" ]] && CC=cc -[[ -z "$FC" ]] && FC=gfortran -[[ -z "$CXX" ]] && CXX=c++ -if ! hash "$CC" &>/dev/null; then - >&2 echo "error: \$CC ($CC) not found" - exit 1 -fi - -# $comp holds the files and options that will be passed to the compiler -# $fname will become the program's argv[0] -if [ -f "$1" ]; then - # given only one file, so that must be our source file - comp=("$1") - fname="$1" -else - # capture all of our source files, - # use the first file as our fname - for arg in $1; do - if [[ "$arg" == "--" ]]; then - fname="$2" - comp=("$2" "${comp[@]}") - shift - else - comp+=("$arg") - fi - done - - # if we don't have an fname yet, pick one out of $comp - # that doesn't start with a '-' - if [[ -z "$fname" ]]; then - for arg in $1; do - if [[ "$arg" != -* ]]; then - fname="$arg" - break - fi - done - fi -fi - -# create cache location -mkdir -p "$tmproot" -chmod 700 "$tmproot" - -# decide on a hash function by using the first one we find -potential_hashes=(md5sum sha256sum sha1sum shasum) -hash_func=: -for hf in "${potential_hashes[@]}"; do - hash "$hf" &>/dev/null && { hash_func="$hf"; break; } -done - -# disable caching if we don't locate a hashing function -[ "$hash_func" == : ] && C_CACHE_SIZE=0 - -# determine if we are C, C++ or Fortran, then use appropriate flags -is_cpp=false -is_fortran=false -for f in "$fname" "${comp[@]}"; do - # only examine files - [[ ! -f "$f" ]] && continue - - # if one file has a C++ extension, then the whole set is C++ - if [[ "$f" =~ \.(cc|c\+\+|cpp|cxx)$ ]]; then - is_cpp=true - - if hash "$CXX" &>/dev/null; then - # found $CXX, we will use that - CC="$CXX" - comp+=("$CXXFLAGS") - else - # couldn't find $CXX, so we make do with $CC and -lstdc++ - comp+=("$CFLAGS -lstdc++") - fi - - break - fi - - # if one file has a Fortran extension, then the whole set is Fortran - # We have to check case insensitive because many fortran suffixes are - # uppercase - shopt -s nocasematch - if [[ "$f" =~ \.(f|f95|f77|f90|f03|f15|for)$ ]]; then - is_fortran=true - CC="${FC}" - comp+=(${FCFLAGS}) - fi - shopt -u nocasematch - -done - -# add $CFLAGS if and only if we are not C++ -if [[ "$is_cpp" == false && "${is_fortran}" == false ]]; then - comp+=($CFLAGS) -fi - -# add preprocessor flags -comp+=("$CPPFLAGS") - -# hash all of our data -prehash="$CC ${comp[*]}" # compiler + flags and files -for f in "${comp[@]}"; do - [ -f "$f" ] && prehash+="$f $(cpp "$f" 2>&1)" -done - -# hash everything into one unique identifier, for caching purposes -id="c$("$hash_func" <<< "$prehash" | cut -d' ' -f1)" -tmpdir="$tmproot/$id.src" -binname="$tmproot/$id.bin" - -# run binary -run() { - trap cleanup SIGINT - - if [ -x "$binname" ]; then - shift - (exec -a "$fname" "$binname" "$@") - ret=$? - else - echo - ret=4 - fi - - trap - SIGINT - cleanup - exit $ret -} - -# run cached file if it exists -if [[ -f "$binname" ]]; then - run "$@" -else - mkdir -p "$tmpdir" -fi - -# assemble our includes, based on the original file locations -includes=("-I'$PWD'") -for f in "${comp[@]}"; do - [[ -f "$f" ]] && includes+=("-I'$(dirname "$f")'") -done - -i=0 -# copy source files to $tmpdir -for f in "${comp[@]}"; do - if [[ -f "$f" && "$f" != $tmpdir* ]]; then - mkdir -p "$tmpdir/$(dirname "$f")" - cp "$f" "$tmpdir/$f" - - # assume language is C, if no extension is given - base="$(basename "$f")" - ext="${base##*.}" - if [[ "$ext" == "$base" ]]; then - comp[$i]="-x c $tmpdir/$f -x none" - else - comp[$i]="$tmpdir/$f" - fi - - # remove shebangs from every source file - if [[ "$(head -n1 "$tmpdir/$f")" == \#\!* ]]; then - echo "$(tail -n +2 "$tmpdir/$f")" > "$tmpdir/$f" - fi - fi - let i++ -done - -# final operations before compilation -rest=() -flags=() -for f in "${comp[@]}"; do - # skip empty elements - [[ -z "$f" ]] && break - - # separate the flags from other arguments - [[ "$f" =~ ^- ]] &&\ - flags+=("$f") ||\ - rest+=("$f") -done - -# compile and run - -# kludgey fix for gcc arguments -out="$("$CC" -O2 -o "$binname" ${flags[@]} "${includes[@]}" "${rest[@]}" 2>&1)" -if [ $? -ne 0 ]; then - eval "$CC" -O2 -o "$binname" ${flags[@]} "${includes[@]}" "${rest[@]}" -else - echo -n "$out" -fi - -if [ $? -eq 0 ]; then - run "$@" -else - cleanup - exit 1 -fi diff --git a/c.rb b/c.rb deleted file mode 100644 index 0fa825e..0000000 --- a/c.rb +++ /dev/null @@ -1,15 +0,0 @@ -class C < Formula - homepage "https://github.com/ryanmjacobs/c" - url "https://github.com/ryanmjacobs/c/archive/v0.14.tar.gz" - sha256 "2b66d79d0d5c60b8e6760dac734b8ec9a7d6a5e57f033b97086821b1985a870b" - head "https://github.com/ryanmjacobs/c.git" - - def install - bin.install "c" - end - - test do - #system "#{bin}/c", "") - pipe_output("#{bin}/c", "int main(void){return 0;}", 0) - end -end diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index 96af5a1..0000000 --- a/examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.tmp.c diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 4bc48e7..0000000 --- a/examples/README.md +++ /dev/null @@ -1,8 +0,0 @@ -c Examples -========== - -```bash -$ ./example_name.c -# OR -$ c example_name.c -``` diff --git a/examples/cube.c b/examples/cube.c deleted file mode 100755 index 1aee680..0000000 --- a/examples/cube.c +++ /dev/null @@ -1,93 +0,0 @@ -#!../c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm -- -/* Copyright (c) Mark J. Kilgard, 1997. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ - -/* This program was requested by Patrick Earl; hopefully someone else - will write the equivalent Direct3D immediate mode program. */ - -#include <GL/glut.h> - -GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */ -GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */ -GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */ - {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, - {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} }; -GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */ - {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4}, - {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} }; -GLfloat v[8][3]; /* Will be filled in with X,Y,Z vertexes. */ - -void -drawBox(void) -{ - int i; - - for (i = 0; i < 6; i++) { - glBegin(GL_QUADS); - glNormal3fv(&n[i][0]); - glVertex3fv(&v[faces[i][0]][0]); - glVertex3fv(&v[faces[i][1]][0]); - glVertex3fv(&v[faces[i][2]][0]); - glVertex3fv(&v[faces[i][3]][0]); - glEnd(); - } -} - -void -display(void) -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - drawBox(); - glutSwapBuffers(); -} - -void -init(void) -{ - /* Setup cube vertex data. */ - v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1; - v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1; - v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1; - v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1; - v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1; - v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1; - - /* Enable a single OpenGL light. */ - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT0, GL_POSITION, light_position); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHTING); - - /* Use depth buffering for hidden surface elimination. */ - glEnable(GL_DEPTH_TEST); - - /* Setup the view of the cube. */ - glMatrixMode(GL_PROJECTION); - gluPerspective( /* field of view in degree */ 40.0, - /* aspect ratio */ 1.0, - /* Z near */ 1.0, /* Z far */ 10.0); - glMatrixMode(GL_MODELVIEW); - gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */ - 0.0, 0.0, 0.0, /* center is at (0,0,0) */ - 0.0, 1.0, 0.); /* up is in positive Y direction */ - - /* Adjust cube position to be asthetic angle. */ - glTranslatef(0.0, 0.0, -1.0); - glRotatef(60, 1.0, 0.0, 0.0); - glRotatef(-20, 0.0, 0.0, 1.0); -} - -int -main(int argc, char **argv) -{ - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); - glutCreateWindow("red 3D lighted cube"); - glutDisplayFunc(display); - init(); - glutMainLoop(); - return 0; /* ANSI C requires main to return int. */ -} diff --git a/examples/dinoshade.c b/examples/dinoshade.c deleted file mode 100755 index 29a2c07..0000000 --- a/examples/dinoshade.c +++ /dev/null @@ -1,893 +0,0 @@ -#!../c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm -- - -/* Copyright (c) Mark J. Kilgard, 1994, 1997. */ - -/* This program is freely distributable without licensing fees - and is provided without guarantee or warrantee expressed or - implied. This program is -not- in the public domain. */ - -/* Example for PC game developers to show how to *combine* texturing, - reflections, and projected shadows all in real-time with OpenGL. - Robust reflections use stenciling. Robust projected shadows - use both stenciling and polygon offset. PC game programmers - should realize that neither stenciling nor polygon offset are - supported by Direct3D, so these real-time rendering algorithms - are only really viable with OpenGL. - - The program has modes for disabling the stenciling and polygon - offset uses. It is worth running this example with these features - toggled off so you can see the sort of artifacts that result. - - Notice that the floor texturing, reflections, and shadowing - all co-exist properly. */ - -/* When you run this program: Left mouse button controls the - view. Middle mouse button controls light position (left & - right rotates light around dino; up & down moves light - position up and down). Right mouse button pops up menu. */ - -/* Check out the comments in the "redraw" routine to see how the - reflection blending and surface stenciling is done. You can - also see in "redraw" how the projected shadows are rendered, - - including the use of stenciling and polygon offset. */ - -/* This program is derived from glutdino.c */ - -/* Compile: cc -o dinoshade dinoshade.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> /* for cos(), sin(), and sqrt() */ -#include <GL/glut.h> /* OpenGL Utility Toolkit header */ - -/* Some <math.h> files do not define M_PI... */ -#ifndef M_PI -#define M_PI 3.14159265 -#endif - -/* Variable controlling various rendering modes. */ -static int stencilReflection = 1, stencilShadow = 1, offsetShadow = 1; -static int renderShadow = 1, renderDinosaur = 1, renderReflection = 1; -static int linearFiltering = 0, useMipmaps = 0, useTexture = 1; -static int reportSpeed = 0; -static int animation = 1; -static GLboolean lightSwitch = GL_TRUE; -static int directionalLight = 1; -static int forceExtension = 0; - -/* Time varying or user-controled variables. */ -static float jump = 0.0; -static float lightAngle = 0.0, lightHeight = 20; -GLfloat angle = -150; /* in degrees */ -GLfloat angle2 = 30; /* in degrees */ - -int moving, startx, starty; -int lightMoving = 0, lightStartX, lightStartY; - -enum { - MISSING, EXTENSION, ONE_DOT_ONE -}; -int polygonOffsetVersion; - -static GLdouble bodyWidth = 3.0; -/* *INDENT-OFF* */ -static GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5}, - {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16}, - {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2}, - {1, 2} }; -static GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9}, - {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10}, - {13, 9}, {11, 11}, {9, 11} }; -static GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0}, - {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} }; -static GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15}, - {9.6, 15.25}, {9, 15.25} }; -static GLfloat lightPosition[4]; -static GLfloat lightColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */ -static GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0}; -/* *INDENT-ON* */ - -/* Nice floor texture tiling pattern. */ -static char *circles[] = { - "....xxxx........", - "..xxxxxxxx......", - ".xxxxxxxxxx.....", - ".xxx....xxx.....", - "xxx......xxx....", - "xxx......xxx....", - "xxx......xxx....", - "xxx......xxx....", - ".xxx....xxx.....", - ".xxxxxxxxxx.....", - "..xxxxxxxx......", - "....xxxx........", - "................", - "................", - "................", - "................", -}; - -static void -makeFloorTexture(void) -{ - GLubyte floorTexture[16][16][3]; - GLubyte *loc; - int s, t; - - /* Setup RGB image for the texture. */ - loc = (GLubyte*) floorTexture; - for (t = 0; t < 16; t++) { - for (s = 0; s < 16; s++) { - if (circles[t][s] == 'x') { - /* Nice green. */ - loc[0] = 0x1f; - loc[1] = 0x8f; - loc[2] = 0x1f; - } else { - /* Light gray. */ - loc[0] = 0xaa; - loc[1] = 0xaa; - loc[2] = 0xaa; - } - loc += 3; - } - } - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - if (useMipmaps) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 16, 16, - GL_RGB, GL_UNSIGNED_BYTE, floorTexture); - } else { - if (linearFiltering) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0, - GL_RGB, GL_UNSIGNED_BYTE, floorTexture); - } -} - -enum { - X, Y, Z, W -}; -enum { - A, B, C, D -}; - -/* Create a matrix that will project the desired shadow. */ -void -shadowMatrix(GLfloat shadowMat[4][4], - GLfloat groundplane[4], - GLfloat lightpos[4]) -{ - GLfloat dot; - - /* Find dot product between light position vector and ground plane normal. */ - dot = groundplane[X] * lightpos[X] + - groundplane[Y] * lightpos[Y] + - groundplane[Z] * lightpos[Z] + - groundplane[W] * lightpos[W]; - - shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; - shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; - shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; - shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; - - shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; - shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; - shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; - shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; - - shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; - shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; - shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; - shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; - - shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; - shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; - shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; - shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; - -} - -/* Find the plane equation given 3 points. */ -void -findPlane(GLfloat plane[4], - GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) -{ - GLfloat vec0[3], vec1[3]; - - /* Need 2 vectors to find cross product. */ - vec0[X] = v1[X] - v0[X]; - vec0[Y] = v1[Y] - v0[Y]; - vec0[Z] = v1[Z] - v0[Z]; - - vec1[X] = v2[X] - v0[X]; - vec1[Y] = v2[Y] - v0[Y]; - vec1[Z] = v2[Z] - v0[Z]; - - /* find cross product to get A, B, and C of plane equation */ - plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; - plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); - plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; - - plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); -} - -void -extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, - GLdouble thickness, GLuint side, GLuint edge, GLuint whole) -{ - static GLUtriangulatorObj *tobj = NULL; - GLdouble vertex[3], dx, dy, len; - int i; - int count = (int) (dataSize / (2 * sizeof(GLfloat))); - - if (tobj == NULL) { - tobj = gluNewTess(); /* create and initialize a GLU - polygon tessellation object */ - gluTessCallback(tobj, GLU_BEGIN, glBegin); - gluTessCallback(tobj, GLU_VERTEX, glVertex2fv); /* semi-tricky */ - gluTessCallback(tobj, GLU_END, glEnd); - } - glNewList(side, GL_COMPILE); - glShadeModel(GL_SMOOTH); /* smooth minimizes seeing - tessellation */ - gluBeginPolygon(tobj); - for (i = 0; i < count; i++) { - vertex[0] = data[i][0]; - vertex[1] = data[i][1]; - vertex[2] = 0; - gluTessVertex(tobj, vertex, data[i]); - } - gluEndPolygon(tobj); - glEndList(); - glNewList(edge, GL_COMPILE); - glShadeModel(GL_FLAT); /* flat shade keeps angular hands - from being "smoothed" */ - glBegin(GL_QUAD_STRIP); - for (i = 0; i <= count; i++) { - /* mod function handles closing the edge */ - glVertex3f(data[i % count][0], data[i % count][1], 0.0); - glVertex3f(data[i % count][0], data[i % count][1], thickness); - /* Calculate a unit normal by dividing by Euclidean - distance. We * could be lazy and use - glEnable(GL_NORMALIZE) so we could pass in * arbitrary - normals for a very slight performance hit. */ - dx = data[(i + 1) % count][1] - data[i % count][1]; - dy = data[i % count][0] - data[(i + 1) % count][0]; - len = sqrt(dx * dx + dy * dy); - glNormal3f(dx / len, dy / len, 0.0); - } - glEnd(); - glEndList(); - glNewList(whole, GL_COMPILE); - glFrontFace(GL_CW); - glCallList(edge); - glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */ - glCallList(side); - glPushMatrix(); - glTranslatef(0.0, 0.0, thickness); - glFrontFace(GL_CCW); - glNormal3f(0.0, 0.0, 1.0); /* opposite normal for other side */ - glCallList(side); - glPopMatrix(); - glEndList(); -} - -/* Enumerants for refering to display lists. */ -typedef enum { - RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE, - LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE -} displayLists; - -static void -makeDinosaur(void) -{ - extrudeSolidFromPolygon(body, sizeof(body), bodyWidth, - BODY_SIDE, BODY_EDGE, BODY_WHOLE); - extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4, - ARM_SIDE, ARM_EDGE, ARM_WHOLE); - extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2, - LEG_SIDE, LEG_EDGE, LEG_WHOLE); - extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2, - EYE_SIDE, EYE_EDGE, EYE_WHOLE); -} - -static void -drawDinosaur(void) - -{ - glPushMatrix(); - /* Translate the dinosaur to be at (0,8,0). */ - glTranslatef(-8, 0, -bodyWidth / 2); - glTranslatef(0.0, jump, 0.0); - glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor); - glCallList(BODY_WHOLE); - glTranslatef(0.0, 0.0, bodyWidth); - glCallList(ARM_WHOLE); - glCallList(LEG_WHOLE); - glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4); - glCallList(ARM_WHOLE); - glTranslatef(0.0, 0.0, -bodyWidth / 4); - glCallList(LEG_WHOLE); - glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1); - glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor); - glCallList(EYE_WHOLE); - glPopMatrix(); -} - -static GLfloat floorVertices[4][3] = { - { -20.0, 0.0, 20.0 }, - { 20.0, 0.0, 20.0 }, - { 20.0, 0.0, -20.0 }, - { -20.0, 0.0, -20.0 }, -}; - -/* Draw a floor (possibly textured). */ -static void -drawFloor(void) -{ - glDisable(GL_LIGHTING); - - if (useTexture) { - glEnable(GL_TEXTURE_2D); - } - - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex3fv(floorVertices[0]); - glTexCoord2f(0.0, 16.0); - glVertex3fv(floorVertices[1]); - glTexCoord2f(16.0, 16.0); - glVertex3fv(floorVertices[2]); - glTexCoord2f(16.0, 0.0); - glVertex3fv(floorVertices[3]); - glEnd(); - - if (useTexture) { - glDisable(GL_TEXTURE_2D); - } - - glEnable(GL_LIGHTING); -} - -static GLfloat floorPlane[4]; -static GLfloat floorShadow[4][4]; - -static void -redraw(void) -{ - int start, end; - - if (reportSpeed) { - start = glutGet(GLUT_ELAPSED_TIME); - } - - /* Clear; default stencil clears to zero. */ - if ((stencilReflection && renderReflection) || (stencilShadow && renderShadow)) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - } else { - /* Avoid clearing stencil when not using it. */ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - - /* Reposition the light source. */ - lightPosition[0] = 12*cos(lightAngle); - lightPosition[1] = lightHeight; - lightPosition[2] = 12*sin(lightAngle); - if (directionalLight) { - lightPosition[3] = 0.0; - } else { - lightPosition[3] = 1.0; - } - - shadowMatrix(floorShadow, floorPlane, lightPosition); - - glPushMatrix(); - /* Perform scene rotations based on user mouse input. */ - glRotatef(angle2, 1.0, 0.0, 0.0); - glRotatef(angle, 0.0, 1.0, 0.0); - - /* Tell GL new light source position. */ - glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); - - if (renderReflection) { - if (stencilReflection) { - /* We can eliminate the visual "artifact" of seeing the "flipped" - dinosaur underneath the floor by using stencil. The idea is - draw the floor without color or depth update but so that - a stencil value of one is where the floor will be. Later when - rendering the dinosaur reflection, we will only update pixels - with a stencil value of 1 to make sure the reflection only - lives on the floor, not below the floor. */ - - /* Don't update color or depth. */ - glDisable(GL_DEPTH_TEST); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - /* Draw 1 into the stencil buffer. */ - glEnable(GL_STENCIL_TEST); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - glStencilFunc(GL_ALWAYS, 1, 0xffffffff); - - /* Now render floor; floor pixels just get their stencil set to 1. */ - drawFloor(); - - /* Re-enable update of color and depth. */ - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glEnable(GL_DEPTH_TEST); - - /* Now, only render where stencil is set to 1. */ - glStencilFunc(GL_EQUAL, 1, 0xffffffff); /* draw if ==1 */ - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - } - - glPushMatrix(); - - /* The critical reflection step: Reflect dinosaur through the floor - (the Y=0 plane) to make a relection. */ - glScalef(1.0, -1.0, 1.0); - - /* Reflect the light position. */ - glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); - - /* To avoid our normals getting reversed and hence botched lighting - on the reflection, turn on normalize. */ - glEnable(GL_NORMALIZE); - glCullFace(GL_FRONT); - - /* Draw the reflected dinosaur. */ - drawDinosaur(); - - /* Disable noramlize again and re-enable back face culling. */ - glDisable(GL_NORMALIZE); - glCullFace(GL_BACK); - - glPopMatrix(); - - /* Switch back to the unreflected light position. */ - glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); - - if (stencilReflection) { - glDisable(GL_STENCIL_TEST); - } - } - - /* Back face culling will get used to only draw either the top or the - bottom floor. This let's us get a floor with two distinct - appearances. The top floor surface is reflective and kind of red. - The bottom floor surface is not reflective and blue. */ - - /* Draw "bottom" of floor in blue. */ - glFrontFace(GL_CW); /* Switch face orientation. */ - glColor4f(0.1, 0.1, 0.7, 1.0); - drawFloor(); - glFrontFace(GL_CCW); - - if (renderShadow) { - if (stencilShadow) { - /* Draw the floor with stencil value 3. This helps us only - draw the shadow once per floor pixel (and only on the - floor pixels). */ - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 3, 0xffffffff); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - } - } - - /* Draw "top" of floor. Use blending to blend in reflection. */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0.7, 0.0, 0.0, 0.3); - glColor4f(1.0, 1.0, 1.0, 0.3); - drawFloor(); - glDisable(GL_BLEND); - - if (renderDinosaur) { - /* Draw "actual" dinosaur, not its reflection. */ - drawDinosaur(); - } - - if (renderShadow) { - - /* Render the projected shadow. */ - - if (stencilShadow) { - - /* Now, only render where stencil is set above 2 (ie, 3 where - the top floor is). Update stencil with 2 where the shadow - gets drawn so we don't redraw (and accidently reblend) the - shadow). */ - glStencilFunc(GL_LESS, 2, 0xffffffff); /* draw if ==1 */ - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - } - - /* To eliminate depth buffer artifacts, we use polygon offset - to raise the depth of the projected shadow slightly so - that it does not depth buffer alias with the floor. */ - if (offsetShadow) { - switch (polygonOffsetVersion) { - case EXTENSION: -#ifdef GL_EXT_polygon_offset - glEnable(GL_POLYGON_OFFSET_EXT); - break; -#endif -#ifdef GL_VERSION_1_1 - case ONE_DOT_ONE: - glEnable(GL_POLYGON_OFFSET_FILL); - break; -#endif - case MISSING: - /* Oh well. */ - break; - } - } - - /* Render 50% black shadow color on top of whatever the - floor appareance is. */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_LIGHTING); /* Force the 50% black. */ - glColor4f(0.0, 0.0, 0.0, 0.5); - - glPushMatrix(); - /* Project the shadow. */ - glMultMatrixf((GLfloat *) floorShadow); - drawDinosaur(); - glPopMatrix(); - - glDisable(GL_BLEND); - glEnable(GL_LIGHTING); - - if (offsetShadow) { - switch (polygonOffsetVersion) { -#ifdef GL_EXT_polygon_offset - case EXTENSION: - glDisable(GL_POLYGON_OFFSET_EXT); - break; -#endif -#ifdef GL_VERSION_1_1 - case ONE_DOT_ONE: - glDisable(GL_POLYGON_OFFSET_FILL); - break; -#endif - case MISSING: - /* Oh well. */ - break; - } - } - if (stencilShadow) { - glDisable(GL_STENCIL_TEST); - } - } - - glPushMatrix(); - glDisable(GL_LIGHTING); - glColor3f(1.0, 1.0, 0.0); - if (directionalLight) { - /* Draw an arrowhead. */ - glDisable(GL_CULL_FACE); - glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); - glRotatef(lightAngle * -180.0 / M_PI, 0, 1, 0); - glRotatef(atan(lightHeight/12) * 180.0 / M_PI, 0, 0, 1); - glBegin(GL_TRIANGLE_FAN); - glVertex3f(0, 0, 0); - glVertex3f(2, 1, 1); - glVertex3f(2, -1, 1); - glVertex3f(2, -1, -1); - glVertex3f(2, 1, -1); - glVertex3f(2, 1, 1); - glEnd(); - /* Draw a white line from light direction. */ - glColor3f(1.0, 1.0, 1.0); - glBegin(GL_LINES); - glVertex3f(0, 0, 0); - glVertex3f(5, 0, 0); - glEnd(); - glEnable(GL_CULL_FACE); - } else { - /* Draw a yellow ball at the light source. */ - glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]); - glutSolidSphere(1.0, 5, 5); - } - glEnable(GL_LIGHTING); - glPopMatrix(); - - glPopMatrix(); - - if (reportSpeed) { - glFinish(); - end = glutGet(GLUT_ELAPSED_TIME); - printf("Speed %.3g frames/sec (%d ms)\n", 1000.0/(end-start), end-start); - } - - glutSwapBuffers(); -} - -/* ARGSUSED2 */ -static void -mouse(int button, int state, int x, int y) -{ - if (button == GLUT_LEFT_BUTTON) { - if (state == GLUT_DOWN) { - moving = 1; - startx = x; - starty = y; - } - if (state == GLUT_UP) { - moving = 0; - } - } - if (button == GLUT_MIDDLE_BUTTON) { - if (state == GLUT_DOWN) { - lightMoving = 1; - lightStartX = x; - lightStartY = y; - } - if (state == GLUT_UP) { - lightMoving = 0; - } - } -} - -/* ARGSUSED1 */ -static void -motion(int x, int y) -{ - if (moving) { - angle = angle + (x - startx); - angle2 = angle2 + (y - starty); - startx = x; - starty = y; - glutPostRedisplay(); - } - if (lightMoving) { - lightAngle += (x - lightStartX)/40.0; - lightHeight += (lightStartY - y)/20.0; - lightStartX = x; - lightStartY = y; - glutPostRedisplay(); - } -} - -/* Advance time varying state when idle callback registered. */ -static void -idle(void) -{ - static float time = 0.0; - - time = glutGet(GLUT_ELAPSED_TIME) / 500.0; - - jump = 4.0 * fabs(sin(time)*0.5); - if (!lightMoving) { - lightAngle += 0.03; - } - glutPostRedisplay(); -} - -enum { - M_NONE, M_MOTION, M_LIGHT, M_TEXTURE, M_SHADOWS, M_REFLECTION, M_DINOSAUR, - M_STENCIL_REFLECTION, M_STENCIL_SHADOW, M_OFFSET_SHADOW, - M_POSITIONAL, M_DIRECTIONAL, M_PERFORMANCE -}; - -static void -controlLights(int value) -{ - switch (value) { - case M_NONE: - return; - case M_MOTION: - animation = 1 - animation; - if (animation) { - glutIdleFunc(idle); - } else { - glutIdleFunc(NULL); - } - break; - case M_LIGHT: - lightSwitch = !lightSwitch; - if (lightSwitch) { - glEnable(GL_LIGHT0); - } else { - glDisable(GL_LIGHT0); - } - break; - case M_TEXTURE: - useTexture = !useTexture; - break; - case M_SHADOWS: - renderShadow = 1 - renderShadow; - break; - case M_REFLECTION: - renderReflection = 1 - renderReflection; - break; - case M_DINOSAUR: - renderDinosaur = 1 - renderDinosaur; - break; - case M_STENCIL_REFLECTION: - stencilReflection = 1 - stencilReflection; - break; - case M_STENCIL_SHADOW: - stencilShadow = 1 - stencilShadow; - break; - case M_OFFSET_SHADOW: - offsetShadow = 1 - offsetShadow; - break; - case M_POSITIONAL: - directionalLight = 0; - break; - case M_DIRECTIONAL: - directionalLight = 1; - break; - case M_PERFORMANCE: - reportSpeed = 1 - reportSpeed; - break; - } - glutPostRedisplay(); -} - -/* When not visible, stop animating. Restart when visible again. */ -static void -visible(int vis) -{ - if (vis == GLUT_VISIBLE) { - if (animation) - glutIdleFunc(idle); - } else { - if (!animation) - glutIdleFunc(NULL); - } -} - -/* Press any key to redraw; good when motion stopped and - performance reporting on. */ -/* ARGSUSED */ -static void -key(unsigned char c, int x, int y) -{ - if (c == 27) { - exit(0); /* IRIS GLism, Escape quits. */ - } - glutPostRedisplay(); -} - -/* Press any key to redraw; good when motion stopped and - performance reporting on. */ -/* ARGSUSED */ -static void -special(int k, int x, int y) -{ - glutPostRedisplay(); -} - -static int -supportsOneDotOne(void) -{ - const char *version; - int major, minor; - - version = (char *) glGetString(GL_VERSION); - if (sscanf(version, "%d.%d", &major, &minor) == 2) - return major >= 1 && minor >= 1; - return 0; /* OpenGL version string malformed! */ -} - -int -main(int argc, char **argv) -{ - int i; - - glutInit(&argc, argv); - - for (i=1; i<argc; i++) { - if (!strcmp("-linear", argv[i])) { - linearFiltering = 1; - } else if (!strcmp("-mipmap", argv[i])) { - useMipmaps = 1; - } else if (!strcmp("-ext", argv[i])) { - forceExtension = 1; - } - } - - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_MULTISAMPLE); - -#if 1 - /* In GLUT 4.0, you'll be able to do this an be sure to - get 2 bits of stencil if the machine has it for you. */ - glutInitDisplayString("samples stencil>=2 rgb double depth"); -#endif - - glutCreateWindow("Shadowy Leapin' Lizards"); - - if (glutGet(GLUT_WINDOW_STENCIL_SIZE) <= 1) { - printf("dinoshade: Sorry, I need at least 2 bits of stencil.\n"); - exit(1); - } - - /* Register GLUT callbacks. */ - glutDisplayFunc(redraw); - glutMouseFunc(mouse); - glutMotionFunc(motion); - glutVisibilityFunc(visible); - glutKeyboardFunc(key); - glutSpecialFunc(special); - - glutCreateMenu(controlLights); - - glutAddMenuEntry("Toggle motion", M_MOTION); - glutAddMenuEntry("-----------------------", M_NONE); - glutAddMenuEntry("Toggle light", M_LIGHT); - glutAddMenuEntry("Toggle texture", M_TEXTURE); - glutAddMenuEntry("Toggle shadows", M_SHADOWS); - glutAddMenuEntry("Toggle reflection", M_REFLECTION); - glutAddMenuEntry("Toggle dinosaur", M_DINOSAUR); - glutAddMenuEntry("-----------------------", M_NONE); - glutAddMenuEntry("Toggle reflection stenciling", M_STENCIL_REFLECTION); - glutAddMenuEntry("Toggle shadow stenciling", M_STENCIL_SHADOW); - glutAddMenuEntry("Toggle shadow offset", M_OFFSET_SHADOW); - glutAddMenuEntry("----------------------", M_NONE); - glutAddMenuEntry("Positional light", M_POSITIONAL); - glutAddMenuEntry("Directional light", M_DIRECTIONAL); - glutAddMenuEntry("-----------------------", M_NONE); - glutAddMenuEntry("Toggle performance", M_PERFORMANCE); - glutAttachMenu(GLUT_RIGHT_BUTTON); - makeDinosaur(); - -#ifdef GL_VERSION_1_1 - if (supportsOneDotOne() && !forceExtension) { - polygonOffsetVersion = ONE_DOT_ONE; - glPolygonOffset(-2.0, -1.0); - } else -#endif - { -#ifdef GL_EXT_polygon_offset - /* check for the polygon offset extension */ - if (glutExtensionSupported("GL_EXT_polygon_offset")) { - polygonOffsetVersion = EXTENSION; - glPolygonOffsetEXT(-0.1, -0.002); - } else -#endif - { - polygonOffsetVersion = MISSING; - printf("\ndinoshine: Missing polygon offset.\n"); - printf(" Expect shadow depth aliasing artifacts.\n\n"); - } - } - - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); - glLineWidth(3.0); - - glMatrixMode(GL_PROJECTION); - gluPerspective( /* field of view in degree */ 40.0, - /* aspect ratio */ 1.0, - /* Z near */ 20.0, /* Z far */ 100.0); - glMatrixMode(GL_MODELVIEW); - gluLookAt(0.0, 8.0, 60.0, /* eye is at (0,8,60) */ - 0.0, 8.0, 0.0, /* center is at (0,8,0) */ - 0.0, 1.0, 0.); /* up is in postivie Y direction */ - - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); - glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor); - glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); - glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHTING); - - makeFloorTexture(); - - /* Setup floor plane for projected shadow calculations. */ - findPlane(floorPlane, floorVertices[1], floorVertices[2], floorVertices[3]); - - glutMainLoop(); - return 0; /* ANSI C requires main to return int. */ -} diff --git a/examples/dns.c b/examples/dns.c deleted file mode 100755 index f6e90b4..0000000 --- a/examples/dns.c +++ /dev/null @@ -1,51 +0,0 @@ -#!../c -Wall -std=c89 -pedantic -- -#define _DEFAULT_SOURCE - -#include <stdio.h> -#include <netdb.h> -#include <stdlib.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/socket.h> - -/* http://linux.die.net/man/3/hstrerror */ -void _hstrerror(int err) { - switch (err) { - case HOST_NOT_FOUND: - fputs("error: host is unknown", stderr); - break; - - case NO_DATA: - fputs("error: name is valid but has no IP address", stderr); - break; - - case NO_RECOVERY: - fputs("error: nonrecoverable name server error occurred", stderr); - break; - - case TRY_AGAIN: - fputs("error: temporary error occurred, try again later", stderr); - break; - } -} - -int main(int argc, char **argv) { - struct hostent *h; - struct in_addr**ia; - - if (argc != 2) { - fprintf(stderr, "Usage: %s <host>\n", argv[0]); - return 1; - } - - h = gethostbyname(argv[1]); - - if (h) { - ia = (struct in_addr**)h->h_addr_list; - while (*ia) printf("%s\n", inet_ntoa(**(ia++))); - } else { - _hstrerror(h_errno); - } - - return 0; -} diff --git a/examples/github_commits.c b/examples/github_commits.c deleted file mode 100755 index 103f0cb..0000000 --- a/examples/github_commits.c +++ /dev/null @@ -1,202 +0,0 @@ -#!../c -ljansson -lcurl -- -/* - * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org> - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#include <stdlib.h> -#include <string.h> - -#include <jansson.h> -#include <curl/curl.h> - -#define BUFFER_SIZE (256 * 1024) /* 256 KB */ - -#define URL_FORMAT "https://api.github.com/repos/%s/%s/commits" -#define URL_SIZE 256 - -/* Return the offset of the first newline in text or the length of - text if there's no newline */ -static int newline_offset(const char *text) -{ - const char *newline = strchr(text, '\n'); - if(!newline) - return strlen(text); - else - return (int)(newline - text); -} - -struct write_result -{ - char *data; - int pos; -}; - -static size_t write_response(void *ptr, size_t size, size_t nmemb, void *stream) -{ - struct write_result *result = (struct write_result *)stream; - - if(result->pos + size * nmemb >= BUFFER_SIZE - 1) - { - fprintf(stderr, "error: too small buffer\n"); - return 0; - } - - memcpy(result->data + result->pos, ptr, size * nmemb); - result->pos += size * nmemb; - - return size * nmemb; -} - -static char *request(const char *url) -{ - CURL *curl = NULL; - CURLcode status; - struct curl_slist *headers = NULL; - char *data = NULL; - long code; - - curl_global_init(CURL_GLOBAL_ALL); - curl = curl_easy_init(); - if(!curl) - goto error; - - data = malloc(BUFFER_SIZE); - if(!data) - goto error; - - struct write_result write_result = { - .data = data, - .pos = 0 - }; - - curl_easy_setopt(curl, CURLOPT_URL, url); - - /* GitHub commits API v3 requires a User-Agent header */ - headers = curl_slist_append(headers, "User-Agent: Jansson-Tutorial"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result); - - status = curl_easy_perform(curl); - if(status != 0) - { - fprintf(stderr, "error: unable to request data from %s:\n", url); - fprintf(stderr, "%s\n", curl_easy_strerror(status)); - goto error; - } - - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); - if(code != 200) - { - fprintf(stderr, "error: server responded with code %ld\n", code); - goto error; - } - - curl_easy_cleanup(curl); - curl_slist_free_all(headers); - curl_global_cleanup(); - - /* zero-terminate the result */ - data[write_result.pos] = '\0'; - - return data; - -error: - if(data) - free(data); - if(curl) - curl_easy_cleanup(curl); - if(headers) - curl_slist_free_all(headers); - curl_global_cleanup(); - return NULL; -} - -int main(int argc, char *argv[]) -{ - size_t i; - char *text; - char url[URL_SIZE]; - - json_t *root; - json_error_t error; - - if(argc != 3) - { - fprintf(stderr, "usage: %s USER REPOSITORY\n\n", argv[0]); - fprintf(stderr, "List commits at USER's REPOSITORY.\n\n"); - return 2; - } - - snprintf(url, URL_SIZE, URL_FORMAT, argv[1], argv[2]); - - text = request(url); - if(!text) - return 1; - - root = json_loads(text, 0, &error); - free(text); - - if(!root) - { - fprintf(stderr, "error: on line %d: %s\n", error.line, error.text); - return 1; - } - - if(!json_is_array(root)) - { - fprintf(stderr, "error: root is not an array\n"); - json_decref(root); - return 1; - } - - for(i = 0; i < json_array_size(root); i++) - { - json_t *data, *sha, *commit, *message; - const char *message_text; - - data = json_array_get(root, i); - if(!json_is_object(data)) - { - fprintf(stderr, "error: commit data %d is not an object\n", (int)(i + 1)); - json_decref(root); - return 1; - } - - sha = json_object_get(data, "sha"); - if(!json_is_string(sha)) - { - fprintf(stderr, "error: commit %d: sha is not a string\n", (int)(i + 1)); - return 1; - } - - commit = json_object_get(data, "commit"); - if(!json_is_object(commit)) - { - fprintf(stderr, "error: commit %d: commit is not an object\n", (int)(i + 1)); - json_decref(root); - return 1; - } - - message = json_object_get(commit, "message"); - if(!json_is_string(message)) - { - fprintf(stderr, "error: commit %d: message is not a string\n", (int)(i + 1)); - json_decref(root); - return 1; - } - - message_text = json_string_value(message); - printf("%.8s %.*s\n", - json_string_value(sha), - newline_offset(message_text), - message_text); - } - - json_decref(root); - return 0; -} diff --git a/examples/hello.c b/examples/hello.c deleted file mode 100755 index 18700a5..0000000 --- a/examples/hello.c +++ /dev/null @@ -1,7 +0,0 @@ -#!../c -#include <stdio.h> - -int main(void) { - puts("Hello World!"); - return 0; -} diff --git a/examples/hello.cpp b/examples/hello.cpp deleted file mode 100755 index 9a4e258..0000000 --- a/examples/hello.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#!../c -#include <iostream> - -using namespace std; - -int main(void) { - cout << "Hello World!" << endl; - return 0; -} diff --git a/examples/hello.f95 b/examples/hello.f95 deleted file mode 100755 index 121b138..0000000 --- a/examples/hello.f95 +++ /dev/null @@ -1,5 +0,0 @@ -#!../c -program main - implicit none - write(*,*) "hello world" -end program main diff --git a/examples/mandelbrot.f90 b/examples/mandelbrot.f90 deleted file mode 100755 index 3ea3bf1..0000000 --- a/examples/mandelbrot.f90 +++ /dev/null @@ -1,47 +0,0 @@ -#!../c -program mandelbrot - implicit none - - Integer, parameter :: grid = 10, iter = 90 - - Complex :: c - Integer :: i, j - real :: xpart, ypart - Logical :: converges - - - do i = 0, grid - do j = 0, grid - xpart = -2.0 + 4.0*real(i)/real(grid) - ypart = -2.0 + 4.0*real(j)/real(grid) - c = cmplx(xpart, ypart) - - if (converges(c, iter)) then - print *, c - end if - - end do - end do -end program mandelbrot - - -function converges (c, iter) result (convergence) - implicit none - Complex, intent(in) :: c - Integer, intent(in) :: iter - - Real, parameter :: threshold = 2.0 - Integer :: i - Complex :: buffer - Logical :: convergence - buffer = (0,0) - - do i=0, iter - buffer = buffer**2 + c - if (abs(buffer)>threshold) then - convergence = .false. - return - end if - end do - convergence = .true. -end function diff --git a/examples/noise.sh b/examples/noise.sh deleted file mode 100755 index f79300a..0000000 --- a/examples/noise.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -################################################################################ -# I found this really cool idea online, and just wanted to post it here... -# -# Run it with: ./noise.sh -# -# Links: -# http://www.xkcdb.com/9067 -# http://apple.stackexchange.com/q/74619 -# https://www.youtube.com/watch?v=GtQdIYUtAHg -################################################################################ - -# our "algorithms" -tiznut="putchar(t*(t>>12|t>>8&63&t>>4));" -jeteez="putchar(t*(t>>11|t>>8&123&t>>3));" - xkcdb="putchar(((t*(t>>8|t>>9)&46&t>>8))^(t&t>>13|t>>6));" - -# determine if we're going to use 'play' or 'aplay' -if type aplay; then - play_cmd="aplay -c2 -t raw" -elif type play; then - play_cmd="play -c2 -b 8 -e unsigned-integer -traw" -else - >&2 echo "error: could not find 'play' or 'aplay'" - exit 1 -fi - -# determine where c is... -if type ../c; then - c="../c" -elif type c; then - c="c" -else - >&2 echo "error: you don't have c installed!" - exit 1 -fi - -# exit on Ctrl-C -trap "exit 1" SIGINT - -# generate and play noise -algo() { - algo=$1 - samples=$2 - rate=$3 - - cat << EOF > .tmp.c - #include <stdio.h> - void main(void) { - for (int t=0; t < $samples; t++) { $algo } - } -EOF - c .tmp.c | $play_cmd -r $rate - - rm .tmp.c -} - -# execute each of our algorithms -algo $tiznut 52000 8000 -algo $xkcdb 100000 8000 -algo $tiznut 250000 48000 -algo $jeteez 100000 8000 diff --git a/examples/rand.c b/examples/rand.c deleted file mode 100755 index 027a495..0000000 --- a/examples/rand.c +++ /dev/null @@ -1,19 +0,0 @@ -#!../c -std=c99 -Wall -Werror -DRUN -- -#include <time.h> -#include <stdio.h> -#include <stdlib.h> - -int main(void) { - puts("Generating 10 random numbers..."); - - srand(time(NULL)); - -#ifdef RUN - for (int i = 0; i < 10; i++) - printf("%d\n", rand()); - return 0; -#else - printf("error: compile with flag -DRUN\n"); - return 1; -#endif -} diff --git a/index.html b/index.html new file mode 100644 index 0000000..e14a033 --- /dev/null +++ b/index.html @@ -0,0 +1,11 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>c</title> + </head> + + <body> + <p>Nothing here yet. :(</p> + </body> +</html> diff --git a/package.json b/package.json deleted file mode 100644 index d93499c..0000000 --- a/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "c", - "version": "v0.15-dev", - "description": "Compile and execute C \'scripts\' in one go!", - "global": "true", - "install": "mkdir -p ${PREFIX:-/usr}/bin; install -m 775 c ${PREFIX:-/usr}/bin", - "scripts": [ "c" ] -} diff --git a/tests/C++/multi_file_1.cpp b/tests/C++/multi_file_1.cpp deleted file mode 100755 index 84b151e..0000000 --- a/tests/C++/multi_file_1.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#!../../c multi_file_2.cpp -Wall -Werror -lm -- -#include <stdio.h> - -void print_pow(void); - -int main(int argc, char **argv) { - unsigned int i; - - printf("argc=%d\n", argc); - - if (argc != 4) { - fputs("error: need 3 arguments\n", stderr); - return 1; - } - - for (i = 0; i < 4; i++) - puts(argv[i]); - - print_pow(); - - return 123; -} diff --git a/tests/C++/multi_file_2.cpp b/tests/C++/multi_file_2.cpp deleted file mode 100644 index 9e919a9..0000000 --- a/tests/C++/multi_file_2.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include <math.h> -#include <stdio.h> - -void print_pow(void) { - printf("%.0f\n", pow(2, 10)); -} diff --git a/tests/C++/single_file.cpp b/tests/C++/single_file.cpp deleted file mode 100755 index 3f3e99b..0000000 --- a/tests/C++/single_file.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#!../../c -Wall -Werror -lm -- -#include <math.h> -#include <stdio.h> - -int main(int argc, char **argv) { - unsigned int i; - - printf("argc=%d\n", argc); - - if (argc != 4) { - fputs("error: need 3 arguments\n", stderr); - return 1; - } - - for (i = 0; i < 4; i++) - puts(argv[i]); - - printf("%.0f\n", pow(2, 10)); - - return 123; -} diff --git a/tests/C++/test.sh b/tests/C++/test.sh deleted file mode 100644 index 294525e..0000000 --- a/tests/C++/test.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -pushd C++ - -## -# Test #4: Compile C++. -# -# $1="command to run C++ file" -# $2="expected value of argv[0]" -## -run() { - out=$(eval "$1") - ret=$? - n=1 - while read -r line; do - case $n in - 1) assert "argc " "'$line' == 'argc=4'";; - 2) assert "argv[0]" "'$line' == '$2'";; - 3) assert "argv[1]" "'$line' == 'arg1'";; - 4) assert "argv[2]" "'$line' == 'arg2'";; - 5) assert "argv[3]" "'$line' == 'arg three'";; - 6) assert "pow() " "'$line' -eq 1024";; - esac - let n++ - done <<< "$out" - assert "return " "$ret -eq 123" -} - -header1 "Test #4: Compile C++." - -## Single File - CLI -header2 "Single File - CLI" -run "$c 'single_file.cpp -Wall -Werror -lm'\ - arg1 arg2 'arg three'" "single_file.cpp" - -## Single File - Shebang -header2 "Single File - Shebang" -run "./single_file.cpp\ - arg1 arg2 'arg three'" "./single_file.cpp" - -# Multi. File - CLI -header2 "Multi. File - CLI" -run "$c 'multi_file_1.cpp multi_file_2.cpp -Wall -Werror -lm'\ - arg1 arg2 'arg three'" "multi_file_1.cpp" - -# Multi. File - CLI -header2 "Multi. File - Shebang" -run "./multi_file_1.cpp\ - arg1 arg2 'arg three'" "./multi_file_1.cpp" -popd; echo diff --git a/tests/argument_and_link_test/multi_file_1.c b/tests/argument_and_link_test/multi_file_1.c deleted file mode 100755 index def98cb..0000000 --- a/tests/argument_and_link_test/multi_file_1.c +++ /dev/null @@ -1,22 +0,0 @@ -#!../../c multi_file_2.c -Wall -Werror -lm -- -#include <stdio.h> - -void print_pow(void); - -int main(int argc, char **argv) { - unsigned int i; - - printf("argc=%d\n", argc); - - if (argc != 4) { - fputs("error: need 3 arguments\n", stderr); - return 1; - } - - for (i = 0; i < 4; i++) - puts(argv[i]); - - print_pow(); - - return 123; -} diff --git a/tests/argument_and_link_test/multi_file_2.c b/tests/argument_and_link_test/multi_file_2.c deleted file mode 100644 index 9e919a9..0000000 --- a/tests/argument_and_link_test/multi_file_2.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <math.h> -#include <stdio.h> - -void print_pow(void) { - printf("%.0f\n", pow(2, 10)); -} diff --git a/tests/argument_and_link_test/single_file.c b/tests/argument_and_link_test/single_file.c deleted file mode 100755 index 3f3e99b..0000000 --- a/tests/argument_and_link_test/single_file.c +++ /dev/null @@ -1,21 +0,0 @@ -#!../../c -Wall -Werror -lm -- -#include <math.h> -#include <stdio.h> - -int main(int argc, char **argv) { - unsigned int i; - - printf("argc=%d\n", argc); - - if (argc != 4) { - fputs("error: need 3 arguments\n", stderr); - return 1; - } - - for (i = 0; i < 4; i++) - puts(argv[i]); - - printf("%.0f\n", pow(2, 10)); - - return 123; -} diff --git a/tests/argument_and_link_test/test.sh b/tests/argument_and_link_test/test.sh deleted file mode 100644 index 4f98b63..0000000 --- a/tests/argument_and_link_test/test.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -pushd argument_and_link_test - -## -# Test #1: Argument parsing and linking capabilities. -# -# $1="command to run C file" -# $2="expected value of argv[0]" -## -run() { - out=$(eval "$1") - ret=$? - n=1 - while read -r line; do - case $n in - 1) assert "argc " "'$line' == 'argc=4'";; - 2) assert "argv[0]" "'$line' == '$2'";; - 3) assert "argv[1]" "'$line' == 'arg1'";; - 4) assert "argv[2]" "'$line' == 'arg2'";; - 5) assert "argv[3]" "'$line' == 'arg three'";; - 6) assert "pow() " "'$line' -eq 1024";; - esac - let n++ - done <<< "$out" - assert "return " "$ret -eq 123" -} - -header1 "Test #1: Argument parsing and linking capabilities." - -## Single File - CLI -header2 "Single File - CLI" -run "$c 'single_file.c -Wall -Werror -lm'\ - arg1 arg2 'arg three'" "single_file.c" - -## Single File - Shebang -header2 "Single File - Shebang" -run "./single_file.c\ - arg1 arg2 'arg three'" "./single_file.c" - -# Multi. File - CLI -header2 "Multi. File - CLI" -run "$c 'multi_file_1.c multi_file_2.c -Wall -Werror -lm'\ - arg1 arg2 'arg three'" "multi_file_1.c" - -# Multi. File - CLI -header2 "Multi. File - Shebang" -run "./multi_file_1.c\ - arg1 arg2 'arg three'" "./multi_file_1.c" -popd; echo diff --git a/tests/complex_arguments/complex_args.c b/tests/complex_arguments/complex_args.c deleted file mode 100755 index c16f6e8..0000000 --- a/tests/complex_arguments/complex_args.c +++ /dev/null @@ -1,21 +0,0 @@ -#!../../c -Wall -Werror -lm -- -#include <math.h> -#include <stdio.h> - -int main(int argc, char **argv) { - unsigned int i; - - printf("argc=%d\n", argc); - - if (argc != 5) { - fputs("error: need 4 arguments\n", stderr); - return 1; - } - - for (i = 0; i < 5; i++) - puts(argv[i]); - - printf("%.0f\n", pow(2, 10)); - - return 123; -} diff --git a/tests/complex_arguments/test.sh b/tests/complex_arguments/test.sh deleted file mode 100644 index 0cc39fd..0000000 --- a/tests/complex_arguments/test.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -pushd complex_arguments - -## -# Test #2: Complex argument parsing. -# -# $1="command to run C file" -# $2="expected value of argv[0]" -## -run() { - out=$(eval "$1") - ret=$? - n=1 - while read -r line; do - case $n in - 1) assert "argc " "'$line' == 'argc=5'";; - 2) assert "argv[0]" "'$line' == '$2'";; - 3) assert "argv[1]" "'$line' == 'arg1'";; - 4) assert "argv[2]" "'$line' == 'arg2'";; - 5) assert "argv[3]" "'$line' == 'arg three'";; - 6) assert "argv[4]" "'$line' == 'arg four'";; - 7) assert "pow() " "'$line' -eq 1024";; - esac - let n++ - done <<< "$out" - assert "return " "$ret -eq 123" -} - -header1 "Test #2: Complex argument parsing." - -## Single File - CLI -header2 "Complex Args. - CLI" -run "$c 'complex_args.c -Wall -Werror -lm'\ - arg1 arg2 'arg three' arg\ four" "complex_args.c" - -## Single File - Shebang -header2 "Complex Args. - Shebang" -run "./complex_args.c\ - arg1 arg2 'arg three' arg\ four" "./complex_args.c" -popd; echo diff --git a/tests/examples/test.sh b/tests/examples/test.sh deleted file mode 100644 index 11ec3e7..0000000 --- a/tests/examples/test.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -header1 "Test #6: Ensure ./examples are running correctly." - -# Sadly, we can't test dinoshade.c or cube.c because they require OpenGL. -files=( - dns.c - hello.c - hello.cpp - rand.c - hello.f95 - mandelbrot.f90 -) -returns=(1 0 0 0 0 0) - -for shebang in "" "$c"; do - [ -z "$shebang" ] &&\ - header2 "using shebang" ||\ - header2 "calling directly" - - for i in `seq 0 $((${#files[@]} - 1))`; do - cmd="$shebang ../examples/${files[$i]}" - - # set CFLAGS for non-shebang - unset cf - [ -n "$shebang" ] && cf="-DRUN -std=c99" - - # run cmd - echo $cmd - CFLAGS=$cf eval $cmd - - assert "return" "$? -eq ${returns[$i]}" - done - echo -done - -echo diff --git a/tests/header/a.h b/tests/header/a.h deleted file mode 100644 index 5ccfe50..0000000 --- a/tests/header/a.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "b.h" -char a = 'a'; diff --git a/tests/header/b.h b/tests/header/b.h deleted file mode 100644 index ec62d1a..0000000 --- a/tests/header/b.h +++ /dev/null @@ -1 +0,0 @@ -char b = 'b'; diff --git a/tests/header/c/c.h b/tests/header/c/c.h deleted file mode 100644 index 88c1fb4..0000000 --- a/tests/header/c/c.h +++ /dev/null @@ -1 +0,0 @@ -char c = 'c'; diff --git a/tests/header/main.c b/tests/header/main.c deleted file mode 100755 index 25918b8..0000000 --- a/tests/header/main.c +++ /dev/null @@ -1,12 +0,0 @@ -#!../../c -#include <stdio.h> -#include "a.h" -#include "c/c.h" - -int main(int argc, char **argv) { - putchar(a); - putchar(b); - putchar(c); - putchar(argv[1][0]); - return 99; -} diff --git a/tests/header/test.sh b/tests/header/test.sh deleted file mode 100644 index 9dcf562..0000000 --- a/tests/header/test.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -pushd header -header1 "Test #7: Run a program uses header files." - -# direct call -out="$($c 'main.c -Wall -Werror' d)" -assert "return" "$? -eq 99" -assert "output" "'$out' == 'abcd'" - -# shebang -out="$(./main.c d)" -assert "return" "$? -eq 99" -assert "output" "'$out' == 'abcd'" - -popd; echo diff --git a/tests/shell/test.sh b/tests/shell/test.sh deleted file mode 100644 index c544df1..0000000 --- a/tests/shell/test.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -pushd shell - -header1 "Test #5: Path handling and misc. outputs." - -## Shell - $C_CACHE_SIZE -header2 "Shell - \$C_CACHE_SIZE warnings" - -# cache=-10 -line=$(eval "C_CACHE_SIZE=-10 $c" 2>&1); ret=$? -fline="$(echo "$line" | head -n1)" -assert "\$C_CACHE_SIZE=-10"\ - "'$fline' =~ warning:\\ \\\$C_CACHE_SIZE\\ should\\ be\\ a\\ positive\\ integer.*" -assert "return" "$ret -eq 2" - -# cache=0 -line=$(eval "C_CACHE_SIZE=0 $c" 2>&1); ret=$? -fline="$(echo "$line" | head -n1)" -assert "\$C_CACHE_SIZE=0" "'$fline' =~ Usage:.*" -assert "return" "$ret -eq 2" - -# cache=10 -line=$(eval "C_CACHE_SIZE=10 $c" 2>&1); ret=$? -fline="$(echo "$line" | head -n1)" -assert "\$C_CACHE_SIZE=10" "'$fline' =~ Usage:.*" -assert "return" "$ret -eq 2" - -## Shell - help flags -header2 "Shell - help flags" - -# gives usage without any args -line=$(eval "$c" 2>&1); ret=$? -fline="$(echo "$line" | head -n1)" -assert "c" "'$fline' =~ Usage:.*" -assert "return" "$ret -eq 2" - -# gives usage with --help -line=$(eval "$c --help" 2>&1); ret=$? -fline="$(echo "$line" | head -n1)" -assert "c --help" "'$fline' =~ Usage:.*" -assert "return" "$ret -eq 0" - -# gives usage with -h -line=$(eval "$c -h" 2>&1); ret=$? -fline="$(echo "$line" | head -n1)" -assert "c -h" "'$fline' =~ Usage:.*" -assert "return" "$ret -eq 0" - -## Shell - Compiles with spaces -header2 "Shell - Compiles with spaces" - -# one file -out=$($c 'with spaces/a b.c' a 'b c' d 2>&1) -assert "one file" "'$out' == '(a) (b c) (d)'" - -# shebang -out=$(with\ spaces/a\ b.c a 'b c' d 2>&1) -assert " shebang" "'$out' == '(a) (b c) (d)'" - -popd; echo diff --git a/tests/shell/with spaces/a b.c b/tests/shell/with spaces/a b.c deleted file mode 100755 index d48794a..0000000 --- a/tests/shell/with spaces/a b.c +++ /dev/null @@ -1,8 +0,0 @@ -#!../../c -#include <stdio.h> - -int main(int argc, char **argv) { - printf("(%s) (%s) (%s)\n", argv[1], argv[2], argv[3]); - - return 88; -} diff --git a/tests/shell/with spaces/cd.c b/tests/shell/with spaces/cd.c deleted file mode 100644 index 3d3b871..0000000 --- a/tests/shell/with spaces/cd.c +++ /dev/null @@ -1,3 +0,0 @@ -int some_func() { - return 123; -} diff --git a/tests/stdin/stdin.c b/tests/stdin/stdin.c deleted file mode 100755 index bf2fac6..0000000 --- a/tests/stdin/stdin.c +++ /dev/null @@ -1,13 +0,0 @@ -#include <stdio.h> - -int main(int argc, char **argv) { - if (argc == 2) - fputs(argv[1], stdout); - - char buf[128]; - while (fgets(buf, 128, stdin)) { - fputs(buf, stdout); - } - - return 77; -} diff --git a/tests/stdin/test.sh b/tests/stdin/test.sh deleted file mode 100644 index 08c7b69..0000000 --- a/tests/stdin/test.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -pushd stdin -header1 "Test #3: Run a program that accepts stdin." - -## stdin - Single File, no args -header2 "stdin - Single File, no args" -out="$(echo hello world | $c 'stdin.c -Wall -Werror')" -assert "return" "$? -eq 77" -assert "output" "'$out' == 'hello world'" - -## stdin - Single File, with args -header2 "stdin - Single File, with args" -out="$(echo hello world | $c 'stdin.c -Wall -Werror' foobar)" -assert "return" "$? -eq 77" -assert "output" "'$out' == 'foobarhello world'" - -popd; echo diff --git a/tests/test.sh b/tests/test.sh deleted file mode 100755 index 3711835..0000000 --- a/tests/test.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# Ensure files are loaded relative to test.sh -cd "$(dirname "$BASH_SOURCE")" - -# Load helpers -source "./test_helpers.sh" - -[ -n "$CC" ] && "$CC" --version -[ -n "$CXX" ] && "$CXX" --version -[ -n "$FC" ] && "$FC" --version -$c --version - -# Run tests -source ./argument_and_link_test/test.sh -source ./complex_arguments/test.sh -source ./stdin/test.sh -source ./C++/test.sh -source ./shell/test.sh -source ./examples/test.sh -source ./header/test.sh - -quit diff --git a/tests/test_helpers.sh b/tests/test_helpers.sh deleted file mode 100644 index db9abc7..0000000 --- a/tests/test_helpers.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - -c="$PWD/../c" - -shopt -s expand_aliases -alias pushd='pushd &>/dev/null' -alias popd='popd &>/dev/null' - -# styles - nc="\033[0m" - bold="\033[1m" - italics="\033[3m" -underline="\033[4m" - -# colors - red="\033[31m" - green="\033[32m" - yellow="\033[33m" - cyan="\033[36m" - -# counters -PASSES=0 - FAILS=0 - -header1() { echo -e "${italics}${bold}${yellow}$@${nc}"; } -header2() { echo -e "${italics}${yellow}$@${nc}"; } - -assert() { - echo -en "${cyan}$1${nc} - " - - if `eval "[[ $2 ]]"`; then - echo -e "${green}pass: $2${nc}" 1>&2 - let PASSES++ - else - echo -e "${red}fail: $2${nc}" 1>&2 - let FAILS++ - fi -} - -# print status and quit -quit() { - END=$(date +%s.%N) - printf "${yellow}Duration: %0.1fs${nc}\n"\ - $(echo - | awk "{print $END - $START}") - - if [ $FAILS -gt 0 ]; then - fail_color=$red - pass_color=$cyan - else - fail_color=$cyan - pass_color=$green - fi - - echo - echo -en "${cyan}$(($PASSES + $FAILS)) tests, ${nc}" - echo -en "${pass_color}$PASSES passed, ${nc}" - echo -en "${fail_color}$FAILS failed${nc}" - echo - - exit $FAILS -} - -# clear out the cache -export C_CACHE_PATH="$(mktemp -d -t c.XXX)" -rm -rf "$C_CACHE_PATH" - -START=$(date +%s.%N)