Esempio n. 1
0
static void
process_child_properties (GType type, GObjectClass *oclass)
{
    guint i, n_properties;
    GParamSpec **specs;

    specs = gtk_container_class_list_child_properties (oclass, &n_properties);
    if (!specs || n_properties == 0) {
        return;
    }

    /* skip types that have parents who have child properties, but
     * that don't actually have any themselves */
    for (i = 0; i < n_properties; i++) {
        if (specs[i]->owner_type == type) {
            goto process_child_properties;
        }
    }
    goto free_specs;

process_child_properties:
    g_print ("%sChildAttrs = ", g_type_name (type));
    comma = FALSE;
    for (i = 0; i < n_properties; i++) {
        if (specs[i]->owner_type == type) {
            if (process_attribute (specs[i])) {
                comma = TRUE;
            }
        }
    }
    child_attrs = g_list_prepend (child_attrs, GSIZE_TO_POINTER (type));

free_specs:
    g_free (specs);
}
Esempio n. 2
0
void FileInfo::process_attr_list_entry(const ATTR_LIST_ENTRY* attr_list_entry, Array<u64>& ext_rec_list) {
  if (attr_list_entry->mft_reference == base_file_rec_num) {
    unsigned attr_off = find_attribute(base_file_rec_buf, attr_list_entry->type, attr_list_entry->instance);
    CHECK_FMT(attr_off != -1);
    process_attribute(base_file_rec_buf, attr_off);
  }
  else {
    if (ext_rec_list.search(attr_list_entry->mft_reference) == -1) {
      ext_rec_list += attr_list_entry->mft_reference;
      mft_rec_cnt++;
    }

    load_mft_record(attr_list_entry->mft_reference, ext_file_rec_buf);
    unsigned attr_off = find_attribute(ext_file_rec_buf, attr_list_entry->type, attr_list_entry->instance);
    CHECK_FMT(attr_off != -1);
    process_attribute(ext_file_rec_buf, attr_off);
  }
}
Esempio n. 3
0
static void
process_properties (GType type, GObjectClass *oclass)
{
    guint i, n_properties;
    GParamSpec **specs;

    comma = TRUE;
    specs = g_object_class_list_properties (oclass, &n_properties);
    if (type == GTK_TYPE_WIDGET) {
        g_print ("%sAttrs = id?, GtkWidgetChildAttrs", g_type_name (type));
    } else {
        g_print ("%sAttrs = %sAttrs", g_type_name (type), g_type_name (g_type_parent (type)));
    }
    for (i = 0; i < n_properties; i++) {
        if (specs[i]->owner_type == type) {
            if (process_attribute (specs[i])) {
                comma = TRUE;
            }
        }
    }
    g_print ("\n\n");
    g_free (specs);
}
Esempio n. 4
0
/**
 *	@param[in]	param	source file
 *	@param[in]	type	#TYPE_C, #TYPE_YACC, #TYPE_LEX
 */
