+ /* FIXME: catch "else" after "else" */
+ if (!cpp->level) {
+ D->error(D, exp->token, PSI_WARNING, "Ingoring lone #else");
+ } else if (psi_cpp_level_skipped(cpp) && !psi_cpp_level_masked(cpp)) {
+ /*
+ * if skip is set on this level and the level has
+ * not been masked yet, then unskip and mask this level
+ */
+ psi_cpp_level_unskip(cpp);
+ psi_cpp_level_mask(cpp);
+ } else if (!cpp->skip && psi_cpp_level_masked(cpp)) {
+ /*
+ * previous block masked this level
+ */
+ psi_cpp_level_skip(cpp);
+ } else {
+ assert(cpp->skip <= cpp->level);
+ }
+ break;
+ case PSI_T_ELIF:
+ if (!cpp->level) {
+ D->error(D, exp->token, PSI_WARNING, "Ingoring lone #elif");
+ } else if (psi_cpp_level_skipped(cpp) && !psi_cpp_level_masked(cpp)) {
+ /*
+ * if skip is set on this level and the level has
+ * not been masked yet, then unskip and mask this
+ * level, if the condition evals truthy
+ */
+ if (psi_cpp_if(cpp, exp)) {
+ psi_cpp_level_unskip(cpp);
+ psi_cpp_level_mask(cpp);
+ }
+ } else if (!cpp->skip && psi_cpp_level_masked(cpp)) {
+ /*
+ * previous block masked this level
+ */
+ psi_cpp_level_skip(cpp);
+ } else {
+ assert(cpp->skip <= cpp->level);
+ }
+ break;
+ case PSI_T_INCLUDE:
+ if (!cpp->skip) {
+ if (!psi_cpp_include(cpp, exp->data.tok, PSI_CPP_INCLUDE)) {
+ D->error(D, exp->token, PSI_WARNING, "Failed to include %s: %s",
+ exp->data.tok->text->val, strerror(errno));
+ }
+ }
+ break;
+ case PSI_T_INCLUDE_NEXT:
+ if (!cpp->skip) {
+ if (!psi_cpp_include(cpp, exp->data.tok, PSI_CPP_INCLUDE_NEXT)) {
+ D->error(D, exp->token, PSI_WARNING, "Failed to include next %s: %s",
+ exp->data.tok->text->val, strerror(errno));
+ }
+ }
+ break;
+ case PSI_T_IMPORT:
+ if (!cpp->skip) {
+ if (!psi_cpp_include(cpp, exp->data.tok, PSI_CPP_INCLUDE_ONCE)) {
+ D->error(D, exp->token, PSI_WARNING, "Failed to include once %s: %s",
+ exp->data.tok->text->val, strerror(errno));
+ }
+ }
+ break;
+ case PSI_T_PRAGMA_ONCE:
+ if (!cpp->skip) {
+ zend_hash_add_empty_element(&cpp->once, exp->token->file);
+ }