| author | |
| committer | |
| log | ee9d1d0414ac6cc877e86055dcb08543db9b57ad |
| tree | ce3b8d86127d634179ea4c78fa9a19fdc730ad6e |
| parent | 848504117f17a5fa8ead8c168e0e430e22be6e43 |
7 files changed, 1987 insertions(+), 28 deletions(-)
src/all_types.hpp-2| ... | @@ -833,7 +833,6 @@ struct AstNode { | ... | @@ -833,7 +833,6 @@ struct AstNode { |
| 833 | enum NodeType type; | 833 | enum NodeType type; |
| 834 | size_t line; | 834 | size_t line; |
| 835 | size_t column; | 835 | size_t column; |
| 836 | uint32_t create_index; // for determinism purposes | ||
| 837 | ImportTableEntry *owner; | 836 | ImportTableEntry *owner; |
| 838 | union { | 837 | union { |
| 839 | AstNodeRoot root; | 838 | AstNodeRoot root; |
| ... | @@ -1523,7 +1522,6 @@ struct CodeGen { | ... | @@ -1523,7 +1522,6 @@ struct CodeGen { |
| 1523 | LLVMValueRef return_address_fn_val; | 1522 | LLVMValueRef return_address_fn_val; |
| 1524 | LLVMValueRef frame_address_fn_val; | 1523 | LLVMValueRef frame_address_fn_val; |
| 1525 | bool error_during_imports; | 1524 | bool error_during_imports; |
| 1526 | uint32_t next_node_index; | ||
| 1527 | TypeTableEntry *err_tag_type; | 1525 | TypeTableEntry *err_tag_type; |
| 1528 | 1526 | ||
| 1529 | const char **clang_argv; | 1527 | const char **clang_argv; |
src/analyze.cpp+1-2| ... | @@ -3163,8 +3163,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a | ... | @@ -3163,8 +3163,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3163 | import_entry->line_offsets = tokenization.line_offsets; | 3163 | import_entry->line_offsets = tokenization.line_offsets; |
| 3164 | import_entry->path = abs_full_path; | 3164 | import_entry->path = abs_full_path; |
| 3165 | 3165 | ||
| 3166 | import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color, | 3166 | import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color); |
| 3167 | &g->next_node_index); | ||
| 3168 | assert(import_entry->root); | 3167 | assert(import_entry->root); |
| 3169 | if (g->verbose) { | 3168 | if (g->verbose) { |
| 3170 | ast_print(stderr, import_entry->root, 0); | 3169 | ast_print(stderr, import_entry->root, 0); |
src/parseh.cpp+493-17| ... | @@ -17,6 +17,7 @@ | ... | @@ -17,6 +17,7 @@ |
| 17 | 17 | ||
| 18 | #include <clang/Frontend/ASTUnit.h> | 18 | #include <clang/Frontend/ASTUnit.h> |
| 19 | #include <clang/Frontend/CompilerInstance.h> | 19 | #include <clang/Frontend/CompilerInstance.h> |
| 20 | #include <clang/AST/Expr.h> | ||
| 20 | 21 | ||
| 21 | #include <string.h> | 22 | #include <string.h> |
| 22 | 23 | ||
| ... | @@ -54,6 +55,7 @@ struct Context { | ... | @@ -54,6 +55,7 @@ struct Context { |
| 54 | uint32_t next_anon_index; | 55 | uint32_t next_anon_index; |
| 55 | 56 | ||
| 56 | CodeGen *codegen; | 57 | CodeGen *codegen; |
| 58 | ASTContext *ctx; | ||
| 57 | }; | 59 | }; |
| 58 | 60 | ||
| 59 | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, | 61 | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, |
| ... | @@ -602,9 +604,477 @@ static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *de | ... | @@ -602,9 +604,477 @@ static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *de |
| 602 | return resolve_qual_type_with_table(c, qt, decl, &c->global_type_table); | 604 | return resolve_qual_type_with_table(c, qt, decl, &c->global_type_table); |
| 603 | } | 605 | } |
| 604 | 606 | ||
| 607 | #include "ast_render.hpp" | ||
| 608 | |||
| 609 | static AstNode * ast_trans_stmt(Context *c, Stmt *stmt); | ||
| 610 | |||
| 611 | static AstNode * ast_trans_expr(Context *c, Expr *expr) { | ||
| 612 | return ast_trans_stmt(c, expr); | ||
| 613 | } | ||
| 614 | |||
| 615 | static AstNode * ast_create_node(Context *c, const SourceRange &range, NodeType id) { | ||
| 616 | AstNode *node = allocate<AstNode>(1); | ||
| 617 | node->type = id; | ||
| 618 | node->owner = c->import; | ||
| 619 | // TODO line/column. mapping to C file?? | ||
| 620 | return node; | ||
| 621 | } | ||
| 622 | |||
| 623 | static AstNode * ast_trans_compound_stmt(Context *c, CompoundStmt *stmt) { | ||
| 624 | AstNode *block_node = ast_create_node(c, stmt->getSourceRange(), NodeTypeBlock); | ||
| 625 | for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) { | ||
| 626 | AstNode *child_node = ast_trans_stmt(c, *it); | ||
| 627 | block_node->data.block.statements.append(child_node); | ||
| 628 | } | ||
| 629 | return block_node; | ||
| 630 | } | ||
| 631 | |||
| 632 | static AstNode *ast_trans_return_stmt(Context *c, ReturnStmt *stmt) { | ||
| 633 | Expr *value_expr = stmt->getRetValue(); | ||
| 634 | if (value_expr == nullptr) { | ||
| 635 | zig_panic("TODO handle C return void"); | ||
| 636 | } else { | ||
| 637 | AstNode *return_node = ast_create_node(c, stmt->getSourceRange(), NodeTypeReturnExpr); | ||
| 638 | return_node->data.return_expr.expr = ast_trans_expr(c, value_expr); | ||
| 639 | return return_node; | ||
| 640 | } | ||
| 641 | } | ||
| 642 | |||
| 643 | static void aps_int_to_bigint(Context *c, const llvm::APSInt &aps_int, BigInt *bigint) { | ||
| 644 | // TODO respect actually big integers | ||
| 645 | if (aps_int.isSigned()) { | ||
| 646 | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { | ||
| 647 | zig_panic("TODO actually bigint in C"); | ||
| 648 | } else { | ||
| 649 | bigint_init_signed(bigint, aps_int.getExtValue()); | ||
| 650 | } | ||
| 651 | } else { | ||
| 652 | if (aps_int > INT64_MAX) { | ||
| 653 | zig_panic("TODO actually bigint in C"); | ||
| 654 | } else { | ||
| 655 | bigint_init_unsigned(bigint, aps_int.getExtValue()); | ||
| 656 | } | ||
| 657 | } | ||
| 658 | } | ||
| 659 | static AstNode * ast_trans_integer_literal(Context *c, IntegerLiteral *stmt) { | ||
| 660 | AstNode *node = ast_create_node(c, stmt->getSourceRange(), NodeTypeIntLiteral); | ||
| 661 | llvm::APSInt result; | ||
| 662 | if (!stmt->EvaluateAsInt(result, *c->ctx)) { | ||
| 663 | fprintf(stderr, "TODO unable to convert integer literal to zig\n"); | ||
| 664 | } | ||
| 665 | node->data.int_literal.bigint = allocate<BigInt>(1); | ||
| 666 | aps_int_to_bigint(c, result, node->data.int_literal.bigint); | ||
| 667 | return node; | ||
| 668 | } | ||
| 669 | |||
| 670 | static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) { | ||
| 671 | Stmt::StmtClass sc = stmt->getStmtClass(); | ||
| 672 | switch (sc) { | ||
| 673 | case Stmt::ReturnStmtClass: | ||
| 674 | return ast_trans_return_stmt(c, (ReturnStmt *)stmt); | ||
| 675 | case Stmt::CompoundStmtClass: | ||
| 676 | return ast_trans_compound_stmt(c, (CompoundStmt *)stmt); | ||
| 677 | case Stmt::IntegerLiteralClass: | ||
| 678 | return ast_trans_integer_literal(c, (IntegerLiteral *)stmt); | ||
| 679 | case Stmt::CaseStmtClass: | ||
| 680 | zig_panic("TODO handle C CaseStmtClass"); | ||
| 681 | case Stmt::DefaultStmtClass: | ||
| 682 | zig_panic("TODO handle C DefaultStmtClass"); | ||
| 683 | case Stmt::SwitchStmtClass: | ||
| 684 | zig_panic("TODO handle C SwitchStmtClass"); | ||
| 685 | case Stmt::WhileStmtClass: | ||
| 686 | zig_panic("TODO handle C WhileStmtClass"); | ||
| 687 | case Stmt::NoStmtClass: | ||
| 688 | zig_panic("TODO handle C NoStmtClass"); | ||
| 689 | case Stmt::GCCAsmStmtClass: | ||
| 690 | zig_panic("TODO handle C GCCAsmStmtClass"); | ||
| 691 | case Stmt::MSAsmStmtClass: | ||
| 692 | zig_panic("TODO handle C MSAsmStmtClass"); | ||
| 693 | case Stmt::AttributedStmtClass: | ||
| 694 | zig_panic("TODO handle C AttributedStmtClass"); | ||
| 695 | case Stmt::BreakStmtClass: | ||
| 696 | zig_panic("TODO handle C BreakStmtClass"); | ||
| 697 | case Stmt::CXXCatchStmtClass: | ||
| 698 | zig_panic("TODO handle C CXXCatchStmtClass"); | ||
| 699 | case Stmt::CXXForRangeStmtClass: | ||
| 700 | zig_panic("TODO handle C CXXForRangeStmtClass"); | ||
| 701 | case Stmt::CXXTryStmtClass: | ||
| 702 | zig_panic("TODO handle C CXXTryStmtClass"); | ||
| 703 | case Stmt::CapturedStmtClass: | ||
| 704 | zig_panic("TODO handle C CapturedStmtClass"); | ||
| 705 | case Stmt::ContinueStmtClass: | ||
| 706 | zig_panic("TODO handle C ContinueStmtClass"); | ||
| 707 | case Stmt::CoreturnStmtClass: | ||
| 708 | zig_panic("TODO handle C CoreturnStmtClass"); | ||
| 709 | case Stmt::CoroutineBodyStmtClass: | ||
| 710 | zig_panic("TODO handle C CoroutineBodyStmtClass"); | ||
| 711 | case Stmt::DeclStmtClass: | ||
| 712 | zig_panic("TODO handle C DeclStmtClass"); | ||
| 713 | case Stmt::DoStmtClass: | ||
| 714 | zig_panic("TODO handle C DoStmtClass"); | ||
| 715 | case Stmt::BinaryConditionalOperatorClass: | ||
| 716 | zig_panic("TODO handle C BinaryConditionalOperatorClass"); | ||
| 717 | case Stmt::ConditionalOperatorClass: | ||
| 718 | zig_panic("TODO handle C ConditionalOperatorClass"); | ||
| 719 | case Stmt::AddrLabelExprClass: | ||
| 720 | zig_panic("TODO handle C AddrLabelExprClass"); | ||
| 721 | case Stmt::ArrayInitIndexExprClass: | ||
| 722 | zig_panic("TODO handle C ArrayInitIndexExprClass"); | ||
| 723 | case Stmt::ArrayInitLoopExprClass: | ||
| 724 | zig_panic("TODO handle C ArrayInitLoopExprClass"); | ||
| 725 | case Stmt::ArraySubscriptExprClass: | ||
| 726 | zig_panic("TODO handle C ArraySubscriptExprClass"); | ||
| 727 | case Stmt::ArrayTypeTraitExprClass: | ||
| 728 | zig_panic("TODO handle C ArrayTypeTraitExprClass"); | ||
| 729 | case Stmt::AsTypeExprClass: | ||
| 730 | zig_panic("TODO handle C AsTypeExprClass"); | ||
| 731 | case Stmt::AtomicExprClass: | ||
| 732 | zig_panic("TODO handle C AtomicExprClass"); | ||
| 733 | case Stmt::BinaryOperatorClass: | ||
| 734 | zig_panic("TODO handle C BinaryOperatorClass"); | ||
| 735 | case Stmt::CompoundAssignOperatorClass: | ||
| 736 | zig_panic("TODO handle C CompoundAssignOperatorClass"); | ||
| 737 | case Stmt::BlockExprClass: | ||
| 738 | zig_panic("TODO handle C BlockExprClass"); | ||
| 739 | case Stmt::CXXBindTemporaryExprClass: | ||
| 740 | zig_panic("TODO handle C CXXBindTemporaryExprClass"); | ||
| 741 | case Stmt::CXXBoolLiteralExprClass: | ||
| 742 | zig_panic("TODO handle C CXXBoolLiteralExprClass"); | ||
| 743 | case Stmt::CXXConstructExprClass: | ||
| 744 | zig_panic("TODO handle C CXXConstructExprClass"); | ||
| 745 | case Stmt::CXXTemporaryObjectExprClass: | ||
| 746 | zig_panic("TODO handle C CXXTemporaryObjectExprClass"); | ||
| 747 | case Stmt::CXXDefaultArgExprClass: | ||
| 748 | zig_panic("TODO handle C CXXDefaultArgExprClass"); | ||
| 749 | case Stmt::CXXDefaultInitExprClass: | ||
| 750 | zig_panic("TODO handle C CXXDefaultInitExprClass"); | ||
| 751 | case Stmt::CXXDeleteExprClass: | ||
| 752 | zig_panic("TODO handle C CXXDeleteExprClass"); | ||
| 753 | case Stmt::CXXDependentScopeMemberExprClass: | ||
| 754 | zig_panic("TODO handle C CXXDependentScopeMemberExprClass"); | ||
| 755 | case Stmt::CXXFoldExprClass: | ||
| 756 | zig_panic("TODO handle C CXXFoldExprClass"); | ||
| 757 | case Stmt::CXXInheritedCtorInitExprClass: | ||
| 758 | zig_panic("TODO handle C CXXInheritedCtorInitExprClass"); | ||
| 759 | case Stmt::CXXNewExprClass: | ||
| 760 | zig_panic("TODO handle C CXXNewExprClass"); | ||
| 761 | case Stmt::CXXNoexceptExprClass: | ||
| 762 | zig_panic("TODO handle C CXXNoexceptExprClass"); | ||
| 763 | case Stmt::CXXNullPtrLiteralExprClass: | ||
| 764 | zig_panic("TODO handle C CXXNullPtrLiteralExprClass"); | ||
| 765 | case Stmt::CXXPseudoDestructorExprClass: | ||
| 766 | zig_panic("TODO handle C CXXPseudoDestructorExprClass"); | ||
| 767 | case Stmt::CXXScalarValueInitExprClass: | ||
| 768 | zig_panic("TODO handle C CXXScalarValueInitExprClass"); | ||
| 769 | case Stmt::CXXStdInitializerListExprClass: | ||
| 770 | zig_panic("TODO handle C CXXStdInitializerListExprClass"); | ||
| 771 | case Stmt::CXXThisExprClass: | ||
| 772 | zig_panic("TODO handle C CXXThisExprClass"); | ||
| 773 | case Stmt::CXXThrowExprClass: | ||
| 774 | zig_panic("TODO handle C CXXThrowExprClass"); | ||
| 775 | case Stmt::CXXTypeidExprClass: | ||
| 776 | zig_panic("TODO handle C CXXTypeidExprClass"); | ||
| 777 | case Stmt::CXXUnresolvedConstructExprClass: | ||
| 778 | zig_panic("TODO handle C CXXUnresolvedConstructExprClass"); | ||
| 779 | case Stmt::CXXUuidofExprClass: | ||
| 780 | zig_panic("TODO handle C CXXUuidofExprClass"); | ||
| 781 | case Stmt::CallExprClass: | ||
| 782 | zig_panic("TODO handle C CallExprClass"); | ||
| 783 | case Stmt::CUDAKernelCallExprClass: | ||
| 784 | zig_panic("TODO handle C CUDAKernelCallExprClass"); | ||
| 785 | case Stmt::CXXMemberCallExprClass: | ||
| 786 | zig_panic("TODO handle C CXXMemberCallExprClass"); | ||
| 787 | case Stmt::CXXOperatorCallExprClass: | ||
| 788 | zig_panic("TODO handle C CXXOperatorCallExprClass"); | ||
| 789 | case Stmt::UserDefinedLiteralClass: | ||
| 790 | zig_panic("TODO handle C UserDefinedLiteralClass"); | ||
| 791 | case Stmt::CStyleCastExprClass: | ||
| 792 | zig_panic("TODO handle C CStyleCastExprClass"); | ||
| 793 | case Stmt::CXXFunctionalCastExprClass: | ||
| 794 | zig_panic("TODO handle C CXXFunctionalCastExprClass"); | ||
| 795 | case Stmt::CXXConstCastExprClass: | ||
| 796 | zig_panic("TODO handle C CXXConstCastExprClass"); | ||
| 797 | case Stmt::CXXDynamicCastExprClass: | ||
| 798 | zig_panic("TODO handle C CXXDynamicCastExprClass"); | ||
| 799 | case Stmt::CXXReinterpretCastExprClass: | ||
| 800 | zig_panic("TODO handle C CXXReinterpretCastExprClass"); | ||
| 801 | case Stmt::CXXStaticCastExprClass: | ||
| 802 | zig_panic("TODO handle C CXXStaticCastExprClass"); | ||
| 803 | case Stmt::ObjCBridgedCastExprClass: | ||
| 804 | zig_panic("TODO handle C ObjCBridgedCastExprClass"); | ||
| 805 | case Stmt::ImplicitCastExprClass: | ||
| 806 | zig_panic("TODO handle C ImplicitCastExprClass"); | ||
| 807 | case Stmt::CharacterLiteralClass: | ||
| 808 | zig_panic("TODO handle C CharacterLiteralClass"); | ||
| 809 | case Stmt::ChooseExprClass: | ||
| 810 | zig_panic("TODO handle C ChooseExprClass"); | ||
| 811 | case Stmt::CompoundLiteralExprClass: | ||
| 812 | zig_panic("TODO handle C CompoundLiteralExprClass"); | ||
| 813 | case Stmt::ConvertVectorExprClass: | ||
| 814 | zig_panic("TODO handle C ConvertVectorExprClass"); | ||
| 815 | case Stmt::CoawaitExprClass: | ||
| 816 | zig_panic("TODO handle C CoawaitExprClass"); | ||
| 817 | case Stmt::CoyieldExprClass: | ||
| 818 | zig_panic("TODO handle C CoyieldExprClass"); | ||
| 819 | case Stmt::DeclRefExprClass: | ||
| 820 | zig_panic("TODO handle C DeclRefExprClass"); | ||
| 821 | case Stmt::DependentCoawaitExprClass: | ||
| 822 | zig_panic("TODO handle C DependentCoawaitExprClass"); | ||
| 823 | case Stmt::DependentScopeDeclRefExprClass: | ||
| 824 | zig_panic("TODO handle C DependentScopeDeclRefExprClass"); | ||
| 825 | case Stmt::DesignatedInitExprClass: | ||
| 826 | zig_panic("TODO handle C DesignatedInitExprClass"); | ||
| 827 | case Stmt::DesignatedInitUpdateExprClass: | ||
| 828 | zig_panic("TODO handle C DesignatedInitUpdateExprClass"); | ||
| 829 | case Stmt::ExprWithCleanupsClass: | ||
| 830 | zig_panic("TODO handle C ExprWithCleanupsClass"); | ||
| 831 | case Stmt::ExpressionTraitExprClass: | ||
| 832 | zig_panic("TODO handle C ExpressionTraitExprClass"); | ||
| 833 | case Stmt::ExtVectorElementExprClass: | ||
| 834 | zig_panic("TODO handle C ExtVectorElementExprClass"); | ||
| 835 | case Stmt::FloatingLiteralClass: | ||
| 836 | zig_panic("TODO handle C FloatingLiteralClass"); | ||
| 837 | case Stmt::FunctionParmPackExprClass: | ||
| 838 | zig_panic("TODO handle C FunctionParmPackExprClass"); | ||
| 839 | case Stmt::GNUNullExprClass: | ||
| 840 | zig_panic("TODO handle C GNUNullExprClass"); | ||
| 841 | case Stmt::GenericSelectionExprClass: | ||
| 842 | zig_panic("TODO handle C GenericSelectionExprClass"); | ||
| 843 | case Stmt::ImaginaryLiteralClass: | ||
| 844 | zig_panic("TODO handle C ImaginaryLiteralClass"); | ||
| 845 | case Stmt::ImplicitValueInitExprClass: | ||
| 846 | zig_panic("TODO handle C ImplicitValueInitExprClass"); | ||
| 847 | case Stmt::InitListExprClass: | ||
| 848 | zig_panic("TODO handle C InitListExprClass"); | ||
| 849 | case Stmt::LambdaExprClass: | ||
| 850 | zig_panic("TODO handle C LambdaExprClass"); | ||
| 851 | case Stmt::MSPropertyRefExprClass: | ||
| 852 | zig_panic("TODO handle C MSPropertyRefExprClass"); | ||
| 853 | case Stmt::MSPropertySubscriptExprClass: | ||
| 854 | zig_panic("TODO handle C MSPropertySubscriptExprClass"); | ||
| 855 | case Stmt::MaterializeTemporaryExprClass: | ||
| 856 | zig_panic("TODO handle C MaterializeTemporaryExprClass"); | ||
| 857 | case Stmt::MemberExprClass: | ||
| 858 | zig_panic("TODO handle C MemberExprClass"); | ||
| 859 | case Stmt::NoInitExprClass: | ||
| 860 | zig_panic("TODO handle C NoInitExprClass"); | ||
| 861 | case Stmt::OMPArraySectionExprClass: | ||
| 862 | zig_panic("TODO handle C OMPArraySectionExprClass"); | ||
| 863 | case Stmt::ObjCArrayLiteralClass: | ||
| 864 | zig_panic("TODO handle C ObjCArrayLiteralClass"); | ||
| 865 | case Stmt::ObjCAvailabilityCheckExprClass: | ||
| 866 | zig_panic("TODO handle C ObjCAvailabilityCheckExprClass"); | ||
| 867 | case Stmt::ObjCBoolLiteralExprClass: | ||
| 868 | zig_panic("TODO handle C ObjCBoolLiteralExprClass"); | ||
| 869 | case Stmt::ObjCBoxedExprClass: | ||
| 870 | zig_panic("TODO handle C ObjCBoxedExprClass"); | ||
| 871 | case Stmt::ObjCDictionaryLiteralClass: | ||
| 872 | zig_panic("TODO handle C ObjCDictionaryLiteralClass"); | ||
| 873 | case Stmt::ObjCEncodeExprClass: | ||
| 874 | zig_panic("TODO handle C ObjCEncodeExprClass"); | ||
| 875 | case Stmt::ObjCIndirectCopyRestoreExprClass: | ||
| 876 | zig_panic("TODO handle C ObjCIndirectCopyRestoreExprClass"); | ||
| 877 | case Stmt::ObjCIsaExprClass: | ||
| 878 | zig_panic("TODO handle C ObjCIsaExprClass"); | ||
| 879 | case Stmt::ObjCIvarRefExprClass: | ||
| 880 | zig_panic("TODO handle C ObjCIvarRefExprClass"); | ||
| 881 | case Stmt::ObjCMessageExprClass: | ||
| 882 | zig_panic("TODO handle C ObjCMessageExprClass"); | ||
| 883 | case Stmt::ObjCPropertyRefExprClass: | ||
| 884 | zig_panic("TODO handle C ObjCPropertyRefExprClass"); | ||
| 885 | case Stmt::ObjCProtocolExprClass: | ||
| 886 | zig_panic("TODO handle C ObjCProtocolExprClass"); | ||
| 887 | case Stmt::ObjCSelectorExprClass: | ||
| 888 | zig_panic("TODO handle C ObjCSelectorExprClass"); | ||
| 889 | case Stmt::ObjCStringLiteralClass: | ||
| 890 | zig_panic("TODO handle C ObjCStringLiteralClass"); | ||
| 891 | case Stmt::ObjCSubscriptRefExprClass: | ||
| 892 | zig_panic("TODO handle C ObjCSubscriptRefExprClass"); | ||
| 893 | case Stmt::OffsetOfExprClass: | ||
| 894 | zig_panic("TODO handle C OffsetOfExprClass"); | ||
| 895 | case Stmt::OpaqueValueExprClass: | ||
| 896 | zig_panic("TODO handle C OpaqueValueExprClass"); | ||
| 897 | case Stmt::UnresolvedLookupExprClass: | ||
| 898 | zig_panic("TODO handle C UnresolvedLookupExprClass"); | ||
| 899 | case Stmt::UnresolvedMemberExprClass: | ||
| 900 | zig_panic("TODO handle C UnresolvedMemberExprClass"); | ||
| 901 | case Stmt::PackExpansionExprClass: | ||
| 902 | zig_panic("TODO handle C PackExpansionExprClass"); | ||
| 903 | case Stmt::ParenExprClass: | ||
| 904 | zig_panic("TODO handle C ParenExprClass"); | ||
| 905 | case Stmt::ParenListExprClass: | ||
| 906 | zig_panic("TODO handle C ParenListExprClass"); | ||
| 907 | case Stmt::PredefinedExprClass: | ||
| 908 | zig_panic("TODO handle C PredefinedExprClass"); | ||
| 909 | case Stmt::PseudoObjectExprClass: | ||
| 910 | zig_panic("TODO handle C PseudoObjectExprClass"); | ||
| 911 | case Stmt::ShuffleVectorExprClass: | ||
| 912 | zig_panic("TODO handle C ShuffleVectorExprClass"); | ||
| 913 | case Stmt::SizeOfPackExprClass: | ||
| 914 | zig_panic("TODO handle C SizeOfPackExprClass"); | ||
| 915 | case Stmt::StmtExprClass: | ||
| 916 | zig_panic("TODO handle C StmtExprClass"); | ||
| 917 | case Stmt::StringLiteralClass: | ||
| 918 | zig_panic("TODO handle C StringLiteralClass"); | ||
| 919 | case Stmt::SubstNonTypeTemplateParmExprClass: | ||
| 920 | zig_panic("TODO handle C SubstNonTypeTemplateParmExprClass"); | ||
| 921 | case Stmt::SubstNonTypeTemplateParmPackExprClass: | ||
| 922 | zig_panic("TODO handle C SubstNonTypeTemplateParmPackExprClass"); | ||
| 923 | case Stmt::TypeTraitExprClass: | ||
| 924 | zig_panic("TODO handle C TypeTraitExprClass"); | ||
| 925 | case Stmt::TypoExprClass: | ||
| 926 | zig_panic("TODO handle C TypoExprClass"); | ||
| 927 | case Stmt::UnaryExprOrTypeTraitExprClass: | ||
| 928 | zig_panic("TODO handle C UnaryExprOrTypeTraitExprClass"); | ||
| 929 | case Stmt::UnaryOperatorClass: | ||
| 930 | zig_panic("TODO handle C UnaryOperatorClass"); | ||
| 931 | case Stmt::VAArgExprClass: | ||
| 932 | zig_panic("TODO handle C VAArgExprClass"); | ||
| 933 | case Stmt::ForStmtClass: | ||
| 934 | zig_panic("TODO handle C ForStmtClass"); | ||
| 935 | case Stmt::GotoStmtClass: | ||
| 936 | zig_panic("TODO handle C GotoStmtClass"); | ||
| 937 | case Stmt::IfStmtClass: | ||
| 938 | zig_panic("TODO handle C IfStmtClass"); | ||
| 939 | case Stmt::IndirectGotoStmtClass: | ||
| 940 | zig_panic("TODO handle C IndirectGotoStmtClass"); | ||
| 941 | case Stmt::LabelStmtClass: | ||
| 942 | zig_panic("TODO handle C LabelStmtClass"); | ||
| 943 | case Stmt::MSDependentExistsStmtClass: | ||
| 944 | zig_panic("TODO handle C MSDependentExistsStmtClass"); | ||
| 945 | case Stmt::NullStmtClass: | ||
| 946 | zig_panic("TODO handle C NullStmtClass"); | ||
| 947 | case Stmt::OMPAtomicDirectiveClass: | ||
| 948 | zig_panic("TODO handle C OMPAtomicDirectiveClass"); | ||
| 949 | case Stmt::OMPBarrierDirectiveClass: | ||
| 950 | zig_panic("TODO handle C OMPBarrierDirectiveClass"); | ||
| 951 | case Stmt::OMPCancelDirectiveClass: | ||
| 952 | zig_panic("TODO handle C OMPCancelDirectiveClass"); | ||
| 953 | case Stmt::OMPCancellationPointDirectiveClass: | ||
| 954 | zig_panic("TODO handle C OMPCancellationPointDirectiveClass"); | ||
| 955 | case Stmt::OMPCriticalDirectiveClass: | ||
| 956 | zig_panic("TODO handle C OMPCriticalDirectiveClass"); | ||
| 957 | case Stmt::OMPFlushDirectiveClass: | ||
| 958 | zig_panic("TODO handle C OMPFlushDirectiveClass"); | ||
| 959 | case Stmt::OMPDistributeDirectiveClass: | ||
| 960 | zig_panic("TODO handle C OMPDistributeDirectiveClass"); | ||
| 961 | case Stmt::OMPDistributeParallelForDirectiveClass: | ||
| 962 | zig_panic("TODO handle C OMPDistributeParallelForDirectiveClass"); | ||
| 963 | case Stmt::OMPDistributeParallelForSimdDirectiveClass: | ||
| 964 | zig_panic("TODO handle C OMPDistributeParallelForSimdDirectiveClass"); | ||
| 965 | case Stmt::OMPDistributeSimdDirectiveClass: | ||
| 966 | zig_panic("TODO handle C OMPDistributeSimdDirectiveClass"); | ||
| 967 | case Stmt::OMPForDirectiveClass: | ||
| 968 | zig_panic("TODO handle C OMPForDirectiveClass"); | ||
| 969 | case Stmt::OMPForSimdDirectiveClass: | ||
| 970 | zig_panic("TODO handle C OMPForSimdDirectiveClass"); | ||
| 971 | case Stmt::OMPParallelForDirectiveClass: | ||
| 972 | zig_panic("TODO handle C OMPParallelForDirectiveClass"); | ||
| 973 | case Stmt::OMPParallelForSimdDirectiveClass: | ||
| 974 | zig_panic("TODO handle C OMPParallelForSimdDirectiveClass"); | ||
| 975 | case Stmt::OMPSimdDirectiveClass: | ||
| 976 | zig_panic("TODO handle C OMPSimdDirectiveClass"); | ||
| 977 | case Stmt::OMPTargetParallelForSimdDirectiveClass: | ||
| 978 | zig_panic("TODO handle C OMPTargetParallelForSimdDirectiveClass"); | ||
| 979 | case Stmt::OMPTargetSimdDirectiveClass: | ||
| 980 | zig_panic("TODO handle C OMPTargetSimdDirectiveClass"); | ||
| 981 | case Stmt::OMPTargetTeamsDistributeDirectiveClass: | ||
| 982 | zig_panic("TODO handle C OMPTargetTeamsDistributeDirectiveClass"); | ||
| 983 | case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: | ||
| 984 | zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass"); | ||
| 985 | case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: | ||
| 986 | zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass"); | ||
| 987 | case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: | ||
| 988 | zig_panic("TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass"); | ||
| 989 | case Stmt::OMPTaskLoopDirectiveClass: | ||
| 990 | zig_panic("TODO handle C OMPTaskLoopDirectiveClass"); | ||
| 991 | case Stmt::OMPTaskLoopSimdDirectiveClass: | ||
| 992 | zig_panic("TODO handle C OMPTaskLoopSimdDirectiveClass"); | ||
| 993 | case Stmt::OMPTeamsDistributeDirectiveClass: | ||
| 994 | zig_panic("TODO handle C OMPTeamsDistributeDirectiveClass"); | ||
| 995 | case Stmt::OMPTeamsDistributeParallelForDirectiveClass: | ||
| 996 | zig_panic("TODO handle C OMPTeamsDistributeParallelForDirectiveClass"); | ||
| 997 | case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: | ||
| 998 | zig_panic("TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass"); | ||
| 999 | case Stmt::OMPTeamsDistributeSimdDirectiveClass: | ||
| 1000 | zig_panic("TODO handle C OMPTeamsDistributeSimdDirectiveClass"); | ||
| 1001 | case Stmt::OMPMasterDirectiveClass: | ||
| 1002 | zig_panic("TODO handle C OMPMasterDirectiveClass"); | ||
| 1003 | case Stmt::OMPOrderedDirectiveClass: | ||
| 1004 | zig_panic("TODO handle C OMPOrderedDirectiveClass"); | ||
| 1005 | case Stmt::OMPParallelDirectiveClass: | ||
| 1006 | zig_panic("TODO handle C OMPParallelDirectiveClass"); | ||
| 1007 | case Stmt::OMPParallelSectionsDirectiveClass: | ||
| 1008 | zig_panic("TODO handle C OMPParallelSectionsDirectiveClass"); | ||
| 1009 | case Stmt::OMPSectionDirectiveClass: | ||
| 1010 | zig_panic("TODO handle C OMPSectionDirectiveClass"); | ||
| 1011 | case Stmt::OMPSectionsDirectiveClass: | ||
| 1012 | zig_panic("TODO handle C OMPSectionsDirectiveClass"); | ||
| 1013 | case Stmt::OMPSingleDirectiveClass: | ||
| 1014 | zig_panic("TODO handle C OMPSingleDirectiveClass"); | ||
| 1015 | case Stmt::OMPTargetDataDirectiveClass: | ||
| 1016 | zig_panic("TODO handle C OMPTargetDataDirectiveClass"); | ||
| 1017 | case Stmt::OMPTargetDirectiveClass: | ||
| 1018 | zig_panic("TODO handle C OMPTargetDirectiveClass"); | ||
| 1019 | case Stmt::OMPTargetEnterDataDirectiveClass: | ||
| 1020 | zig_panic("TODO handle C OMPTargetEnterDataDirectiveClass"); | ||
| 1021 | case Stmt::OMPTargetExitDataDirectiveClass: | ||
| 1022 | zig_panic("TODO handle C OMPTargetExitDataDirectiveClass"); | ||
| 1023 | case Stmt::OMPTargetParallelDirectiveClass: | ||
| 1024 | zig_panic("TODO handle C OMPTargetParallelDirectiveClass"); | ||
| 1025 | case Stmt::OMPTargetParallelForDirectiveClass: | ||
| 1026 | zig_panic("TODO handle C OMPTargetParallelForDirectiveClass"); | ||
| 1027 | case Stmt::OMPTargetTeamsDirectiveClass: | ||
| 1028 | zig_panic("TODO handle C OMPTargetTeamsDirectiveClass"); | ||
| 1029 | case Stmt::OMPTargetUpdateDirectiveClass: | ||
| 1030 | zig_panic("TODO handle C OMPTargetUpdateDirectiveClass"); | ||
| 1031 | case Stmt::OMPTaskDirectiveClass: | ||
| 1032 | zig_panic("TODO handle C OMPTaskDirectiveClass"); | ||
| 1033 | case Stmt::OMPTaskgroupDirectiveClass: | ||
| 1034 | zig_panic("TODO handle C OMPTaskgroupDirectiveClass"); | ||
| 1035 | case Stmt::OMPTaskwaitDirectiveClass: | ||
| 1036 | zig_panic("TODO handle C OMPTaskwaitDirectiveClass"); | ||
| 1037 | case Stmt::OMPTaskyieldDirectiveClass: | ||
| 1038 | zig_panic("TODO handle C OMPTaskyieldDirectiveClass"); | ||
| 1039 | case Stmt::OMPTeamsDirectiveClass: | ||
| 1040 | zig_panic("TODO handle C OMPTeamsDirectiveClass"); | ||
| 1041 | case Stmt::ObjCAtCatchStmtClass: | ||
| 1042 | zig_panic("TODO handle C ObjCAtCatchStmtClass"); | ||
| 1043 | case Stmt::ObjCAtFinallyStmtClass: | ||
| 1044 | zig_panic("TODO handle C ObjCAtFinallyStmtClass"); | ||
| 1045 | case Stmt::ObjCAtSynchronizedStmtClass: | ||
| 1046 | zig_panic("TODO handle C ObjCAtSynchronizedStmtClass"); | ||
| 1047 | case Stmt::ObjCAtThrowStmtClass: | ||
| 1048 | zig_panic("TODO handle C ObjCAtThrowStmtClass"); | ||
| 1049 | case Stmt::ObjCAtTryStmtClass: | ||
| 1050 | zig_panic("TODO handle C ObjCAtTryStmtClass"); | ||
| 1051 | case Stmt::ObjCAutoreleasePoolStmtClass: | ||
| 1052 | zig_panic("TODO handle C ObjCAutoreleasePoolStmtClass"); | ||
| 1053 | case Stmt::ObjCForCollectionStmtClass: | ||
| 1054 | zig_panic("TODO handle C ObjCForCollectionStmtClass"); | ||
| 1055 | case Stmt::SEHExceptStmtClass: | ||
| 1056 | zig_panic("TODO handle C SEHExceptStmtClass"); | ||
| 1057 | case Stmt::SEHFinallyStmtClass: | ||
| 1058 | zig_panic("TODO handle C SEHFinallyStmtClass"); | ||
| 1059 | case Stmt::SEHLeaveStmtClass: | ||
| 1060 | zig_panic("TODO handle C SEHLeaveStmtClass"); | ||
| 1061 | case Stmt::SEHTryStmtClass: | ||
| 1062 | zig_panic("TODO handle C SEHTryStmtClass"); | ||
| 1063 | } | ||
| 1064 | zig_unreachable(); | ||
| 1065 | } | ||
| 1066 | |||
| 605 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | 1067 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 606 | Buf *fn_name = buf_create_from_str(decl_name(fn_decl)); | 1068 | Buf *fn_name = buf_create_from_str(decl_name(fn_decl)); |
| 607 | 1069 | ||
| 1070 | if (fn_decl->hasBody()) { | ||
| 1071 | fprintf(stderr, "fn %s\n", buf_ptr(fn_name)); | ||
| 1072 | Stmt *body = fn_decl->getBody(); | ||
| 1073 | AstNode *body_node = ast_trans_stmt(c, body); | ||
| 1074 | ast_render(c->codegen, stderr, body_node, 4); | ||
| 1075 | fprintf(stderr, "\n"); | ||
| 1076 | } | ||
| 1077 | |||
| 608 | if (get_global(c, fn_name)) { | 1078 | if (get_global(c, fn_name)) { |
| 609 | // we already saw this function | 1079 | // we already saw this function |
| 610 | return; | 1080 | return; |
| ... | @@ -1373,7 +1843,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1373,7 +1843,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1373 | 1843 | ||
| 1374 | std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>(); | 1844 | std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>(); |
| 1375 | 1845 | ||
| 1376 | bool skip_function_bodies = true; | 1846 | bool skip_function_bodies = false; |
| 1377 | bool only_local_decls = true; | 1847 | bool only_local_decls = true; |
| 1378 | bool capture_diagnostics = true; | 1848 | bool capture_diagnostics = true; |
| 1379 | bool user_files_are_volatile = true; | 1849 | bool user_files_are_volatile = true; |
| ... | @@ -1390,7 +1860,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1390,7 +1860,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1390 | single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit, | 1860 | single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit, |
| 1391 | nullptr)); | 1861 | nullptr)); |
| 1392 | 1862 | ||
| 1393 | |||
| 1394 | // Early failures in LoadFromCommandLine may return with ErrUnit unset. | 1863 | // Early failures in LoadFromCommandLine may return with ErrUnit unset. |
| 1395 | if (!ast_unit && !err_unit) { | 1864 | if (!ast_unit && !err_unit) { |
| 1396 | return ErrorFileSystem; | 1865 | return ErrorFileSystem; |
| ... | @@ -1416,29 +1885,36 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1416,29 +1885,36 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1416 | break; | 1885 | break; |
| 1417 | } | 1886 | } |
| 1418 | StringRef msg_str_ref = it->getMessage(); | 1887 | StringRef msg_str_ref = it->getMessage(); |
| 1419 | FullSourceLoc fsl = it->getLocation(); | ||
| 1420 | FileID file_id = fsl.getFileID(); | ||
| 1421 | StringRef filename = fsl.getManager().getFilename(fsl); | ||
| 1422 | unsigned line = fsl.getSpellingLineNumber() - 1; | ||
| 1423 | unsigned column = fsl.getSpellingColumnNumber() - 1; | ||
| 1424 | unsigned offset = fsl.getManager().getFileOffset(fsl); | ||
| 1425 | const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin(); | ||
| 1426 | Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin()); | 1888 | Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin()); |
| 1427 | Buf *path; | 1889 | FullSourceLoc fsl = it->getLocation(); |
| 1428 | if (filename.empty()) { | 1890 | if (fsl.hasManager()) { |
| 1429 | path = buf_alloc(); | 1891 | FileID file_id = fsl.getFileID(); |
| 1430 | } else { | 1892 | StringRef filename = fsl.getManager().getFilename(fsl); |
| 1431 | path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size()); | 1893 | unsigned line = fsl.getSpellingLineNumber() - 1; |
| 1432 | } | 1894 | unsigned column = fsl.getSpellingColumnNumber() - 1; |
| 1895 | unsigned offset = fsl.getManager().getFileOffset(fsl); | ||
| 1896 | const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin(); | ||
| 1897 | Buf *path; | ||
| 1898 | if (filename.empty()) { | ||
| 1899 | path = buf_alloc(); | ||
| 1900 | } else { | ||
| 1901 | path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size()); | ||
| 1902 | } | ||
| 1433 | 1903 | ||
| 1434 | ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg); | 1904 | ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg); |
| 1435 | 1905 | ||
| 1436 | c->errors->append(err_msg); | 1906 | c->errors->append(err_msg); |
| 1907 | } else { | ||
| 1908 | // NOTE the only known way this gets triggered right now is if you have a lot of errors | ||
| 1909 | // clang emits "too many errors emitted, stopping now" | ||
| 1910 | fprintf(stderr, "unexpected error from clang: %s\n", buf_ptr(msg)); | ||
| 1911 | } | ||
| 1437 | } | 1912 | } |
| 1438 | 1913 | ||
| 1439 | return 0; | 1914 | return 0; |
| 1440 | } | 1915 | } |
| 1441 | 1916 | ||
| 1917 | c->ctx = &ast_unit->getASTContext(); | ||
| 1442 | c->source_manager = &ast_unit->getSourceManager(); | 1918 | c->source_manager = &ast_unit->getSourceManager(); |
| 1443 | 1919 | ||
| 1444 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); | 1920 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); |
src/parser.cpp+1-5| ... | @@ -20,7 +20,6 @@ struct ParseContext { | ... | @@ -20,7 +20,6 @@ struct ParseContext { |
| 20 | ZigList<Token> *tokens; | 20 | ZigList<Token> *tokens; |
| 21 | ImportTableEntry *owner; | 21 | ImportTableEntry *owner; |
| 22 | ErrColor err_color; | 22 | ErrColor err_color; |
| 23 | uint32_t *next_node_index; | ||
| 24 | // These buffers are used freqently so we preallocate them once here. | 23 | // These buffers are used freqently so we preallocate them once here. |
| 25 | Buf *void_buf; | 24 | Buf *void_buf; |
| 26 | Buf *empty_buf; | 25 | Buf *empty_buf; |
| ... | @@ -70,8 +69,6 @@ static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) { | ... | @@ -70,8 +69,6 @@ static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) { |
| 70 | AstNode *node = allocate<AstNode>(1); | 69 | AstNode *node = allocate<AstNode>(1); |
| 71 | node->type = type; | 70 | node->type = type; |
| 72 | node->owner = pc->owner; | 71 | node->owner = pc->owner; |
| 73 | node->create_index = *pc->next_node_index; | ||
| 74 | *pc->next_node_index += 1; | ||
| 75 | return node; | 72 | return node; |
| 76 | } | 73 | } |
| 77 | 74 | ||
| ... | @@ -2611,7 +2608,7 @@ static AstNode *ast_parse_root(ParseContext *pc, size_t *token_index) { | ... | @@ -2611,7 +2608,7 @@ static AstNode *ast_parse_root(ParseContext *pc, size_t *token_index) { |
| 2611 | } | 2608 | } |
| 2612 | 2609 | ||
| 2613 | AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, | 2610 | AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, |
| 2614 | ErrColor err_color, uint32_t *next_node_index) | 2611 | ErrColor err_color) |
| 2615 | { | 2612 | { |
| 2616 | ParseContext pc = {0}; | 2613 | ParseContext pc = {0}; |
| 2617 | pc.void_buf = buf_create_from_str("void"); | 2614 | pc.void_buf = buf_create_from_str("void"); |
| ... | @@ -2620,7 +2617,6 @@ AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, | ... | @@ -2620,7 +2617,6 @@ AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, |
| 2620 | pc.owner = owner; | 2617 | pc.owner = owner; |
| 2621 | pc.buf = buf; | 2618 | pc.buf = buf; |
| 2622 | pc.tokens = tokens; | 2619 | pc.tokens = tokens; |
| 2623 | pc.next_node_index = next_node_index; | ||
| 2624 | size_t token_index = 0; | 2620 | size_t token_index = 0; |
| 2625 | pc.root = ast_parse_root(&pc, &token_index); | 2621 | pc.root = ast_parse_root(&pc, &token_index); |
| 2626 | return pc.root; | 2622 | return pc.root; |
src/parser.hpp+1-2| ... | @@ -17,8 +17,7 @@ void ast_token_error(Token *token, const char *format, ...); | ... | @@ -17,8 +17,7 @@ void ast_token_error(Token *token, const char *format, ...); |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | // This function is provided by generated code, generated by parsergen.cpp | 19 | // This function is provided by generated code, generated by parsergen.cpp |
| 20 | AstNode * ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, ErrColor err_color, | 20 | AstNode * ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, ErrColor err_color); |
| 21 | uint32_t *next_node_index); | ||
| 22 | 21 | ||
| 23 | void ast_print(AstNode *node, int indent); | 22 | void ast_print(AstNode *node, int indent); |
| 24 | 23 |
std/zlib/deflate.zig created+522| ... | @@ -0,0 +1,522 @@ | ||
| 1 | const z_stream = struct { | ||
| 2 | /// next input byte */ | ||
| 3 | next_in: &const u8, | ||
| 4 | |||
| 5 | /// number of bytes available at next_in | ||
| 6 | avail_in: u16, | ||
| 7 | /// total number of input bytes read so far | ||
| 8 | total_in: u32, | ||
| 9 | |||
| 10 | /// next output byte will go here | ||
| 11 | next_out: u8, | ||
| 12 | /// remaining free space at next_out | ||
| 13 | avail_out: u16, | ||
| 14 | /// total number of bytes output so far | ||
| 15 | total_out: u32, | ||
| 16 | |||
| 17 | /// last error message, NULL if no error | ||
| 18 | msg: ?&const u8, | ||
| 19 | /// not visible by applications | ||
| 20 | state: | ||
| 21 | struct internal_state FAR *state; // not visible by applications */ | ||
| 22 | |||
| 23 | alloc_func zalloc; // used to allocate the internal state */ | ||
| 24 | free_func zfree; // used to free the internal state */ | ||
| 25 | voidpf opaque; // private data object passed to zalloc and zfree */ | ||
| 26 | |||
| 27 | int data_type; // best guess about the data type: binary or text | ||
| 28 | // for deflate, or the decoding state for inflate */ | ||
| 29 | uint32_t adler; // Adler-32 or CRC-32 value of the uncompressed data */ | ||
| 30 | uint32_t reserved; // reserved for future use */ | ||
| 31 | }; | ||
| 32 | |||
| 33 | typedef struct internal_state { | ||
| 34 | z_stream * strm; /* pointer back to this zlib stream */ | ||
| 35 | int status; /* as the name implies */ | ||
| 36 | uint8_t *pending_buf; /* output still pending */ | ||
| 37 | ulg pending_buf_size; /* size of pending_buf */ | ||
| 38 | uint8_t *pending_out; /* next pending byte to output to the stream */ | ||
| 39 | ulg pending; /* nb of bytes in the pending buffer */ | ||
| 40 | int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ | ||
| 41 | gz_headerp gzhead; /* gzip header information to write */ | ||
| 42 | ulg gzindex; /* where in extra, name, or comment */ | ||
| 43 | uint8_t method; /* can only be DEFLATED */ | ||
| 44 | int last_flush; /* value of flush param for previous deflate call */ | ||
| 45 | |||
| 46 | /* used by deflate.c: */ | ||
| 47 | |||
| 48 | uint16_t w_size; /* LZ77 window size (32K by default) */ | ||
| 49 | uint16_t w_bits; /* log2(w_size) (8..16) */ | ||
| 50 | uint16_t w_mask; /* w_size - 1 */ | ||
| 51 | |||
| 52 | uint8_t *window; | ||
| 53 | /* Sliding window. Input bytes are read into the second half of the window, | ||
| 54 | * and move to the first half later to keep a dictionary of at least wSize | ||
| 55 | * bytes. With this organization, matches are limited to a distance of | ||
| 56 | * wSize-MAX_MATCH bytes, but this ensures that IO is always | ||
| 57 | * performed with a length multiple of the block size. Also, it limits | ||
| 58 | * the window size to 64K, which is quite useful on MSDOS. | ||
| 59 | * To do: use the user input buffer as sliding window. | ||
| 60 | */ | ||
| 61 | |||
| 62 | ulg window_size; | ||
| 63 | /* Actual size of window: 2*wSize, except when the user input buffer | ||
| 64 | * is directly used as sliding window. | ||
| 65 | */ | ||
| 66 | |||
| 67 | Posf *prev; | ||
| 68 | /* Link to older string with same hash index. To limit the size of this | ||
| 69 | * array to 64K, this link is maintained only for the last 32K strings. | ||
| 70 | * An index in this array is thus a window index modulo 32K. | ||
| 71 | */ | ||
| 72 | |||
| 73 | Posf *head; /* Heads of the hash chains or NIL. */ | ||
| 74 | |||
| 75 | uint16_t ins_h; /* hash index of string to be inserted */ | ||
| 76 | uint16_t hash_size; /* number of elements in hash table */ | ||
| 77 | uint16_t hash_bits; /* log2(hash_size) */ | ||
| 78 | uint16_t hash_mask; /* hash_size-1 */ | ||
| 79 | |||
| 80 | uint16_t hash_shift; | ||
| 81 | /* Number of bits by which ins_h must be shifted at each input | ||
| 82 | * step. It must be such that after MIN_MATCH steps, the oldest | ||
| 83 | * byte no longer takes part in the hash key, that is: | ||
| 84 | * hash_shift * MIN_MATCH >= hash_bits | ||
| 85 | */ | ||
| 86 | |||
| 87 | long block_start; | ||
| 88 | /* Window position at the beginning of the current output block. Gets | ||
| 89 | * negative when the window is moved backwards. | ||
| 90 | */ | ||
| 91 | |||
| 92 | uint16_t match_length; /* length of best match */ | ||
| 93 | IPos prev_match; /* previous match */ | ||
| 94 | int match_available; /* set if previous match exists */ | ||
| 95 | uint16_t strstart; /* start of string to insert */ | ||
| 96 | uint16_t match_start; /* start of matching string */ | ||
| 97 | uint16_t lookahead; /* number of valid bytes ahead in window */ | ||
| 98 | |||
| 99 | uint16_t prev_length; | ||
| 100 | /* Length of the best match at previous step. Matches not greater than this | ||
| 101 | * are discarded. This is used in the lazy match evaluation. | ||
| 102 | */ | ||
| 103 | |||
| 104 | uint16_t max_chain_length; | ||
| 105 | /* To speed up deflation, hash chains are never searched beyond this | ||
| 106 | * length. A higher limit improves compression ratio but degrades the | ||
| 107 | * speed. | ||
| 108 | */ | ||
| 109 | |||
| 110 | uint16_t max_lazy_match; | ||
| 111 | /* Attempt to find a better match only when the current match is strictly | ||
| 112 | * smaller than this value. This mechanism is used only for compression | ||
| 113 | * levels >= 4. | ||
| 114 | */ | ||
| 115 | # define max_insert_length max_lazy_match | ||
| 116 | /* Insert new strings in the hash table only if the match length is not | ||
| 117 | * greater than this length. This saves time but degrades compression. | ||
| 118 | * max_insert_length is used only for compression levels <= 3. | ||
| 119 | */ | ||
| 120 | |||
| 121 | int level; /* compression level (1..9) */ | ||
| 122 | int strategy; /* favor or force Huffman coding*/ | ||
| 123 | |||
| 124 | uint16_t good_match; | ||
| 125 | /* Use a faster search when the previous match is longer than this */ | ||
| 126 | |||
| 127 | int nice_match; /* Stop searching when current match exceeds this */ | ||
| 128 | |||
| 129 | /* used by trees.c: */ | ||
| 130 | /* Didn't use ct_data typedef below to suppress compiler warning */ | ||
| 131 | struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ | ||
| 132 | struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ | ||
| 133 | struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ | ||
| 134 | |||
| 135 | struct tree_desc_s l_desc; /* desc. for literal tree */ | ||
| 136 | struct tree_desc_s d_desc; /* desc. for distance tree */ | ||
| 137 | struct tree_desc_s bl_desc; /* desc. for bit length tree */ | ||
| 138 | |||
| 139 | ush bl_count[MAX_BITS+1]; | ||
| 140 | /* number of codes at each bit length for an optimal tree */ | ||
| 141 | |||
| 142 | int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ | ||
| 143 | int heap_len; /* number of elements in the heap */ | ||
| 144 | int heap_max; /* element of largest frequency */ | ||
| 145 | /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. | ||
| 146 | * The same heap array is used to build all trees. | ||
| 147 | */ | ||
| 148 | |||
| 149 | uch depth[2*L_CODES+1]; | ||
| 150 | /* Depth of each subtree used as tie breaker for trees of equal frequency | ||
| 151 | */ | ||
| 152 | |||
| 153 | uchf *l_buf; /* buffer for literals or lengths */ | ||
| 154 | |||
| 155 | uint16_t lit_bufsize; | ||
| 156 | /* Size of match buffer for literals/lengths. There are 4 reasons for | ||
| 157 | * limiting lit_bufsize to 64K: | ||
| 158 | * - frequencies can be kept in 16 bit counters | ||
| 159 | * - if compression is not successful for the first block, all input | ||
| 160 | * data is still in the window so we can still emit a stored block even | ||
| 161 | * when input comes from standard input. (This can also be done for | ||
| 162 | * all blocks if lit_bufsize is not greater than 32K.) | ||
| 163 | * - if compression is not successful for a file smaller than 64K, we can | ||
| 164 | * even emit a stored file instead of a stored block (saving 5 bytes). | ||
| 165 | * This is applicable only for zip (not gzip or zlib). | ||
| 166 | * - creating new Huffman trees less frequently may not provide fast | ||
| 167 | * adaptation to changes in the input data statistics. (Take for | ||
| 168 | * example a binary file with poorly compressible code followed by | ||
| 169 | * a highly compressible string table.) Smaller buffer sizes give | ||
| 170 | * fast adaptation but have of course the overhead of transmitting | ||
| 171 | * trees more frequently. | ||
| 172 | * - I can't count above 4 | ||
| 173 | */ | ||
| 174 | |||
| 175 | uint16_t last_lit; /* running index in l_buf */ | ||
| 176 | |||
| 177 | ushf *d_buf; | ||
| 178 | /* Buffer for distances. To simplify the code, d_buf and l_buf have | ||
| 179 | * the same number of elements. To use different lengths, an extra flag | ||
| 180 | * array would be necessary. | ||
| 181 | */ | ||
| 182 | |||
| 183 | ulg opt_len; /* bit length of current block with optimal trees */ | ||
| 184 | ulg static_len; /* bit length of current block with static trees */ | ||
| 185 | uint16_t matches; /* number of string matches in current block */ | ||
| 186 | uint16_t insert; /* bytes at end of window left to insert */ | ||
| 187 | |||
| 188 | #ifdef ZLIB_DEBUG | ||
| 189 | ulg compressed_len; /* total bit length of compressed file mod 2^32 */ | ||
| 190 | ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ | ||
| 191 | #endif | ||
| 192 | |||
| 193 | ush bi_buf; | ||
| 194 | /* Output buffer. bits are inserted starting at the bottom (least | ||
| 195 | * significant bits). | ||
| 196 | */ | ||
| 197 | int bi_valid; | ||
| 198 | /* Number of valid bits in bi_buf. All bits above the last valid bit | ||
| 199 | * are always zero. | ||
| 200 | */ | ||
| 201 | |||
| 202 | ulg high_water; | ||
| 203 | /* High water mark offset in window for initialized bytes -- bytes above | ||
| 204 | * this are set to zero in order to avoid memory check warnings when | ||
| 205 | * longest match routines access bytes past the input. This is then | ||
| 206 | * updated to the new high water mark. | ||
| 207 | */ | ||
| 208 | |||
| 209 | } FAR deflate_state; | ||
| 210 | |||
| 211 | fn deflate(strm: &z_stream, flush: int) -> %void { | ||
| 212 | |||
| 213 | } | ||
| 214 | |||
| 215 | int deflate (z_stream * strm, int flush) { | ||
| 216 | int old_flush; /* value of flush param for previous deflate call */ | ||
| 217 | deflate_state *s; | ||
| 218 | |||
| 219 | if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { | ||
| 220 | return Z_STREAM_ERROR; | ||
| 221 | } | ||
| 222 | s = strm->state; | ||
| 223 | |||
| 224 | if (strm->next_out == Z_NULL || | ||
| 225 | (strm->avail_in != 0 && strm->next_in == Z_NULL) || | ||
| 226 | (s->status == FINISH_STATE && flush != Z_FINISH)) { | ||
| 227 | ERR_RETURN(strm, Z_STREAM_ERROR); | ||
| 228 | } | ||
| 229 | if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); | ||
| 230 | |||
| 231 | old_flush = s->last_flush; | ||
| 232 | s->last_flush = flush; | ||
| 233 | |||
| 234 | /* Flush as much pending output as possible */ | ||
| 235 | if (s->pending != 0) { | ||
| 236 | flush_pending(strm); | ||
| 237 | if (strm->avail_out == 0) { | ||
| 238 | /* Since avail_out is 0, deflate will be called again with | ||
| 239 | * more output space, but possibly with both pending and | ||
| 240 | * avail_in equal to zero. There won't be anything to do, | ||
| 241 | * but this is not an error situation so make sure we | ||
| 242 | * return OK instead of BUF_ERROR at next call of deflate: | ||
| 243 | */ | ||
| 244 | s->last_flush = -1; | ||
| 245 | return Z_OK; | ||
| 246 | } | ||
| 247 | |||
| 248 | /* Make sure there is something to do and avoid duplicate consecutive | ||
| 249 | * flushes. For repeated and useless calls with Z_FINISH, we keep | ||
| 250 | * returning Z_STREAM_END instead of Z_BUF_ERROR. | ||
| 251 | */ | ||
| 252 | } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && | ||
| 253 | flush != Z_FINISH) { | ||
| 254 | ERR_RETURN(strm, Z_BUF_ERROR); | ||
| 255 | } | ||
| 256 | |||
| 257 | /* User must not provide more input after the first FINISH: */ | ||
| 258 | if (s->status == FINISH_STATE && strm->avail_in != 0) { | ||
| 259 | ERR_RETURN(strm, Z_BUF_ERROR); | ||
| 260 | } | ||
| 261 | |||
| 262 | /* Write the header */ | ||
| 263 | if (s->status == INIT_STATE) { | ||
| 264 | /* zlib header */ | ||
| 265 | uint16_t header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; | ||
| 266 | uint16_t level_flags; | ||
| 267 | |||
| 268 | if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) | ||
| 269 | level_flags = 0; | ||
| 270 | else if (s->level < 6) | ||
| 271 | level_flags = 1; | ||
| 272 | else if (s->level == 6) | ||
| 273 | level_flags = 2; | ||
| 274 | else | ||
| 275 | level_flags = 3; | ||
| 276 | header |= (level_flags << 6); | ||
| 277 | if (s->strstart != 0) header |= PRESET_DICT; | ||
| 278 | header += 31 - (header % 31); | ||
| 279 | |||
| 280 | putShortMSB(s, header); | ||
| 281 | |||
| 282 | /* Save the adler32 of the preset dictionary: */ | ||
| 283 | if (s->strstart != 0) { | ||
| 284 | putShortMSB(s, (uint16_t)(strm->adler >> 16)); | ||
| 285 | putShortMSB(s, (uint16_t)(strm->adler & 0xffff)); | ||
| 286 | } | ||
| 287 | strm->adler = adler32(0L, Z_NULL, 0); | ||
| 288 | s->status = BUSY_STATE; | ||
| 289 | |||
| 290 | /* Compression must start with an empty pending buffer */ | ||
| 291 | flush_pending(strm); | ||
| 292 | if (s->pending != 0) { | ||
| 293 | s->last_flush = -1; | ||
| 294 | return Z_OK; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | #ifdef GZIP | ||
| 298 | if (s->status == GZIP_STATE) { | ||
| 299 | /* gzip header */ | ||
| 300 | strm->adler = crc32(0L, Z_NULL, 0); | ||
| 301 | put_byte(s, 31); | ||
| 302 | put_byte(s, 139); | ||
| 303 | put_byte(s, 8); | ||
| 304 | if (s->gzhead == Z_NULL) { | ||
| 305 | put_byte(s, 0); | ||
| 306 | put_byte(s, 0); | ||
| 307 | put_byte(s, 0); | ||
| 308 | put_byte(s, 0); | ||
| 309 | put_byte(s, 0); | ||
| 310 | put_byte(s, s->level == 9 ? 2 : | ||
| 311 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | ||
| 312 | 4 : 0)); | ||
| 313 | put_byte(s, OS_CODE); | ||
| 314 | s->status = BUSY_STATE; | ||
| 315 | |||
| 316 | /* Compression must start with an empty pending buffer */ | ||
| 317 | flush_pending(strm); | ||
| 318 | if (s->pending != 0) { | ||
| 319 | s->last_flush = -1; | ||
| 320 | return Z_OK; | ||
| 321 | } | ||
| 322 | } | ||
| 323 | else { | ||
| 324 | put_byte(s, (s->gzhead->text ? 1 : 0) + | ||
| 325 | (s->gzhead->hcrc ? 2 : 0) + | ||
| 326 | (s->gzhead->extra == Z_NULL ? 0 : 4) + | ||
| 327 | (s->gzhead->name == Z_NULL ? 0 : 8) + | ||
| 328 | (s->gzhead->comment == Z_NULL ? 0 : 16) | ||
| 329 | ); | ||
| 330 | put_byte(s, (uint8_t)(s->gzhead->time & 0xff)); | ||
| 331 | put_byte(s, (uint8_t)((s->gzhead->time >> 8) & 0xff)); | ||
| 332 | put_byte(s, (uint8_t)((s->gzhead->time >> 16) & 0xff)); | ||
| 333 | put_byte(s, (uint8_t)((s->gzhead->time >> 24) & 0xff)); | ||
| 334 | put_byte(s, s->level == 9 ? 2 : | ||
| 335 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | ||
| 336 | 4 : 0)); | ||
| 337 | put_byte(s, s->gzhead->os & 0xff); | ||
| 338 | if (s->gzhead->extra != Z_NULL) { | ||
| 339 | put_byte(s, s->gzhead->extra_len & 0xff); | ||
| 340 | put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); | ||
| 341 | } | ||
| 342 | if (s->gzhead->hcrc) | ||
| 343 | strm->adler = crc32(strm->adler, s->pending_buf, | ||
| 344 | s->pending); | ||
| 345 | s->gzindex = 0; | ||
| 346 | s->status = EXTRA_STATE; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | if (s->status == EXTRA_STATE) { | ||
| 350 | if (s->gzhead->extra != Z_NULL) { | ||
| 351 | ulg beg = s->pending; /* start of bytes to update crc */ | ||
| 352 | uint16_t left = (s->gzhead->extra_len & 0xffff) - s->gzindex; | ||
| 353 | while (s->pending + left > s->pending_buf_size) { | ||
| 354 | uint16_t copy = s->pending_buf_size - s->pending; | ||
| 355 | zmemcpy(s->pending_buf + s->pending, | ||
| 356 | s->gzhead->extra + s->gzindex, copy); | ||
| 357 | s->pending = s->pending_buf_size; | ||
| 358 | HCRC_UPDATE(beg); | ||
| 359 | s->gzindex += copy; | ||
| 360 | flush_pending(strm); | ||
| 361 | if (s->pending != 0) { | ||
| 362 | s->last_flush = -1; | ||
| 363 | return Z_OK; | ||
| 364 | } | ||
| 365 | beg = 0; | ||
| 366 | left -= copy; | ||
| 367 | } | ||
| 368 | zmemcpy(s->pending_buf + s->pending, | ||
| 369 | s->gzhead->extra + s->gzindex, left); | ||
| 370 | s->pending += left; | ||
| 371 | HCRC_UPDATE(beg); | ||
| 372 | s->gzindex = 0; | ||
| 373 | } | ||
| 374 | s->status = NAME_STATE; | ||
| 375 | } | ||
| 376 | if (s->status == NAME_STATE) { | ||
| 377 | if (s->gzhead->name != Z_NULL) { | ||
| 378 | ulg beg = s->pending; /* start of bytes to update crc */ | ||
| 379 | int val; | ||
| 380 | do { | ||
| 381 | if (s->pending == s->pending_buf_size) { | ||
| 382 | HCRC_UPDATE(beg); | ||
| 383 | flush_pending(strm); | ||
| 384 | if (s->pending != 0) { | ||
| 385 | s->last_flush = -1; | ||
| 386 | return Z_OK; | ||
| 387 | } | ||
| 388 | beg = 0; | ||
| 389 | } | ||
| 390 | val = s->gzhead->name[s->gzindex++]; | ||
| 391 | put_byte(s, val); | ||
| 392 | } while (val != 0); | ||
| 393 | HCRC_UPDATE(beg); | ||
| 394 | s->gzindex = 0; | ||
| 395 | } | ||
| 396 | s->status = COMMENT_STATE; | ||
| 397 | } | ||
| 398 | if (s->status == COMMENT_STATE) { | ||
| 399 | if (s->gzhead->comment != Z_NULL) { | ||
| 400 | ulg beg = s->pending; /* start of bytes to update crc */ | ||
| 401 | int val; | ||
| 402 | do { | ||
| 403 | if (s->pending == s->pending_buf_size) { | ||
| 404 | HCRC_UPDATE(beg); | ||
| 405 | flush_pending(strm); | ||
| 406 | if (s->pending != 0) { | ||
| 407 | s->last_flush = -1; | ||
| 408 | return Z_OK; | ||
| 409 | } | ||
| 410 | beg = 0; | ||
| 411 | } | ||
| 412 | val = s->gzhead->comment[s->gzindex++]; | ||
| 413 | put_byte(s, val); | ||
| 414 | } while (val != 0); | ||
| 415 | HCRC_UPDATE(beg); | ||
| 416 | } | ||
| 417 | s->status = HCRC_STATE; | ||
| 418 | } | ||
| 419 | if (s->status == HCRC_STATE) { | ||
| 420 | if (s->gzhead->hcrc) { | ||
| 421 | if (s->pending + 2 > s->pending_buf_size) { | ||
| 422 | flush_pending(strm); | ||
| 423 | if (s->pending != 0) { | ||
| 424 | s->last_flush = -1; | ||
| 425 | return Z_OK; | ||
| 426 | } | ||
| 427 | } | ||
| 428 | put_byte(s, (uint8_t)(strm->adler & 0xff)); | ||
| 429 | put_byte(s, (uint8_t)((strm->adler >> 8) & 0xff)); | ||
| 430 | strm->adler = crc32(0L, Z_NULL, 0); | ||
| 431 | } | ||
| 432 | s->status = BUSY_STATE; | ||
| 433 | |||
| 434 | /* Compression must start with an empty pending buffer */ | ||
| 435 | flush_pending(strm); | ||
| 436 | if (s->pending != 0) { | ||
| 437 | s->last_flush = -1; | ||
| 438 | return Z_OK; | ||
| 439 | } | ||
| 440 | } | ||
| 441 | #endif | ||
| 442 | |||
| 443 | /* Start a new block or continue the current one. | ||
| 444 | */ | ||
| 445 | if (strm->avail_in != 0 || s->lookahead != 0 || | ||
| 446 | (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { | ||
| 447 | block_state bstate; | ||
| 448 | |||
| 449 | bstate = s->level == 0 ? deflate_stored(s, flush) : | ||
| 450 | s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : | ||
| 451 | s->strategy == Z_RLE ? deflate_rle(s, flush) : | ||
| 452 | (*(configuration_table[s->level].func))(s, flush); | ||
| 453 | |||
| 454 | if (bstate == finish_started || bstate == finish_done) { | ||
| 455 | s->status = FINISH_STATE; | ||
| 456 | } | ||
| 457 | if (bstate == need_more || bstate == finish_started) { | ||
| 458 | if (strm->avail_out == 0) { | ||
| 459 | s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ | ||
| 460 | } | ||
| 461 | return Z_OK; | ||
| 462 | /* If flush != Z_NO_FLUSH && avail_out == 0, the next call | ||
| 463 | * of deflate should use the same flush parameter to make sure | ||
| 464 | * that the flush is complete. So we don't have to output an | ||
| 465 | * empty block here, this will be done at next call. This also | ||
| 466 | * ensures that for a very small output buffer, we emit at most | ||
| 467 | * one empty block. | ||
| 468 | */ | ||
| 469 | } | ||
| 470 | if (bstate == block_done) { | ||
| 471 | if (flush == Z_PARTIAL_FLUSH) { | ||
| 472 | _tr_align(s); | ||
| 473 | } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ | ||
| 474 | _tr_stored_block(s, (char*)0, 0L, 0); | ||
| 475 | /* For a full flush, this empty block will be recognized | ||
| 476 | * as a special marker by inflate_sync(). | ||
| 477 | */ | ||
| 478 | if (flush == Z_FULL_FLUSH) { | ||
| 479 | CLEAR_HASH(s); /* forget history */ | ||
| 480 | if (s->lookahead == 0) { | ||
| 481 | s->strstart = 0; | ||
| 482 | s->block_start = 0L; | ||
| 483 | s->insert = 0; | ||
| 484 | } | ||
| 485 | } | ||
| 486 | } | ||
| 487 | flush_pending(strm); | ||
| 488 | if (strm->avail_out == 0) { | ||
| 489 | s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ | ||
| 490 | return Z_OK; | ||
| 491 | } | ||
| 492 | } | ||
| 493 | } | ||
| 494 | |||
| 495 | if (flush != Z_FINISH) return Z_OK; | ||
| 496 | if (s->wrap <= 0) return Z_STREAM_END; | ||
| 497 | |||
| 498 | /* Write the trailer */ | ||
| 499 | #ifdef GZIP | ||
| 500 | if (s->wrap == 2) { | ||
| 501 | put_byte(s, (uint8_t)(strm->adler & 0xff)); | ||
| 502 | put_byte(s, (uint8_t)((strm->adler >> 8) & 0xff)); | ||
| 503 | put_byte(s, (uint8_t)((strm->adler >> 16) & 0xff)); | ||
| 504 | put_byte(s, (uint8_t)((strm->adler >> 24) & 0xff)); | ||
| 505 | put_byte(s, (uint8_t)(strm->total_in & 0xff)); | ||
| 506 | put_byte(s, (uint8_t)((strm->total_in >> 8) & 0xff)); | ||
| 507 | put_byte(s, (uint8_t)((strm->total_in >> 16) & 0xff)); | ||
| 508 | put_byte(s, (uint8_t)((strm->total_in >> 24) & 0xff)); | ||
| 509 | } | ||
| 510 | else | ||
| 511 | #endif | ||
| 512 | { | ||
| 513 | putShortMSB(s, (uint16_t)(strm->adler >> 16)); | ||
| 514 | putShortMSB(s, (uint16_t)(strm->adler & 0xffff)); | ||
| 515 | } | ||
| 516 | flush_pending(strm); | ||
| 517 | /* If avail_out is zero, the application will call deflate again | ||
| 518 | * to flush the rest. | ||
| 519 | */ | ||
| 520 | if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ | ||
| 521 | return s->pending != 0 ? Z_OK : Z_STREAM_END; | ||
| 522 | } | ||
std/zlib/inflate.zig created+969| ... | @@ -0,0 +1,969 @@ | ||
| 1 | |||
| 2 | error Z_STREAM_ERROR; | ||
| 3 | error Z_STREAM_END; | ||
| 4 | error Z_NEED_DICT; | ||
| 5 | error Z_ERRNO; | ||
| 6 | error Z_STREAM_ERROR; | ||
| 7 | error Z_DATA_ERROR; | ||
| 8 | error Z_MEM_ERROR; | ||
| 9 | error Z_BUF_ERROR; | ||
| 10 | error Z_VERSION_ERROR; | ||
| 11 | |||
| 12 | pub Flush = enum { | ||
| 13 | NO_FLUSH, | ||
| 14 | PARTIAL_FLUSH, | ||
| 15 | SYNC_FLUSH, | ||
| 16 | FULL_FLUSH, | ||
| 17 | FINISH, | ||
| 18 | BLOCK, | ||
| 19 | TREES, | ||
| 20 | }; | ||
| 21 | |||
| 22 | const code = struct { | ||
| 23 | /// operation, extra bits, table bits | ||
| 24 | op: u8, | ||
| 25 | /// bits in this part of the code | ||
| 26 | bits: u8, | ||
| 27 | /// offset in table or code value | ||
| 28 | val: u16, | ||
| 29 | }; | ||
| 30 | |||
| 31 | /// State maintained between inflate() calls -- approximately 7K bytes, not | ||
| 32 | /// including the allocated sliding window, which is up to 32K bytes. | ||
| 33 | const inflate_state = struct { | ||
| 34 | z_stream * strm; /* pointer back to this zlib stream */ | ||
| 35 | inflate_mode mode; /* current inflate mode */ | ||
| 36 | int last; /* true if processing last block */ | ||
| 37 | int wrap; /* bit 0 true for zlib, bit 1 true for gzip, | ||
| 38 | bit 2 true to validate check value */ | ||
| 39 | int havedict; /* true if dictionary provided */ | ||
| 40 | int flags; /* gzip header method and flags (0 if zlib) */ | ||
| 41 | unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ | ||
| 42 | unsigned long check; /* protected copy of check value */ | ||
| 43 | unsigned long total; /* protected copy of output count */ | ||
| 44 | gz_headerp head; /* where to save gzip header information */ | ||
| 45 | /* sliding window */ | ||
| 46 | unsigned wbits; /* log base 2 of requested window size */ | ||
| 47 | unsigned wsize; /* window size or zero if not using window */ | ||
| 48 | unsigned whave; /* valid bytes in the window */ | ||
| 49 | unsigned wnext; /* window write index */ | ||
| 50 | u8 FAR *window; /* allocated sliding window, if needed */ | ||
| 51 | /* bit accumulator */ | ||
| 52 | unsigned long hold; /* input bit accumulator */ | ||
| 53 | unsigned bits; /* number of bits in "in" */ | ||
| 54 | /* for string and stored block copying */ | ||
| 55 | unsigned length; /* literal or length of data to copy */ | ||
| 56 | unsigned offset; /* distance back to copy string from */ | ||
| 57 | /* for table and code decoding */ | ||
| 58 | unsigned extra; /* extra bits needed */ | ||
| 59 | /* fixed and dynamic code tables */ | ||
| 60 | code const FAR *lencode; /* starting table for length/literal codes */ | ||
| 61 | code const FAR *distcode; /* starting table for distance codes */ | ||
| 62 | unsigned lenbits; /* index bits for lencode */ | ||
| 63 | unsigned distbits; /* index bits for distcode */ | ||
| 64 | /* dynamic table building */ | ||
| 65 | unsigned ncode; /* number of code length code lengths */ | ||
| 66 | unsigned nlen; /* number of length code lengths */ | ||
| 67 | unsigned ndist; /* number of distance code lengths */ | ||
| 68 | unsigned have; /* number of code lengths in lens[] */ | ||
| 69 | code FAR *next; /* next available space in codes[] */ | ||
| 70 | unsigned short lens[320]; /* temporary storage for code lengths */ | ||
| 71 | unsigned short work[288]; /* work area for code table building */ | ||
| 72 | code codes[ENOUGH]; /* space for code tables */ | ||
| 73 | int sane; /* if false, allow invalid distance too far */ | ||
| 74 | int back; /* bits back of last unprocessed length/lit */ | ||
| 75 | unsigned was; /* initial length of match */ | ||
| 76 | }; | ||
| 77 | |||
| 78 | const alloc_func = fn(opaque: &c_void, items: u16, size: u16); | ||
| 79 | const free_func = fn(opaque: &c_void, address: &c_void); | ||
| 80 | |||
| 81 | const z_stream = struct { | ||
| 82 | /// next input byte | ||
| 83 | next_in: &u8, | ||
| 84 | /// number of bytes available at next_in | ||
| 85 | avail_in: u16, | ||
| 86 | /// total number of input bytes read so far | ||
| 87 | total_in: u32, | ||
| 88 | |||
| 89 | /// next output byte will go here | ||
| 90 | next_out: &u8, | ||
| 91 | /// remaining free space at next_out | ||
| 92 | avail_out: u16, | ||
| 93 | /// total number of bytes output so far */ | ||
| 94 | total_out: u32, | ||
| 95 | |||
| 96 | /// last error message, NULL if no error | ||
| 97 | msg: &const u8, | ||
| 98 | /// not visible by applications | ||
| 99 | state: &inflate_state, | ||
| 100 | |||
| 101 | /// used to allocate the internal state | ||
| 102 | zalloc: alloc_func, | ||
| 103 | /// used to free the internal state | ||
| 104 | zfree: free_func, | ||
| 105 | /// private data object passed to zalloc and zfree | ||
| 106 | opaque: &c_void, | ||
| 107 | |||
| 108 | /// best guess about the data type: binary or text | ||
| 109 | /// for deflate, or the decoding state for inflate | ||
| 110 | data_type: i32, | ||
| 111 | |||
| 112 | /// Adler-32 or CRC-32 value of the uncompressed data | ||
| 113 | adler: u32, | ||
| 114 | }; | ||
| 115 | |||
| 116 | // Possible inflate modes between inflate() calls | ||
| 117 | /// i: waiting for magic header | ||
| 118 | pub const HEAD = 16180; | ||
| 119 | /// i: waiting for method and flags (gzip) | ||
| 120 | pub const FLAGS = 16181; | ||
| 121 | /// i: waiting for modification time (gzip) | ||
| 122 | pub const TIME = 16182; | ||
| 123 | /// i: waiting for extra flags and operating system (gzip) | ||
| 124 | pub const OS = 16183; | ||
| 125 | /// i: waiting for extra length (gzip) | ||
| 126 | pub const EXLEN = 16184; | ||
| 127 | /// i: waiting for extra bytes (gzip) | ||
| 128 | pub const EXTRA = 16185; | ||
| 129 | /// i: waiting for end of file name (gzip) | ||
| 130 | pub const NAME = 16186; | ||
| 131 | /// i: waiting for end of comment (gzip) | ||
| 132 | pub const COMMENT = 16187; | ||
| 133 | /// i: waiting for header crc (gzip) | ||
| 134 | pub const HCRC = 16188; | ||
| 135 | /// i: waiting for dictionary check value | ||
| 136 | pub const DICTID = 16189; | ||
| 137 | /// waiting for inflateSetDictionary() call | ||
| 138 | pub const DICT = 16190; | ||
| 139 | /// i: waiting for type bits, including last-flag bit | ||
| 140 | pub const TYPE = 16191; | ||
| 141 | /// i: same, but skip check to exit inflate on new block | ||
| 142 | pub const TYPEDO = 16192; | ||
| 143 | /// i: waiting for stored size (length and complement) | ||
| 144 | pub const STORED = 16193; | ||
| 145 | /// i/o: same as COPY below, but only first time in | ||
| 146 | pub const COPY_ = 16194; | ||
| 147 | /// i/o: waiting for input or output to copy stored block | ||
| 148 | pub const COPY = 16195; | ||
| 149 | /// i: waiting for dynamic block table lengths | ||
| 150 | pub const TABLE = 16196; | ||
| 151 | /// i: waiting for code length code lengths | ||
| 152 | pub const LENLENS = 16197; | ||
| 153 | /// i: waiting for length/lit and distance code lengths | ||
| 154 | pub const CODELENS = 16198; | ||
| 155 | /// i: same as LEN below, but only first time in | ||
| 156 | pub const LEN_ = 16199; | ||
| 157 | /// i: waiting for length/lit/eob code | ||
| 158 | pub const LEN = 16200; | ||
| 159 | /// i: waiting for length extra bits | ||
| 160 | pub const LENEXT = 16201; | ||
| 161 | /// i: waiting for distance code | ||
| 162 | pub const DIST = 16202; | ||
| 163 | /// i: waiting for distance extra bits | ||
| 164 | pub const DISTEXT = 16203; | ||
| 165 | /// o: waiting for output space to copy string | ||
| 166 | pub const MATCH = 16204; | ||
| 167 | /// o: waiting for output space to write literal | ||
| 168 | pub const LIT = 16205; | ||
| 169 | /// i: waiting for 32-bit check value | ||
| 170 | pub const CHECK = 16206; | ||
| 171 | /// i: waiting for 32-bit length (gzip) | ||
| 172 | pub const LENGTH = 16207; | ||
| 173 | /// finished check, done -- remain here until reset | ||
| 174 | pub const DONE = 16208; | ||
| 175 | /// got a data error -- remain here until reset | ||
| 176 | pub const BAD = 16209; | ||
| 177 | /// got an inflate() memory error -- remain here until reset | ||
| 178 | pub const MEM = 16210; | ||
| 179 | /// looking for synchronization bytes to restart inflate() */ | ||
| 180 | pub const SYNC = 16211; | ||
| 181 | |||
| 182 | /// inflate() uses a state machine to process as much input data and generate as | ||
| 183 | /// much output data as possible before returning. The state machine is | ||
| 184 | /// structured roughly as follows: | ||
| 185 | /// | ||
| 186 | /// for (;;) switch (state) { | ||
| 187 | /// ... | ||
| 188 | /// case STATEn: | ||
| 189 | /// if (not enough input data or output space to make progress) | ||
| 190 | /// return; | ||
| 191 | /// ... make progress ... | ||
| 192 | /// state = STATEm; | ||
| 193 | /// break; | ||
| 194 | /// ... | ||
| 195 | /// } | ||
| 196 | /// | ||
| 197 | /// so when inflate() is called again, the same case is attempted again, and | ||
| 198 | /// if the appropriate resources are provided, the machine proceeds to the | ||
| 199 | /// next state. The NEEDBITS() macro is usually the way the state evaluates | ||
| 200 | /// whether it can proceed or should return. NEEDBITS() does the return if | ||
| 201 | /// the requested bits are not available. The typical use of the BITS macros | ||
| 202 | /// is: | ||
| 203 | /// | ||
| 204 | /// NEEDBITS(n); | ||
| 205 | /// ... do something with BITS(n) ... | ||
| 206 | /// DROPBITS(n); | ||
| 207 | /// | ||
| 208 | /// where NEEDBITS(n) either returns from inflate() if there isn't enough | ||
| 209 | /// input left to load n bits into the accumulator, or it continues. BITS(n) | ||
| 210 | /// gives the low n bits in the accumulator. When done, DROPBITS(n) drops | ||
| 211 | /// the low n bits off the accumulator. INITBITS() clears the accumulator | ||
| 212 | /// and sets the number of available bits to zero. BYTEBITS() discards just | ||
| 213 | /// enough bits to put the accumulator on a byte boundary. After BYTEBITS() | ||
| 214 | /// and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. | ||
| 215 | /// | ||
| 216 | /// NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return | ||
| 217 | /// if there is no input available. The decoding of variable length codes uses | ||
| 218 | /// PULLBYTE() directly in order to pull just enough bytes to decode the next | ||
| 219 | /// code, and no more. | ||
| 220 | /// | ||
| 221 | /// Some states loop until they get enough input, making sure that enough | ||
| 222 | /// state information is maintained to continue the loop where it left off | ||
| 223 | /// if NEEDBITS() returns in the loop. For example, want, need, and keep | ||
| 224 | /// would all have to actually be part of the saved state in case NEEDBITS() | ||
| 225 | /// returns: | ||
| 226 | /// | ||
| 227 | /// case STATEw: | ||
| 228 | /// while (want < need) { | ||
| 229 | /// NEEDBITS(n); | ||
| 230 | /// keep[want++] = BITS(n); | ||
| 231 | /// DROPBITS(n); | ||
| 232 | /// } | ||
| 233 | /// state = STATEx; | ||
| 234 | /// case STATEx: | ||
| 235 | /// | ||
| 236 | /// As shown above, if the next state is also the next case, then the break | ||
| 237 | /// is omitted. | ||
| 238 | /// | ||
| 239 | /// A state may also return if there is not enough output space available to | ||
| 240 | /// complete that state. Those states are copying stored data, writing a | ||
| 241 | /// literal byte, and copying a matching string. | ||
| 242 | /// | ||
| 243 | /// When returning, a "goto inf_leave" is used to update the total counters, | ||
| 244 | /// update the check value, and determine whether any progress has been made | ||
| 245 | /// during that inflate() call in order to return the proper return code. | ||
| 246 | /// Progress is defined as a change in either strm->avail_in or strm->avail_out. | ||
| 247 | /// When there is a window, goto inf_leave will update the window with the last | ||
| 248 | /// output written. If a goto inf_leave occurs in the middle of decompression | ||
| 249 | /// and there is no window currently, goto inf_leave will create one and copy | ||
| 250 | /// output to the window for the next call of inflate(). | ||
| 251 | /// | ||
| 252 | /// In this implementation, the flush parameter of inflate() only affects the | ||
| 253 | /// return code (per zlib.h). inflate() always writes as much as possible to | ||
| 254 | /// strm->next_out, given the space available and the provided input--the effect | ||
| 255 | /// documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers | ||
| 256 | /// the allocation of and copying into a sliding window until necessary, which | ||
| 257 | /// provides the effect documented in zlib.h for Z_FINISH when the entire input | ||
| 258 | /// stream available. So the only thing the flush parameter actually does is: | ||
| 259 | /// when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it | ||
| 260 | /// will return Z_BUF_ERROR if it has not reached the end of the stream. | ||
| 261 | pub fn inflate(strm: &z_stream, flush: Flush, gunzip: bool) -> %void { | ||
| 262 | // next input | ||
| 263 | var next: &const u8 = undefined; | ||
| 264 | // next output | ||
| 265 | var put: &u8 = undefined; | ||
| 266 | |||
| 267 | // available input and output | ||
| 268 | var have: u16 = undefined; | ||
| 269 | var left: u16 = undefined; | ||
| 270 | |||
| 271 | // bit buffer | ||
| 272 | var hold: u32 = undefined; | ||
| 273 | // bits in bit buffer | ||
| 274 | var bits: u16 = undefined; | ||
| 275 | // save starting available input and output | ||
| 276 | var in: u16 = undefined; | ||
| 277 | var out: u16 = undefined; | ||
| 278 | // number of stored or match bytes to copy | ||
| 279 | var copy: u16 = undefined; | ||
| 280 | // where to copy match bytes from | ||
| 281 | var from: &u8 = undefined; | ||
| 282 | // current decoding table entry | ||
| 283 | var here: code = undefined; | ||
| 284 | // parent table entry | ||
| 285 | var last: code = undefined; | ||
| 286 | // length to copy for repeats, bits to drop | ||
| 287 | var len: u16 = undefined; | ||
| 288 | |||
| 289 | // return code | ||
| 290 | var ret: error = undefined; | ||
| 291 | |||
| 292 | // buffer for gzip header crc calculation | ||
| 293 | var hbuf: [4]u8 = undefined; | ||
| 294 | |||
| 295 | // permutation of code lengths | ||
| 296 | const short_order = []u16 = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; | ||
| 297 | |||
| 298 | if (inflateStateCheck(strm) or strm.next_out == Z_NULL or (strm.next_in == Z_NULL and strm.avail_in != 0)) { | ||
| 299 | return error.Z_STREAM_ERROR; | ||
| 300 | } | ||
| 301 | |||
| 302 | var state: &inflate_state = strm.state; | ||
| 303 | if (state.mode == TYPE) { | ||
| 304 | state.mode = TYPEDO; // skip check | ||
| 305 | } | ||
| 306 | put = strm.next_out; \ | ||
| 307 | left = strm.avail_out; \ | ||
| 308 | next = strm.next_in; \ | ||
| 309 | have = strm.avail_in; \ | ||
| 310 | hold = state.hold; \ | ||
| 311 | bits = state.bits; \ | ||
| 312 | in = have; | ||
| 313 | out = left; | ||
| 314 | ret = Z_OK; | ||
| 315 | for (;;) | ||
| 316 | switch (state.mode) { | ||
| 317 | case HEAD: | ||
| 318 | if (state.wrap == 0) { | ||
| 319 | state.mode = TYPEDO; | ||
| 320 | break; | ||
| 321 | } | ||
| 322 | NEEDBITS(16); | ||
| 323 | #ifdef GUNZIP | ||
| 324 | if ((state.wrap & 2) && hold == 0x8b1f) { /* gzip header */ | ||
| 325 | if (state.wbits == 0) | ||
| 326 | state.wbits = 15; | ||
| 327 | state.check = crc32(0L, Z_NULL, 0); | ||
| 328 | CRC2(state.check, hold); | ||
| 329 | INITBITS(); | ||
| 330 | state.mode = FLAGS; | ||
| 331 | break; | ||
| 332 | } | ||
| 333 | state.flags = 0; /* expect zlib header */ | ||
| 334 | if (state.head != Z_NULL) | ||
| 335 | state.head.done = -1; | ||
| 336 | if (!(state.wrap & 1) || /* check if zlib header allowed */ | ||
| 337 | #else | ||
| 338 | if ( | ||
| 339 | #endif | ||
| 340 | ((BITS(8) << 8) + (hold >> 8)) % 31) { | ||
| 341 | strm.msg = (char *)"incorrect header check"; | ||
| 342 | state.mode = BAD; | ||
| 343 | break; | ||
| 344 | } | ||
| 345 | if (BITS(4) != Z_DEFLATED) { | ||
| 346 | strm.msg = (char *)"unknown compression method"; | ||
| 347 | state.mode = BAD; | ||
| 348 | break; | ||
| 349 | } | ||
| 350 | DROPBITS(4); | ||
| 351 | len = BITS(4) + 8; | ||
| 352 | if (state.wbits == 0) | ||
| 353 | state.wbits = len; | ||
| 354 | if (len > 15 || len > state.wbits) { | ||
| 355 | strm.msg = (char *)"invalid window size"; | ||
| 356 | state.mode = BAD; | ||
| 357 | break; | ||
| 358 | } | ||
| 359 | state.dmax = 1U << len; | ||
| 360 | Tracev((stderr, "inflate: zlib header ok\n")); | ||
| 361 | strm.adler = state.check = adler32(0L, Z_NULL, 0); | ||
| 362 | state.mode = hold & 0x200 ? DICTID : TYPE; | ||
| 363 | INITBITS(); | ||
| 364 | break; | ||
| 365 | #ifdef GUNZIP | ||
| 366 | case FLAGS: | ||
| 367 | NEEDBITS(16); | ||
| 368 | state.flags = (int)(hold); | ||
| 369 | if ((state.flags & 0xff) != Z_DEFLATED) { | ||
| 370 | strm.msg = (char *)"unknown compression method"; | ||
| 371 | state.mode = BAD; | ||
| 372 | break; | ||
| 373 | } | ||
| 374 | if (state.flags & 0xe000) { | ||
| 375 | strm.msg = (char *)"unknown header flags set"; | ||
| 376 | state.mode = BAD; | ||
| 377 | break; | ||
| 378 | } | ||
| 379 | if (state.head != Z_NULL) | ||
| 380 | state.head.text = (int)((hold >> 8) & 1); | ||
| 381 | if ((state.flags & 0x0200) && (state.wrap & 4)) | ||
| 382 | CRC2(state.check, hold); | ||
| 383 | INITBITS(); | ||
| 384 | state.mode = TIME; | ||
| 385 | case TIME: | ||
| 386 | NEEDBITS(32); | ||
| 387 | if (state.head != Z_NULL) | ||
| 388 | state.head.time = hold; | ||
| 389 | if ((state.flags & 0x0200) && (state.wrap & 4)) | ||
| 390 | CRC4(state.check, hold); | ||
| 391 | INITBITS(); | ||
| 392 | state.mode = OS; | ||
| 393 | case OS: | ||
| 394 | NEEDBITS(16); | ||
| 395 | if (state.head != Z_NULL) { | ||
| 396 | state.head.xflags = (int)(hold & 0xff); | ||
| 397 | state.head.os = (int)(hold >> 8); | ||
| 398 | } | ||
| 399 | if ((state.flags & 0x0200) && (state.wrap & 4)) | ||
| 400 | CRC2(state.check, hold); | ||
| 401 | INITBITS(); | ||
| 402 | state.mode = EXLEN; | ||
| 403 | case EXLEN: | ||
| 404 | if (state.flags & 0x0400) { | ||
| 405 | NEEDBITS(16); | ||
| 406 | state.length = (unsigned)(hold); | ||
| 407 | if (state.head != Z_NULL) | ||
| 408 | state.head.extra_len = (unsigned)hold; | ||
| 409 | if ((state.flags & 0x0200) && (state.wrap & 4)) | ||
| 410 | CRC2(state.check, hold); | ||
| 411 | INITBITS(); | ||
| 412 | } | ||
| 413 | else if (state.head != Z_NULL) | ||
| 414 | state.head.extra = Z_NULL; | ||
| 415 | state.mode = EXTRA; | ||
| 416 | case EXTRA: | ||
| 417 | if (state.flags & 0x0400) { | ||
| 418 | copy = state.length; | ||
| 419 | if (copy > have) copy = have; | ||
| 420 | if (copy) { | ||
| 421 | if (state.head != Z_NULL && | ||
| 422 | state.head.extra != Z_NULL) { | ||
| 423 | len = state.head.extra_len - state.length; | ||
| 424 | zmemcpy(state.head.extra + len, next, | ||
| 425 | len + copy > state.head.extra_max ? | ||
| 426 | state.head.extra_max - len : copy); | ||
| 427 | } | ||
| 428 | if ((state.flags & 0x0200) && (state.wrap & 4)) | ||
| 429 | state.check = crc32(state.check, next, copy); | ||
| 430 | have -= copy; | ||
| 431 | next += copy; | ||
| 432 | state.length -= copy; | ||
| 433 | } | ||
| 434 | if (state.length) goto inf_leave; | ||
| 435 | } | ||
| 436 | state.length = 0; | ||
| 437 | state.mode = NAME; | ||
| 438 | case NAME: | ||
| 439 | if (state.flags & 0x0800) { | ||
| 440 | if (have == 0) goto inf_leave; | ||
| 441 | copy = 0; | ||
| 442 | do { | ||
| 443 | len = (unsigned)(next[copy++]); | ||
| 444 | if (state.head != Z_NULL && | ||
| 445 | state.head.name != Z_NULL && | ||
| 446 | state.length < state.head.name_max) | ||
| 447 | state.head.name[state.length++] = (Bytef)len; | ||
| 448 | } while (len && copy < have); | ||
| 449 | if ((state.flags & 0x0200) && (state.wrap & 4)) | ||
| 450 | state.check = crc32(state.check, next, copy); | ||
| 451 | have -= copy; | ||
| 452 | next += copy; | ||
| 453 | if (len) goto inf_leave; | ||
| 454 | } | ||
| 455 | else if (state.head != Z_NULL) | ||
| 456 | state.head.name = Z_NULL; | ||
| 457 | state.length = 0; | ||
| 458 | state.mode = COMMENT; | ||
| 459 | case COMMENT: | ||
| 460 | if (state.flags & 0x1000) { | ||
| 461 | if (have == 0) goto inf_leave; | ||
| 462 | copy = 0; | ||
| 463 | do { | ||
| 464 | len = (unsigned)(next[copy++]); | ||
| 465 | if (state.head != Z_NULL && | ||
| 466 | state.head.comment != Z_NULL && | ||
| 467 | state.length < state.head.comm_max) | ||
| 468 | state.head.comment[state.length++] = (Bytef)len; | ||
| 469 | } while (len && copy < have); | ||
| 470 | if ((state.flags & 0x0200) && (state.wrap & 4)) | ||
| 471 | state.check = crc32(state.check, next, copy); | ||
| 472 | have -= copy; | ||
| 473 | next += copy; | ||
| 474 | if (len) goto inf_leave; | ||
| 475 | } | ||
| 476 | else if (state.head != Z_NULL) | ||
| 477 | state.head.comment = Z_NULL; | ||
| 478 | state.mode = HCRC; | ||
| 479 | case HCRC: | ||
| 480 | if (state.flags & 0x0200) { | ||
| 481 | NEEDBITS(16); | ||
| 482 | if ((state.wrap & 4) && hold != (state.check & 0xffff)) { | ||
| 483 | strm.msg = (char *)"header crc mismatch"; | ||
| 484 | state.mode = BAD; | ||
| 485 | break; | ||
| 486 | } | ||
| 487 | INITBITS(); | ||
| 488 | } | ||
| 489 | if (state.head != Z_NULL) { | ||
| 490 | state.head.hcrc = (int)((state.flags >> 9) & 1); | ||
| 491 | state.head.done = 1; | ||
| 492 | } | ||
| 493 | strm.adler = state.check = crc32(0L, Z_NULL, 0); | ||
| 494 | state.mode = TYPE; | ||
| 495 | break; | ||
| 496 | #endif | ||
| 497 | case DICTID: | ||
| 498 | NEEDBITS(32); | ||
| 499 | strm.adler = state.check = ZSWAP32(hold); | ||
| 500 | INITBITS(); | ||
| 501 | state.mode = DICT; | ||
| 502 | case DICT: | ||
| 503 | if (state.havedict == 0) { | ||
| 504 | strm.next_out = put; \ | ||
| 505 | strm.avail_out = left; \ | ||
| 506 | strm.next_in = next; \ | ||
| 507 | strm.avail_in = have; \ | ||
| 508 | state.hold = hold; \ | ||
| 509 | state.bits = bits; \ | ||
| 510 | return Z_NEED_DICT; | ||
| 511 | } | ||
| 512 | strm.adler = state.check = adler32(0L, Z_NULL, 0); | ||
| 513 | state.mode = TYPE; | ||
| 514 | case TYPE: | ||
| 515 | if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; | ||
| 516 | case TYPEDO: | ||
| 517 | if (state.last) { | ||
| 518 | BYTEBITS(); | ||
| 519 | state.mode = CHECK; | ||
| 520 | break; | ||
| 521 | } | ||
| 522 | NEEDBITS(3); | ||
| 523 | state.last = BITS(1); | ||
| 524 | DROPBITS(1); | ||
| 525 | switch (BITS(2)) { | ||
| 526 | case 0: /* stored block */ | ||
| 527 | Tracev((stderr, "inflate: stored block%s\n", | ||
| 528 | state.last ? " (last)" : "")); | ||
| 529 | state.mode = STORED; | ||
| 530 | break; | ||
| 531 | case 1: /* fixed block */ | ||
| 532 | fixedtables(state); | ||
| 533 | Tracev((stderr, "inflate: fixed codes block%s\n", | ||
| 534 | state.last ? " (last)" : "")); | ||
| 535 | state.mode = LEN_; /* decode codes */ | ||
| 536 | if (flush == Z_TREES) { | ||
| 537 | DROPBITS(2); | ||
| 538 | goto inf_leave; | ||
| 539 | } | ||
| 540 | break; | ||
| 541 | case 2: /* dynamic block */ | ||
| 542 | Tracev((stderr, "inflate: dynamic codes block%s\n", | ||
| 543 | state.last ? " (last)" : "")); | ||
| 544 | state.mode = TABLE; | ||
| 545 | break; | ||
| 546 | case 3: | ||
| 547 | strm.msg = (char *)"invalid block type"; | ||
| 548 | state.mode = BAD; | ||
| 549 | } | ||
| 550 | DROPBITS(2); | ||
| 551 | break; | ||
| 552 | case STORED: | ||
| 553 | BYTEBITS(); /* go to byte boundary */ | ||
| 554 | NEEDBITS(32); | ||
| 555 | if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { | ||
| 556 | strm.msg = (char *)"invalid stored block lengths"; | ||
| 557 | state.mode = BAD; | ||
| 558 | break; | ||
| 559 | } | ||
| 560 | state.length = (unsigned)hold & 0xffff; | ||
| 561 | Tracev((stderr, "inflate: stored length %u\n", | ||
| 562 | state.length)); | ||
| 563 | INITBITS(); | ||
| 564 | state.mode = COPY_; | ||
| 565 | if (flush == Z_TREES) goto inf_leave; | ||
| 566 | case COPY_: | ||
| 567 | state.mode = COPY; | ||
| 568 | case COPY: | ||
| 569 | copy = state.length; | ||
| 570 | if (copy) { | ||
| 571 | if (copy > have) copy = have; | ||
| 572 | if (copy > left) copy = left; | ||
| 573 | if (copy == 0) goto inf_leave; | ||
| 574 | zmemcpy(put, next, copy); | ||
| 575 | have -= copy; | ||
| 576 | next += copy; | ||
| 577 | left -= copy; | ||
| 578 | put += copy; | ||
| 579 | state.length -= copy; | ||
| 580 | break; | ||
| 581 | } | ||
| 582 | Tracev((stderr, "inflate: stored end\n")); | ||
| 583 | state.mode = TYPE; | ||
| 584 | break; | ||
| 585 | case TABLE: | ||
| 586 | NEEDBITS(14); | ||
| 587 | state.nlen = BITS(5) + 257; | ||
| 588 | DROPBITS(5); | ||
| 589 | state.ndist = BITS(5) + 1; | ||
| 590 | DROPBITS(5); | ||
| 591 | state.ncode = BITS(4) + 4; | ||
| 592 | DROPBITS(4); | ||
| 593 | #ifndef PKZIP_BUG_WORKAROUND | ||
| 594 | if (state.nlen > 286 || state.ndist > 30) { | ||
| 595 | strm.msg = (char *)"too many length or distance symbols"; | ||
| 596 | state.mode = BAD; | ||
| 597 | break; | ||
| 598 | } | ||
| 599 | #endif | ||
| 600 | Tracev((stderr, "inflate: table sizes ok\n")); | ||
| 601 | state.have = 0; | ||
| 602 | state.mode = LENLENS; | ||
| 603 | case LENLENS: | ||
| 604 | while (state.have < state.ncode) { | ||
| 605 | NEEDBITS(3); | ||
| 606 | state.lens[order[state.have++]] = (unsigned short)BITS(3); | ||
| 607 | DROPBITS(3); | ||
| 608 | } | ||
| 609 | while (state.have < 19) | ||
| 610 | state.lens[order[state.have++]] = 0; | ||
| 611 | state.next = state.codes; | ||
| 612 | state.lencode = (const code FAR *)(state.next); | ||
| 613 | state.lenbits = 7; | ||
| 614 | ret = inflate_table(CODES, state.lens, 19, &(state.next), | ||
| 615 | &(state.lenbits), state.work); | ||
| 616 | if (ret) { | ||
| 617 | strm.msg = (char *)"invalid code lengths set"; | ||
| 618 | state.mode = BAD; | ||
| 619 | break; | ||
| 620 | } | ||
| 621 | Tracev((stderr, "inflate: code lengths ok\n")); | ||
| 622 | state.have = 0; | ||
| 623 | state.mode = CODELENS; | ||
| 624 | case CODELENS: | ||
| 625 | while (state.have < state.nlen + state.ndist) { | ||
| 626 | for (;;) { | ||
| 627 | here = state.lencode[BITS(state.lenbits)]; | ||
| 628 | if ((unsigned)(here.bits) <= bits) break; | ||
| 629 | PULLBYTE(); | ||
| 630 | } | ||
| 631 | if (here.val < 16) { | ||
| 632 | DROPBITS(here.bits); | ||
| 633 | state.lens[state.have++] = here.val; | ||
| 634 | } | ||
| 635 | else { | ||
| 636 | if (here.val == 16) { | ||
| 637 | NEEDBITS(here.bits + 2); | ||
| 638 | DROPBITS(here.bits); | ||
| 639 | if (state.have == 0) { | ||
| 640 | strm.msg = (char *)"invalid bit length repeat"; | ||
| 641 | state.mode = BAD; | ||
| 642 | break; | ||
| 643 | } | ||
| 644 | len = state.lens[state.have - 1]; | ||
| 645 | copy = 3 + BITS(2); | ||
| 646 | DROPBITS(2); | ||
| 647 | } | ||
| 648 | else if (here.val == 17) { | ||
| 649 | NEEDBITS(here.bits + 3); | ||
| 650 | DROPBITS(here.bits); | ||
| 651 | len = 0; | ||
| 652 | copy = 3 + BITS(3); | ||
| 653 | DROPBITS(3); | ||
| 654 | } | ||
| 655 | else { | ||
| 656 | NEEDBITS(here.bits + 7); | ||
| 657 | DROPBITS(here.bits); | ||
| 658 | len = 0; | ||
| 659 | copy = 11 + BITS(7); | ||
| 660 | DROPBITS(7); | ||
| 661 | } | ||
| 662 | if (state.have + copy > state.nlen + state.ndist) { | ||
| 663 | strm.msg = (char *)"invalid bit length repeat"; | ||
| 664 | state.mode = BAD; | ||
| 665 | break; | ||
| 666 | } | ||
| 667 | while (copy--) | ||
| 668 | state.lens[state.have++] = (unsigned short)len; | ||
| 669 | } | ||
| 670 | } | ||
| 671 | |||
| 672 | /* handle error breaks in while */ | ||
| 673 | if (state.mode == BAD) break; | ||
| 674 | |||
| 675 | /* check for end-of-block code (better have one) */ | ||
| 676 | if (state.lens[256] == 0) { | ||
| 677 | strm.msg = (char *)"invalid code -- missing end-of-block"; | ||
| 678 | state.mode = BAD; | ||
| 679 | break; | ||
| 680 | } | ||
| 681 | |||
| 682 | /* build code tables -- note: do not change the lenbits or distbits | ||
| 683 | values here (9 and 6) without reading the comments in inftrees.h | ||
| 684 | concerning the ENOUGH constants, which depend on those values */ | ||
| 685 | state.next = state.codes; | ||
| 686 | state.lencode = (const code FAR *)(state.next); | ||
| 687 | state.lenbits = 9; | ||
| 688 | ret = inflate_table(LENS, state.lens, state.nlen, &(state.next), | ||
| 689 | &(state.lenbits), state.work); | ||
| 690 | if (ret) { | ||
| 691 | strm.msg = (char *)"invalid literal/lengths set"; | ||
| 692 | state.mode = BAD; | ||
| 693 | break; | ||
| 694 | } | ||
| 695 | state.distcode = (const code FAR *)(state.next); | ||
| 696 | state.distbits = 6; | ||
| 697 | ret = inflate_table(DISTS, state.lens + state.nlen, state.ndist, | ||
| 698 | &(state.next), &(state.distbits), state.work); | ||
| 699 | if (ret) { | ||
| 700 | strm.msg = (char *)"invalid distances set"; | ||
| 701 | state.mode = BAD; | ||
| 702 | break; | ||
| 703 | } | ||
| 704 | Tracev((stderr, "inflate: codes ok\n")); | ||
| 705 | state.mode = LEN_; | ||
| 706 | if (flush == Z_TREES) goto inf_leave; | ||
| 707 | case LEN_: | ||
| 708 | state.mode = LEN; | ||
| 709 | case LEN: | ||
| 710 | if (have >= 6 && left >= 258) { | ||
| 711 | strm.next_out = put; \ | ||
| 712 | strm.avail_out = left; \ | ||
| 713 | strm.next_in = next; \ | ||
| 714 | strm.avail_in = have; \ | ||
| 715 | state.hold = hold; \ | ||
| 716 | state.bits = bits; \ | ||
| 717 | |||
| 718 | inflate_fast(strm, out); | ||
| 719 | |||
| 720 | put = strm.next_out; \ | ||
| 721 | left = strm.avail_out; \ | ||
| 722 | next = strm.next_in; \ | ||
| 723 | have = strm.avail_in; \ | ||
| 724 | hold = state.hold; \ | ||
| 725 | bits = state.bits; \ | ||
| 726 | if (state.mode == TYPE) | ||
| 727 | state.back = -1; | ||
| 728 | break; | ||
| 729 | } | ||
| 730 | state.back = 0; | ||
| 731 | for (;;) { | ||
| 732 | here = state.lencode[BITS(state.lenbits)]; | ||
| 733 | if ((unsigned)(here.bits) <= bits) break; | ||
| 734 | PULLBYTE(); | ||
| 735 | } | ||
| 736 | if (here.op && (here.op & 0xf0) == 0) { | ||
| 737 | last = here; | ||
| 738 | for (;;) { | ||
| 739 | here = state.lencode[last.val + | ||
| 740 | (BITS(last.bits + last.op) >> last.bits)]; | ||
| 741 | if ((unsigned)(last.bits + here.bits) <= bits) break; | ||
| 742 | PULLBYTE(); | ||
| 743 | } | ||
| 744 | DROPBITS(last.bits); | ||
| 745 | state.back += last.bits; | ||
| 746 | } | ||
| 747 | DROPBITS(here.bits); | ||
| 748 | state.back += here.bits; | ||
| 749 | state.length = (unsigned)here.val; | ||
| 750 | if ((int)(here.op) == 0) { | ||
| 751 | Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? | ||
| 752 | "inflate: literal '%c'\n" : | ||
| 753 | "inflate: literal 0x%02x\n", here.val)); | ||
| 754 | state.mode = LIT; | ||
| 755 | break; | ||
| 756 | } | ||
| 757 | if (here.op & 32) { | ||
| 758 | Tracevv((stderr, "inflate: end of block\n")); | ||
| 759 | state.back = -1; | ||
| 760 | state.mode = TYPE; | ||
| 761 | break; | ||
| 762 | } | ||
| 763 | if (here.op & 64) { | ||
| 764 | strm.msg = (char *)"invalid literal/length code"; | ||
| 765 | state.mode = BAD; | ||
| 766 | break; | ||
| 767 | } | ||
| 768 | state.extra = (unsigned)(here.op) & 15; | ||
| 769 | state.mode = LENEXT; | ||
| 770 | case LENEXT: | ||
| 771 | if (state.extra) { | ||
| 772 | NEEDBITS(state.extra); | ||
| 773 | state.length += BITS(state.extra); | ||
| 774 | DROPBITS(state.extra); | ||
| 775 | state.back += state.extra; | ||
| 776 | } | ||
| 777 | Tracevv((stderr, "inflate: length %u\n", state.length)); | ||
| 778 | state.was = state.length; | ||
| 779 | state.mode = DIST; | ||
| 780 | case DIST: | ||
| 781 | for (;;) { | ||
| 782 | here = state.distcode[BITS(state.distbits)]; | ||
| 783 | if ((unsigned)(here.bits) <= bits) break; | ||
| 784 | PULLBYTE(); | ||
| 785 | } | ||
| 786 | if ((here.op & 0xf0) == 0) { | ||
| 787 | last = here; | ||
| 788 | for (;;) { | ||
| 789 | here = state.distcode[last.val + | ||
| 790 | (BITS(last.bits + last.op) >> last.bits)]; | ||
| 791 | if ((unsigned)(last.bits + here.bits) <= bits) break; | ||
| 792 | PULLBYTE(); | ||
| 793 | } | ||
| 794 | DROPBITS(last.bits); | ||
| 795 | state.back += last.bits; | ||
| 796 | } | ||
| 797 | DROPBITS(here.bits); | ||
| 798 | state.back += here.bits; | ||
| 799 | if (here.op & 64) { | ||
| 800 | strm.msg = (char *)"invalid distance code"; | ||
| 801 | state.mode = BAD; | ||
| 802 | break; | ||
| 803 | } | ||
| 804 | state.offset = (unsigned)here.val; | ||
| 805 | state.extra = (unsigned)(here.op) & 15; | ||
| 806 | state.mode = DISTEXT; | ||
| 807 | case DISTEXT: | ||
| 808 | if (state.extra) { | ||
| 809 | NEEDBITS(state.extra); | ||
| 810 | state.offset += BITS(state.extra); | ||
| 811 | DROPBITS(state.extra); | ||
| 812 | state.back += state.extra; | ||
| 813 | } | ||
| 814 | #ifdef INFLATE_STRICT | ||
| 815 | if (state.offset > state.dmax) { | ||
| 816 | strm.msg = (char *)"invalid distance too far back"; | ||
| 817 | state.mode = BAD; | ||
| 818 | break; | ||
| 819 | } | ||
| 820 | #endif | ||
| 821 | Tracevv((stderr, "inflate: distance %u\n", state.offset)); | ||
| 822 | state.mode = MATCH; | ||
| 823 | case MATCH: | ||
| 824 | if (left == 0) goto inf_leave; | ||
| 825 | copy = out - left; | ||
| 826 | if (state.offset > copy) { /* copy from window */ | ||
| 827 | copy = state.offset - copy; | ||
| 828 | if (copy > state.whave) { | ||
| 829 | if (state.sane) { | ||
| 830 | strm.msg = (char *)"invalid distance too far back"; | ||
| 831 | state.mode = BAD; | ||
| 832 | break; | ||
| 833 | } | ||
| 834 | #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR | ||
| 835 | Trace((stderr, "inflate.c too far\n")); | ||
| 836 | copy -= state.whave; | ||
| 837 | if (copy > state.length) copy = state.length; | ||
| 838 | if (copy > left) copy = left; | ||
| 839 | left -= copy; | ||
| 840 | state.length -= copy; | ||
| 841 | do { | ||
| 842 | *put++ = 0; | ||
| 843 | } while (--copy); | ||
| 844 | if (state.length == 0) state.mode = LEN; | ||
| 845 | break; | ||
| 846 | #endif | ||
| 847 | } | ||
| 848 | if (copy > state.wnext) { | ||
| 849 | copy -= state.wnext; | ||
| 850 | from = state.window + (state.wsize - copy); | ||
| 851 | } | ||
| 852 | else | ||
| 853 | from = state.window + (state.wnext - copy); | ||
| 854 | if (copy > state.length) copy = state.length; | ||
| 855 | } | ||
| 856 | else { /* copy from output */ | ||
| 857 | from = put - state.offset; | ||
| 858 | copy = state.length; | ||
| 859 | } | ||
| 860 | if (copy > left) copy = left; | ||
| 861 | left -= copy; | ||
| 862 | state.length -= copy; | ||
| 863 | do { | ||
| 864 | *put++ = *from++; | ||
| 865 | } while (--copy); | ||
| 866 | if (state.length == 0) state.mode = LEN; | ||
| 867 | break; | ||
| 868 | case LIT: | ||
| 869 | if (left == 0) goto inf_leave; | ||
| 870 | *put++ = (u8)(state.length); | ||
| 871 | left--; | ||
| 872 | state.mode = LEN; | ||
| 873 | break; | ||
| 874 | case CHECK: | ||
| 875 | if (state.wrap) { | ||
| 876 | NEEDBITS(32); | ||
| 877 | out -= left; | ||
| 878 | strm.total_out += out; | ||
| 879 | state.total += out; | ||
| 880 | if ((state.wrap & 4) && out) | ||
| 881 | strm.adler = state.check = | ||
| 882 | UPDATE(state.check, put - out, out); | ||
| 883 | out = left; | ||
| 884 | if ((state.wrap & 4) && ( | ||
| 885 | #ifdef GUNZIP | ||
| 886 | state.flags ? hold : | ||
| 887 | #endif | ||
| 888 | ZSWAP32(hold)) != state.check) { | ||
| 889 | strm.msg = (char *)"incorrect data check"; | ||
| 890 | state.mode = BAD; | ||
| 891 | break; | ||
| 892 | } | ||
| 893 | INITBITS(); | ||
| 894 | Tracev((stderr, "inflate: check matches trailer\n")); | ||
| 895 | } | ||
| 896 | #ifdef GUNZIP | ||
| 897 | state.mode = LENGTH; | ||
| 898 | case LENGTH: | ||
| 899 | if (state.wrap && state.flags) { | ||
| 900 | NEEDBITS(32); | ||
| 901 | if (hold != (state.total & 0xffffffffUL)) { | ||
| 902 | strm.msg = (char *)"incorrect length check"; | ||
| 903 | state.mode = BAD; | ||
| 904 | break; | ||
| 905 | } | ||
| 906 | INITBITS(); | ||
| 907 | Tracev((stderr, "inflate: length matches trailer\n")); | ||
| 908 | } | ||
| 909 | #endif | ||
| 910 | state.mode = DONE; | ||
| 911 | case DONE: | ||
| 912 | ret = Z_STREAM_END; | ||
| 913 | goto inf_leave; | ||
| 914 | case BAD: | ||
| 915 | ret = Z_DATA_ERROR; | ||
| 916 | goto inf_leave; | ||
| 917 | case MEM: | ||
| 918 | return Z_MEM_ERROR; | ||
| 919 | case SYNC: | ||
| 920 | default: | ||
| 921 | return Z_STREAM_ERROR; | ||
| 922 | } | ||
| 923 | |||
| 924 | /* | ||
| 925 | Return from inflate(), updating the total counts and the check value. | ||
| 926 | If there was no progress during the inflate() call, return a buffer | ||
| 927 | error. Call updatewindow() to create and/or update the window state. | ||
| 928 | Note: a memory error from inflate() is non-recoverable. | ||
| 929 | */ | ||
| 930 | inf_leave: | ||
| 931 | strm.next_out = put; \ | ||
| 932 | strm.avail_out = left; \ | ||
| 933 | strm.next_in = next; \ | ||
| 934 | strm.avail_in = have; \ | ||
| 935 | state.hold = hold; \ | ||
| 936 | state.bits = bits; \ | ||
| 937 | if (state.wsize || (out != strm.avail_out && state.mode < BAD && | ||
| 938 | (state.mode < CHECK || flush != Z_FINISH))) | ||
| 939 | if (updatewindow(strm, strm.next_out, out - strm.avail_out)) { | ||
| 940 | state.mode = MEM; | ||
| 941 | return Z_MEM_ERROR; | ||
| 942 | } | ||
| 943 | in -= strm.avail_in; | ||
| 944 | out -= strm.avail_out; | ||
| 945 | strm.total_in += in; | ||
| 946 | strm.total_out += out; | ||
| 947 | state.total += out; | ||
| 948 | if ((state.wrap & 4) && out) | ||
| 949 | strm.adler = state.check = | ||
| 950 | UPDATE(state.check, strm.next_out - out, out); | ||
| 951 | strm.data_type = (int)state.bits + (state.last ? 64 : 0) + | ||
| 952 | (state.mode == TYPE ? 128 : 0) + | ||
| 953 | (state.mode == LEN_ || state.mode == COPY_ ? 256 : 0); | ||
| 954 | if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) | ||
| 955 | ret = Z_BUF_ERROR; | ||
| 956 | return ret; | ||
| 957 | } | ||
| 958 | |||
| 959 | local int inflateStateCheck(z_stream * strm) { | ||
| 960 | struct inflate_state FAR *state; | ||
| 961 | if (strm == Z_NULL || | ||
| 962 | strm.zalloc == (alloc_func)0 || strm.zfree == (free_func)0) | ||
| 963 | return 1; | ||
| 964 | state = (struct inflate_state FAR *)strm.state; | ||
| 965 | if (state == Z_NULL || state.strm != strm || | ||
| 966 | state.mode < HEAD || state.mode > SYNC) | ||
| 967 | return 1; | ||
| 968 | return 0; | ||
| 969 | } | ||