int main() //@ : main //@ requires true; //@ ensures true; { struct socket *s = create_client_socket(12345); struct reader *r = socket_get_reader(s); struct writer *w = socket_get_writer(s); bool stop = false; struct string_buffer *line = create_string_buffer(); struct string_buffer *nick = create_string_buffer(); struct string_buffer *text = create_string_buffer(); reader_read_line(r, line); reader_read_line(r, line); writer_write_string(w, "BoT\r\n"); while (!stop) //@ invariant reader(r) &*& writer(w) &*& stop ? emp : string_buffer(line, _) &*& string_buffer(nick, _) &*& string_buffer(text, _); { bool test = true; bool result = false; reader_read_line(r, line); result = string_buffer_split(line, " says: ", nick, text); test = string_buffer_equals_string(nick, "BoT"); if (result && !test) { test = string_buffer_equals_string(text, "!hello"); if (test) { writer_write_string(w, "Hello "); writer_write_string_buffer(w, nick); writer_write_string(w, "!\r\n"); } else { test = string_buffer_equals_string(text, "!quit"); if (test) { writer_write_string(w, "Byebye!\r\n"); stop = true; string_buffer_dispose(line); string_buffer_dispose(nick); string_buffer_dispose(text); } } } } socket_close(s); return 0; }
void tokenizer_dispose(struct tokenizer *tokenizer) //@ requires Tokenizer(tokenizer); //@ ensures true; { string_buffer_dispose(tokenizer->buffer); free(tokenizer); }
static void log_lookup_error(value_t condition, value_t tags, frame_t *frame) { size_t arg_count = get_call_tags_entry_count(tags); string_buffer_t buf; string_buffer_init(&buf); string_buffer_printf(&buf, "%v: {", condition); for (size_t i = 0; i < arg_count; i++) { if (i > 0) string_buffer_printf(&buf, ", "); value_t tag = get_call_tags_tag_at(tags, i); value_t value = frame_get_pending_argument_at(frame, tags, i); string_buffer_printf(&buf, "%v: %v", tag, value); } string_buffer_printf(&buf, "}"); string_t str; string_buffer_flush(&buf, &str); ERROR("%s", str.chars); string_buffer_dispose(&buf); }
void string_buffer_drop_front(struct string_buffer *buffer, int length) //@ requires string_buffer(buffer, ?bcs) &*& length >= 0; //@ ensures string_buffer(buffer, _); { int length_buffer = string_buffer_get_length(buffer); if (length >= length_buffer){ string_buffer_clear(buffer); }else{ char *chars = string_buffer_get_chars(buffer); struct string_buffer *temp = create_string_buffer(); //@ chars_split(chars, length); //@ chars_limits(chars); string_buffer_append_chars(temp, chars+length, length_buffer - length); //@ string_buffer_merge_chars(buffer); string_buffer_clear(buffer); string_buffer_append_string_buffer(buffer, temp); string_buffer_dispose(temp); } }
void session_run(void *data) //@ : thread_run //@ requires thread_run_data(session_run)(data) &*& lockset(currentThread, nil); //@ ensures lockset(currentThread, nil); { //@ open thread_run_data(session_run)(data); struct session *session = data; //@ open session(session); struct room *room = session->room; struct lock *roomLock = session->room_lock; struct socket *socket = session->socket; struct writer *writer = socket_get_writer(socket); struct reader *reader = socket_get_reader(socket); free(session); writer_write_string(writer, "Welcome to the chat room.\r\n"); writer_write_string(writer, "The following members are present:\r\n"); lock_acquire(roomLock); //@ open room_ctor(room)(); //@ open room(room); { struct member *iter = room->members; //@ assert lseg(?membersList, 0, ?ms, member); //@ close lseg(membersList, membersList, nil, member); while (iter != 0) //@ invariant writer(writer) &*& lseg(membersList, iter, ?ms0, member) &*& lseg(iter, 0, ?ms1, member) &*& ms == append(ms0, ms1); { //@ open lseg(iter, 0, ms1, member); //@ open member(iter); writer_write_string_buffer(writer, iter->nick); writer_write_string(writer, "\r\n"); //@ close member(iter); iter = *(void **)(void *)iter; //@ lseg_add(membersList); } //@ lseg_append_final(membersList); } //@ close room(room); //@ close room_ctor(room)(); lock_release(roomLock); { struct string_buffer *nick = create_string_buffer(); bool done = false; while (!done) //@ invariant writer(writer) &*& reader(reader) &*& string_buffer(nick, _) &*& [_]lock(roomLock, _, room_ctor(room)) &*& lockset(currentThread, nil); { writer_write_string(writer, "Please enter your nick: "); { bool eof = reader_read_line(reader, nick); if (eof) { done = true; } else { lock_acquire(roomLock); //@ open room_ctor(room)(); { bool hasMember = room_has_member(room, nick); if (hasMember) { //@ close room_ctor(room)(); lock_release(roomLock); writer_write_string(writer, "Error: This nick is already in use.\r\n"); } else { session_run_with_nick(room, roomLock, reader, writer, nick); done = true; } } } } } string_buffer_dispose(nick); } socket_close(socket); }
void session_run_with_nick(struct room *room, struct lock *roomLock, struct reader *reader, struct writer *writer, struct string_buffer *nick) /*@ requires locked(roomLock, ?roomLockId, room_ctor(room), currentThread, _) &*& lockset(currentThread, cons(roomLockId, nil)) &*& room(room) &*& reader(reader) &*& writer(writer) &*& string_buffer(nick, _); @*/ /*@ ensures [_]lock(roomLock, roomLockId, room_ctor(room)) &*& lockset(currentThread, nil) &*& reader(reader) &*& writer(writer) &*& string_buffer(nick, _); @*/ { struct member *member = 0; struct string_buffer *joinMessage = create_string_buffer(); string_buffer_append_string_buffer(joinMessage, nick); string_buffer_append_string(joinMessage, " has joined the room."); room_broadcast_message(room, joinMessage); string_buffer_dispose(joinMessage); { struct string_buffer *nickCopy = string_buffer_copy(nick); //@ open room(room); member = malloc(sizeof(struct member)); if (member == 0) { abort(); } member->nick = nickCopy; member->writer = writer; //@ split_fraction member_writer(member, _) by 1/2; //@ close member(member); //@ assert room->members |-> ?list &*& lseg(list, 0, ?members, @member); member->next = room->members; room->members = member; //@ open member_next(member, _); //@ close lseg(member, 0, cons(member, members), @member); //@ assert [_]room->ghost_list_id |-> ?id; //@ split_fraction room_ghost_list_id(room, id); //@ ghost_list_add(id, member); //@ close room(room); } //@ close room_ctor(room)(); lock_release(roomLock); //@ leak [_]lock(roomLock, roomLockId, room_ctor(room)); { bool eof = false; struct string_buffer *message = create_string_buffer(); while (!eof) //@ invariant reader(reader) &*& string_buffer(nick, _) &*& string_buffer(message, _) &*& [_]lock(roomLock, roomLockId, room_ctor(room)) &*& lockset(currentThread, nil); { eof = reader_read_line(reader, message); if (eof) { } else { lock_acquire(roomLock); //@ open room_ctor(room)(); { struct string_buffer *fullMessage = create_string_buffer(); string_buffer_append_string_buffer(fullMessage, nick); string_buffer_append_string(fullMessage, " says: "); string_buffer_append_string_buffer(fullMessage, message); room_broadcast_message(room, fullMessage); string_buffer_dispose(fullMessage); } //@ close room_ctor(room)(); lock_release(roomLock); } } string_buffer_dispose(message); } lock_acquire(roomLock); //@ open room_ctor(room)(); //@ open room(room); { struct member *membersList = room->members; //@ open room_members(room, _); //@ assert lseg(membersList, 0, ?members, @member); //@ assert [_]ghost_list_member_handle(?id, ?d); //@ ghost_list_member_handle_lemma(id, d); lseg_remove(&room->members, member); //@ assert pointer(&room->members, ?list); //@ close room_members(room, list); //@ assert pointer((void *)member, ?memberNext); //@ close member_next(member, memberNext); } //@ assert ghost_list(?id, _); //@ ghost_list_remove(id, member); //@ close room(room); { struct string_buffer *goodbyeMessage = create_string_buffer(); string_buffer_append_string_buffer(goodbyeMessage, nick); string_buffer_append_string(goodbyeMessage, " left the room."); room_broadcast_message(room, goodbyeMessage); string_buffer_dispose(goodbyeMessage); } //@ close room_ctor(room)(); lock_release(roomLock); //@ open member(member); string_buffer_dispose(member->nick); free(member); }
static int do_parse_lists (FILE *h_file, FILE *c_file, const ListDescription *lists) { int k; int result = 1; int had_c_includes = 0; int had_h_includes = 0; int in_list = 0; int equal_to_last = 0; int h_file_line_length = 0; int num_c_file_array_elements = 0; int pending_linefeeds = 0; const char *h_file_enum_name = NULL; const char *c_file_array_name = NULL; char *last_identifier = NULL; char *pending_h_comment = NULL; char *pending_c_comment = NULL; char *pending_eol_comment = NULL; StringBuffer c_file_arrays[NUM_LIST_SORT_ORDERS]; StringBuffer *list_c_file_array = NULL; StringBuffer h_file_enums; string_buffer_init (&h_file_top, 0x2000, 0x1000); string_buffer_init (&h_file_bottom, 0x2000, 0x1000); string_buffer_init (&h_file_enums, 0x2000, 0x1000); string_buffer_init (&c_file_top, 0x2000, 0x1000); string_buffer_init (&c_file_bottom, 0x2000, 0x1000); for (k = 0; k < NUM_LIST_SORT_ORDERS; k++) string_buffer_init (&c_file_arrays[k], 0x2000, 0x1000); while (1) { char *line = read_line (); if (!line) { while (lists->name && lists->multiple_lists_allowed) lists++; if (!condition_stack) { if (!lists->name) { result = 0; if (lists->list_finalizer) { if (lists->list_finalizer (NULL)) result = 1; } } else { fprintf (stderr, "%s: unexpected end of file: list of type `%s' expected\n", short_program_name, lists->name); } } else { fprintf (stderr, "%s: unexpected end of file: condition `%s' unterminated\n", short_program_name, condition_stack->condition->identifier); } break; } if (! *line) continue; if (line[0] == '#') { if (line[1] == '>') { line = line + 2; while (isspace (*line)) line++; utils_free (pending_h_comment); pending_h_comment = utils_duplicate_string (line); utils_free (pending_c_comment); pending_c_comment = utils_duplicate_string (line); } continue; } if (in_list) { if (line[0] != '}') { char first_char = line[0]; const char *identifier = NULL; if (first_char != '=' && first_char != '+') { if (lists->line_parser1) { if (lists->line_parser1 (&line)) break; if (!line) continue; while (*line && isspace (*line)) line++; } } else { if (!h_file_enum_name) { print_error ("`+' and `=' directives are not allowed " "in lists that don't generate enumerations"); break; } do line++; while (isspace (*line)); } if ((!pending_eol_comment || ! *pending_eol_comment) && last_identifier && h_file_enum_name) string_buffer_cat_string (&h_file_enums, ",\n"); if (pending_eol_comment) { if (*pending_eol_comment && h_file_enum_name) { string_buffer_cprintf (&h_file_enums, ",%s/* %s */\n", TABBING (7, h_file_line_length + 1), pending_eol_comment); } utils_free (pending_eol_comment); pending_eol_comment = NULL; } if (pending_h_comment) { if (*pending_h_comment && h_file_enum_name) { if (last_identifier) string_buffer_add_character (&h_file_enums, '\n'); string_buffer_cat_strings (&h_file_enums, " /* ", pending_h_comment, " */\n", NULL); } utils_free (pending_h_comment); pending_h_comment = NULL; } if (h_file_enum_name) { identifier = parse_thing (IDENTIFIER, &line, "identifier"); if (!identifier) break; string_buffer_cat_strings (&h_file_enums, " ", identifier, NULL); h_file_line_length = 2 + strlen (identifier); if (first_char == '=' || equal_to_last) { string_buffer_cat_strings (&h_file_enums, " = ", last_identifier, NULL); h_file_line_length += 3 + strlen (last_identifier); } utils_free (last_identifier); last_identifier = utils_duplicate_string (identifier); } if (first_char != '+') { if (first_char != '=') { if (c_file_array_name && *lists->c_file_array_type) { if (num_c_file_array_elements > 0) { string_buffer_add_character (list_c_file_array, ','); string_buffer_add_characters (list_c_file_array, '\n', 1 + pending_linefeeds); } if (pending_c_comment) { if (*pending_c_comment) { if (num_c_file_array_elements > 0) string_buffer_add_character (list_c_file_array, '\n'); string_buffer_cat_strings (list_c_file_array, " /* ", pending_c_comment, " */\n", NULL); } utils_free (pending_c_comment); pending_c_comment = NULL; } } if (c_file_array_name) num_c_file_array_elements++; pending_linefeeds = 0; if (lists->line_parser2 (list_c_file_array, &line, identifier, &pending_eol_comment, &pending_linefeeds)) break; if (*line) { print_error ("unexpected characters at the end of line"); break; } if (pending_linefeeds < 0) { pending_linefeeds = 0; if (! *line) { while (1) { line = read_line (); if (line && ! *line) pending_linefeeds++; else { reuse_last_line (&line); break; } } } } } equal_to_last = 0; } else { if (equal_to_last) { print_error ("second inserted identifier in a row; " "did you mean `='?"); break; } equal_to_last = 1; } } else { if (!last_identifier && num_c_file_array_elements == 0) { print_error ("empty list `%s'", lists->name); break; } if (pending_eol_comment) { if (*pending_eol_comment && h_file_enum_name) { string_buffer_cprintf (&h_file_enums, "%s/* %s */", TABBING (7, h_file_line_length), pending_eol_comment); } utils_free (pending_eol_comment); pending_eol_comment = NULL; } if (lists->list_finalizer) { if (lists->list_finalizer (list_c_file_array)) break; } if (h_file_enum_name) { if (strcmp (h_file_enum_name, "unnamed") != 0) { string_buffer_cat_strings (&h_file_enums, "\n} ", h_file_enum_name, ";\n", NULL); } else string_buffer_cat_string (&h_file_enums, "\n};\n"); } if (c_file_array_name && *lists->c_file_array_type) string_buffer_cat_string (list_c_file_array, "\n};\n"); if (!lists->multiple_lists_allowed) lists++; in_list = 0; } } else { if (looking_at ("@include", &line) || looking_at ("@c_include", &line)) { if (! *line) { print_error ("filename expected"); break; } if (!had_c_includes) { fputs ("\n\n", c_file); had_c_includes = 1; } fprintf (c_file, "#include %s\n", line); } else if (looking_at ("@h_include", &line)) { if (! *line) { print_error ("filename expected"); break; } if (had_h_includes != 1) { fputs ((had_h_includes == 0 ? "\n\n" : "\n"), h_file); had_h_includes = 1; } fprintf (h_file, "#include %s\n", line); } else if (looking_at ("@define_condition", &line)) { const PredefinedCondition *condition = get_condition (&line); if (!condition) break; if (had_h_includes != 2) { fputs ((had_h_includes == 0 ? "\n\n" : "\n"), h_file); had_h_includes = 2; } fprintf (h_file, "#define %s%s%d\n", condition->identifier, TABBING (4, 8 + strlen (condition->identifier)), condition->value); } else { const char *identifier = parse_thing (IDENTIFIER, &line, "list name"); if (!identifier) break; if (!lists->name) { print_error ("unexpected list beginning"); break; } if (lists->multiple_lists_allowed && strcmp (identifier, lists->name) != 0 && (lists + 1)->name) lists++; if (strcmp (identifier, lists->name) == 0) { if (looking_at ("-", &line)) { if (lists->enumeration_required) { print_error ("enumeration name expected"); break; } h_file_enum_name = NULL; } else { h_file_enum_name = parse_thing (IDENTIFIER, &line, "enumeration name"); if (!h_file_enum_name) break; } if (!lists->c_file_array_type) { if (!looking_at ("-", &line)) { print_error ("unexpected array name"); break; } c_file_array_name = NULL; } else { if (looking_at ("-", &line)) { print_error ("array name expected"); break; } c_file_array_name = parse_thing (IDENTIFIER, &line, "array name"); if (!c_file_array_name) break; } if (*line != '{') { print_error ("list opening brace expected"); break; } if (*(line + 1)) { print_error ("unexpected characters at the end of line"); break; } if (pending_h_comment) { if (*pending_h_comment && h_file_enum_name) { string_buffer_cat_strings (&h_file_enums, "/* ", pending_h_comment, " */\n", NULL); } utils_free (pending_h_comment); pending_h_comment = NULL; } assert (0 <= lists->sort_order && lists->sort_order <= NUM_LIST_SORT_ORDERS); list_c_file_array = &c_file_arrays[lists->sort_order]; if (h_file_enum_name) { if (strcmp (h_file_enum_name, "unnamed") != 0) string_buffer_cat_string (&h_file_enums, "\n\ntypedef enum {\n"); else string_buffer_cat_string (&h_file_enums, "\n\nenum {\n"); } if (c_file_array_name && *lists->c_file_array_type) { string_buffer_cat_strings (list_c_file_array, "\n\n", lists->c_file_array_type, c_file_array_name, "[] = {\n", NULL); } if (lists->list_initializer) { if (lists->list_initializer (list_c_file_array, h_file_enum_name, c_file_array_name)) break; } in_list = 1; equal_to_last = 0; num_c_file_array_elements = 0; pending_linefeeds = 1; utils_free (last_identifier); last_identifier = NULL; } else { print_error ("list name `%s' expected, got `%s'", lists->name, identifier); break; } } } } if (h_file_top.length > 0) fwrite (h_file_top.string, h_file_top.length, 1, h_file); if (h_file_enums.length > 0) fwrite (h_file_enums.string, h_file_enums.length, 1, h_file); if (h_file_bottom.length > 0) fwrite (h_file_bottom.string, h_file_bottom.length, 1, h_file); string_buffer_dispose (&h_file_top); string_buffer_dispose (&h_file_bottom); string_buffer_dispose (&h_file_enums); if (c_file_top.length > 0) fwrite (c_file_top.string, c_file_top.length, 1, c_file); for (k = 0; k < NUM_LIST_SORT_ORDERS; k++) { fwrite (c_file_arrays[k].string, c_file_arrays[k].length, 1, c_file); string_buffer_dispose (&c_file_arrays[k]); } if (c_file_bottom.length > 0) fwrite (c_file_bottom.string, c_file_bottom.length, 1, c_file); string_buffer_dispose (&c_file_top); string_buffer_dispose (&c_file_bottom); utils_free (last_identifier); utils_free (pending_h_comment); utils_free (pending_c_comment); utils_free (pending_eol_comment); string_list_empty (&lines); return result; }