Giter Club home page Giter Club logo

handlebars.c's People

Contributors

jbboehr avatar martinec avatar rekgrpth avatar remicollet 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

handlebars.c's Issues

Benchmarks

Need to run benchmarks to get an idea of how fast it is currently vs other implementations and languages to get an idea of how much performance improvement might be necessary before starting optimizations.

Handlebars decorators and inline partial support

Inline partials in handlebars.js are implemented using decorators. We should ideally implement both, but implementing either would be great. We don't necessarily need to implement inline partials using decorators.

preventIndent might not be working

1) Handlebars\Tests\Spec\Compiler\HandlebarsPartialsTest::testIntegrationStandalonePartialsPreventNestedIndentedPartials1
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
 'Dudes:
   Yehuda
- http://yehuda!
+   http://yehuda!
   Alan
- http://alan!
+   http://alan!
 '

does not compile with configure --disable-refcounting

solve

diff --git a/src/handlebars_string.c b/src/handlebars_string.c
index 317125a..7e46d2b 100644
--- a/src/handlebars_string.c
+++ b/src/handlebars_string.c
@@ -170,20 +170,24 @@ void handlebars_string_delref(struct handlebars_string * string)
 
 void handlebars_string_addref_ex(struct handlebars_string * string, const char * expr, const char * loc)
 {
+#ifndef HANDLEBARS_NO_REFCOUNT
     if (getenv("HANDLEBARS_RC_DEBUG")) { // LCOV_EXCL_START
         size_t rc = handlebars_rc_refcount(&string->rc);
         fprintf(stderr, "STR ADDREF %p (%zu -> %zu) %s %s\n", string, rc, rc + 1, expr, loc);
     } // LCOV_EXCL_STOP
     handlebars_string_addref(string);
+#endif
 }
 
 void handlebars_string_delref_ex(struct handlebars_string * string, const char * expr, const char * loc)
 {
+#ifndef HANDLEBARS_NO_REFCOUNT
     if (getenv("HANDLEBARS_RC_DEBUG")) { // LCOV_EXCL_START
         size_t rc = handlebars_rc_refcount(&string->rc);
         fprintf(stderr, "STR DELREF %p (%zu -> %zu) %s %s\n", string, rc, rc - 1, expr, loc);
     } // LCOV_EXCL_STOP
     handlebars_string_delref(string);
+#endif
 }
 
 #ifdef HANDLEBARS_ENABLE_DEBUG
