char *justify(char **original_words, uint8_t word_count) { char **words = (char **) calloc(word_count, sizeof(char *)); memcpy(words, original_words, word_count * sizeof(char *)); char *result = (char *) calloc(MAX_MESSAGE_LENGTH + 1, sizeof(char)); justify_state state; state.cursor = result; state.line_index = 0; state.line_length = 0; for (uint8_t i = 0; i < word_count; ++i) { char *word = words[i]; uint8_t word_length = strlen(word); uint8_t words_left = word_count - i; uint8_t line_chars_left = LINE_LENGTH - state.line_length; // If there are already words on the current line, count the space needed after them. if (state.line_length > 0 && line_chars_left > 0) { line_chars_left -= 1; } uint8_t lines_below = LINE_COUNT - (state.line_index + 1); uint8_t room_below = lines_below * LINE_LENGTH; // If word fits on current line. if (word_length <= line_chars_left) { add_word(word, word_length, &state); } // If word does not fit on current line but can be moved to next line. else if (room_needed(words + i, words_left) <= room_below && word_length <= LINE_LENGTH) { add_newline(&state); add_word(word, word_length, &state); } // Otherwise, word must be broken. else { uint8_t first_part_length = line_chars_left; add_word(word, first_part_length, &state); add_newline(&state); // Move current string pointer and decrement word index, // "tricking" the program into thinking that we've inserted a new word. words[i] += first_part_length; --i; } } free(words); return result; }
Datum dbms_output_new_line(PG_FUNCTION_ARGS) { if (buffer) add_newline(); PG_RETURN_VOID(); }
Datum dbms_output_put_line(PG_FUNCTION_ARGS) { if (buffer) { add_text(PG_GETARG_TEXT_PP(0)); add_newline(); } PG_RETURN_VOID(); }
int main(int argc, char **argv) { program_name = basename(argv[0]); snprintf(doc,DOC_BUFFER_LEN,"%s -- a simple client for COMP-535",program_name); struct arguments arguments; /* Default values. */ arguments.port = -1; arguments.host = NULL; arguments.adaptive = 0; arguments.verbose = 0; arguments.silent = 0; arguments.batch = 0; arguments.devnull = 0; arguments.infile = NULL; argp_parse (&argp, argc, argv, 0, 0, &arguments); verbose_f = 0; if (arguments.verbose) verbose_f = 1; if (arguments.silent) { freopen("/dev/null", "w", stderr); freopen("/dev/null", "w", stdout); } batch_f = arguments.batch; adaptive_f = arguments.adaptive; if (arguments.infile) { if(freopen(arguments.infile, "r", stdin) == NULL){ exit(1); } } sockfd = -1; if (adaptive_f) adaptivefd = -1; signal(SIGINT, interrupt); char foldertmp[] = "clientimgXXXXXX"; char s[INET6_ADDRSTRLEN], *t, *line, linebuf[LINE_SIZE]; char *filename, *filebuf; int cid, l; /* Return values, temp values */ FILE *file; size_t filesize, read, remain, total, chunk; sockfd = connect_to_host(arguments.host, arguments.port, s, sizeof s); if (sockfd == -1) { fprintf(stderr, "failed to connect to server.\n"); global_exit(1); } fprintf(stdout, "Connected to %s\n", s); buffer = ALLOC(readbuffer); buffer->used = 0; // HELLO YES THIS IS SERVER line = recvline(); t = strtok(line,DELIM); if (strcmp(t, "HELLO") != 0){ fprintf(stderr,"Unexpected message from server: %s\nExiting.\n", line); global_exit(0); } t = strtok(NULL,DELIM); cid = (int)strtol(t,NULL,0); if (errno == ERANGE) { /* Not a number? or number too big? */ fprintf(stderr, "Invalid client ID from server. Exiting"); global_exit(1); } fprintf(stdout, "Got client ID: %d\n", cid); if (adaptive_f) { if ((t = strtok(NULL,DELIM)) == NULL){ fprintf(stderr, "Server is not in adaptive mode. Exiting\n"); global_exit(1); } errno = 0; l = (int)strtol(t,NULL,0); if (errno == ERANGE) { /* Not a number? or number too big? */ fprintf(stderr, "Invalid port number from server. Exiting"); global_exit(1); } adaptivefd = connect_to_host(arguments.host, l, NULL, 0); if (adaptivefd == -1) { fprintf(stderr, "failed to connect to adaptive server.\n"); global_exit(2); } snprintf(linebuf, LINE_SIZE, "%d\n", cid); if (send(adaptivefd, linebuf, strlen(linebuf), 0) == -1){ perror("send"); global_exit(1); } } efree(line); if (!arguments.devnull){ mkdtemp(foldertmp); fprintf(stdout, "Storing downloaded images in directory %s.\n", foldertmp); } for (;;) { #ifdef HAS_GNUREADLINE if(snreadline(linebuf, LINE_SIZE, "GET> ") == NULL){ #else if (!batch_f) fprintf(stderr, "GET> "); if(fgets(linebuf, LINE_SIZE, stdin) == NULL){ #endif printf("exit\n"); global_exit(0); } #ifndef HAS_GNUREADLINE trim_in_place(linebuf); #endif if (strlen(linebuf) == 0) continue; /* Hacky hack to transmit panning speed, any 2 or less digit number is considered a pan speed */ if (adaptive_f && strlen(linebuf) < 3 && is_number(linebuf)) { add_newline(linebuf, LINE_SIZE); if (send(adaptivefd, linebuf, strlen(linebuf), 0) == -1){ perror("send"); global_exit(1); } continue; } if (add_newline(linebuf, LINE_SIZE)) { fprintf(stderr, "Command too long.\n"); continue; } if (send(sockfd, linebuf, strlen(linebuf), 0) == -1){ perror("send"); global_exit(1); } remove_newline(linebuf); line = recvline(); t = strtok(line,DELIM); if (strcmp(t, "ERROR") == 0){ t = strtok(NULL,DELIM); fprintf(stderr, "Server> Error: %s\n", t); } else if (strcmp(t, "FILE") == 0) { t = strtok(NULL,DELIM); errno = 0; size_t filesize = (size_t)strtol(t,NULL,0); if (errno == ERANGE) { fprintf(stderr,"Fatal Error: Could not parse file size.\n", t); global_exit(0); } if (!arguments.devnull) { l = snprintf(NULL, 0, "%s/%s", foldertmp, linebuf); filename = (char *)emalloc(l+1); snprintf(filename, l+1, "%s/%s", foldertmp, linebuf); } else { filename = (char *)emalloc(10); snprintf(filename, 10, "/dev/null"); } file = fopen(filename,"wb"); efree(filename); chunk = (filesize > MAX_FILE_BUFFER) ? MAX_FILE_BUFFER : filesize; filebuf = (char *)emalloc(chunk); remain = filesize; total = 0; if (buffer->used > 0){ fwrite(buffer->data, 1, buffer->used, file); total += buffer->used; remain -= buffer->used; buffer->used = 0; } fprintf(stderr,"'%s' [%ld/%ld] (%ld%%)", linebuf, (long)total, (long)filesize, (long)(100*total)/filesize); while (remain > 0) { read = recv(sockfd, filebuf, chunk, 0); if (read == -1) { perror("recv"); global_exit(3); } else if (read == 0) { fprintf(stderr,"Server dropped connection.\n"); global_exit(4); } total += read; remain -= read; fprintf(stderr,"%c[2K\r", 27); fprintf(stderr,"'%s' [%ld/%ld] (%ld%%)", linebuf, (long)total, (long)filesize, (long)(100*total)/filesize); fwrite(filebuf, 1, read, file); } fprintf(stderr,"%c[2K\r", 27); printf("'%s' saved. [%ld/%ld]\n", linebuf, (long)total, (long)filesize); fclose(file); efree(filebuf); } else { verbose("Ignoring unexpected message from server: %s\n", t); } efree(line); } }