示例#1
0
文件: getlines.c 项目: indera/miller
// ================================================================
static char* read_line_fgetc_psb(FILE* fp, string_builder_t* psb, char* irs) {
	while (TRUE) {
		int c = fgetc(fp);
		if (c == EOF) {
			if (sb_is_empty(psb))
				return NULL;
			else
				return sb_finish(psb);
		} else if (c == irs[0]) {
			return sb_finish(psb);
		} else {
			sb_append_char(psb, c);
		}
	}
}
示例#2
0
文件: getlines.c 项目: indera/miller
// ================================================================
static char* read_line_mmap_psb(file_reader_mmap_state_t* ph, string_builder_t* psb, char* irs) {
	char *p = ph->sol;
	while (TRUE) {
		if (p == ph->eof) {
			ph->sol = p;
			if (sb_is_empty(psb))
				return NULL;
			else
				return sb_finish(psb);
		} else if (*p == irs[0]) {
			ph->sol = p+1;
			return sb_finish(psb);
		} else {
			sb_append_char(psb, *p);
			p++;
		}
	}
}
示例#3
0
// ================================================================
static char* read_line_pfr_psb(peek_file_reader_t* pfr, string_builder_t* psb, char* irs, int irs_len) {
	while (TRUE) {
		if (pfr_at_eof(pfr)) {
			if (sb_is_empty(psb))
				return NULL;
			else
				return sb_finish(psb);
		} else if (pfr_next_is(pfr, irs, irs_len)) {
			if (!pfr_advance_past(pfr, irs)) {
				fprintf(stderr, "%s: Internal coding error: IRS found and lost.\n", MLR_GLOBALS.argv0);
				exit(1);
			}
			return sb_finish(psb);
		} else {
			sb_append_char(psb, pfr_read_char(pfr));
		}
	}
}
示例#4
0
文件: getlines.c 项目: indera/miller
static char* read_line_pfr_psb(peek_file_reader_t* pfr, string_builder_t* psb, parse_trie_t* ptrie) {
	int rc, stridx, matchlen;
	while (TRUE) {
		pfr_buffer_by(pfr, ptrie->maxlen);
		rc = parse_trie_ring_match(ptrie, pfr->peekbuf, pfr->sob, pfr->npeeked, pfr->peekbuflenmask,
			&stridx, &matchlen);
		if (rc) {
			pfr_advance_by(pfr, matchlen);
			switch(stridx) {
			case IRS_STRIDX:
				return sb_finish(psb);
				break;
			case IRSEOF_STRIDX:
				return sb_finish(psb);
				break;
			case EOF_STRIDX:
				return NULL;
				break;
			}
		} else {
			sb_append_char(psb, pfr_read_char(pfr));
		}
	}
}
示例#5
0
文件: lrec.c 项目: indera/miller
char* lrec_sprint(lrec_t* prec, char* ors, char* ofs, char* ops) {
	string_builder_t* psb = sb_alloc(SB_ALLOC_LENGTH);
	if (prec == NULL) {
		sb_append_string(psb, "NULL");
	} else {
		int nf = 0;
		for (lrece_t* pe = prec->phead; pe != NULL; pe = pe->pnext) {
			if (nf > 0)
				sb_append_string(psb, ofs);
			sb_append_string(psb, pe->key);
			sb_append_string(psb, ops);
			sb_append_string(psb, pe->value);
			nf++;
		}
		sb_append_string(psb, ors);
	}
	char* rv = sb_finish(psb);
	sb_free(psb);
	return rv;
}
示例#6
0
int
main(int argc, char **argv) {
    int i;
    UpClient *upclient;
    IxpClient *client;

    signals_setup(&quit_handler);

    client = ixp_nsmount("wmii");
    if(client == NULL) {
        printf("ixp_nsmount: %s\n", ixp_errbuf());
        abort();
    }

    mainloop = g_main_loop_new(NULL, FALSE);

    upclient = up_client_new();

    sb_init(&sb, client);
    sb_add(&sb, &sbe_ac);    
    for(i = 0; i < MAX_BATTERIES; i++) {
        sb_add(&sb, &sbe_batteries[i]);
    }

    up_client_enumerate_devices_sync(upclient, NULL, NULL);

    g_signal_connect(upclient, "device-added", G_CALLBACK(device_added_cb), NULL);
    g_signal_connect(upclient, "device-removed", G_CALLBACK(device_removed_cb), NULL);
    g_signal_connect(upclient, "device-changed", G_CALLBACK(device_changed_cb), NULL);
    g_signal_connect(upclient, "changed", G_CALLBACK(changed_cb), NULL);

    update_sb(upclient);

    g_main_loop_run(mainloop);

    sb_finish(&sb);

    ixp_unmount(client);
}
示例#7
0
/*
 * JSON serializes a collection of dSets.
 *
 * sets -- A collection of dSet objects.
 * count -- The number of dSets in sets.
 *
 */