@@ -211,7 +215,9 @@ static inline struct handlebars_string * separate_string(struct handlebars_strin
 
 void handlebars_string_immortalize(struct handlebars_string * string)
 {
+#ifndef HANDLEBARS_NO_REFCOUNT
     string->rc.refcount = UINT8_MAX;
+#endif
 }
 // }}} Reference Counting
 
@@ -750,9 +756,11 @@ struct handlebars_string * handlebars_string_indent(
     const struct handlebars_string * indent_str
 ) {
     struct handlebars_string * new_string = handlebars_string_init(context, string->len);
+#ifndef HANDLEBARS_NO_REFCOUNT
     if (handlebars_rc_refcount(&string->rc) > 0) {
         handlebars_string_addref(new_string);
     }
+#endif
     return handlebars_string_indent_append(context, new_string, string, indent_str);
 }
 
diff --git a/src/handlebars_map.c b/src/handlebars_map.c
index d20ae06..50f0c8c 100644
--- a/src/handlebars_map.c
+++ b/src/handlebars_map.c
@@ -291,20 +291,24 @@ void handlebars_map_delref(struct handlebars_map * map)
 
 void handlebars_map_addref_ex(struct handlebars_map * map, const char * expr, const char * loc)
 {
+#ifndef HANDLEBARS_NO_REFCOUNT
     if (getenv("HANDLEBARS_RC_DEBUG")) { // LCOV_EXCL_START
         size_t rc = handlebars_rc_refcount(&map->rc);
         fprintf(stderr, "MAP ADDREF %p (%zu -> %zu) %s %s\n", map, rc, rc + 1, expr, loc);
     } // LCOV_EXCL_STOP
     handlebars_map_addref(map);
+#endif
 }
 
 void handlebars_map_delref_ex(struct handlebars_map * map, const char * expr, const char * loc)
 {
+#ifndef HANDLEBARS_NO_REFCOUNT
     if (getenv("HANDLEBARS_RC_DEBUG")) { // LCOV_EXCL_START
         size_t rc = handlebars_rc_refcount(&map->rc);
         fprintf(stderr, "MAP DELREF %p (%zu -> %zu) %s %s\n", map, rc, rc - 1, expr, loc);
     } // LCOV_EXCL_STOP
     handlebars_map_delref(map);
+#endif
 }
 
 #ifdef HANDLEBARS_ENABLE_DEBUG
@@ -523,9 +527,11 @@ struct handlebars_map * handlebars_map_rehash(struct handlebars_map * map, bool
         size_t vec_capacity = 1 << map_choose_vec_capacity_log2(map->i + 1);
         struct handlebars_map * prev_map = map;
         map = handlebars_map_copy_ctor(prev_map, vec_capacity);
+#ifndef HANDLEBARS_NO_REFCOUNT
         if (handlebars_rc_refcount(&prev_map->rc) >= 1) { // ugh
             handlebars_map_addref(map);
         }
+#endif
         handlebars_map_delref(prev_map);
     }
 
diff --git a/src/handlebars_value_handlers.c b/src/handlebars_value_handlers.c
index ee89a1e..8636f37 100644
--- a/src/handlebars_value_handlers.c
+++ b/src/handlebars_value_handlers.c
@@ -63,20 +63,24 @@ void handlebars_user_delref(struct handlebars_user * user)
 
 void handlebars_user_addref_ex(struct handlebars_user * user, const char * expr, const char * loc)
 {
+#ifndef HANDLEBARS_NO_REFCOUNT
     if (getenv("HANDLEBARS_RC_DEBUG")) { // LCOV_EXCL_START
         size_t rc = handlebars_rc_refcount(&user->rc);
         fprintf(stderr, "USR ADDREF %p (%zu -> %zu) %s %s\n", user, rc, rc + 1, expr, loc);
     } // LCOV_EXCL_STOP
     handlebars_user_addref(user);
+#endif
 }
 
 void handlebars_user_delref_ex(struct handlebars_user * user, const char * expr, const char * loc)
 {
+#ifndef HANDLEBARS_NO_REFCOUNT
     if (getenv("HANDLEBARS_RC_DEBUG")) { // LCOV_EXCL_START
         size_t rc = handlebars_rc_refcount(&user->rc);
         fprintf(stderr, "USR DELREF %p (%zu -> %zu) %s %s\n", user, rc, rc - 1, expr, loc);
     } // LCOV_EXCL_STOP
     handlebars_user_delref(user);
+#endif
 }
 
 #ifdef HANDLEBARS_ENABLE_DEBUG

diff --git a/src/handlebars_closure.c b/src/handlebars_closure.c
index 4b9daa4..ab8b0a8 100644
--- a/src/handlebars_closure.c
+++ b/src/handlebars_closure.c
@@ -86,7 +86,9 @@ struct handlebars_closure * handlebars_closure_ctor(
 ) {
     struct handlebars_closure * closure = handlebars_talloc_zero_size(vm, sizeof(struct handlebars_closure) + (sizeof(struct handlebars_value) * localc));
     talloc_set_type(closure, struct handlebars_closure);
+#ifndef HANDLEBARS_NO_REFCOUNT
     handlebars_rc_init(&closure->rc);
+#endif
     closure->vm = vm;
     closure->fn = fn;
     closure->localc = localc;

diff --git a/src/handlebars_ptr.c b/src/handlebars_ptr.c
index c37ce8e..f3ce723 100644
--- a/src/handlebars_ptr.c
+++ b/src/handlebars_ptr.c
@@ -36,7 +36,9 @@
 
 
 struct handlebars_ptr {
+#ifndef HANDLEBARS_NO_REFCOUNT
     struct handlebars_rc rc;
+#endif
     const char * typ;
     void * uptr;
     bool nofree;
@@ -75,7 +77,9 @@ struct handlebars_ptr * handlebars_ptr_ctor_ex(
 ) {
     struct handlebars_ptr * ptr = handlebars_talloc(ctx, struct handlebars_ptr);
     HANDLEBARS_MEMCHECK(ptr, ctx);
+#ifndef HANDLEBARS_NO_REFCOUNT
     handlebars_rc_init(&ptr->rc);
+#endif
     ptr->typ = typ;
     ptr->nofree = nofree;
     ptr->uptr = uptr;

[0.7.0] segfaults in tes suite

Version seems unusable


...
not ok 1 - test_spec_handlebars.c:AST to string on handlebars spec:test_ast_to_string_on_handlebars_spec: Received signal 11 (Segmentation fault)
FAIL: test_spec_handlebars 1 - test_spec_handlebars.c:AST to string on handlebars spec:test_ast_to_string_on_handlebars_spec: Received signal 11 (Segmentation fault)
...


Testsuite summary for handlebars-c 0.7.0
============================================================================
# TOTAL: 1855
# PASS:  1487
# SKIP:  0
# XFAIL: 0
# FAIL:  367
# XPASS: 0
# ERROR: 1
============================================================================

Use of uninitialised value

==16412== Use of uninitialised value of size 8
==16412==    at 0x7726C67: handlebars_rtrim_ex (handlebars_utils.c:127)
==16412==    by 0x771E5E6: handlebars_ast_helper_omit_left (handlebars_ast_helpers.c:237)
==16412==    by 0x771F417: handlebars_ast_helper_prepare_program (handlebars_ast_helpers.c:545)
==16412==    by 0x77132D4: handlebars_yy_parse (handlebars.y:130)
==16412==    by 0x750AF69: zif_handlebars_compile (handlebars.c:636)
==16412==    by 0x6DDA0A: dtrace_execute_internal (zend_dtrace.c:97)
==16412==    by 0x79DA64: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:552)
==16412==    by 0x717797: execute_ex (zend_vm_execute.h:363)
==16412==    by 0x6DD908: dtrace_execute_ex (zend_dtrace.c:73)
==16412==    by 0x6EF38F: zend_execute_scripts (zend.c:1316)
==16412==    by 0x68F274: php_execute_script (main.c:2506)
==16412==    by 0x79FA3D: do_cli (php_cli.c:994)

windows support

I see windows support listed in the recent commits, but no install/compile instructions anywhere. Can you update any doc w/ that?

String operations should support UTF-8

The very latest re2c has a UTF-8 mode, so perhaps it can be used to generate replacements for any string functions that don't support UTF-8. Otherwise, implement support manually. Currently ltrim/rtrim are the main functions that don't have support. The lexer and lexer rules may also need to be checked.

handlebars_value_init_json_string_length

how about string with length like

void handlebars_value_init_json_string_length(struct handlebars_context *ctx, struct handlebars_value * value, const char * json, size_t length) {
    enum json_tokener_error error;
    struct json_object *root;
    struct json_tokener *tok;
    if (!(tok = json_tokener_new())) handlebars_throw(ctx, HANDLEBARS_ERROR, "!json_tokener_new");
    do root = json_tokener_parse_ex(tok, json, length); while ((error = json_tokener_get_error(tok)) == json_tokener_continue);
    if (error != json_tokener_success) handlebars_throw(ctx, HANDLEBARS_ERROR, "!json_tokener_parse_ex and %s", json_tokener_error_desc(error));
    if (json_tokener_get_parse_end(tok) < length) handlebars_throw(ctx, HANDLEBARS_ERROR, "json_tokener_get_parse_end < %li", length);
    json_tokener_free(tok);
    handlebars_value_init_json_object(ctx, value, root);
    json_object_put(root);
}

Question: Documentation / this

I saw there is a doc folder with some doxygen stuff in it. Is the available documentation available online to read in a browser? That would be great. If there is, could the link to the documentation be added in the readme?

I wanted to read about the this variable, in javascript this variable is a reference to the original data you passed in (see example below), how does the C implementation handle this?

<!doctype html>
<html lang="en">
<head>
  <title>handlebars test</title>
</head>
<body>
  <script src="handlebars-v4.0.5.js"></script>
  <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script id="entry-template" type="text/x-handlebars-template">
{{#myCustomBlock}} some data to analyze{{/myCustomBlock}}
{{#otherPart}}use analyzed data{{/otherPart}}
</script>
<script>
Handlebars.registerHelper('myCustomBlock', function(options) {
  this.extradata = options.fn();
  return options.fn(this);
});
Handlebars.registerHelper('otherPart', function(options) {
  console.log(this);
  // Output of this console.log is:
  // Object {startData: "initial data loaded", extradata: " some data to analyze"}
  // this means that i can transfer data from one block to another block even if loose scope
  // because this is a reference to the original data i passed in and not a copy !!
  return options.fn(this);
});
var source   = $("#entry-template").html();
var template = Handlebars.compile(source);
var context = {startData: "initial data loaded"};
var html    = template(context);
</script>
</body>
</html>

Opcode improvements

Add a serializer for the opcodes. so deep arrays don't have to be transferred to the PHP VM

Emulated length property

Ideally it would be possible to get the length of a string or array:

{{string.length}} {{array.length}}

Mustache-style lambdas

Ideally we can support the full mustache spec with extra flags - key missing features are:

  • delimiters (added in #66!)
  • lambdas (mustache-style)

AlpineLinux apk Package

Hi!

Lots of Docker images are based on Alpine Linux, because is extremely lightweight.

Many of those images come with spaghetti code to turn docker variables into configuration files.

That is why I searched for Handlebars in C, and I found this project.

I think it would be great to make an apk package. is there support planned?

I offer help.

I will also check to integrate ansible->docker->handlebars.c->happy microservice.

I think this project could work very well for that use case.

test_cache.c:LMDB Cache (Reset):test_lmdb_cache_reset failed (Alpine Linux)

test_cache fails after rebuilding handlebars.c with json-c-0.13.1. I don't know if json-c upgrade is related or if the test failure is triggered by something else.

This is Alpine Linux x86_64

Running suite(s): Handlebars Spec
85%: Checks: 7, Failures: 1, Errors: 0
test_cache.c:189:F:LMDB Cache (Reset):test_lmdb_cache_reset:0: Assertion 'vm->buffer->val == "baz"' failed: vm->buffer->val == "", "baz" == "baz"

Segmentation fault using lookup with non-string key parameter

<?php
$vm = new \Handlebars\VM();
var_dump($vm->render('{{lookup a null}}', array(
    'a' => array('c' => null),
)));
==1519== Invalid read of size 8
==1519==    at 0x132F0DEC: ??? (in /usr/lib/php/20151012/handlebars.so)
==1519==    by 0x13512FE4: handlebars_builtin_lookup (in /usr/lib/x86_64-linux-gnu/libhandlebars.so.5.0.0)
==1519==    by 0x1351DF67: ??? (in /usr/lib/x86_64-linux-gnu/libhandlebars.so.5.0.0)
==1519==    by 0x1351E54C: handlebars_vm_execute_program_ex (in /usr/lib/x86_64-linux-gnu/libhandlebars.so.5.0.0)
==1519==    by 0x1351BCCA: handlebars_vm_execute (in /usr/lib/x86_64-linux-gnu/libhandlebars.so.5.0.0)
==1519==    by 0x132F0325: zim_HandlebarsVM_renderFile (in /usr/lib/php/20151012/handlebars.so)
==1519==    by 0x3E34B5: ??? (in /usr/sbin/php-fpm7.0)
==1519==    by 0x39E11A: execute_ex (in /usr/sbin/php-fpm7.0)
==1519==    by 0x34EEA2: zend_call_function (in /usr/sbin/php-fpm7.0)
==1519==    by 0x34F278: call_user_function_ex (in /usr/sbin/php-fpm7.0)
==1519==    by 0x387538: zim_Closure___invoke (in /usr/sbin/php-fpm7.0)
==1519==    by 0x34EDFE: zend_call_function (in /usr/sbin/php-fpm7.0)
==1519==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==1519== 
==1519== 
==1519== Process terminating with default action of signal 11 (SIGSEGV)
==1519==  Access not within mapped region at address 0x0
==1519==    at 0x132F0DEC: ??? (in /usr/lib/php/20151012/handlebars.so)
==1519==    by 0x13512FE4: handlebars_builtin_lookup (in /usr/lib/x86_64-linux-gnu/libhandlebars.so.5.0.0)
==1519==    by 0x1351DF67: ??? (in /usr/lib/x86_64-linux-gnu/libhandlebars.so.5.0.0)
==1519==    by 0x1351E54C: handlebars_vm_execute_program_ex (in /usr/lib/x86_64-linux-gnu/libhandlebars.so.5.0.0)
==1519==    by 0x1351BCCA: handlebars_vm_execute (in /usr/lib/x86_64-linux-gnu/libhandlebars.so.5.0.0)
==1519==    by 0x132F0325: zim_HandlebarsVM_renderFile (in /usr/lib/php/20151012/handlebars.so)
==1519==    by 0x3E34B5: ??? (in /usr/sbin/php-fpm7.0)
==1519==    by 0x39E11A: execute_ex (in /usr/sbin/php-fpm7.0)
==1519==    by 0x34EEA2: zend_call_function (in /usr/sbin/php-fpm7.0)
==1519==    by 0x34F278: call_user_function_ex (in /usr/sbin/php-fpm7.0)
==1519==    by 0x387538: zim_Closure___invoke (in /usr/sbin/php-fpm7.0)
==1519==    by 0x34EDFE: zend_call_function (in /usr/sbin/php-fpm7.0)
==1519==  If you believe this happened as a result of a stack
==1519==  overflow in your program's main thread (unlikely but
==1519==  possible), you can try to increase the size of the
==1519==  main thread stack using the --main-stacksize= flag.
==1519==  The main thread stack size used in this run was 8388608.
==1519== 
==1519== HEAP SUMMARY:
==1519==     in use at exit: 4,790,761 bytes in 34,333 blocks
==1519==   total heap usage: 50,787 allocs, 16,454 frees, 13,688,943 bytes allocated
==1519== 
==1519== LEAK SUMMARY:
==1519==    definitely lost: 2,336 bytes in 17 blocks
==1519==    indirectly lost: 4,657 bytes in 35 blocks
==1519==      possibly lost: 3,651,485 bytes in 26,932 blocks
==1519==    still reachable: 1,132,283 bytes in 7,349 blocks
==1519==         suppressed: 0 bytes in 0 blocks
==1519== Rerun with --leak-check=full to see details of leaked memory
==1519== 
==1519== For counts of detected and suppressed errors, rerun with: -v
==1519== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==1519== could not unlink /tmp/vgdb-pipe-from-vgdb-to-1519-by-???-on-???
==1519== could not unlink /tmp/vgdb-pipe-to-vgdb-from-1519-by-???-on-???
==1519== could not unlink /tmp/vgdb-pipe-shared-mem-vgdb-1519-by-???-on-???

Input buffer overflow

For a template with a large single block of content, the following error is generated:

input buffer overflow, can't enlarge buffer because scanner uses REJECT

Solution should be to break up large content blocks, at least at the lexical stage. Workaround is to insert handlebars comments occasionally.

Create shared library

Hi, I really want to use at my python code, and for that I need to compile shared library, I tried to make it from bin/handlebarsc.c but probably its not correct, cause at result SO file I have a lot of undefined reference, can you please help me if its possible at all?

Mustache lex bug

The following template from the mustache spec is not lexing correctly:
'Hello from {Mustache}!'

Produces:

CONTENT [Hello from ] 
CONTENT [Mustache}!]

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.