static void
C_family(const struct parser_param *param, int type)
{
	int c, cc;
	int savelevel;
	int startmacro, startsharp;
	const char *interested = "{}=;";
	STRBUF *sb = strbuf_open(0);
	/*
	 * yacc file format is like the following.
	 *
	 * declarations
	 * %%
	 * rules
	 * %%
	 * programs
	 *
	 */
	int yaccstatus = (type == TYPE_YACC) ? DECLARATIONS : PROGRAMS;
	int inC = (type == TYPE_YACC) ? 0 : 1;	/* 1 while C source */

	level = piflevel = externclevel = 0;
	savelevel = -1;
	startmacro = startsharp = 0;

	if (!opentoken(param->file))
		die("'%s' cannot open.", param->file);
	cmode = 1;			/* allow token like '#xxx' */
	crflag = 1;			/* require '\n' as a token */
	if (type == TYPE_YACC)
		ymode = 1;		/* allow token like '%xxx' */

	while ((cc = nexttoken(interested, c_reserved_word)) != EOF) {
		switch (cc) {
		case SYMBOL:		/* symbol	*/
			if (inC && peekc(0) == '('/* ) */) {
				if (param->isnotfunction(token)) {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				} else if (level > 0 || startmacro) {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				} else if (level == 0 && !startmacro && !startsharp) {
					char arg1[MAXTOKEN], savetok[MAXTOKEN], *saveline;
					int savelineno = lineno;

					strlimcpy(savetok, token, sizeof(savetok));
					strbuf_reset(sb);
					strbuf_puts(sb, sp);
					saveline = strbuf_value(sb);
					arg1[0] = '\0';
					/*
					 * Guile function entry using guile-snarf is like follows:
					 *
					 * SCM_DEFINE (scm_list, "list", 0, 0, 1, 
					 *           (SCM objs),
					 *            "Return a list containing OBJS, the arguments to `list'.")
					 * #define FUNC_NAME s_scm_list
					 * {
					 *   return objs;
					 * }
					 * #undef FUNC_NAME
					 *
					 * We should assume the first argument as a function name instead of 'SCM_DEFINE'.
					 */
					if (function_definition(param, arg1)) {
						if (!strcmp(savetok, "SCM_DEFINE") && *arg1)
							strlimcpy(savetok, arg1, sizeof(savetok));
						PUT(PARSER_DEF, savetok, savelineno, saveline);
					} else {
						PUT(PARSER_REF_SYM, savetok, savelineno, saveline);
					}
				}
			} else {
				PUT(PARSER_REF_SYM, token, lineno, sp);
			}
			break;
		case '{':  /* } */
			DBG_PRINT(level, "{"); /* } */
			if (yaccstatus == RULES && level == 0)
				inC = 1;
			++level;
			if ((param->flags & PARSER_BEGIN_BLOCK) && atfirst) {
				if ((param->flags & PARSER_WARNING) && level != 1)
					warning("forced level 1 block start by '{' at column 0 [+%d %s].", lineno, curfile); /* } */
				level = 1;
			}
			break;
			/* { */
		case '}':
			if (--level < 0) {
				if (externclevel > 0)
					externclevel--;
				else if (param->flags & PARSER_WARNING)
					warning("missing left '{' [+%d %s].", lineno, curfile); /* } */
				level = 0;
			}
			if ((param->flags & PARSER_END_BLOCK) && atfirst) {
				if ((param->flags & PARSER_WARNING) && level != 0) /* { */
					warning("forced level 0 block end by '}' at column 0 [+%d %s].", lineno, curfile);
				level = 0;
			}
			if (yaccstatus == RULES && level == 0)
				inC = 0;
			/* { */
			DBG_PRINT(level, "}");
			break;
		case '\n':
			if (startmacro && level != savelevel) {
				if (param->flags & PARSER_WARNING)
					warning("different level before and after #define macro. reseted. [+%d %s].", lineno, curfile);
				level = savelevel;
			}
			startmacro = startsharp = 0;
			break;
		case YACC_SEP:		/* %% */
			if (level != 0) {
				if (param->flags & PARSER_WARNING)
					warning("forced level 0 block end by '%%' [+%d %s].", lineno, curfile);
				level = 0;
			}
			if (yaccstatus == DECLARATIONS) {
				PUT(PARSER_DEF, "yyparse", lineno, sp);
				yaccstatus = RULES;
			} else if (yaccstatus == RULES)
				yaccstatus = PROGRAMS;
			inC = (yaccstatus == PROGRAMS) ? 1 : 0;
			break;
		case YACC_BEGIN:	/* %{ */
			if (level != 0) {
				if (param->flags & PARSER_WARNING)
					warning("forced level 0 block end by '%%{' [+%d %s].", lineno, curfile);
				level = 0;
			}
			if (inC == 1 && (param->flags & PARSER_WARNING))
				warning("'%%{' appeared in C mode. [+%d %s].", lineno, curfile);
			inC = 1;
			break;
		case YACC_END:		/* %} */
			if (level != 0) {
				if (param->flags & PARSER_WARNING)
					warning("forced level 0 block end by '%%}' [+%d %s].", lineno, curfile);
				level = 0;
			}
			if (inC == 0 && (param->flags & PARSER_WARNING))
				warning("'%%}' appeared in Yacc mode. [+%d %s].", lineno, curfile);
			inC = 0;
			break;
		case YACC_UNION:	/* %union {...} */
			if (yaccstatus == DECLARATIONS)
				PUT(PARSER_DEF, "YYSTYPE", lineno, sp);
			break;
		/*
		 * #xxx
		 */
		case SHARP_DEFINE:
		case SHARP_UNDEF:
			startmacro = 1;
			savelevel = level;
			if ((c = nexttoken(interested, c_reserved_word)) != SYMBOL) {
				pushbacktoken();
				break;
			}
			if (peekc(1) == '('/* ) */) {
				PUT(PARSER_DEF, token, lineno, sp);
				while ((c = nexttoken("()", c_reserved_word)) != EOF && c != '\n' && c != /* ( */ ')')
					if (c == SYMBOL)
						PUT(PARSER_REF_SYM, token, lineno, sp);
				if (c == '\n')
					pushbacktoken();
			} else {
				PUT(PARSER_DEF, token, lineno, sp);
			}
			break;
		case SHARP_IMPORT:
		case SHARP_INCLUDE:
		case SHARP_INCLUDE_NEXT:
		case SHARP_ERROR:
		case SHARP_LINE:
		case SHARP_PRAGMA:
		case SHARP_WARNING:
		case SHARP_IDENT:
		case SHARP_SCCS:
			while ((c = nexttoken(interested, c_reserved_word)) != EOF && c != '\n')
				;
			break;
		case SHARP_IFDEF:
		case SHARP_IFNDEF:
		case SHARP_IF:
		case SHARP_ELIF:
		case SHARP_ELSE:
		case SHARP_ENDIF:
			condition_macro(param, cc);
			break;
		case SHARP_SHARP:		/* ## */
			(void)nexttoken(interested, c_reserved_word);
			break;
		case C_EXTERN: /* for 'extern "C"/"C++"' */
			if (peekc(0) != '"') /* " */
				continue; /* If does not start with '"', continue. */
			while ((c = nexttoken(interested, c_reserved_word)) == '\n')
				;
			/*
			 * 'extern "C"/"C++"' block is a kind of namespace block.
			 * (It doesn't have any influence on level.)
			 */
			if (c == '{') /* } */
				externclevel++;
			else
				pushbacktoken();
			break;
		case C_STRUCT:
		case C_ENUM:
		case C_UNION:
			while ((c = nexttoken(interested, c_reserved_word)) == C___ATTRIBUTE__)
				process_attribute(param);
			if (c == SYMBOL) {
				if (peekc(0) == '{') /* } */ {
					PUT(PARSER_DEF, token, lineno, sp);
				} else {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				}
				c = nexttoken(interested, c_reserved_word);
			}
			if (c == '{' /* } */ && cc == C_ENUM) {
				enumerator_list(param);
			} else {
				pushbacktoken();
			}
			break;
		/* control statement check */
		case C_BREAK:
		case C_CASE:
		case C_CONTINUE:
		case C_DEFAULT:
		case C_DO:
		case C_ELSE:
		case C_FOR:
		case C_GOTO:
		case C_IF:
		case C_RETURN:
		case C_SWITCH:
		case C_WHILE:
			if ((param->flags & PARSER_WARNING) && !startmacro && level == 0)
				warning("Out of function. %8s [+%d %s]", token, lineno, curfile);
			break;
		case C_TYPEDEF:
			{
				/*
				 * This parser is too complex to maintain.
				 * We should rewrite the whole.
				 */
				char savetok[MAXTOKEN];
				int savelineno = 0;
				int typedef_savelevel = level;

				savetok[0] = 0;

				/* skip type qualifiers */
				do {
					c = nexttoken("{}(),;", c_reserved_word);
				} while (IS_TYPE_QUALIFIER(c) || c == '\n');

				if ((param->flags & PARSER_WARNING) && c == EOF) {
					warning("unexpected eof. [+%d %s]", lineno, curfile);
					break;
				} else if (c == C_ENUM || c == C_STRUCT || c == C_UNION) {
					char *interest_enum = "{},;";
					int c_ = c;

					while ((c = nexttoken(interest_enum, c_reserved_word)) == C___ATTRIBUTE__)
						process_attribute(param);
					/* read tag name if exist */
					if (c == SYMBOL) {
						if (peekc(0) == '{') /* } */ {
							PUT(PARSER_DEF, token, lineno, sp);
						} else {
							PUT(PARSER_REF_SYM, token, lineno, sp);
						}
						c = nexttoken(interest_enum, c_reserved_word);
					}
				
					if (c_ == C_ENUM) {
						if (c == '{') /* } */
							c = enumerator_list(param);
						else
							pushbacktoken();
					} else {
						for (; c != EOF; c = nexttoken(interest_enum, c_reserved_word)) {
							switch (c) {
							case SHARP_IFDEF:
							case SHARP_IFNDEF:
							case SHARP_IF:
							case SHARP_ELIF:
							case SHARP_ELSE:
							case SHARP_ENDIF:
								condition_macro(param, c);
								continue;
							default:
								break;
							}
							if (c == ';' && level == typedef_savelevel) {
								if (savetok[0])
									PUT(PARSER_DEF, savetok, savelineno, sp);
								break;
							} else if (c == '{')
								level++;
							else if (c == '}') {
								if (--level == typedef_savelevel)
									break;
							} else if (c == SYMBOL) {
								PUT(PARSER_REF_SYM, token, lineno, sp);
								/* save lastest token */
								strlimcpy(savetok, token, sizeof(savetok));
								savelineno = lineno;
							}
						}
						if (c == ';')
							break;
					}
					if ((param->flags & PARSER_WARNING) && c == EOF) {
						warning("unexpected eof. [+%d %s]", lineno, curfile);
						break;
					}
				} else if (c == SYMBOL) {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				}
				savetok[0] = 0;
				while ((c = nexttoken("(),;", c_reserved_word)) != EOF) {
					switch (c) {
					case SHARP_IFDEF:
					case SHARP_IFNDEF:
					case SHARP_IF:
					case SHARP_ELIF:
					case SHARP_ELSE:
					case SHARP_ENDIF:
						condition_macro(param, c);
						continue;
					default:
						break;
					}
					if (c == '(')
						level++;
					else if (c == ')')
						level--;
					else if (c == SYMBOL) {
						if (level > typedef_savelevel) {
							PUT(PARSER_REF_SYM, token, lineno, sp);
						} else {
							/* put latest token if any */
							if (savetok[0]) {
								PUT(PARSER_REF_SYM, savetok, savelineno, sp);
							}
							/* save lastest token */
							strlimcpy(savetok, token, sizeof(savetok));
							savelineno = lineno;
						}
					} else if (c == ',' || c == ';') {
						if (savetok[0]) {
							PUT(PARSER_DEF, savetok, lineno, sp);
							savetok[0] = 0;
						}
					}
					if (level == typedef_savelevel && c == ';')
						break;
				}
				if (param->flags & PARSER_WARNING) {
					if (c == EOF)
						warning("unexpected eof. [+%d %s]", lineno, curfile);
					else if (level != typedef_savelevel)
						warning("unmatched () block. (last at level %d.)[+%d %s]", level, lineno, curfile);
				}
			}
			break;
		case C___ATTRIBUTE__:
			process_attribute(param);
			break;
		default:
			break;
		}
	}
	strbuf_close(sb);
	if (param->flags & PARSER_WARNING) {
		if (level != 0)
			warning("unmatched {} block. (last at level %d.)[+%d %s]", level, lineno, curfile);
		if (piflevel != 0)
			warning("unmatched #if block. (last at level %d.)[+%d %s]", piflevel, lineno, curfile);
	}
	closetoken();
}
Esempio n. 5
0
/**
 * function_definition: return if function definition or not.
 *
 *	@param	param	
 *	@param[out]	arg1	the first argument
 *	@return	target type
 */
