/* annotated-file.c: * * vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2 **************************************************************** * Copyright (C) 2005 Canonical Limited * Authors: Robert Collins * * See the file "COPYING" for further information about * the copyright and warranty status of this work. */ #include "hackerlab/bugs/exception.h" #include "hackerlab/char/str.h" #include "hackerlab/os/errno.h" #include "libarch/annotated-file.h" static int arch_annotated_file_destroy (void *data); void arch_annotated_file_init (arch_annotated_file_t *file, t_uchar const * file_id, int lines) { file->lines = lim_zalloc (0, sizeof (file->lines[0]) * lines ); file->file_id = talloc_strdup (file, file_id); file->unknown_lines = lines; file->max_lines = lines; file_offset_mapper_init (&file->mapper, lines); } void arch_annotated_file_finalise (arch_annotated_file_t *file) { int position; for (position = 0; position < file->max_lines; ++ position) arch_patch_delete (&(file->lines[position])); lim_free (0, file->lines); file->lines = NULL; file_offset_mapper_finalise (&file->mapper); } arch_annotated_file_t * arch_annotated_file_new (void * context, t_uchar const *file_id, int lines) { arch_annotated_file_t *result = talloc (context, arch_annotated_file_t); talloc_set_destructor (result, arch_annotated_file_destroy); arch_annotated_file_init (result, file_id, lines); return result; } int arch_annotated_file_destroy (void *data) { arch_annotated_file_t *patch = talloc_get_type (data, arch_annotated_file_t); if (!patch) return 0; arch_annotated_file_finalise (patch); return 0; } #include "hackerlab/vu/safe.h" /** * \brief annotate a specific line in the file * if final is true, then this is not the result of a merge. * \throw EINVAL if patch is NULL */ void arch_annotated_file_note_line (arch_annotated_file_t *file, int line, arch_patch_t *patch, int final) { int mapped_line; if (!patch) Throw (exception (EINVAL, "No patch supplied to arch_annotated_file_note_line")); mapped_line = file_offset_mapper_map (&file->mapper, line); if (mapped_line >= file->max_lines) Throw (exception (EDOM, "arch_annotated_file_note_line: line is invalid")); file_offset_mapper_add (&file->mapper, line); if (mapped_line < 0) return; if (file->lines[mapped_line]) { safe_printfmt (2, "Error : line %d mapped to %d which already has an annotation of %s\n", line, mapped_line, arch_patch_id_patch_id(arch_patch_patch_id(file->lines[mapped_line]))); file_offset_mapper_print (2, &file->mapper); } if (file->lines[mapped_line] != NULL) Throw (exception (EEXIST, "arch_annotated_file_note_line: already mapped to")); file->lines[mapped_line] = arch_patch_copy (patch); if (final) --file->unknown_lines; } /** * \@brief note a - line from a patch. */ void arch_annotated_file_note_subtract (arch_annotated_file_t *file, int line) { file_offset_mapper_subtract (&file->mapper, line); }