~ubuntu-branches/ubuntu/raring/luatex/raring

« back to all changes in this revision

Viewing changes to source/texk/web2c/luatexdir/lua/lnodelib.c

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2011-05-20 09:40:39 UTC
  • mfrom: (0.8.1) (1.8.1) (19.2.3 oneiric)
  • Revision ID: package-import@ubuntu.com-20110520094039-7sezr4kqonjqxqz6
Tags: 0.70.1-1
* new upstream release (probably) matching TeX Live 2011
* deactivate fix-luatex-build-with-old-libpng patch, included upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
   with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
19
19
 
20
20
static const char _svn_version[] =
21
 
    "$Id: lnodelib.c 3726 2010-06-24 12:13:43Z taco $ "
22
 
    "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.2/source/texk/web2c/luatexdir/lua/lnodelib.c $";
 
21
    "$Id: lnodelib.c 4166 2011-04-16 09:12:20Z taco $ "
 
22
    "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.70.1/source/texk/web2c/luatexdir/lua/lnodelib.c $";
23
23
 
24
24
#include "lua/luatex-api.h"
25
25
#include "ptexlib.h"
39
39
#define luaS_ptr_eq(a,b) (a==luaS_##b##_ptr)
40
40
 
41
41
#define NODE_METATABLE  "luatex_node"
 
42
 
 
43
#define DEBUG 0
 
44
#define DEBUG_OUT stdout
42
45
 
43
46
make_luaS_index(luatex_node);
44
47
 
45
 
halfword *check_isnode(lua_State * L, int ud)
 
48
static halfword *maybe_isnode(lua_State * L, int ud)
46
49
{
47
 
    register halfword *p = lua_touserdata(L, ud);
 
50
    halfword *p = lua_touserdata(L, ud);
48
51
    if (p != NULL) {
49
52
        if (lua_getmetatable(L, ud)) {
50
53
            lua_rawgeti(L, LUA_REGISTRYINDEX, luaS_index(luatex_node));
51
54
            lua_gettable(L, LUA_REGISTRYINDEX);
52
 
            if (lua_rawequal(L, -1, -2)) {
53
 
                lua_pop(L, 2);
54
 
                return p;
 
55
            if (!lua_rawequal(L, -1, -2)) {
 
56
                p = NULL;
55
57
            }
 
58
            lua_pop(L, 2);
56
59
        }
57
60
    }
58
 
    luaL_typerror(L, ud, NODE_METATABLE);
 
61
    return p;
 
62
}
 
63
 
 
64
halfword *check_isnode(lua_State * L, int ud)
 
65
{
 
66
    halfword *p = maybe_isnode(L, ud);
 
67
    if (p != NULL) {
 
68
        return p;
 
69
    }
 
70
    pdftex_fail("There should have been a lua <node> here, not an object with type %s!", luaL_typename(L, ud));
59
71
    return NULL;
60
72
}
61
73
 
115
127
    return i;
116
128
}
117
129
 
 
130
/* returns true is the argument is a userdata object of type node */
 
131
 
 
132
static int lua_nodelib_isnode(lua_State * L)
 
133
{
 
134
    if (maybe_isnode(L,1) != NULL)
 
135
        lua_pushboolean(L,1);
 
136
    else
 
137
        lua_pushboolean(L,0);
 
138
    return 1;
 
139
}
 
140
 
 
141
/* two simple helpers to speed up and simplify lua code: */
 
142
 
 
143
static int lua_nodelib_next(lua_State * L)
 
144
{
 
145
    halfword *p = maybe_isnode(L,1);
 
146
    if (p != NULL && *p && vlink(*p)) {
 
147
        lua_nodelib_push_fast(L,vlink(*p));
 
148
    } else {
 
149
        lua_pushnil(L);
 
150
    }
 
151
    return 1;
 
152
}
 
153
 
 
154
static int lua_nodelib_prev(lua_State * L)
 