char* json_serialize(dSet** sets, int count)
{
    SB sb;

    sb_init(&sb);

    sb_putc(&sb, '[');

    int i;
    for (i = 0; i < count; i++) {
        sb_put_dset(&sb, sets[i]);
        
        if (i != count - 1) {
            sb_putc(&sb, ',');
        }
    }
    
    sb_putc(&sb, ']');
    
    sb_finish(&sb);

    return sb.start;
}
示例#8
0
int
main(int argc, char **argv) {
    int n, nfds, res;
    struct itimerspec timerits;
    struct epoll_event events[MAX_EVENTS];
    struct epoll_event timerevent;
    IxpClient* client;
    struct sb sb;

    signals_setup(&quit_handler);

    struct sb_entry sbe_sda = {
        .sbe_path = "/rbar/60_sda",
        .sbe_private = "sda",
        .sbe_init = &init_block,
        .sbe_update = &update_block,
        .sbe_foreground = 0xbbbbbb,
        .sbe_background = 0x444444,
        .sbe_border     = 0x555555,        
    };

    struct sb_entry sbe_sdb = {
        .sbe_path = "/rbar/61_sdb",
        .sbe_private = "sdb",
        .sbe_init = &init_block,
        .sbe_update = &update_block,
        .sbe_foreground = 0xbbbbbb,
        .sbe_background = 0x444444,
        .sbe_border     = 0x555555,        
    };

    struct sb_entry sbe_sdc = {
        .sbe_path = "/rbar/62_sdc",
        .sbe_private = "sdc",
        .sbe_init = &init_block,
        .sbe_update = &update_block,
        .sbe_foreground = 0xbbbbbb,
        .sbe_background = 0x444444,
        .sbe_border     = 0x555555,        
    };

    int epollfd = epoll_create1(EPOLL_CLOEXEC);
    if(epollfd == -1) {
        perror("epoll_create");
        abort();
    }

    int timerfd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
    if(timerfd == -1) {
        perror("timerfd_create");
        abort();
    }
    timerevent.events = EPOLLIN;
    timerevent.data.fd = timerfd;
    timerits.it_interval.tv_sec = 0;
    timerits.it_interval.tv_nsec = 250 * 1000 * 1000;
    timerits.it_value.tv_sec = timerits.it_interval.tv_sec;
    timerits.it_value.tv_nsec = timerits.it_interval.tv_nsec;

    client = ixp_nsmount("wmii");
    if(client == NULL) {
        printf("ixp_nsmount: %s\n", ixp_errbuf());
        abort();
    }

    res = epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &timerevent);
    if(res == -1) {
        perror("epoll_ctl");
        abort();
    }
        
    res = timerfd_settime(timerfd, 0, &timerits, NULL);
    if(res == -1) {
        perror("timerfd_settime");
        abort();
    }

    sb_init(&sb, client);
    sb_add(&sb, &sbe_sda);
    sb_add(&sb, &sbe_sdb);
    sb_add(&sb, &sbe_sdc);

    while(1) {
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if(nfds == -1) {
		    if(errno != EINTR) {
                perror("epoll_wait");
                abort();
			}
        }

        if(should_quit) {
            break;
        }
        
        for (n = 0; n < nfds; n++) {
            if(events[n].data.fd == timerfd) {
                uint64_t x;
                read(timerfd, &x, sizeof(x));
                sb_update(&sb);
            }
        }
    }

    sb_finish(&sb);

    ixp_unmount(client);

    return 0;
}
示例#9
0
static int lrec_reader_stdio_csv_get_fields(lrec_reader_stdio_csv_state_t* pstate, rslls_t* pfields,
	context_t* pctx, int is_header)
{
	int rc, stridx, matchlen, record_done, field_done;
	peek_file_reader_t* pfr = pstate->pfr;
	string_builder_t*   psb = pstate->psb;
	char* field = NULL;
	int field_length = 0;

	if (pfr_peek_char(pfr) == (char)EOF) // char defaults to unsigned on some platforms
		return FALSE;

	// Strip the UTF-8 BOM, if any. This is MUCH simpler for mmap, and for stdio on files.  For mmap
	// we can test the first 3 bytes, then skip past them or not. For stdio on files we can fread
	// the first 3 bytes, then rewind the fp if they're not the UTF-8 BOM. But for stdio on stdin
	// (which is the primary reason we support stdio in Miller), we cannot rewind: stdin is not
	// rewindable.
	if (is_header) {
		pfr_buffer_by(pfr, UTF8_BOM_LENGTH);
		int rc = parse_trie_ring_match(pstate->putf8_bom_parse_trie,
			pfr->peekbuf, pfr->sob, pfr->npeeked, pfr->peekbuflenmask,
			&stridx, &matchlen);
#ifdef DEBUG_PARSER
		printf("RC=%d stridx=0x%04x matchlen=%d\n", rc, stridx, matchlen);
#endif
		if (rc == TRUE && stridx == UTF8_BOM_STRIDX) {
			pfr_advance_by(pfr, matchlen);
		}
	}

	// Loop over fields in record
	record_done = FALSE;
	while (!record_done) {
		// Assumption is dquote is "\""
		if (pfr_peek_char(pfr) != pstate->dquote[0]) { // NOT DOUBLE-QUOTED

			// Loop over characters in field
			field_done = FALSE;
			while (!field_done) {
				pfr_buffer_by(pfr, pstate->pno_dquote_parse_trie->maxlen);

				rc = parse_trie_ring_match(pstate->pno_dquote_parse_trie,
					pfr->peekbuf, pfr->sob, pfr->npeeked, pfr->peekbuflenmask,
					&stridx, &matchlen);
#ifdef DEBUG_PARSER
				pfr_print(pfr);
#endif
				if (rc) {
#ifdef DEBUG_PARSER
					printf("RC=%d stridx=0x%04x matchlen=%d\n", rc, stridx, matchlen);
#endif
					switch(stridx) {
					case EOF_STRIDX: // end of record
						rslls_append(pfields, sb_finish(psb), FREE_ENTRY_VALUE, 0);
						field_done  = TRUE;
						record_done = TRUE;
						break;
					case IFS_EOF_STRIDX:
						fprintf(stderr, "%s: syntax error: record-ending field separator at line %lld.\n",
							MLR_GLOBALS.bargv0, pstate->ilno);
						exit(1);
						break;
					case IFS_STRIDX: // end of field
						rslls_append(pfields, sb_finish(psb), FREE_ENTRY_VALUE, 0);
						field_done  = TRUE;
						break;
					case IRS_STRIDX: // end of record
						field = sb_finish_with_length(psb, &field_length);

						// The line-ending '\n' won't be included in the field buffer.
						if (pstate->do_auto_line_term) {
							if (field_length > 0 && field[field_length-1] == '\r') {
								field[field_length-1] = 0;
								context_set_autodetected_crlf(pctx);
							} else {
								context_set_autodetected_lf(pctx);
							}
						}

						rslls_append(pfields, field, FREE_ENTRY_VALUE, 0);
						field_done  = TRUE;
						record_done = TRUE;
						break;
					case DQUOTE_STRIDX: // CSV syntax error: fields containing quotes must be fully wrapped in quotes
						fprintf(stderr, "%s: syntax error: unwrapped double quote at line %lld.\n",
							MLR_GLOBALS.bargv0, pstate->ilno);
						exit(1);
						break;
					default:
						fprintf(stderr, "%s: internal coding error: unexpected token %d at line %lld.\n",
							MLR_GLOBALS.bargv0, stridx, pstate->ilno);
						exit(1);
						break;
					}
					pfr_advance_by(pfr, matchlen);
				} else {
#ifdef DEBUG_PARSER
					char c = pfr_read_char(pfr);
					printf("CHAR=%c [%02x]\n", isprint((unsigned char)c) ? c : ' ', (unsigned)c);
					sb_append_char(psb, c);
#else
					sb_append_char(psb, pfr_read_char(pfr));
#endif
				}
			}

		} else { // DOUBLE-QUOTED
			pfr_advance_by(pfr, pstate->dquotelen);

			// loop over characters in field
			field_done = FALSE;
			char* field = NULL;
			int field_length = 0;
			while (!field_done) {
				pfr_buffer_by(pfr, pstate->pdquote_parse_trie->maxlen);

				rc = parse_trie_ring_match(pstate->pdquote_parse_trie,
					pfr->peekbuf, pfr->sob, pfr->npeeked, pfr->peekbuflenmask,
					&stridx, &matchlen);

				if (rc) {
					switch(stridx) {
					case EOF_STRIDX: // end of record
						fprintf(stderr, "%s: unmatched double quote at line %lld.\n",
							MLR_GLOBALS.bargv0, pstate->ilno);
						exit(1);
						break;
					case DQUOTE_EOF_STRIDX: // end of record
						rslls_append(pfields, sb_finish(psb), FREE_ENTRY_VALUE, FIELD_QUOTED_ON_INPUT);
						field_done  = TRUE;
						record_done = TRUE;
						break;
					case DQUOTE_IFS_STRIDX: // end of field
						rslls_append(pfields, sb_finish(psb), FREE_ENTRY_VALUE, FIELD_QUOTED_ON_INPUT);
						field_done  = TRUE;
						break;
					case DQUOTE_IRS_STRIDX: // end of record
					case DQUOTE_IRS2_STRIDX: // end of record

						field = sb_finish_with_length(psb, &field_length);

						// The line-ending '\n' won't be included in the field buffer.
						if (pstate->do_auto_line_term) {
							if (field_length > 0 && field[field_length-1] == '\r') {
								field[field_length-1] = 0;
								context_set_autodetected_crlf(pctx);
							} else {
								context_set_autodetected_lf(pctx);
							}
						}

						rslls_append(pfields, field, FREE_ENTRY_VALUE, FIELD_QUOTED_ON_INPUT);
						field_done  = TRUE;
						record_done = TRUE;
						break;
					case DQUOTE_DQUOTE_STRIDX: // RFC-4180 CSV: "" inside a dquoted field is an escape for "
						sb_append_char(psb, pstate->dquote[0]);
						break;
					default:
						fprintf(stderr, "%s: internal coding error: unexpected token %d at line %lld.\n",
							MLR_GLOBALS.bargv0, stridx, pstate->ilno);
						exit(1);
						break;
					}
					pfr_advance_by(pfr, matchlen);
				} else {
					sb_append_char(psb, pfr_read_char(pfr));
				}
			}

		}
	}

	return TRUE;
}
示例#10
0
static int lrec_reader_mmap_csv_get_fields(lrec_reader_mmap_csv_state_t* pstate,
	rslls_t* pfields, file_reader_mmap_state_t* phandle, context_t* pctx)
{
	int rc, stridx, matchlen, record_done, field_done;
	string_builder_t* psb = pstate->psb;

	if (phandle->sol >= phandle->eof)
		return FALSE;

	char* p = phandle->sol;
	char* e = p;

	// loop over fields in record
	record_done = FALSE;
	while (!record_done) {
		// Assumption is dquote is "\""
		if (*e != pstate->dquote[0]) { // start of non-quoted field

			// Loop over characters in field
			field_done = FALSE;
			while (!field_done) {
				MLR_INTERNAL_CODING_ERROR_IF(e > phandle->eof);
				rc = parse_trie_match(pstate->pno_dquote_parse_trie, e, phandle->eof, &stridx, &matchlen);
				if (rc) {
					switch(stridx) {
					case IFS_STRIDX: // end of field
						*e = 0;
						rslls_append(pfields, p, NO_FREE, 0);
						p = e + matchlen;
						field_done  = TRUE;
						break;
					case IRS_STRIDX: // end of record
						*e = 0;

						if (pstate->do_auto_line_term) {
							if (e > p && e[-1] == '\r') {
								e[-1] = 0;
								context_set_autodetected_crlf(pctx);
							} else {
								context_set_autodetected_lf(pctx);
							}
						}

						rslls_append(pfields, p, NO_FREE, 0);
						p = e + matchlen;
						field_done  = TRUE;
						record_done = TRUE;
						break;
					case DQUOTE_STRIDX: // CSV syntax error: fields containing quotes must be fully wrapped in quotes
						fprintf(stderr, "%s: syntax error: unwrapped double quote at line %lld.\n",
							MLR_GLOBALS.bargv0, pstate->ilno);
						exit(1);
						break;
					default:
						fprintf(stderr, "%s: internal coding error: unexpected token %d at line %lld.\n",
							MLR_GLOBALS.bargv0, stridx, pstate->ilno);
						exit(1);
						break;
					}
					e += matchlen;
				} else if (e >= phandle->eof) {
					// We read to end of file without seeing end of line.  We can't always zero-poke a null character to
					// terminate the C string: if the file size is not a multiple of the OS page size it'll work (it's
					// our copy-on-write memory). But if the file size is a multiple of the page size, then zero-poking
					// at EOF is one byte past the page and that will segv us.
				    char* copy = mlr_alloc_string_from_char_range(p, phandle->eof - p);
					rslls_append(pfields, copy, FREE_ENTRY_VALUE, 0);
					p = e + matchlen;
					field_done  = TRUE;
					record_done = TRUE;
					break;
				} else {
					e++;
				}
			}

		} else { // start of quoted field
			e += pstate->dquotelen;
			p = e;

			// loop over characters in field
			field_done = FALSE;
			int contiguous = TRUE;
			// If there are no embedded double-double quotes, then the field value is a contiguous
			// array of bytes between the start and end double-quotes (non-inclusive). E.g. "ab,c"
			// has contents ab,c. In that case we can point the rslls at that range of bytes
			// with no data-copying. However, if there are embedded double-double quotes, then
			// we use the string-build logic to build up a dynamically allocated string. E.g.
			// "ab""c" becomes ab"c.
			while (!field_done) {
				if (e >= phandle->eof) {
					fprintf(stderr, "%s: unmatched double quote at line %lld.\n",
						MLR_GLOBALS.bargv0, pstate->ilno);
					exit(1);
				}

				rc = parse_trie_match(pstate->pdquote_parse_trie, e, phandle->eof, &stridx, &matchlen);

				if (rc) {
					switch(stridx) {
					case DQUOTE_IFS_STRIDX: // end of field
						*e = 0;
						if (contiguous)
							rslls_append(pfields, p, NO_FREE, FIELD_QUOTED_ON_INPUT);
						else
							rslls_append(pfields, sb_finish(psb), FREE_ENTRY_VALUE, FIELD_QUOTED_ON_INPUT);
						p = e + matchlen;
						field_done  = TRUE;
						break;
					case DQUOTE_IRS_STRIDX: // end of record
					case DQUOTE_IRS2_STRIDX: // end of record
						*e = 0;

						if (pstate->do_auto_line_term) {
							if (e > p && e[-1] == '\r') {
								e[-1] = 0;
								context_set_autodetected_crlf(pctx);
							} else {
								context_set_autodetected_lf(pctx);
							}
						}

						if (contiguous)
							rslls_append(pfields, p, NO_FREE, FIELD_QUOTED_ON_INPUT);
						else
							rslls_append(pfields, sb_finish(psb), FREE_ENTRY_VALUE, FIELD_QUOTED_ON_INPUT);
						p = e + matchlen;
						field_done  = TRUE;
						record_done = TRUE;
						break;
					case DQUOTE_DQUOTE_STRIDX: // RFC-4180 CSV: "" inside a dquoted field is an escape for "
						if (contiguous) { // not anymore it isn't
							sb_append_char_range(psb, p, e);
							contiguous = FALSE;
						} else {
							sb_append_char(psb, pstate->dquote[0]);
						}
						break;
					default:
						fprintf(stderr, "%s: internal coding error: unexpected token %d at line %lld.\n",
							MLR_GLOBALS.bargv0, stridx, pstate->ilno);
						exit(1);
						break;
					}
					e += matchlen;
				} else {
					if (!contiguous)
						sb_append_char(psb, *e);
					e++;
				}
			}
		}
	}
	phandle->sol = e;

	return TRUE;
}