Giter Club home page Giter Club logo

c's Introduction

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.)

GIF Demo

Here's a simple example:

#include <stdio.h>

int main(void) {
    printf("Hello World!\n");
    return 0;
}

Run it by typing:

$ c hello.c
Hello World!

Or, call it from the shebang!

#!/usr/bin/c
#include <stdio.h>

int main(void) {
    printf("Hello World!\n");
    return 0;
}
$ chmod +x hello.c
$ ./hello.c
Hello World!

Hooked? Here's how to install it:

Use a package manager? Check here.

For the entire system:

$ 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:

$ 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:

$ 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.).

$ 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:

$ 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.

$ chmod +x file.c
$ ./file.c

Single File - Shebang

Add this to the top of your C file:

#!/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.

#!/usr/bin/c file1.c file2.c -lncurses -lm --

Caching

The default cache size is set to 5 MB. You can change this with:

$ export C_CACHE_SIZE=$((10*1024)) # 10 MB

The default cache path is set to $TMPDIR/c.cache. You can change this with:

$ export C_CACHE_PATH="/tmp/the_cache"

Clear cache

You can clear the cache with the --clear-cache flag:

$ 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. 😬

Just hack away and make sure that all the tests pass.

$ 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:

$ 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/
bpkg: bpkg install ryanmjacobs/c
brew: brew install c (shebang will be #!/usr/local/bin/c for Intel-based Macs or #!/opt/homebrew/bin/c for Apple Silicon)

Todo

Maybe later we can implement caching. Done!

License

MIT 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.

c's People

Contributors

agentydragon avatar alejandrogallo avatar alistairking avatar cielavenir avatar haguenau avatar jwerle avatar nashidau avatar ryanmjacobs avatar sdlyyxy avatar souramoo avatar svaniksharma avatar szaydel avatar timgates42 avatar tp151209 avatar tyilo avatar uladox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

c's Issues

A better shebang

A better "shebang" would be

///bin/true; /usr/bin/c "$0" "$*"; exit $?

as it would keep file compileable with normal gcc invocation. See example of this here (also discussion on StackOverflow).

freebsd support

I got your script working on freebsd with multiple parameters using this as my first line

#!/usr/bin/env -S c "-I/usr/local/include/ -g -L/usr/local/lib/mysql/ -lmysqlclient --"

might be worth mentioning in the readme

Homebrew installation fails

~                                                                             ⍉
▶ brew install https://raw.githubusercontent.com/ryanmjacobs/c/master/c.rb
######################################################################## 100.0%
==> Downloading https://github.com/ryanmjacobs/c/archive/v0.12.tar.gz
==> Downloading from https://codeload.github.com/ryanmjacobs/c/tar.gz/v0.12

curl: (22) The requested URL returned error: 404 Not Found
Error: Failed to download resource "c"
Download failed: https://github.com/ryanmjacobs/c/archive/v0.12.tar.gz

Move license file out into separate file

Having the license in the same file as the readme makes this more difficult to package than it needs to be., as I would need to manually parse the readme file. If the license was in a separate file, I could just copy it into place.

Not all command line arguments seem to be processed

Hi, I noticed that depending upon what I pass to C sometimes result is not what I expect. Having looked at https://github.com/ryanmjacobs/c/blob/master/c#L54 I am a bit confused and thought it is worth raising this question. I see that here instead of trying to process all command line arguments, we there is a for arg in $1, which even if we do a shift later won't mean that this for look is going to run more than once. I assumed that maybe that should have been $@, but it would break some of this logic also.

Anyway, I think my question, since there are not comments there to help me understand, is whether or not this loop at line 54 was meant to be gone through more than once. If so, I think there may be problems with it.

Thanks!

多文件问题

root@niuyuling:/mnt/c/Users/niuyuling/Desktop/libini# ../c/c test.c -L./ -lini -static
/usr/bin/ld: /tmp/cc3AcSun.o: in function main': test.c:(.text.startup+0x21): undefined reference to getinikeystring'
/usr/bin/ld: test.c:(.text.startup+0x5f): undefined reference to getinikeystring' /usr/bin/ld: test.c:(.text.startup+0x9a): undefined reference to getinikeyint'
/usr/bin/ld: test.c:(.text.startup+0xdd): undefined reference to getinikeylong' /usr/bin/ld: test.c:(.text.startup+0x121): undefined reference to getinikeyfloat'
/usr/bin/ld: test.c:(.text.startup+0x170): undefined reference to putinikeystring' /usr/bin/ld: test.c:(.text.startup+0x18d): undefined reference to getinikeystring'
/usr/bin/ld: test.c:(.text.startup+0x1cd): undefined reference to `getinikeystring'
collect2: error: ld returned 1 exit status
root@niuyuling:/mnt/c/Users/niuyuling/Desktop/libini#

root@niuyuling:/mnt/c/Users/niuyuling/Desktop/libini# ../c/c 'test.c -L./ -lini -static'
/usr/bin/ld: 找不到 -lini
collect2: error: ld returned 1 exit status
root@niuyuling:/mnt/c/Users/niuyuling/Desktop/libini#

可不可以支持多文件或者链接库文件
Can I support multiple files or link library files?

License?

What is the license for this code? I'm interested in it, as I am the maintainer of awesome-c, and would prefer to have license terms to include.

du --block-size does not work on MacOS

Hi,

pretty useful tool. In order to make it work on MacOS I had to make this change:

-    size="$(du --block-size=1024 -s "$tmproot" | tail -n1 | cut -f1)"
+    size="$(du -k -s "$tmproot" | tail -n1 | cut -f1)"

The reason is that du on MacOS does not support --block-size. I can try to fix the script to detect MacOS and use du -k, but I noticed that this line has been edited in commit 91b66a0, so I don't know which is the best solution.

Thanks!

Giovanni

Support prefixed install in examples

What do you think about using

#!/usr/bin/env c

as shebang to support prefixed install. Then you can e.g. install in /usr/local and still run the examples:

PREFIX=/usr/local bpkg install ryanmjacobs/c

RPATH support?

It would be awesome if we could pass comma separated RPATH's in the shebang.

sed for shebang fails on OSX

The sed command that removes/replaces the shebang appears to fail on OSX yosemite:

$ c << EOF
#include <stdio.h>

int main()
{
  printf("Hello World!\n");
  return 0;
}
EOF
sed: 1: "/tmp/c.ox3.stdin.c": command c expects \ followed by text
Hello World!
sed: 1: "/tmp/c.ox3.stdin.c": command c expects \ followed by text

-D option isn't present on BSD `install`, causing bpkg install to fail on some systems

BSD install doesn't have the -D option, which causes installation to fail on systems that use this version of install.

My (probably incomplete) understanding is that this can be resolved by splitting this into a mkdir -p followed by install sans the -D option, but I don't know if there is a better way that works with the bpkg 'install' field.

For reference, the relevant install command: https://github.com/ryanmjacobs/c/blob/master/package.json#L6

Does not work in paths containing spaces

The script does not work on files with paths containing whitespaces.

[jimmy@toolbox my folder]$ pwd
/home/jimmy/my folder
[jimmy@toolbox my folder]$ ./foo.c 
cc: error: folder: No such file or directory
[jimmy@toolbox my folder]$ c foo.c
cc: error: folder: No such file or directory
[jimmy@toolbox my folder]$ c "/home/jimmy/my folder/foo.c"
cc: error: /home/jimmy/my: No such file or directory
cc: error: folder/foo.c: No such file or directory
cc: error: folder: No such file or directory
cc: fatal error: no input files
compilation terminated.

help in C language ..

hello man can you help me in C ?
i now how to extract ANCII chars and concaternate them..
what i need to know its how can i execute that ancii string after concaternation ..

example:
1º i what to extract the string whoami from ancii chart
2º concaternate the chars to build whoami command
3º and execute the string concaternated ..

this code does allmost everything..
it extracts the chars, concaternate them ...
but it only prints the string ..
but i dont what to print ..i want to execute ..

#include <stdio.h>
#include <string.h>

  int main(void)
    {
      /* variable declarations */
      char a = 119;  /* ancii character w */
      char b = 104;  /* ancii character h */
      char c = 111;  /* ancii character o */
      char d = 97;   /* ancii character a */
      char e = 109;  /* ancii character m */
      char f = 105;  /* ancii character i */
 
      /* concaternate and transform decimal values to ancii chars using putchar */
      //char command = putchar('a');putchar('b');putchar('c');putchar('d');putchar('e');putchar('f');

      /* execute command using system() */
      int system(char command);
        system(command);
    }

disabling caching

While caching is great in general, I found it to be hard if you are developing code in a header file. Is there a way to shut off the caching?

Brew

Hi, can we please get this on brew?

debugging

it would be great to have a --debug flag to launch gdb

Issue with MacOS Catalina

Thanks for this tool. I've been looking for something like this for a while.

I'm running into an issue where, if I run c ./main.c, and the contents is something like this:

#include <stdio.h>

int main(void)
{
    printf("%s\n", "Hello, World");
    return 0;
}

I get the following output:

Hello, World
du: illegal option -- -
usage: du [-H | -L | -P] [-a | -s | -d depth] [-c] [-h | -k | -m | -g] [-x] [-I mask] [file ...]

Seems like --block-size in size="$(du --block-size=1024 -s "$tmproot" | tail -n1 | cut -f1)" isn't valid on Catalina.

Any ideas? #38 mentions this error.

Reading shebang in comment

In my Emacs config, I have clang-format do most of my formatting.

Adding a shebang: #!/usr/bin/c -Wall -Wextra -Werror seems to mess with the formatter.

Perhaps it might be possible to put the shebang in a comment:

// #!/usr/bin/c -Wall -Wextra -Werror

and have c look for it with regex: ^\/\/[\s]?#!.*?

Smarter caching

Instead of always hashing to check if cache is invalidated, why not use stat or date to check if a script has been modified since last compilation? If the script has been modified, we can fallback to hashing, as usual

Programs with stdin redirection/piping

Currently we can't pipe stdin input into a C program, e.g.

#include <stdio.h>

int main(void) {
    char buf[1024];
    while (fgets(buf, 1024, stdin) != NULL) {
        puts(buf);
    }
}
$ c file.c arg1 arg2 < /dev/urandom
$ ./file.c arg1 arg2 < /dev/urandom

Because we use stdin for file input, I don't think we can also use it for program input as well. I'm not quite sure how to approach this... maybe we can only choose one or the other?

(btw, stdin input without piping works just fine)

$ c file.c arg1 arg2
hello
hello

world
world

^C

GNU/BSD sed compatibility

We need a command that doesn't require gnu-sed to be installed with brew.

This should work on both GNU and BSD systems:

$ cat > file.c
#!/usr/bin/c blah blah blah
^D
$ sed -i.bak '1!b;s/^#!/\/\/#!/' file.c
$ cat file.c
//#!/usr/bin/c blah blah blah

However, I don't have access to a BSD system...
It works just fine on GNU. Can someone confirm that it works on BSD systems, too? Thanks.

Feature request : Piping

It would be great to be able to pipe into c :

cat file.c | c
c < file.c

This would allow the use of tools that compile into c such as awib.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.