155
{
 
156
    halfword *p = maybe_isnode(L,1);
 
157
    if (p != NULL && *p && alink(*p)) {
 
158
        lua_nodelib_push_fast(L,alink(*p));
 
159
    } else {
 
160
        lua_pushnil(L);
 
161
    }
 
162
    return 1;
 
163
}
118
164
 
119
165
 
120
166
/* Creates a userdata object for a number found at the stack top, 
209
255
 
210
256
static int lua_nodelib_type(lua_State * L)
211
257
{
212
 
    int i = get_node_type_id(L, 1);
213
 
    if (i >= 0) {
214
 
        lua_pushstring(L, node_data[i].name);
215
 
    } else {
216
 
        lua_pushnil(L);
 
258
    if (lua_type(L,1) == LUA_TNUMBER) {
 
259
        int i = get_node_type_id(L, 1);
 
260
        if (i >= 0) {
 
261
            lua_pushstring(L, node_data[i].name);
 
262
            return 1;
 
263
        }
 
264
    } else if (maybe_isnode(L, 1) != NULL) {
 
265
        lua_pushstring(L,"node");
 
266
        return 1;
217
267
    }
 
268
    lua_pushnil(L);
218
269
    return 1;
219
270
}
220
271
 
293
344
 
294
345
/* remove a node from a list */
295
346
 
296
 
 
 
347
#if DEBUG
 
348
static void show_node_links (halfword l, const char * p) 
 
349
{
 
350
    halfword t = l;
 
351
    while (t) {
 
352
        fprintf(DEBUG_OUT, "%s t = %d, prev = %d, next = %d\n", p, (int)t, (int)alink(t), (int)vlink(t));
 
353
        t = vlink(t);
 
354
    }    
 
355
}
 
356
#endif
 
357
 
297
358
static int lua_nodelib_remove(lua_State * L)
298
359
{
299
360
    halfword head, current, t;
301
362
        luaL_error(L, "Not enough arguments for node.remove()");
302
363
    }
303
364
    head = *(check_isnode(L, 1));
 
365
#if DEBUG
 
366
    show_node_links(head, "before");
 
367
#endif
304
368
    if (lua_isnil(L, 2)) {
305
369
        return 2;               /* the arguments, as they are */
306
370
    }
328
392
        }
329
393
        current = vlink(current);
330
394
    }
 
395
#if DEBUG
 
396
    show_node_links(head, "after");
 
397
#endif
331
398
    lua_pushnumber(L, head);
332
399
    lua_nodelib_push(L);
333
400
    lua_pushnumber(L, current);
573
640
        return 3;
574
641
    } else {
575
642
        luaL_error(L,
576
 
                       "missing  argument to 'dimensions' (luatex_node expected)");
 
643
                       "missing  argument to 'dimensions' (node expected)");
577
644
    }
578
645
    return 0;                   /* not reached */
579
646
}
683
750
make_luaS_index(height);
684
751
make_luaS_index(depth);
685
752
make_luaS_index(expansion_factor);
 
753
make_luaS_index(list);
 
754
make_luaS_index(head);
686
755
 
687
756
 
688
757
static void initialize_luaS_indexes(lua_State * L)
705
774
    init_luaS_index(height);
706
775
    init_luaS_index(depth);
707
776
    init_luaS_index(expansion_factor);
 
777
    init_luaS_index(list);
 
778
    init_luaS_index(head);
708
779
}
709
780
 
