authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-01 03:16:35-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-01 03:16:35-04:00
logee9d1d0414ac6cc877e86055dcb08543db9b57ad
treece3b8d86127d634179ea4c78fa9a19fdc730ad6e
parent848504117f17a5fa8ead8c168e0e430e22be6e43

c-to-zig: return statement


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;
15281526
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;
31653165
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 @@
1717
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>
2021
21#include <string.h>22#include <string.h>
2223
...@@ -54,6 +55,7 @@ struct Context {...@@ -54,6 +55,7 @@ struct Context {
54 uint32_t next_anon_index;55 uint32_t next_anon_index;
5556
56 CodeGen *codegen;57 CodeGen *codegen;
58 ASTContext *ctx;
57};59};
5860
59static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl,61static 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}
604606
607#include "ast_render.hpp"
608
609static AstNode * ast_trans_stmt(Context *c, Stmt *stmt);
610
611static AstNode * ast_trans_expr(Context *c, Expr *expr) {
612 return ast_trans_stmt(c, expr);
613}
614
615static 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
623static 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
632static 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
643static 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}
659static 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
670static 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
605static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {1067static 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));
6071069
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 function1079 // 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
13731843
1374 std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>();1844 std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>();
13751845
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));
13921862
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 }
14331903
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);
14351905
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 }
14381913
1439 return 0;1914 return 0;
1440 }1915 }
14411916
1917 c->ctx = &ast_unit->getASTContext();
1442 c->source_manager = &ast_unit->getSourceManager();1918 c->source_manager = &ast_unit->getSourceManager();
14431919
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}
7774
...@@ -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}
26122609
2613AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner,2610AstNode *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, ...);
1717
1818
19// This function is provided by generated code, generated by parsergen.cpp19// This function is provided by generated code, generated by parsergen.cpp
20AstNode * ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, ErrColor err_color,20AstNode * ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner, ErrColor err_color);
21 uint32_t *next_node_index);
2221
23void ast_print(AstNode *node, int indent);22void ast_print(AstNode *node, int indent);
2423
std/zlib/deflate.zig created+522
...@@ -0,0 +1,522 @@
1const 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
33typedef 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
211fn deflate(strm: &z_stream, flush: int) -> %void {
212
213}
214
215int 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
2error Z_STREAM_ERROR;
3error Z_STREAM_END;
4error Z_NEED_DICT;
5error Z_ERRNO;
6error Z_STREAM_ERROR;
7error Z_DATA_ERROR;
8error Z_MEM_ERROR;
9error Z_BUF_ERROR;
10error Z_VERSION_ERROR;
11
12pub Flush = enum {
13 NO_FLUSH,
14 PARTIAL_FLUSH,
15 SYNC_FLUSH,
16 FULL_FLUSH,
17 FINISH,
18 BLOCK,
19 TREES,
20};
21
22const 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.
33const 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
78const alloc_func = fn(opaque: &c_void, items: u16, size: u16);
79const free_func = fn(opaque: &c_void, address: &c_void);
80
81const 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
118pub const HEAD = 16180;
119/// i: waiting for method and flags (gzip)
120pub const FLAGS = 16181;
121/// i: waiting for modification time (gzip)
122pub const TIME = 16182;
123/// i: waiting for extra flags and operating system (gzip)
124pub const OS = 16183;
125/// i: waiting for extra length (gzip)
126pub const EXLEN = 16184;
127/// i: waiting for extra bytes (gzip)
128pub const EXTRA = 16185;
129/// i: waiting for end of file name (gzip)
130pub const NAME = 16186;
131/// i: waiting for end of comment (gzip)
132pub const COMMENT = 16187;
133/// i: waiting for header crc (gzip)
134pub const HCRC = 16188;
135/// i: waiting for dictionary check value
136pub const DICTID = 16189;
137/// waiting for inflateSetDictionary() call
138pub const DICT = 16190;
139/// i: waiting for type bits, including last-flag bit
140pub const TYPE = 16191;
141/// i: same, but skip check to exit inflate on new block
142pub const TYPEDO = 16192;
143/// i: waiting for stored size (length and complement)
144pub const STORED = 16193;
145/// i/o: same as COPY below, but only first time in
146pub const COPY_ = 16194;
147/// i/o: waiting for input or output to copy stored block
148pub const COPY = 16195;
149/// i: waiting for dynamic block table lengths
150pub const TABLE = 16196;
151/// i: waiting for code length code lengths
152pub const LENLENS = 16197;
153/// i: waiting for length/lit and distance code lengths
154pub const CODELENS = 16198;
155/// i: same as LEN below, but only first time in
156pub const LEN_ = 16199;
157/// i: waiting for length/lit/eob code
158pub const LEN = 16200;
159/// i: waiting for length extra bits
160pub const LENEXT = 16201;
161/// i: waiting for distance code
162pub const DIST = 16202;
163/// i: waiting for distance extra bits
164pub const DISTEXT = 16203;
165/// o: waiting for output space to copy string
166pub const MATCH = 16204;
167/// o: waiting for output space to write literal
168pub const LIT = 16205;
169/// i: waiting for 32-bit check value
170pub const CHECK = 16206;
171/// i: waiting for 32-bit length (gzip)
172pub const LENGTH = 16207;
173/// finished check, done -- remain here until reset
174pub const DONE = 16208;
175/// got a data error -- remain here until reset
176pub const BAD = 16209;
177/// got an inflate() memory error -- remain here until reset
178pub const MEM = 16210;
179/// looking for synchronization bytes to restart inflate() */
180pub 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.
261pub 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
959local 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}