static int
function_definition(const struct parser_param *param, char arg1[MAXTOKEN])
{
	int c;
	int brace_level, isdefine;
	int accept_arg1 = 0;

	brace_level = isdefine = 0;
	while ((c = nexttoken("()", c_reserved_word)) != EOF) {
		switch (c) {
		case SHARP_IFDEF:
		case SHARP_IFNDEF:
		case SHARP_IF:
		case SHARP_ELIF:
		case SHARP_ELSE:
		case SHARP_ENDIF:
			condition_macro(param, c);
			continue;
		default:
			break;
		}
		if (c == '('/* ) */)
			brace_level++;
		else if (c == /* ( */')') {
			if (--brace_level == 0)
				break;
		}
		/* pick up symbol */
		if (c == SYMBOL) {
			if (accept_arg1 == 0) {
				accept_arg1 = 1;
				strlimcpy(arg1, token, MAXTOKEN);
			}
			PUT(PARSER_REF_SYM, token, lineno, sp);
		}
	}
	if (c == EOF)
		return 0;
	brace_level = 0;
	while ((c = nexttoken(",;[](){}=", c_reserved_word)) != EOF) {
		switch (c) {
		case SHARP_IFDEF:
		case SHARP_IFNDEF:
		case SHARP_IF:
		case SHARP_ELIF:
		case SHARP_ELSE:
		case SHARP_ENDIF:
			condition_macro(param, c);
			continue;
		case C___ATTRIBUTE__:
			process_attribute(param);
			continue;
		default:
			break;
		}
		if (c == '('/* ) */ || c == '[')
			brace_level++;
		else if (c == /* ( */')' || c == ']')
			brace_level--;
		else if (brace_level == 0
		    && ((c == SYMBOL && strcmp(token, "__THROW")) || IS_RESERVED_WORD(c)))
			isdefine = 1;
		else if (c == ';' || c == ',') {
			if (!isdefine)
				break;
		} else if (c == '{' /* } */) {
			pushbacktoken();
			return 1;
		} else if (c == /* { */'}')
			break;
		else if (c == '=')
			break;

		/* pick up symbol */
		if (c == SYMBOL)
			PUT(PARSER_REF_SYM, token, lineno, sp);
	}
	return 0;
}
Esempio n. 6
0
/*
 *	Initialize the dictionary.
 */
