/* Control the refresh of dynamic elements in the page */ PUBLIC void espRefresh(HttpConn *conn, cchar *on, cchar *off, cchar *optionString) { MprHash *options; options = httpGetOptions(optionString); espRender(conn, "<img src='%s' " EDATA("on") "='%s' " EDATA("off") "='%s%s' class='" ESTYLE("refresh") "' />", on, on, off, map(conn, options)); }
/* tabs(makeGrid("[{ name: 'Status', uri: 'pane-1' }, { name: 'Edit', uri: 'pane-2' }]")) Options: click toggle remote */ PUBLIC void espTabs(HttpConn *conn, EdiGrid *grid, cchar *optionString) { MprHash *options; EdiRec *rec; cchar *attr, *uri, *name, *klass; int r, toggle; options = httpGetOptions(optionString); httpInsertOption(options, "class", ESTYLE("tabs")); attr = httpGetOption(options, "toggle", EDATA("click")); if ((toggle = smatch(attr, "true")) != 0) { attr = EDATA("toggle"); } espRender(conn, "<div%s>\r\n <ul>\r\n", map(conn, options)); for (r = 0; r < grid->nrecords; r++) { rec = grid->records[r]; name = ediGetFieldValue(rec, "name"); uri = ediGetFieldValue(rec, "uri"); uri = toggle ? uri : httpUri(conn, uri); if ((r == 0 && toggle) || smatch(uri, conn->rx->pathInfo)) { klass = smatch(uri, conn->rx->pathInfo) ? " class='esp-selected'" : ""; } else { klass = ""; } espRender(conn, " <li %s='%s'%s>%s</li>\r\n", attr, uri, klass, name); } espRender(conn, " </ul>\r\n </div>\r\n"); }
PUBLIC void form(EdiRec *record, cchar *optionString) { HttpConn *conn; MprHash *options; cchar *action, *recid, *method, *uri, *token; conn = getConn(); if (record == 0) { record = getRec(); } else { conn->record = record; } options = httpGetOptions(optionString); recid = 0; /* If record provided, get the record id. Can be overridden using options.recid */ if (record) { if (record->id && !httpGetOption(options, "recid", 0)) { httpAddOption(options, "recid", record->id); } recid = httpGetOption(options, "recid", 0); emitFormErrors(conn, record, options); } if ((method = httpGetOption(options, "method", 0)) == 0) { method = (recid) ? "PUT" : "POST"; } if (!scaselessmatch(method, "GET") && !scaselessmatch(method, "POST")) { /* All methods use POST and tunnel method in data-method */ httpAddOption(options, EDATA("method"), method); method = "POST"; } if ((action = httpGetOption(options, "action", 0)) == 0) { action = (recid) ? "@update" : "@create"; } uri = httpUri(conn, action); if (smatch(httpGetOption(options, "remote", 0), "true")) { espRender(conn, "<form method='%s' " EDATA("remote") "='%s'%s >\r\n", method, uri, map(conn, options)); } else { espRender(conn, "<form method='%s' action='%s'%s >\r\n", method, uri, map(conn, options)); } if (recid) { espRender(conn, " <input name='recid' type='hidden' value='%s' />\r\n", recid); } if (!httpGetOption(options, "insecure", 0)) { if ((token = httpGetOption(options, "securityToken", 0)) == 0) { token = httpGetSecurityToken(conn, 0); } espRender(conn, " <input name='%s' type='hidden' value='%s' />\r\n", BIT_XSRF_PARAM, token); } }
/* Map options to an attribute string. Remove all internal control specific options and transparently handle URI link options. WARNING: this returns a non-cloned reference and relies on no GC yield until the returned value is used or cloned. This is done as an optimization to reduce memeory allocations. */ static cchar *map(HttpConn *conn, MprHash *options) { Esp *esp; EspReq *req; MprHash *params; MprKey *kp; MprBuf *buf; cchar *value; char *pstr; if (options == 0 || mprGetHashLength(options) == 0) { return MPR->emptyString; } req = conn->data; if (httpGetOption(options, EDATA("refresh"), 0) && !httpGetOption(options, "id", 0)) { httpAddOption(options, "id", sfmt("id_%d", req->lastDomID++)); } esp = MPR->espService; buf = mprCreateBuf(-1, -1); for (kp = 0; (kp = mprGetNextKey(options, kp)) != 0; ) { if (kp->type != MPR_JSON_OBJ && kp->type != MPR_JSON_ARRAY && !mprLookupKey(esp->internalOptions, kp->key)) { mprPutCharToBuf(buf, ' '); value = kp->data; /* Support link template resolution for these options */ if (smatch(kp->key, EDATA("click")) || smatch(kp->key, EDATA("remote")) || smatch(kp->key, EDATA("refresh"))) { value = httpUriEx(conn, value, options); if ((params = httpGetOptionHash(options, "params")) != 0) { pstr = (char*) ""; for (kp = 0; (kp = mprGetNextKey(params, kp)) != 0; ) { pstr = sjoin(pstr, mprUriEncode(kp->key, MPR_ENCODE_URI_COMPONENT), "=", mprUriEncode(kp->data, MPR_ENCODE_URI_COMPONENT), "&", NULL); } if (pstr[0]) { /* Trim last "&" */ pstr[strlen(pstr) - 1] = '\0'; } mprPutToBuf(buf, "%s-params='%s", params); } } mprPutStringToBuf(buf, kp->key); mprPutStringToBuf(buf, "='"); mprPutStringToBuf(buf, value); mprPutCharToBuf(buf, '\''); } } mprAddNullToBuf(buf); return mprGetBufStart(buf); }
static void eload(Space *s, uint8_t old_type, int32_t &addr) { uint8_t num = read_8(addr); if (!s->setup_nums(num, num)) { debug("Failed to set up extruder axes"); uint8_t n = min(s->num_axes, s->num_motors); if (!s->setup_nums(n, n)) { debug("Trouble! Failed to abort. Cancelling."); s->cancel_update(); } } for (int a = EDATA(s).num_axes; a < s->num_axes; ++a) { s->axis[a]->type_data = new ExtruderAxisData; for (int i = 0; i < 3; ++i) EADATA(s, a).offset[i] = 0; } EDATA(s).num_axes = s->num_axes; bool move = false; if (motors_busy && !computing_move && settings.queue_start == settings.queue_end && !settings.queue_full) { move = true; queue[settings.queue_end].probe = false; queue[settings.queue_end].cb = false; queue[settings.queue_end].f[0] = INFINITY; queue[settings.queue_end].f[1] = INFINITY; for (int i = 0; i < spaces[0].num_axes; ++i) { queue[settings.queue_end].data[i] = spaces[0].axis[i]->settings.current; for (int ss = 0; ss < 2; ++ss) queue[settings.queue_end].data[i] = space_types[spaces[ss].type].unchange0(&spaces[ss], i, queue[settings.queue_end].data[i]); if (i == 2) queue[settings.queue_end].data[i] -= zoffset; } for (int i = spaces[0].num_axes; i < QUEUE_LENGTH; ++i) { queue[settings.queue_end].data[i] = NAN; } cpdebug(0, 0, "eload end"); settings.queue_end = (settings.queue_end + 1) % QUEUE_LENGTH; // This shouldn't happen and causes communication problems, but if you have a 1-item buffer it is correct. if (settings.queue_end == settings.queue_start) settings.queue_full = true; } for (int a = 0; a < s->num_axes; ++a) { for (int o = 0; o < 3; ++o) EADATA(s, a).offset[o] = read_float(addr); } if (move) { next_move(); buffer_refill(); } }
PUBLIC void espButtonLink(HttpConn *conn, cchar *text, cchar *uri, cchar *optionString) { MprHash *options; options = httpGetOptions(optionString); httpSetOption(options, EDATA("click"), httpUri(conn, uri)); espRender(conn, "<button%s>%s</button>", map(conn, options), text); }
PUBLIC void espProgress(HttpConn *conn, cchar *percent, cchar *optionString) { MprHash *options; options = httpGetOptions(optionString); httpAddOption(options, EDATA("progress"), percent); espRender(conn, "<div class='" ESTYLE("progress") "'>\r\n"); espRender(conn, " <div class='" ESTYLE("progress-inner") "'%s>%s %%</div>\r\n</div>", map(conn, options), percent); }
static void process_otr (bfd *abfd, struct ext_otr *otr, int pass) { unsigned long shift; unsigned char *srcp = otr->data; unsigned char *endp = (unsigned char *) otr + otr->size; unsigned int bits = (otr->map[0] << 24) | (otr->map[1] << 16) | (otr->map[2] << 8) | (otr->map[3] << 0); struct esdid *esdid = &EDATA (abfd, otr->esdid - 1); unsigned char *contents = esdid->contents; int need_contents = 0; unsigned int dst_idx = esdid->pc; for (shift = ((unsigned long) 1 << 31); shift && srcp < endp; shift >>= 1) { if (bits & shift) { int flag = *srcp++; int esdids = (flag >> 5) & 0x7; int sizeinwords = ((flag >> 3) & 1) ? 2 : 1; int offsetlen = flag & 0x7; int j; if (esdids == 0) { /* A zero esdid means the new pc is the offset given. */ dst_idx += get_offset (offsetlen, srcp); srcp += offsetlen; } else { int val = get_offset (offsetlen, srcp + esdids); if (pass == 1) need_contents = 1; else for (j = 0; j < sizeinwords * 2; j++) { contents[dst_idx + (sizeinwords * 2) - j - 1] = val; val >>= 8; } for (j = 0; j < esdids; j++) { int esdid = *srcp++; if (esdid) { int rn = EDATA (abfd, otr->esdid - 1).relocs++; if (pass == 1) { /* This is the first pass over the data, just remember that we need a reloc. */ } else { arelent *n = EDATA (abfd, otr->esdid - 1).section->relocation + rn; n->address = dst_idx; n->sym_ptr_ptr = (asymbol **) (size_t) esdid; n->addend = 0; n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1); } } } srcp += offsetlen; dst_idx += sizeinwords * 2; } } else {
static void process_esd (bfd *abfd, struct ext_esd *esd, int pass) { /* Read through the ext def for the est entries. */ int togo = esd->size - 2; bfd_vma size; bfd_vma start; asection *sec; char name[11]; unsigned char *ptr = esd->esd_entries; unsigned char *end = ptr + togo; while (ptr < end) { int scn = *ptr & 0xf; int typ = (*ptr >> 4) & 0xf; /* Declare this section. */ sprintf (name, "%d", scn); sec = bfd_make_section_old_way (abfd, strdup (name)); sec->target_index = scn; EDATA (abfd, scn).section = sec; ptr++; switch (typ) { default: abort (); case ESD_XREF_SEC: case ESD_XREF_SYM: { int snum = VDATA (abfd)->ref_idx++; get_10 (&ptr, name); if (pass == 1) VDATA (abfd)->stringlen += strlen (name) + 1; else { int esidx; asymbol *s; char *n = new_symbol_string (abfd, name); s = versados_new_symbol (abfd, snum, n, (bfd_vma) 0, bfd_und_section_ptr); esidx = VDATA (abfd)->es_done++; RDATA (abfd, esidx - ES_BASE) = s; } } break; case ESD_ABS: size = get_4 (&ptr); start = get_4 (&ptr); break; case ESD_STD_REL_SEC: case ESD_SHRT_REL_SEC: sec->size = get_4 (&ptr); sec->flags |= SEC_ALLOC; break; case ESD_XDEF_IN_ABS: sec = (asection *) & bfd_abs_section; case ESD_XDEF_IN_SEC: { int snum = VDATA (abfd)->def_idx++; bfd_vma val; get_10 (&ptr, name); val = get_4 (&ptr); if (pass == 1) /* Just remember the symbol. */ VDATA (abfd)->stringlen += strlen (name) + 1; else { asymbol *s; char *n = new_symbol_string (abfd, name); s = versados_new_symbol (abfd, snum + VDATA (abfd)->nrefs, n, val, sec); s->flags |= BSF_GLOBAL; } } break; } } }
static void process_otr (bfd *abfd, struct ext_otr *otr, int pass) { unsigned long shift; unsigned char *srcp = otr->data; unsigned char *endp = (unsigned char *) otr + otr->size; unsigned int bits = (otr->map[0] << 24) | (otr->map[1] << 16) | (otr->map[2] << 8) | (otr->map[3] << 0); struct esdid *esdid; unsigned char *contents; bfd_boolean need_contents = FALSE; unsigned int dst_idx; /* PR 17512: file: ac7da425. */ if (otr->esdid == 0) return; esdid = &EDATA (abfd, otr->esdid - 1); contents = esdid->contents; dst_idx = esdid->pc; for (shift = ((unsigned long) 1 << 31); shift && srcp < endp; shift >>= 1) { if (bits & shift) { int flag = *srcp++; int esdids = (flag >> 5) & 0x7; int sizeinwords = ((flag >> 3) & 1) ? 2 : 1; unsigned int offsetlen = flag & 0x7; int j; /* PR 21591: Check for invalid lengths. */ if (srcp + esdids + offsetlen >= endp) return; if (esdids == 0) { /* A zero esdid means the new pc is the offset given. */ dst_idx += get_offset (offsetlen, srcp); srcp += offsetlen; } else { int val = get_offset (offsetlen, srcp + esdids); if (pass == 1) need_contents = TRUE; else if (contents && dst_idx < esdid->content_size - sizeinwords * 2) for (j = 0; j < sizeinwords * 2; j++) { contents[dst_idx + (sizeinwords * 2) - j - 1] = val; val >>= 8; } for (j = 0; j < esdids; j++) { int id = *srcp++; if (id) { int rn = EDATA (abfd, otr->esdid - 1).relocs++; if (pass == 1) { /* This is the first pass over the data, just remember that we need a reloc. */ } else { arelent *n; /* PR 17512: file: 54f733e0. */ if (EDATA (abfd, otr->esdid - 1).section == NULL) continue; n = EDATA (abfd, otr->esdid - 1).section->relocation + rn; n->address = dst_idx; n->sym_ptr_ptr = (asymbol **) (size_t) id; n->addend = 0; n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1); } } } srcp += offsetlen; dst_idx += sizeinwords * 2; } } else {
PUBLIC void espTable(HttpConn *conn, EdiGrid *grid, cchar *optionString) { MprHash *options, *colOptions, *rowOptions, *thisCol; MprList *cols; EdiRec *rec; EdiField *fp; cchar *title, *width, *o, *header, *value, *sortColumn; char index[8]; int c, r, ncols, sortOrder; assert(grid); if (grid == 0) { return; } options = httpGetOptions(optionString); if (grid->nrecords == 0) { espRender(conn, "<p>No Data</p>\r\n"); return; } if (grid->flags & EDI_GRID_READ_ONLY) { grid = ediCloneGrid(grid); } if ((sortColumn = httpGetOption(options, "sort", 0)) != 0) { sortOrder = httpOption(options, "sortOrder", "ascending", 1); ediSortGrid(grid, sortColumn, sortOrder); } colOptions = httpGetOptionHash(options, "columns"); filterCols(grid, options, colOptions); if (httpOption(options, "pivot", "true", 0) != 0) { pivotTable(conn, ediPivotGrid(grid, 1), options); return; } cols = ediGetGridColumns(grid); ncols = mprGetListLength(cols); rowOptions = mprCreateHash(0, MPR_HASH_STABLE); httpSetOption(rowOptions, EDATA("click"), httpGetOption(options, EDATA("click"), 0)); httpRemoveOption(options, EDATA("click")); httpSetOption(rowOptions, EDATA("remote"), httpGetOption(options, EDATA("remote"), 0)); httpSetOption(rowOptions, EDATA("key"), httpGetOption(options, EDATA("key"), 0)); httpSetOption(rowOptions, EDATA("params"), httpGetOption(options, EDATA("params"), 0)); httpSetOption(rowOptions, EDATA("edit"), httpGetOption(options, EDATA("edit"), 0)); httpInsertOption(options, "class", ESTYLE("table")); httpInsertOption(options, "class", ESTYLE("stripe")); espRender(conn, "<table%s>\r\n", map(conn, options)); /* Table header */ if (httpOption(options, "showHeader", "true", 1)) { espRender(conn, " <thead>\r\n"); if ((title = httpGetOption(options, "title", 0)) != 0) { espRender(conn, " <tr class='" ESTYLE("table-title") "'><td colspan='%s'>%s</td></tr>\r\n", mprGetListLength(cols), title); } espRender(conn, " <tr class='" ESTYLE("table-header") "'>\r\n"); rec = grid->records[0]; for (c = 0; c < ncols; c++) { assert(c <= rec->nfields); fp = &rec->fields[c]; width = ((o = httpGetOption(options, "width", 0)) != 0) ? sfmt(" width='%s'", o) : ""; thisCol = mprLookupKey(colOptions, itosbuf(index, sizeof(index), c, 10)); header = httpGetOption(thisCol, "header", spascal(fp->name)); espRender(conn, " <th%s>%s</th>\r\n", width, header); } espRender(conn, " </tr>\r\n </thead>\r\n"); } espRender(conn, " <tbody>\r\n"); /* Table body data */ for (r = 0; r < grid->nrecords; r++) { rec = grid->records[r]; httpSetOption(rowOptions, "id", rec->id); espRender(conn, " <tr%s>\r\n", map(conn, rowOptions)); for (c = 0; c < ncols; c++) { fp = &rec->fields[c]; thisCol = mprLookupKey(colOptions, itosbuf(index, sizeof(index), c, 10)); if (httpGetOption(thisCol, "align", 0) == 0) { if (fp->type == EDI_TYPE_INT || fp->type == EDI_TYPE_FLOAT) { if (!thisCol) { thisCol = mprCreateHash(0, MPR_HASH_STABLE); } httpInsertOption(thisCol, "align", "right"); } } value = formatValue(fp, thisCol); espRender(conn, " <td%s>%s</td>\r\n", map(conn, thisCol), value); } espRender(conn, " </tr>\r\n"); } espRender(conn, " </tbody>\r\n</table>\r\n"); }
/* Render a table from a data grid Examples: table(grid, "{ refresh:'@update', period:'1000', pivot:'true' }"); table(grid, "{ click:'@edit' }"); table(grid, "columns: [ \ { name: product, header: 'Product', width: '20%' }, \ { name: date, format: '%m-%d-%y' }, \ { name: 'user.name' }, \ ]"); table(readTable("users")); table(makeGrid("[{'name': 'peter', age: 23 }, {'name': 'mary', age: 22}]") table(grid, "{ \ columns: [ \ { name: 'speed', header: 'Speed', dropdown: [100, 1000, 40000] }, \ { name: 'adminMode', header: 'Admin Mode', radio: ['Up', 'Down'] }, \ { name: 'state', header: 'State', radio: ['Enabled', 'Disabled'] }, \ { name: 'autoNegotiate', header: 'Auto Negotiate', checkbox: ['enabled'] }, \ { name: 'type', header: 'Type' }, \ ], \ edit: true, \ pivot: true, \ showHeader: false, \ class: 'esp-pivot', \ }"); */ static void pivotTable(HttpConn *conn, EdiGrid *grid, MprHash *options) { MprHash *colOptions, *rowOptions, *thisCol, *dropdown, *radio; MprList *cols; EdiRec *rec; EdiField *fp; cchar *title, *width, *o, *header, *name, *checkbox; char index[8]; int c, r, ncols; assert(grid); if (grid->nrecords == 0) { espRender(conn, "<p>No Data</p>\r\n"); return; } colOptions = httpGetOptionHash(options, "columns"); cols = ediGetGridColumns(grid); ncols = mprGetListLength(cols); rowOptions = mprCreateHash(0, MPR_HASH_STABLE); httpSetOption(rowOptions, EDATA("click"), httpGetOption(options, EDATA("click"), 0)); httpInsertOption(options, "class", ESTYLE("pivot")); httpInsertOption(options, "class", ESTYLE("table")); espRender(conn, "<table%s>\r\n", map(conn, options)); /* Table header */ if (httpOption(options, "showHeader", "true", 1)) { espRender(conn, " <thead>\r\n"); if ((title = httpGetOption(options, "title", 0)) != 0) { espRender(conn, " <tr class='" ESTYLE("table-title") "'><td colspan='%s'>%s</td></tr>\r\n", mprGetListLength(cols), title); } espRender(conn, " <tr class='" ESTYLE("header") "'>\r\n"); rec = grid->records[0]; for (r = 0; r < ncols; r++) { assert(r <= grid->nrecords); width = ((o = httpGetOption(options, "width", 0)) != 0) ? sfmt(" width='%s'", o) : ""; thisCol = mprLookupKey(colOptions, itosbuf(index, sizeof(index), r, 10)); header = httpGetOption(thisCol, "header", spascal(rec->id)); espRender(conn, " <th%s>%s</th>\r\n", width, header); } espRender(conn, " </tr>\r\n </thead>\r\n"); } espRender(conn, " <tbody>\r\n"); /* Table body data */ for (r = 0; r < grid->nrecords; r++) { rec = grid->records[r]; httpSetOption(rowOptions, "id", rec->id); espRender(conn, " <tr%s>\r\n", map(conn, rowOptions)); for (c = 0; c < ncols; c++) { fp = &rec->fields[c]; thisCol = mprLookupKey(colOptions, itosbuf(index, sizeof(index), r, 10)); if (httpGetOption(thisCol, "align", 0) == 0) { if (fp->type == EDI_TYPE_INT || fp->type == EDI_TYPE_FLOAT) { if (!thisCol) { thisCol = mprCreateHash(0, MPR_HASH_STABLE); } httpInsertOption(thisCol, "align", "right"); } } if (c == 0) { /* Render column name */ name = httpGetOption(thisCol, "header", spascal(rec->id)); if (httpOption(options, "edit", "true", 0) && httpOption(thisCol, "edit", "true", 1)) { espRender(conn, " <td%s>%s</td><td>", map(conn, thisCol), name); if ((dropdown = httpGetOption(thisCol, "dropdown", 0)) != 0) { espDropdown(conn, fp->name, hashToGrid(dropdown), 0); } else if ((radio = httpGetOption(thisCol, "radio", 0)) != 0) { espRadio(conn, fp->name, hashToString(radio, 0), 0); } else if ((checkbox = httpGetOption(thisCol, "checkbox", 0)) != 0) { espCheckbox(conn, fp->name, checkbox, 0); } else { input(fp->name, 0); } espRender(conn, "</td>\r\n"); } else { espRender(conn, " <td%s>%s</td><td>%s</td>\r\n", map(conn, thisCol), name, fp->value); } } else { espRender(conn, " <td%s>%s</td>\r\n", map(conn, thisCol), fp->value); } } } espRender(conn, " </tr>\r\n"); espRender(conn, " </tbody>\r\n</table>\r\n"); }
static bool einit(Space *s) { s->type_data = new ExtruderData; EDATA(s).num_axes = 0; return true; }