710
781
static int get_node_field_id(lua_State * L, int n, int node)
711
782
{
712
783
    register int t = type(node);
713
784
    register const char *s = lua_tostring(L, n);
 
785
    if (s == NULL)
 
786
        return -2;
 
787
    if (luaS_ptr_eq(s, list)) {
 
788
        s = luaS_head_ptr; /* create a |head| alias for now */
 
789
    }
714
790
    if (luaS_ptr_eq(s, next)) {
715
791
        return 0;
716
792
    } else if (luaS_ptr_eq(s, id)) {
749
825
        } else if (luaS_ptr_eq(s, expansion_factor)) {
750
826
            return 16;
751
827
        }
752
 
    } else if (luaS_ptr_eq(s, prev)) {
 
828
    } else if (luaS_ptr_eq(s, prev)  && nodetype_has_prev(t)) {
753
829
        return -1;
754
 
    } else if (luaS_ptr_eq(s, subtype)) {
 
830
    } else if (luaS_ptr_eq(s, subtype) && nodetype_has_subtype(t)) {
755
831
        return 2;
756
832
    } else {
757
833
        int j;
758
834
        const char **fields = node_data[t].fields;
759
835
        if (t == whatsit_node)
760
836
            fields = whatsit_node_data[subtype(node)].fields;
761
 
        for (j = 0; fields[j] != NULL; j++) {
762
 
            if (strcmp(s, fields[j]) == 0) {
763
 
                return j + 3;
764
 
            }
 
837
        if (fields != NULL) {
 
838
            for (j = 0; fields[j] != NULL; j++) {
 
839
                if (strcmp(s, fields[j]) == 0) {
 
840
                    return j + 3;
 
841
                }
 
842
            }
765
843
        }
766
844
    }
767
845
    return -2;
819
897
static int lua_nodelib_fields(lua_State * L)
820
898
{
821
899
    int i = -1;
 
900
    int offset = 2;
822
901
    const char **fields;
823
902
    int t = get_valid_node_type_id(L, 1);
824
903
    if (t == whatsit_node) {
833
912
    lua_rawseti(L, -2, 0);
834
913
    lua_pushstring(L, "id");
835
914
    lua_rawseti(L, -2, 1);
836
 
    lua_pushstring(L, "subtype");
837
 
    lua_rawseti(L, -2, 2);
 
915
    if (nodetype_has_subtype(t)) {
 
916
      lua_pushstring(L, "subtype");
 
917
      lua_rawseti(L, -2, 2);
 
918
      offset++;
 
919
    }
838
920
    if (fields != NULL) {
839
 
        lua_pushstring(L, "prev");
840
 
        lua_rawseti(L, -2, -1);
 
921
        if (nodetype_has_prev(t)) {
 
922
          lua_pushstring(L, "prev");
 
923
          lua_rawseti(L, -2, -1);
 
924
        }
841
925
        for (i = 0; fields[i] != NULL; i++) {
842
926
            lua_pushstring(L, fields[i]);
843
 
            lua_rawseti(L, -2, (i + 3));
 
927
            lua_rawseti(L, -2, (i + offset));
844
928
        }
845
929
    }
846
930
    return 1;
858
942
    t = *n;
859
943
    if (t == null)
860
944
        return 1;               /* the old userdata */
861
 
    alink(t) = null;
 
945
    /* alink(t) = null; */ /* don't do this, |t|'s |alink| may be a valid pointer */
862
946
    while (vlink(t) != null) {
863
947
        alink(vlink(t)) = t;
864
948
        t = vlink(t);
1374
1458
            break;
1375
1459
        case late_lua_node:
1376
1460
            switch (field) {
1377
 
            case 4:
 
1461
            case 4: /* regid (obsolete?)*/
1378
1462
                lua_pushnumber(L, late_lua_reg(n));
1379
1463
                break;
1380
 
            case 5:
1381
 
                tokenlist_to_luastring(L, late_lua_data(n));
1382
 
                break;
1383
 
            case 6:
 
1464
            case 6: /* name */
1384
1465
                tokenlist_to_luastring(L, late_lua_name(n));
1385
1466
                break;
 
1467
            case 5: /* data */
 
1468
            case 7: /* string */
 
1469
                if (late_lua_type(n) == lua_refid_literal) {
 
1470
                    lua_rawgeti(Luas, LUA_REGISTRYINDEX, late_lua_data(n));
 
1471
                } else {
 
1472
                    tokenlist_to_luastring(L, late_lua_data(n));
 
1473
                }
 
1474
                break;
1386
1475
            default:
1387
1476
                lua_pushnil(L);
1388
1477
            }
1520
1609
            lua_pushnumber(L, (double) glue_set(n));
1521
1610
            break;
1522
1611
        case 12:
 
1612
            if (list_ptr(n)) {
 
1613
                alink(list_ptr(n)) = null;
 
1614
            }
1523
1615
            nodelib_pushlist(L, list_ptr(n));
1524
1616
            break;
1525
1617
        default:
1559
1651
            lua_pushnumber(L, span_count(n));
1560
1652
            break;
1561
1653
        case 13:
 
1654
            if (list_ptr(n)) {
 
1655
                alink(list_ptr(n)) = null;
 
1656
            }
1562
1657
            nodelib_pushlist(L, list_ptr(n));
1563
1658
            break;
1564
1659
        default:
1604
1699
            nodelib_pushspec(L, split_top_ptr(n));
1605
1700
            break;
1606
1701
        case 8:
 
1702
            if (ins_ptr(n)) {
 
1703
                alink(ins_ptr(n)) = null;
 
1704
            }
1607
1705
            nodelib_pushlist(L, ins_ptr(n));
1608
1706
            break;
1609
1707
        default:
1631
1729
            lua_pushnumber(L, subtype(n));
1632
1730
            break;
1633
1731
        case 4:
 
1732
            if (adjust_ptr(n)) {
 
1733
                alink(adjust_ptr(n)) = null;
 
1734
            }
1634
1735
            nodelib_pushlist(L, adjust_ptr(n));
1635
1736
            break;
1636
1737
        default:
1944
2045
            lua_pushnumber(L, subtype(n));
1945
2046
            break;
1946
2047
        case 4:
 
2048
            if (math_list(n)) {
 
2049
                alink(math_list(n)) = null;
 
2050
            }
1947
2051
            nodelib_pushlist(L, math_list(n));
1948
2052
            break;
1949
2053
        default:
2458
2562
        case 4:
2459
2563
            late_lua_reg(n) = (halfword) lua_tointeger(L, 3);
2460
2564
            break;
2461
 
        case 5:
 
2565
        case 5: /* data */
2462
2566
            late_lua_data(n) = nodelib_gettoks(L, 3);
 
2567
            late_lua_type(n) = normal;
2463
2568
            break;
2464
2569
        case 6:
2465
2570
            late_lua_name(n) = nodelib_gettoks(L, 3);
2466
2571
            break;
 
2572
        case 7: /* string */
 
2573
            if (ini_version) {
 
2574
                late_lua_data(n) = nodelib_gettoks(L, 3);
 
2575
                late_lua_type(n) = normal;
 
2576
            } else {
 
2577
                lua_pushvalue(L, 3);
 
2578
                late_lua_data(n) = luaL_ref(L, LUA_REGISTRYINDEX);
 
2579
                late_lua_type(n) = lua_refid_literal;
 
2580
            }
 
2581
            break;
2467
2582
        default:
2468
2583
            return nodelib_cantset(L, field, n);
2469
2584
        }
2561
2676
        /* return implied */
2562
2677
    }
2563
2678
    if (field == 0) {
2564
 
        vlink(n) = nodelib_getlist(L, 3);
 
2679
        halfword x = nodelib_getlist(L, 3);
 
2680
        if (x>0 && type(x) == glue_spec_node) {
 
2681
            return luaL_error(L, "You can't assign a %s node to a next field\n", node_data[type(x)].name);
 
2682
        }
 
2683
        vlink(n) = x;
2565
2684
    } else if (field == -1) {
2566
 
        alink(n) = nodelib_getlist(L, 3);
 
2685
        halfword x = nodelib_getlist(L, 3);
 
2686
        if (x>0 && type(x) == glue_spec_node) {
 
2687
            return luaL_error(L, "You can't assign a %s node to a prev field\n", node_data[type(x)].name);
 
2688
        }
 
2689
        alink(n) = x;
2567
2690
    } else if (field == 3 && nodetype_has_attributes(type(n))) {
2568
2691
        nodelib_setattr(L, 3, n);
2569
2692
    } else if (type(n) == glyph_node) {
3278
3401
    return 2;
3279
3402
}
3280
3403
 
3281
 
 
3282
 
static int lua_nodelib_first_character(lua_State * L)
 
3404
static int lua_nodelib_first_glyph(lua_State * L)
3283
3405
{
3284
3406
    /* on the stack are two nodes and a direction */
3285
3407
    halfword h, savetail = null, t = null;
3294
3416
        savetail = vlink(t);
3295
3417
        vlink(t) = null;
3296
3418
    }
3297
 
    while (h != null && !is_simple_character(h)) {
 
3419
    while (h != null && (type(h) != glyph_node || !is_simple_character(h))) {
3298
3420
        h = vlink(h);
3299
3421
    }
3300
3422
    if (savetail != null) {
3306
3428
    return 2;
3307
3429
}
3308
3430
 
 
3431
static int lua_nodelib_first_character(lua_State * L)
 
3432
{
 
3433
    pdftex_warn("node.first_character() is deprecated, please update to node.first_glyph()");
 
3434
    return lua_nodelib_first_glyph(L);
 
3435
}
 
3436
 
 
3437
 
3309
3438
 
3310
3439
/* this is too simplistic, but it helps Hans to get going */
3311
3440
 
3356
3485
    return 1;
3357
3486
}
3358
3487
 
 
3488
static int lua_nodelib_currentattr(lua_State * L)
 
3489
{
 
3490
    int n = lua_gettop(L);
 
3491
    if (n == 0) {
 
3492
        /* query */
 
3493
        if (max_used_attr >= 0) {
 
3494
            if (attr_list_cache == cache_disabled) {
 
3495
                update_attribute_cache();
 
3496
                if (attr_list_cache == null) {
 
3497
                    lua_pushnil (L);
 
3498
                    return 1;
 
3499
                }
 
3500
            }
 
3501
            attr_list_ref(attr_list_cache)++;
 
3502
            lua_pushnumber(L, attr_list_cache);
 
3503
            lua_nodelib_push(L);
 
3504
        } else {
 
3505
            lua_pushnil (L);
 
3506
        }
 
3507
        return 1;
 
3508
    } else {
 
3509
        /* assign */
 
3510
        pdftex_warn("Assignment via node.current_attr(<list>) is not supported (yet)");
 
3511
        return 0;
 
3512
    }
 
3513
}
 
3514
 
 
3515
 
3359
3516
static const struct luaL_reg nodelib_f[] = {
3360
 
    {"id", lua_nodelib_id},
3361
 
    {"subtype", lua_nodelib_subtype},
3362
 
    {"type", lua_nodelib_type},
3363
 
    {"new", lua_nodelib_new},
3364
 
    {"length", lua_nodelib_length},
 
3517
    {"copy", lua_nodelib_copy},
 
3518
    {"copy_list", lua_nodelib_copy_list},
3365
3519
    {"count", lua_nodelib_count},
3366
 
    {"traverse", lua_nodelib_traverse},
3367
 
    {"traverse_id", lua_nodelib_traverse_filtered},
3368
 
    {"tail", lua_nodelib_tail_only},
3369
 
    {"slide", lua_nodelib_tail},
3370
 
    {"types", lua_nodelib_types},
3371
 
    {"whatsits", lua_nodelib_whatsits},
 
3520
    {"current_attr", lua_nodelib_currentattr},
 
3521
    {"dimensions", lua_nodelib_dimensions},
 
3522
    {"do_ligature_n", lua_nodelib_do_ligature_n},
 
3523
    {"family_font", lua_nodelib_mfont},
3372
3524
    {"fields", lua_nodelib_fields},
 
3525
    {"first_character", lua_nodelib_first_character},
 
3526
    {"first_glyph", lua_nodelib_first_glyph},
 
3527
    {"flush_list", lua_nodelib_flush_list},
 
3528
    {"free", lua_nodelib_free},
 
3529
    {"has_attribute", lua_nodelib_has_attribute},
3373
3530
    {"has_field", lua_nodelib_has_field},
3374
 
    {"free", lua_nodelib_free},
3375
 
    {"flush_list", lua_nodelib_flush_list},
3376
 
    {"remove", lua_nodelib_remove},
 
3531
    {"hpack", lua_nodelib_hpack},
 
3532
    {"id", lua_nodelib_id},
 
3533
    {"insert_after", lua_nodelib_insert_after},
3377
3534
    {"insert_before", lua_nodelib_insert_before},
3378
 
    {"insert_after", lua_nodelib_insert_after},
3379
 
    {"write", lua_nodelib_append},
 
3535
    {"is_node", lua_nodelib_isnode},
 
3536
    {"kerning", font_tex_kerning},
3380
3537
    {"last_node", lua_nodelib_last_node},
3381
 
    {"copy", lua_nodelib_copy},
3382
 
    {"copy_list", lua_nodelib_copy_list},
3383
 
    {"dimensions", lua_nodelib_dimensions},
3384
 
    {"hpack", lua_nodelib_hpack},
3385
 
    {"vpack", lua_nodelib_vpack},
 
3538
    {"length", lua_nodelib_length},
 
3539
    {"ligaturing", font_tex_ligaturing},
3386
3540
    {"mlist_to_hlist", lua_nodelib_mlist_to_hlist},
3387
 
    {"family_font", lua_nodelib_mfont},
3388
 
    {"has_attribute", lua_nodelib_has_attribute},
 
3541
    {"new", lua_nodelib_new},
 
3542
    {"next", lua_nodelib_next},
 
3543
    {"prev", lua_nodelib_prev},
 
3544
    {"protect_glyphs", lua_nodelib_protect_glyphs},
 
3545
    {"protrusion_skippable", lua_nodelib_cp_skipable},
 
3546
    {"remove", lua_nodelib_remove},
3389
3547
    {"set_attribute", lua_nodelib_set_attribute},
 
3548
    {"slide", lua_nodelib_tail},
 
3549
    {"subtype", lua_nodelib_subtype},
 
3550
    {"tail", lua_nodelib_tail_only},
 
3551
    {"traverse", lua_nodelib_traverse},
 
3552
    {"traverse_id", lua_nodelib_traverse_filtered},
 
3553
    {"type", lua_nodelib_type},
 
3554
    {"types", lua_nodelib_types},
 
3555
    {"unprotect_glyphs", lua_nodelib_unprotect_glyphs},
3390
3556
    {"unset_attribute", lua_nodelib_unset_attribute},
3391
 
    {"do_ligature_n", lua_nodelib_do_ligature_n},
3392
 
    {"ligaturing", font_tex_ligaturing},
3393
 
    {"kerning", font_tex_kerning},
3394
 
    {"first_character", lua_nodelib_first_character},
3395
3557
    {"usedlist", lua_nodelib_usedlist},
3396
 
    {"protect_glyphs", lua_nodelib_protect_glyphs},
3397
 
    {"unprotect_glyphs", lua_nodelib_unprotect_glyphs},
3398
 
    {"protrusion_skipable", lua_nodelib_cp_skipable},
3399
 
    {"protrusion_skippable", lua_nodelib_cp_skipable},
 
3558
    {"vpack", lua_nodelib_vpack},
 
3559
    {"whatsits", lua_nodelib_whatsits},
 
3560
    {"write", lua_nodelib_append},
3400
3561
   {NULL, NULL}                /* sentinel */
3401
3562
};
3402
3563
 
3432
3593
    if (lua_isnil(L, -1))
3433
3594
        return null;
3434
3595
    n = check_isnode(L, -1);
3435
 
    return *n;
 
3596
    return (n ? *n : null);
3436
3597
}