static int my_dict_init(const char *dir, const char *fn,
			const char *src_file, int src_line)
{
	FILE	*fp;
	char 	dirtmp[256];
	char	buf[256];
	char	*p;
	int	line = 0;
	int	vendor;
	int	block_vendor;
	struct stat statbuf;
	char	*argv[MAX_ARGV];
	int	argc;
	DICT_ATTR *da, *block_tlv = NULL;

	if (strlen(fn) >= sizeof(dirtmp) / 2 ||
	    strlen(dir) >= sizeof(dirtmp) / 2) {
		fr_strerror_printf("dict_init: filename name too long");
		return -1;
	}

	/*
	 *	First see if fn is relative to dir. If so, create
	 *	new filename. If not, remember the absolute dir.
	 */
	if ((p = strrchr(fn, FR_DIR_SEP)) != NULL) {
		strcpy(dirtmp, fn);
		dirtmp[p - fn] = 0;
		dir = dirtmp;
	} else if (dir && dir[0] && strcmp(dir, ".") != 0) {
		snprintf(dirtmp, sizeof(dirtmp), "%s/%s", dir, fn);
		fn = dirtmp;
	}

	if ((fp = fopen(fn, "r")) == NULL) {
		if (!src_file) {
			fr_strerror_printf("dict_init: Couldn't open dictionary \"%s\": %s",
				   fn, strerror(errno));
		} else {
			fr_strerror_printf("dict_init: %s[%d]: Couldn't open dictionary \"%s\": %s",
				   src_file, src_line, fn, strerror(errno));
		}
		return -1;
	}

	stat(fn, &statbuf); /* fopen() guarantees this will succeed */
	if (!S_ISREG(statbuf.st_mode)) {
		fclose(fp);
		fr_strerror_printf("dict_init: Dictionary \"%s\" is not a regular file",
			   fn);
		return -1;
	}

	/*
	 *	Globally writable dictionaries means that users can control
	 *	the server configuration with little difficulty.
	 */
#ifdef S_IWOTH
	if ((statbuf.st_mode & S_IWOTH) != 0) {
		fclose(fp);
		fr_strerror_printf("dict_init: Dictionary \"%s\" is globally writable.  Refusing to start due to insecure configuration.",
			   fn);
		return -1;
	}
#endif

	dict_stat_add(fn, &statbuf);

	/*
	 *	Seed the random pool with data.
	 */
	fr_rand_seed(&statbuf, sizeof(statbuf));

	block_vendor = 0;

	while (fgets(buf, sizeof(buf), fp) != NULL) {
		line++;
		if (buf[0] == '#' || buf[0] == 0 ||
		    buf[0] == '\n' || buf[0] == '\r')
			continue;

		/*
		 *  Comment characters should NOT be appearing anywhere but
		 *  as start of a comment;
		 */
		p = strchr(buf, '#');
		if (p) *p = '\0';

		argc = str2argv(buf, argv, MAX_ARGV);
		if (argc == 0) continue;

		if (argc == 1) {
			fr_strerror_printf( "dict_init: %s[%d] invalid entry",
				    fn, line);
			fclose(fp);
			return -1;
		}

		/*
		 *	Process VALUE lines.
		 */
		if (strcasecmp(argv[0], "VALUE") == 0) {
			if (process_value(fn, line,
					  argv + 1, argc - 1) == -1) {
				fclose(fp);
				return -1;
			}
			continue;
		}

		/*
		 *	Perhaps this is an attribute.
		 */
		if (strcasecmp(argv[0], "ATTRIBUTE") == 0) {
			if (process_attribute(fn, line, block_vendor,
					      block_tlv,
					      argv + 1, argc - 1) == -1) {
				fclose(fp);
				return -1;
			}
			continue;
		}

		/*
		 *	See if we need to import another dictionary.
		 */
		if (strcasecmp(argv[0], "$INCLUDE") == 0) {
			if (my_dict_init(dir, argv[1], fn, line) < 0) {
				fclose(fp);
				return -1;
			}
			continue;
		} /* $INCLUDE */

		if (strcasecmp(argv[0], "VALUE-ALIAS") == 0) {
			if (process_value_alias(fn, line,
						argv + 1, argc - 1) == -1) {
				fclose(fp);
				return -1;
			}
			continue;
		}

		/*
		 *	Process VENDOR lines.
		 */
		if (strcasecmp(argv[0], "VENDOR") == 0) {
			if (process_vendor(fn, line,
					   argv + 1, argc - 1) == -1) {
				fclose(fp);
				return -1;
			}
			continue;
		}

		if (strcasecmp(argv[0], "BEGIN-TLV") == 0) {
			if (argc != 2) {
				fr_strerror_printf(
				"dict_init: %s[%d] invalid BEGIN-TLV entry",
					fn, line);
				fclose(fp);
				return -1;
			}

			da = dict_attrbyname(argv[1]);
			if (!da) {
				fr_strerror_printf(
					"dict_init: %s[%d]: unknown attribute %s",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}

			if (da->type != PW_TYPE_TLV) {
				fr_strerror_printf(
					"dict_init: %s[%d]: attribute %s is not of type tlv",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}

			if (block_tlv) {
				fr_strerror_printf(
					"dict_init: %s[%d]: Cannot nest TLVs",
					fn, line);
				fclose(fp);
				return -1;
			}

			block_tlv = da;
			continue;
		} /* BEGIN-TLV */

		if (strcasecmp(argv[0], "END-TLV") == 0) {
			if (argc != 2) {
				fr_strerror_printf(
				"dict_init: %s[%d] invalid END-TLV entry",
					fn, line);
				fclose(fp);
				return -1;
			}

			da = dict_attrbyname(argv[1]);
			if (!da) {
				fr_strerror_printf(
					"dict_init: %s[%d]: unknown attribute %s",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}

			if (da != block_tlv) {
				fr_strerror_printf(
					"dict_init: %s[%d]: END-TLV %s does not match any previous BEGIN-TLV",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}
			block_tlv = NULL;
			continue;
		} /* END-VENDOR */

		if (strcasecmp(argv[0], "BEGIN-VENDOR") == 0) {
			if (argc != 2) {
				fr_strerror_printf(
				"dict_init: %s[%d] invalid BEGIN-VENDOR entry",
					fn, line);
				fclose(fp);
				return -1;
			}

			vendor = dict_vendorbyname(argv[1]);
			if (!vendor) {
				fr_strerror_printf(
					"dict_init: %s[%d]: unknown vendor %s",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}
			block_vendor = vendor;
			continue;
		} /* BEGIN-VENDOR */

		if (strcasecmp(argv[0], "END-VENDOR") == 0) {
			if (argc != 2) {
				fr_strerror_printf(
				"dict_init: %s[%d] invalid END-VENDOR entry",
					fn, line);
				fclose(fp);
				return -1;
			}

			vendor = dict_vendorbyname(argv[1]);
			if (!vendor) {
				fr_strerror_printf(
					"dict_init: %s[%d]: unknown vendor %s",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}

			if (vendor != block_vendor) {
				fr_strerror_printf(
					"dict_init: %s[%d]: END-VENDOR %s does not match any previous BEGIN-VENDOR",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}
			block_vendor = 0;
			continue;
		} /* END-VENDOR */

		/*
		 *	Any other string: We don't recognize it.
		 */
		fr_strerror_printf("dict_init: %s[%d] invalid keyword \"%s\"",
			   fn, line, argv[0]);
		fclose(fp);
		return -1;
	}
	fclose(fp);
	return 0;
}
Esempio n. 7
0
File: Cpp.c Progetto: gsliu/emacs_C
/*
 * Cpp: read C++ file and pickup tag entries.
 */
void
Cpp(const struct parser_param *param)
{
	int c, cc;
	int savelevel;
	int startclass, startthrow, startmacro, startsharp, startequal;
	char classname[MAXTOKEN];
	char completename[MAXCOMPLETENAME];
	int classlevel;
	struct {
		char *classname;
		char *terminate;
		int level;
	} stack[MAXCLASSSTACK];
	const char *interested = "{}=;~";
	STRBUF *sb = strbuf_open(0);

	*classname = *completename = 0;
	stack[0].classname = completename;
	stack[0].terminate = completename;
	stack[0].level = 0;
	level = classlevel = piflevel = namespacelevel = 0;
	savelevel = -1;
	startclass = startthrow = startmacro = startsharp = startequal = 0;

	if (!opentoken(param->file))
		die("'%s' cannot open.", param->file);
	cmode = 1;			/* allow token like '#xxx' */
	crflag = 1;			/* require '\n' as a token */
	cppmode = 1;			/* treat '::' as a token */

	while ((cc = nexttoken(interested, cpp_reserved_word)) != EOF) {
		if (cc == '~' && level == stack[classlevel].level)
			continue;
		switch (cc) {
		case SYMBOL:		/* symbol	*/
			if (startclass || startthrow) {
				PUT(PARSER_REF_SYM, token, lineno, sp);
			} else if (peekc(0) == '('/* ) */) {
				if (param->isnotfunction(token)) {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				} else if (level > stack[classlevel].level || startequal || startmacro) {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				} else if (level == stack[classlevel].level && !startmacro && !startsharp && !startequal) {
					char savetok[MAXTOKEN], *saveline;
					int savelineno = lineno;

					strlimcpy(savetok, token, sizeof(savetok));
					strbuf_reset(sb);
					strbuf_puts(sb, sp);
					saveline = strbuf_value(sb);
					if (function_definition(param)) {
						/* ignore constructor */
						if (strcmp(stack[classlevel].classname, savetok))
							PUT(PARSER_DEF, savetok, savelineno, saveline);
					} else {
						PUT(PARSER_REF_SYM, savetok, savelineno, saveline);
					}
				}
			} else {
				PUT(PARSER_REF_SYM, token, lineno, sp);
			}
			break;
		case CPP_USING:
			/*
			 * using namespace name;
			 * using ...;
			 */
			if ((c = nexttoken(interested, cpp_reserved_word)) == CPP_NAMESPACE) {
				if ((c = nexttoken(interested, cpp_reserved_word)) == SYMBOL) {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				} else {
					if (param->flags & PARSER_WARNING)
						warning("missing namespace name. [+%d %s].", lineno, curfile);
					pushbacktoken();
				}
			} else
				pushbacktoken();
			break;
		case CPP_NAMESPACE:
			crflag = 0;
			/*
			 * namespace name = ...;
			 * namespace [name] { ... }
			 */
			if ((c = nexttoken(interested, cpp_reserved_word)) == SYMBOL) {
				PUT(PARSER_DEF, token, lineno, sp);
				if ((c = nexttoken(interested, cpp_reserved_word)) == '=') {
					crflag = 1;
					break;
				}
			}
			/*
			 * Namespace block doesn't have any influence on level.
			 */
			if (c == '{') /* } */ {
				namespacelevel++;
			} else {
				if (param->flags & PARSER_WARNING)
					warning("missing namespace block. [+%d %s](0x%x).", lineno, curfile, c);
			}
			crflag = 1;
			break;
		case CPP_EXTERN: /* for 'extern "C"/"C++"' */
			if (peekc(0) != '"') /* " */
				continue; /* If does not start with '"', continue. */
			while ((c = nexttoken(interested, cpp_reserved_word)) == '\n')
				;
			/*
			 * 'extern "C"/"C++"' block is a kind of namespace block.
			 * (It doesn't have any influence on level.)
			 */
			if (c == '{') /* } */
				namespacelevel++;
			else
				pushbacktoken();
			break;
		case CPP_CLASS:
			DBG_PRINT(level, "class");
			if ((c = nexttoken(interested, cpp_reserved_word)) == SYMBOL) {
				strlimcpy(classname, token, sizeof(classname));
				/*
				 * Ignore forward definitions.
				 * "class name;"
				 */
				if (peekc(0) != ';') {
					startclass = 1;
					PUT(PARSER_DEF, token, lineno, sp);
				}
			}
			break;
		case '{':  /* } */
			DBG_PRINT(level, "{"); /* } */
			++level;
			if ((param->flags & PARSER_BEGIN_BLOCK) && atfirst) {
				if ((param->flags & PARSER_WARNING) && level != 1)
					warning("forced level 1 block start by '{' at column 0 [+%d %s].", lineno, curfile); /* } */
				level = 1;
			}
			if (startclass) {
				char *p = stack[classlevel].terminate;
				char *q = classname;

				if (++classlevel >= MAXCLASSSTACK)
					die("class stack over flow.[%s]", curfile);
				if (classlevel > 1)
					*p++ = '.';
				stack[classlevel].classname = p;
				while (*q)
					*p++ = *q++;
				stack[classlevel].terminate = p;
				stack[classlevel].level = level;
				*p++ = 0;
			}
			startclass = startthrow = 0;
			break;
			/* { */
		case '}':
			if (--level < 0) {
				if (namespacelevel > 0)
					namespacelevel--;
				else if (param->flags & PARSER_WARNING)
					warning("missing left '{' [+%d %s].", lineno, curfile); /* } */
				level = 0;
			}
			if ((param->flags & PARSER_END_BLOCK) && atfirst) {
				if ((param->flags & PARSER_WARNING) && level != 0)
					/* { */
					warning("forced level 0 block end by '}' at column 0 [+%d %s].", lineno, curfile);
				level = 0;
			}
			if (level < stack[classlevel].level)
				*(stack[--classlevel].terminate) = 0;
			/* { */
			DBG_PRINT(level, "}");
			break;
		case '=':
			/* dirty hack. Don't mimic this. */
			if (peekc(0) == '=') {
				throwaway_nextchar();
			} else {
				startequal = 1;
			}
			break;
		case ';':
			startthrow = startequal = 0;
			break;
		case '\n':
			if (startmacro && level != savelevel) {
				if (param->flags & PARSER_WARNING)
					warning("different level before and after #define macro. reseted. [+%d %s].", lineno, curfile);
				level = savelevel;
			}
			startmacro = startsharp = 0;
			break;
		/*
		 * #xxx
		 */
		case SHARP_DEFINE:
		case SHARP_UNDEF:
			startmacro = 1;
			savelevel = level;
			if ((c = nexttoken(interested, cpp_reserved_word)) != SYMBOL) {
				pushbacktoken();
				break;
			}
			if (peekc(1) == '('/* ) */) {
				PUT(PARSER_DEF, token, lineno, sp);
				while ((c = nexttoken("()", cpp_reserved_word)) != EOF && c != '\n' && c != /* ( */ ')')
					if (c == SYMBOL)
						PUT(PARSER_REF_SYM, token, lineno, sp);
				if (c == '\n')
					pushbacktoken();
			}  else {
				PUT(PARSER_DEF, token, lineno, sp);
			}
			break;
		case SHARP_IMPORT:
		case SHARP_INCLUDE:
		case SHARP_INCLUDE_NEXT:
		case SHARP_ERROR:
		case SHARP_LINE:
		case SHARP_PRAGMA:
		case SHARP_WARNING:
		case SHARP_IDENT:
		case SHARP_SCCS:
			while ((c = nexttoken(interested, cpp_reserved_word)) != EOF && c != '\n')
				;
			break;
		case SHARP_IFDEF:
		case SHARP_IFNDEF:
		case SHARP_IF:
		case SHARP_ELIF:
		case SHARP_ELSE:
		case SHARP_ENDIF:
			condition_macro(param, cc);
			break;
		case SHARP_SHARP:		/* ## */
			(void)nexttoken(interested, cpp_reserved_word);
			break;
		case CPP_NEW:
			if ((c = nexttoken(interested, cpp_reserved_word)) == SYMBOL)
				PUT(PARSER_REF_SYM, token, lineno, sp);
			break;
		case CPP_STRUCT:
		case CPP_ENUM:
		case CPP_UNION:
			c = nexttoken(interested, cpp_reserved_word);
			if (c == SYMBOL) {
				if (peekc(0) == '{') /* } */ {
					PUT(PARSER_DEF, token, lineno, sp);
				} else {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				}
				c = nexttoken(interested, cpp_reserved_word);
			}
			if (c == '{' /* } */ && cc == CPP_ENUM) {
				enumerator_list(param);
			} else {
				pushbacktoken();
			}
			break;
		case CPP_TEMPLATE:
			{
				int level = 0;

				while ((c = nexttoken("<>", cpp_reserved_word)) != EOF) {
					if (c == '<')
						++level;
					else if (c == '>') {
						if (--level == 0)
							break;
					} else if (c == SYMBOL) {
						PUT(PARSER_REF_SYM, token, lineno, sp);
					}
				}
				if (c == EOF && (param->flags & PARSER_WARNING))
					warning("template <...> isn't closed. [+%d %s].", lineno, curfile);
			}
			break;
		case CPP_OPERATOR:
			while ((c = nexttoken(";{", /* } */ cpp_reserved_word)) != EOF) {
				if (c == '{') /* } */ {
					pushbacktoken();
					break;
				} else if (c == ';') {
					break;
				} else if (c == SYMBOL) {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				}
			}
			if (c == EOF && (param->flags & PARSER_WARNING))
				warning("'{' doesn't exist after 'operator'. [+%d %s].", lineno, curfile); /* } */
			break;
		/* control statement check */
		case CPP_THROW:
			startthrow = 1;
		case CPP_BREAK:
		case CPP_CASE:
		case CPP_CATCH:
		case CPP_CONTINUE:
		case CPP_DEFAULT:
		case CPP_DELETE:
		case CPP_DO:
		case CPP_ELSE:
		case CPP_FOR:
		case CPP_GOTO:
		case CPP_IF:
		case CPP_RETURN:
		case CPP_SWITCH:
		case CPP_TRY:
		case CPP_WHILE:
			if ((param->flags & PARSER_WARNING) && !startmacro && level == 0)
				warning("Out of function. %8s [+%d %s]", token, lineno, curfile);
			break;
		case CPP_TYPEDEF:
			{
				/*
				 * This parser is too complex to maintain.
				 * We should rewrite the whole.
				 */
				char savetok[MAXTOKEN];
				int savelineno = 0;
				int typedef_savelevel = level;

				savetok[0] = 0;

				/* skip CV qualifiers */
				do {
					c = nexttoken("{}(),;", cpp_reserved_word);
				} while (IS_CV_QUALIFIER(c) || c == '\n');

				if ((param->flags & PARSER_WARNING) && c == EOF) {
					warning("unexpected eof. [+%d %s]", lineno, curfile);
					break;
				} else if (c == CPP_ENUM || c == CPP_STRUCT || c == CPP_UNION) {
					char *interest_enum = "{},;";
					int c_ = c;

					c = nexttoken(interest_enum, cpp_reserved_word);
					/* read tag name if exist */
					if (c == SYMBOL) {
						if (peekc(0) == '{') /* } */ {
							PUT(PARSER_DEF, token, lineno, sp);
						} else {
							PUT(PARSER_REF_SYM, token, lineno, sp);
						}
						c = nexttoken(interest_enum, cpp_reserved_word);
					}
					if (c_ == CPP_ENUM) {
						if (c == '{') /* } */
							c = enumerator_list(param);
						else
							pushbacktoken();
					} else {
						for (; c != EOF; c = nexttoken(interest_enum, cpp_reserved_word)) {
							switch (c) {
							case SHARP_IFDEF:
							case SHARP_IFNDEF:
							case SHARP_IF:
							case SHARP_ELIF:
							case SHARP_ELSE:
							case SHARP_ENDIF:
								condition_macro(param, c);
								continue;
							default:
								break;
							}
							if (c == ';' && level == typedef_savelevel) {
								if (savetok[0])
									PUT(PARSER_DEF, savetok, savelineno, sp);
								break;
							} else if (c == '{')
								level++;
							else if (c == '}') {
								if (--level == typedef_savelevel)
									break;
							} else if (c == SYMBOL) {
								PUT(PARSER_REF_SYM, token, lineno, sp);
								/* save lastest token */
								strlimcpy(savetok, token, sizeof(savetok));
								savelineno = lineno;
							}
						}
						if (c == ';')
							break;
					}
					if ((param->flags & PARSER_WARNING) && c == EOF) {
						warning("unexpected eof. [+%d %s]", lineno, curfile);
						break;
					}
				} else if (c == SYMBOL) {
					PUT(PARSER_REF_SYM, token, lineno, sp);
				}
				savetok[0] = 0;
				while ((c = nexttoken("(),;", cpp_reserved_word)) != EOF) {
					switch (c) {
					case SHARP_IFDEF:
					case SHARP_IFNDEF:
					case SHARP_IF:
					case SHARP_ELIF:
					case SHARP_ELSE:
					case SHARP_ENDIF:
						condition_macro(param, c);
						continue;
					default:
						break;
					}
					if (c == '(')
						level++;
					else if (c == ')')
						level--;
					else if (c == SYMBOL) {
						if (level > typedef_savelevel) {
							PUT(PARSER_REF_SYM, token, lineno, sp);
						} else {
							/* put latest token if any */
							if (savetok[0]) {
								PUT(PARSER_REF_SYM, savetok, savelineno, sp);
							}
							/* save lastest token */
							strlimcpy(savetok, token, sizeof(savetok));
							savelineno = lineno;
						}
					} else if (c == ',' || c == ';') {
						if (savetok[0]) {
							PUT(PARSER_DEF, savetok, lineno, sp);
							savetok[0] = 0;
						}
					}
					if (level == typedef_savelevel && c == ';')
						break;
				}
				if (param->flags & PARSER_WARNING) {
					if (c == EOF)
						warning("unexpected eof. [+%d %s]", lineno, curfile);
					else if (level != typedef_savelevel)
						warning("unmatched () block. (last at level %d.)[+%d %s]", level, lineno, curfile);
				}
			}
			break;
		case CPP___ATTRIBUTE__:
			process_attribute(param);
			break;
		default:
			break;
		}
	}
	strbuf_close(sb);
	if (param->flags & PARSER_WARNING) {
		if (level != 0)
			warning("unmatched {} block. (last at level %d.)[+%d %s]", level, lineno, curfile);
		if (piflevel != 0)
			warning("unmatched #if block. (last at level %d.)[+%d %s]", piflevel, lineno, curfile);
	}
	closetoken();
}
Esempio n. 8
0
File: Cpp.c Progetto: gsliu/emacs_C
/*
 * function_definition: return if function definition or not.
 *
 *	r)	target type
 */
static int
function_definition(const struct parser_param *param)
{
	int c;
	int brace_level;

	brace_level = 0;
	while ((c = nexttoken("()", cpp_reserved_word)) != EOF) {
		switch (c) {
		case SHARP_IFDEF:
		case SHARP_IFNDEF:
		case SHARP_IF:
		case SHARP_ELIF:
		case SHARP_ELSE:
		case SHARP_ENDIF:
			condition_macro(param, c);
			continue;
		default:
			break;
		}
		if (c == '('/* ) */)
			brace_level++;
		else if (c == /* ( */')') {
			if (--brace_level == 0)
				break;
		}
		/* pick up symbol */
		if (c == SYMBOL)
			PUT(PARSER_REF_SYM, token, lineno, sp);
	}
	if (c == EOF)
		return 0;
	if (peekc(0) == ';') {
		(void)nexttoken(";", NULL);
		return 0;
	}
	brace_level = 0;
	while ((c = nexttoken(",;[](){}=", cpp_reserved_word)) != EOF) {
		switch (c) {
		case SHARP_IFDEF:
		case SHARP_IFNDEF:
		case SHARP_IF:
		case SHARP_ELIF:
		case SHARP_ELSE:
		case SHARP_ENDIF:
			condition_macro(param, c);
			continue;
		case CPP___ATTRIBUTE__:
			process_attribute(param);
			continue;
		default:
			break;
		}
		if (c == '('/* ) */ || c == '[')
			brace_level++;
		else if (c == /* ( */')' || c == ']')
			brace_level--;
		else if (brace_level == 0 && (c == ';' || c == ','))
			break;
		else if (c == '{' /* } */) {
			pushbacktoken();
			return 1;
		} else if (c == /* { */'}')
			break;
		else if (c == '=')
			break;
		/* pick up symbol */
		if (c == SYMBOL)
			PUT(PARSER_REF_SYM, token, lineno, sp);
	}
	return 0;
}
Esempio n. 9
0
/*
 * function_definition: return if function definition or not.
 *
 *	r)	target type
 */
static int
function_definition(int target)
{
	int c;
	int brace_level;

	brace_level = 0;
	while ((c = nexttoken("()", cpp_reserved_word)) != EOF) {
		switch (c) {
		case SHARP_IFDEF:
		case SHARP_IFNDEF:
		case SHARP_IF:
		case SHARP_ELIF:
		case SHARP_ELSE:
		case SHARP_ENDIF:
			condition_macro(c, target);
			continue;
		default:
			break;
		}
		if (c == '('/* ) */)
			brace_level++;
		else if (c == /* ( */')') {
			if (--brace_level == 0)
				break;
		}
		/* pick up symbol */
		if (c == SYMBOL) {
			if (target == REF) {
				if (seems_datatype(token) && defined(token))
					PUT(token, lineno, sp);
			} else if (target == SYM) {
				if (!seems_datatype(token) || !defined(token))
					PUT(token, lineno, sp);
			}
		}
	}
	if (c == EOF)
		return 0;
	if (peekc(0) == ';') {
		(void)nexttoken(";", NULL);
		return 0;
	}
	brace_level = 0;
	while ((c = nexttoken(",;[](){}=", cpp_reserved_word)) != EOF) {
		switch (c) {
		case SHARP_IFDEF:
		case SHARP_IFNDEF:
		case SHARP_IF:
		case SHARP_ELIF:
		case SHARP_ELSE:
		case SHARP_ENDIF:
			condition_macro(c, target);
			continue;
		case CPP___ATTRIBUTE__:
			process_attribute(target);
			continue;
		default:
			break;
		}
		if (c == '('/* ) */ || c == '[')
			brace_level++;
		else if (c == /* ( */')' || c == ']')
			brace_level--;
		else if (brace_level == 0 && (c == ';' || c == ','))
			break;
		else if (c == '{' /* } */) {
			pushbacktoken();
			return 1;
		} else if (c == /* { */'}')
			break;
		else if (c == '=')
			break;
		/* pick up symbol */
		if (c == SYMBOL) {
			if (target == REF) {
				if (seems_datatype(token) && defined(token))
					PUT(token, lineno, sp);
			} else if (target == SYM) {
				if (!seems_datatype(token) || !defined(token))
					PUT(token, lineno, sp);
			}
		}
	}
	return 0;
}
Esempio n. 10
0
int main (int argc, char **argv)
{
	enum ParserState state = 0;
	gunichar in;
	gboolean init = FALSE;
	/* used to parse attribute */
	gint attributes = 0;
	/* Input/output */
	FILE *input = stdin;
	FILE  *output = stdout;
	/* Error */
	GError *error = NULL;

	/* init the glib system  */
	g_type_init();
	/* needed to get the right charset from g_get_charset */
	setlocale(LC_ALL, "");
	/* Get charset */
	g_get_charset(&input_charset);

	/* parse options */
	parse_cmd_options(&argc, &argv);

	/* Handle input file */
	if(input_file && strcmp(input_file, "-")) {
		input = g_fopen(input_file, "r");
		EXCEPTION(input == NULL, "Failed to open: %s: %s\n", input_file, strerror(errno));
	}
	/* Handle output file */
	if(output_file) {
		output = g_fopen(output_file, "w");
		EXCEPTION(output == NULL, "Failed to open: %s: %s\n", output_file, strerror(errno));
	}
	/* Create channel for input */
	GIOChannel *chan = g_io_channel_unix_new(fileno(input));
	/* Set channel encoding */
	g_io_channel_set_encoding(chan, input_charset,&error);
	EXCEPTION(error != NULL, "Failed to set input encoding: %s\n", error->message);

	/* Read input */
	while(g_io_channel_read_unichar(chan, &in, &error) == G_IO_STATUS_NORMAL && error == NULL)
	{
		if(!init) {
			/* Output html header */
			print_page_header(output);
			/* Convert and print body */
			fprintf(output, "<pre style='font-family:monospace'>\n");
			init = TRUE;
		}
		/* If we hit the escape character, go into 'attribute parsing' mode */
		if(in == ESCAPE_CHAR) {
			state = PARSE_ATTRIBUTE;
			/* reset */
			attributes = 0;
		}
		/* if we are in attribute parsing mode, parse attribute */
		else if(state == PARSE_ATTRIBUTE) {
			if(in == '[') {
				/* Begin of attributes */
				state = PARSE_COLOR_ATTRIBUTE;
			}else {
				WARNING("Unknown Escape sequence found: %i\n", in);
				state = PARSE_NORMAL;
			}
		} else if(state == PARSE_COLOR_ATTRIBUTE) {
			if (in == ';') { /* End of element */
				process_attribute(output, attributes);
				attributes = 0;
			} else if(in == 'm') { /* end of attribute */
				process_attribute(output, attributes);
				state = PARSE_NORMAL;
			} else if(in >= '0' && in <= '9') {
				attributes *= 10;
				attributes += in-'0';
			}else if (in == 'h' || in == 'l' ) {
				WARNING("Unsupported attribute found: %i\n", in);
				state = PARSE_NORMAL;
			}
			continue;
		} else if (state == PARSE_NORMAL) {
			/* special chars (htmlspecialchars php doc) */
			if(in == '"') fputs("&quot;", output);
			else if(in == '\'') fputs("&#039;", output);
			else if(in == '&') fputs("&amp;", output);
			else if(in == '<') fputs("&lt;", output);
			else if(in == '>') fputs("&gt;", output);
			/* ascii values stay ascii*/
			else if(in >= 0 && in <= 177)
				fprintf(output, "%c", (char)in);
			/* Rest we encode in utf8 */
			else fprintf(output, "&#%i;", in);
		}
	}
	EXCEPTION(error != NULL, "Failed to read input character: %s\n", error->message);
	if(init) {
		/* Close open tags */
		process_attribute(output, 0);
		fprintf(output,"\n  </pre>\n");
		print_page_footer(output);
	}

	/* free input channel */
	g_io_channel_unref(chan);

	/* close i/o */
	if(input != stdin) fclose(input);
	if(output != stdout) fclose(output);

	return EXIT_SUCCESS;
}
Esempio n. 11
0
void FileInfo::process_base_file_rec() {
  attr_list.clear();
  file_name_list.clear();
  // is attr. list present?
  unsigned attr_list_off = find_attribute(base_file_rec_buf, AT_ATTRIBUTE_LIST);
  // init. mft record counter
  mft_rec_cnt = 1;
  Array<u64> ext_rec_list;
  // no ATTRIBUTE_LIST - one MFT file record
  if (attr_list_off == -1) {
    const MFT_RECORD* mft_rec = reinterpret_cast<const MFT_RECORD*>(base_file_rec_buf.data());

    // walk over list of attributes stored in a base file record
    unsigned attr_off = mft_rec->attrs_offset;
    while (true) {
      const ATTR_HEADER* attr_header = reinterpret_cast<const ATTR_HEADER*>(base_file_rec_buf.data() + attr_off);
      CHECK_FMT(attr_off + sizeof(attr_header->type) <= base_file_rec_buf.size());
      if (attr_header->type == AT_END) break; // end of attribute list
      CHECK_FMT(attr_off + sizeof(ATTR_HEADER) <= base_file_rec_buf.size());

      process_attribute(base_file_rec_buf, attr_off);

      CHECK_FMT(attr_header->length != 0); // prevent infinite loop
      attr_off += attr_header->length;
    }
  }
  // ATTRIBUTE_LIST present
  else {
    process_attribute(base_file_rec_buf, attr_list_off);
    const ATTR_HEADER* attr_header = reinterpret_cast<const ATTR_HEADER*>(base_file_rec_buf.data() + attr_list_off);
    // non-resident ATTRIBUTE_LIST
    if (attr_header->non_resident) {
      CHECK_FMT(attr_list_off + sizeof(ATTR_HEADER) + sizeof(ATTR_NONRESIDENT) <= base_file_rec_buf.size());
      const ATTR_NONRESIDENT* attr_info = reinterpret_cast<const ATTR_NONRESIDENT*>(base_file_rec_buf.data() + attr_list_off + sizeof(ATTR_HEADER));
      CHECK_FMT(attr_info->allocated_size <= MAX_ATTR_LIST_SIZE);
      Array<DataRun> data_runs = decode_data_runs(base_file_rec_buf, attr_list_off);
      // calculate disk size using data runs
      u64 attr_disk_size = 0;
      for (unsigned i = 0; i < data_runs.size(); i++) {
        CHECK_FMT(data_runs[i].lcn != -1); // compressed or sparse not allowed
        attr_disk_size += data_runs[i].len * volume->cluster_size;
      }
      CHECK_FMT(attr_disk_size == attr_info->allocated_size);
      CHECK_FMT(attr_info->data_size <= attr_info->allocated_size);

      // load attribute list data from disk
      u8* attr_data_buf = static_cast<u8*>(VirtualAlloc(NULL, static_cast<SIZE_T>(attr_disk_size), MEM_COMMIT, PAGE_READWRITE));
      CHECK_SYS(attr_data_buf != NULL);
      CLEAN(u8*, attr_data_buf, CHECK_SYS(VirtualFree(attr_data_buf, 0, MEM_RELEASE)));

      unsigned buf_pos = 0;
      for (unsigned i = 0; i < data_runs.size(); i++) {
        LARGE_INTEGER pos;
        pos.QuadPart = data_runs[i].lcn * volume->cluster_size;
        CHECK_SYS(SetFilePointerEx(volume->handle, pos, NULL, FILE_BEGIN));

        unsigned size = static_cast<unsigned>(data_runs[i].len * volume->cluster_size);
        DWORD bytes_ret;
        volume->flush();
        CHECK_SYS(ReadFile(volume->handle, attr_data_buf + buf_pos, size, &bytes_ret, NULL));
        CHECK_FMT(size == bytes_ret);
        buf_pos += size;
      }

      // process attribute list entries
      unsigned idx = 0;
      while (idx != attr_info->data_size) {
        CHECK_FMT(idx + sizeof(ATTR_LIST_ENTRY) <= attr_info->data_size);
        const ATTR_LIST_ENTRY* attr_list_entry = reinterpret_cast<const ATTR_LIST_ENTRY*>(attr_data_buf + idx);

        process_attr_list_entry(attr_list_entry, ext_rec_list);

        CHECK_FMT(attr_list_entry->length != 0);
        idx += attr_list_entry->length;
      }
    }
    // resident ATTRIBUTE_LIST
    else {