//------------------------------------------------------------------- //------------------------------------------------------------------- int assemble ( void ) { unsigned int ra; unsigned int rb; unsigned int rc; curradd=0; nlabs=0; memset(mem,0x00,sizeof(mem)); memset(mark,0x00,sizeof(mark)); line=0; while(fgets(newline,sizeof(newline)-1,fpin)) { line++; //tabs to spaces and other things for(ra=0;newline[ra];ra++) { if(newline[ra]<0x20) newline[ra]=0x20; if(newline[ra]>=0x7F) newline[ra]=0; } //various ways to comment lines for(ra=0;newline[ra];ra++) { if(newline[ra]==';') newline[ra]=0; if(newline[ra]=='@') newline[ra]=0; if((newline[ra]=='/')&&(newline[ra+1]=='/')) newline[ra]=0; if(newline[ra]==0) break; } //skip spaces for(ra=0;newline[ra];ra++) if(newline[ra]!=0x20) break; if(newline[ra]==0) continue; //look for a label? for(rb=ra;newline[rb];rb++) { if(newline[rb]==0x20) break; //no spaces in labels if(newline[rb]==':') break; } if(newline[rb]==':') { //got a label rc=rb-ra; if(rc==0) { printf("<%u> Error: Invalid label\n",line); return(1); } rc--; if(rc>=LABLEN) { printf("<%u> Error: Label too long\n",line); return(1); } for(rb=0;rb<=rc;rb++) { lab_struct[nlabs].name[rb]=newline[ra++]; } lab_struct[nlabs].name[rb]=0; lab_struct[nlabs].addr=0x3000+curradd; lab_struct[nlabs].line=line; lab_struct[nlabs].type=0; ra++; for(lab=0;lab<nlabs;lab++) { if(lab_struct[lab].type) continue; if(strcmp(lab_struct[lab].name,lab_struct[nlabs].name)==0) break; } if(lab<nlabs) { printf("<%u> Error: label [%s] already defined on line %u\n",line,lab_struct[lab].name,lab_struct[lab].line); return(1); } nlabs++; //skip spaces for(;newline[ra];ra++) if(newline[ra]!=0x20) break; if(newline[ra]==0) continue; } // .word ----------------------------------------------------------- if(strncmp(&newline[ra],".word ",6)==0) { ra+=6; ra=parse_immed(ra); if(ra==0) return(1); mem[curradd]=rx; mark[curradd]|=0x80000000; curradd++; if(rest_of_line(ra)) return(1); continue; } // add ----------------------------------------------------------- if(strncmp(&newline[ra],"add ",4)==0) { ra+=4; //add rd,rs,rx //add rd,rs,#imm ra=parse_two_regs(ra); if(ra==0) return(1); ra=parse_comma(ra); if(ra==0) return(1); if(newline[ra]=='#') { ra=parse_immed(ra+1); if(ra==0) return(1); if(check_simmed5(rx)) return(1); mem[curradd]=0x1020|(rd<<9)|(rs<<6)|(rx&0x1F); mark[curradd]|=0x80000000; curradd++; } else { ra=parse_reg(ra); if(ra==0) return(1); mem[curradd]=0x1000|(rd<<9)|(rs<<6)|rx; mark[curradd]|=0x80000000; curradd++; } if(rest_of_line(ra)) return(1); continue; } // and ----------------------------------------------------------- if(strncmp(&newline[ra],"and ",4)==0) { ra+=4; //and rd,rs,rx //and rd,rs,#imm ra=parse_two_regs(ra); if(ra==0) return(1); ra=parse_comma(ra); if(ra==0) return(1); if(newline[ra]=='#') { ra=parse_immed(ra+1); if(ra==0) return(1); if(check_simmed5(rx)) return(1); mem[curradd]=0x5020|(rd<<9)|(rs<<6)|(rx&0x1F); mark[curradd]|=0x80000000; curradd++; } else { ra=parse_reg(ra); if(ra==0) return(1); mem[curradd]=0x5000|(rd<<9)|(rs<<6)|rx; mark[curradd]|=0x80000000; curradd++; } if(rest_of_line(ra)) return(1); continue; } // jmp ----------------------------------------------------------- if(strncmp(&newline[ra],"jmp ",4)==0) { ra+=4; //jmp rs ra=parse_reg(ra); if(ra==0) return(1); mem[curradd]=0xC000|(rx<<6); mark[curradd]|=0x80000000; curradd++; if(rest_of_line(ra)) return(1); continue; } // jsrr ----------------------------------------------------------- if(strncmp(&newline[ra],"jsrr ",5)==0) { ra+=5; //jsrr rs ra=parse_reg(ra); if(ra==0) return(1); mem[curradd]=0x4000|(rx<<6); mark[curradd]|=0x80000000; curradd++; if(rest_of_line(ra)) return(1); continue; } // not ----------------------------------------------------------- if(strncmp(&newline[ra],"not ",4)==0) { ra+=4; //not rd,rs ra=parse_two_regs(ra); if(ra==0) return(1); mem[curradd]=0x9000|(rd<<9)|(rs<<6); mark[curradd]|=0x80000000; curradd++; if(rest_of_line(ra)) return(1); continue; } // ret ----------------------------------------------------------- if(strncmp(&newline[ra],"ret",3)==0) { ra+=3; //ret mem[curradd]=0xC1C0; mark[curradd]|=0x80000000; curradd++; if(rest_of_line(ra)) return(1); continue; } // rti ----------------------------------------------------------- if(strncmp(&newline[ra],"rti",3)==0) { ra+=3; //rti mem[curradd]=0x8000; mark[curradd]|=0x80000000; curradd++; if(rest_of_line(ra)) return(1); continue; } // brn ----------------------------------------------------------- if(strncmp(&newline[ra],"brn ",4)==0) { ra+=4; //brn offset/label ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: branch too far\n",line); return(1); } mem[curradd]=0x0800|(rx&0x1FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x0800; mark[curradd]|=0x80000002; curradd++; } continue; } // brz ----------------------------------------------------------- if(strncmp(&newline[ra],"brz ",4)==0) { ra+=4; //brz offset/label ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: branch too far\n",line); return(1); } mem[curradd]=0x0400|(rx&0x1FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x0400; mark[curradd]|=0x80000002; curradd++; } continue; } // brp ----------------------------------------------------------- if(strncmp(&newline[ra],"brp ",4)==0) { ra+=4; //brp offset/label ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: branch too far\n",line); return(1); } mem[curradd]=0x0200|(rx&0x1FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x0200; mark[curradd]|=0x80000002; curradd++; } continue; } // brnz ----------------------------------------------------------- if(strncmp(&newline[ra],"brnz ",5)==0) { ra+=5; //brnzp offset/label ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: branch too far\n",line); return(1); } mem[curradd]=0x0C00|(rx&0x1FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x0C00; mark[curradd]|=0x80000002; curradd++; } continue; } // brnp ----------------------------------------------------------- if(strncmp(&newline[ra],"brnp ",5)==0) { ra+=5; //brnp offset/label ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: branch too far\n",line); return(1); } mem[curradd]=0x0A00|(rx&0x1FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x0A00; mark[curradd]|=0x80000002; curradd++; } continue; } // brzp ----------------------------------------------------------- if(strncmp(&newline[ra],"brzp ",5)==0) { ra+=5; //brzp offset/label ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: branch too far\n",line); return(1); } mem[curradd]=0x0600|(rx&0x1FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x0600; mark[curradd]|=0x80000002; curradd++; } continue; } // brnzp ----------------------------------------------------------- if(strncmp(&newline[ra],"brnzp ",6)==0) { ra+=6; //brnzp offset/label ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: branch too far\n",line); return(1); } mem[curradd]=0x0E00|(rx&0x1FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x0E00; mark[curradd]|=0x80000002; curradd++; } continue; } // jsr ----------------------------------------------------------- if(strncmp(&newline[ra],"jsr ",4)==0) { ra+=4; //jsr offset/label ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset11(rx)) { printf("<%u> Error: jsr too far\n",line); return(1); } mem[curradd]=0x4800|(rx&0x07FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x4800; mark[curradd]|=0x80000002; curradd++; } continue; } // ld ----------------------------------------------------------- if(strncmp(&newline[ra],"ld ",3)==0) { ra+=3; //ld rd,offset/label ra=parse_reg(ra); if(ra==0) return(1); rd=rx; ra=parse_comma(ra); if(ra==0) return(1); ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: ld too far\n",line); return(1); } mem[curradd]=0x2000|(rd<<9)|(rx&0x01FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x2000|(rd<<9); mark[curradd]|=0x80000002; curradd++; } continue; } // ldi ----------------------------------------------------------- if(strncmp(&newline[ra],"ldi ",4)==0) { ra+=4; //ldi rd,offset/label ra=parse_reg(ra); if(ra==0) return(1); rd=rx; ra=parse_comma(ra); if(ra==0) return(1); ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: ldi too far\n",line); return(1); } mem[curradd]=0xA000|(rd<<9)|(rx&0x01FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0xA000|(rd<<9); mark[curradd]|=0x80000002; curradd++; } continue; } // ldr ----------------------------------------------------------- if(strncmp(&newline[ra],"ldr ",4)==0) { ra+=4; //ldr rd,rs,#offset ra=parse_two_regs(ra); if(ra==0) return(1); ra=parse_comma(ra); if(ra==0) return(1); ra=parse_pound(ra); if(ra==0) return(1); ra=parse_immed(ra); if(ra==0) return(1); if(rest_of_line(ra)) return(1); if(check_simmed6(rx)) return(1); mem[curradd]=0x6000|(rd<<9)|(rs<<6)|(rx&0x003F); mark[curradd]|=0x80000000; curradd++; continue; } // lea ----------------------------------------------------------- if(strncmp(&newline[ra],"lea ",4)==0) { ra+=4; //ldi rd,offset/label ra=parse_reg(ra); if(ra==0) return(1); rd=rx; ra=parse_comma(ra); if(ra==0) return(1); ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: lea too far\n",line); return(1); } mem[curradd]=0xE000|(rd<<9)|(rx&0x01FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0xE000|(rd<<9); mark[curradd]|=0x80000002; curradd++; } continue; } // st ----------------------------------------------------------- if(strncmp(&newline[ra],"st ",3)==0) { ra+=3; //st rd,offset/label ra=parse_reg(ra); if(ra==0) return(1); rd=rx; ra=parse_comma(ra); if(ra==0) return(1); ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: st too far\n",line); return(1); } mem[curradd]=0x3000|(rd<<9)|(rx&0x01FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0x3000|(rd<<9); mark[curradd]|=0x80000002; curradd++; } continue; } // sti ----------------------------------------------------------- if(strncmp(&newline[ra],"sti ",4)==0) { ra+=4; //sti rd,offset/label ra=parse_reg(ra); if(ra==0) return(1); rd=rx; ra=parse_comma(ra); if(ra==0) return(1); ra=parse_branch_label(ra); if(ra==0) return(0); if(rest_of_line(ra)) return(1); if(is_const) { if(check_offset9(rx)) { printf("<%u> Error: sti too far\n",line); return(1); } mem[curradd]=0xB000|(rd<<9)|(rx&0x01FF); mark[curradd]|=0x80000000; curradd++; } else { mem[curradd]=0xB000|(rd<<9); mark[curradd]|=0x80000002; curradd++; } continue; } // str ----------------------------------------------------------- if(strncmp(&newline[ra],"str ",4)==0) { ra+=4; //str rd,rs,#offset ra=parse_two_regs(ra); if(ra==0) return(1); ra=parse_comma(ra); if(ra==0) return(1); ra=parse_pound(ra); if(ra==0) return(1); ra=parse_immed(ra); if(ra==0) return(1); if(rest_of_line(ra)) return(1); if(check_simmed6(rx)) return(1); mem[curradd]=0x7000|(rd<<9)|(rs<<6)|(rx&0x003F); mark[curradd]|=0x80000000; curradd++; continue; } // trap ----------------------------------------------------------- if(strncmp(&newline[ra],"trap ",5)==0) { ra+=5; //trap imm ra=parse_immed(ra); if(ra==0) return(1); if((rx&0xFF)!=rx) { printf("<%u> Error: invalid trap vector\n",line); return(1); } mem[curradd]=0xF000|(rx&0xFF); mark[curradd]|=0x80000000; curradd++; if(rest_of_line(ra)) return(1); continue; } // ----------------------------------------------------------- printf("<%u> Error: syntax error\n",line); return(1); } return(0); }
/* ** Read the git-fast-import format from pIn and insert the corresponding ** content into the database. */ static void git_fast_import(FILE *pIn){ ImportFile *pFile, *pNew; int i, mx; char *z; char *zUuid; char *zName; char *zPerm; char *zFrom; char *zTo; char zLine[1000]; gg.xFinish = finish_noop; while( fgets(zLine, sizeof(zLine), pIn) ){ if( zLine[0]=='\n' || zLine[0]=='#' ) continue; if( memcmp(zLine, "blob", 4)==0 ){ gg.xFinish(); gg.xFinish = finish_blob; }else if( memcmp(zLine, "commit ", 7)==0 ){ gg.xFinish(); gg.xFinish = finish_commit; trim_newline(&zLine[7]); z = &zLine[7]; /* The argument to the "commit" line might match either of these ** patterns: ** ** (A) refs/heads/BRANCHNAME ** (B) refs/tags/TAGNAME ** ** If pattern A is used, then the branchname used is as shown. ** Except, the "master" branch which is the default branch name in ** Git is changed to "trunk" which is the default name in Fossil. ** If the pattern is B, then the new commit should be on the same ** branch as its parent. And, we might need to add the TAGNAME ** tag to the new commit. However, if there are multiple instances ** of pattern B with the same TAGNAME, then only put the tag on the ** last commit that holds that tag. ** ** None of the above is explained in the git-fast-export ** documentation. We had to figure it out via trial and error. */ for(i=strlen(z)-1; i>=0 && z[i]!='/'; i--){} gg.tagCommit = memcmp(&z[i-4], "tags", 4)==0; /* True for pattern B */ if( z[i+1]!=0 ) z += i+1; if( fossil_strcmp(z, "master")==0 ) z = "trunk"; gg.zBranch = fossil_strdup(z); gg.fromLoaded = 0; }else if( memcmp(zLine, "tag ", 4)==0 ){ gg.xFinish(); gg.xFinish = finish_tag; trim_newline(&zLine[4]); gg.zTag = fossil_strdup(&zLine[4]); }else if( memcmp(zLine, "reset ", 4)==0 ){ gg.xFinish(); }else if( memcmp(zLine, "checkpoint", 10)==0 ){ gg.xFinish(); }else if( memcmp(zLine, "feature", 7)==0 ){ gg.xFinish(); }else if( memcmp(zLine, "option", 6)==0 ){ gg.xFinish(); }else if( memcmp(zLine, "progress ", 9)==0 ){ gg.xFinish(); trim_newline(&zLine[9]); fossil_print("%s\n", &zLine[9]); fflush(stdout); }else if( memcmp(zLine, "data ", 5)==0 ){ fossil_free(gg.aData); gg.aData = 0; gg.nData = atoi(&zLine[5]); if( gg.nData ){ int got; gg.aData = fossil_malloc( gg.nData+1 ); got = fread(gg.aData, 1, gg.nData, pIn); if( got!=gg.nData ){ fossil_fatal("short read: got %d of %d bytes", got, gg.nData); } gg.aData[got] = 0; if( gg.zComment==0 && gg.xFinish==finish_commit ){ gg.zComment = gg.aData; gg.aData = 0; gg.nData = 0; } } }else if( memcmp(zLine, "author ", 7)==0 ){ /* No-op */ }else if( memcmp(zLine, "mark ", 5)==0 ){ trim_newline(&zLine[5]); fossil_free(gg.zMark); gg.zMark = fossil_strdup(&zLine[5]); }else if( memcmp(zLine, "tagger ", 7)==0 || memcmp(zLine, "committer ",10)==0 ){ sqlite3_int64 secSince1970; for(i=0; zLine[i] && zLine[i]!='<'; i++){} if( zLine[i]==0 ) goto malformed_line; z = &zLine[i+1]; for(i=i+1; zLine[i] && zLine[i]!='>'; i++){} if( zLine[i]==0 ) goto malformed_line; zLine[i] = 0; fossil_free(gg.zUser); gg.zUser = fossil_strdup(z); secSince1970 = 0; for(i=i+2; fossil_isdigit(zLine[i]); i++){ secSince1970 = secSince1970*10 + zLine[i] - '0'; } fossil_free(gg.zDate); gg.zDate = db_text(0, "SELECT datetime(%lld, 'unixepoch')", secSince1970); gg.zDate[10] = 'T'; }else if( memcmp(zLine, "from ", 5)==0 ){ trim_newline(&zLine[5]); fossil_free(gg.zFromMark); gg.zFromMark = fossil_strdup(&zLine[5]); fossil_free(gg.zFrom); gg.zFrom = resolve_committish(&zLine[5]); }else if( memcmp(zLine, "merge ", 6)==0 ){ trim_newline(&zLine[6]); if( gg.nMerge>=gg.nMergeAlloc ){ gg.nMergeAlloc = gg.nMergeAlloc*2 + 10; gg.azMerge = fossil_realloc(gg.azMerge, gg.nMergeAlloc*sizeof(char*)); } gg.azMerge[gg.nMerge] = resolve_committish(&zLine[6]); if( gg.azMerge[gg.nMerge] ) gg.nMerge++; }else if( memcmp(zLine, "M ", 2)==0 ){ import_prior_files(); z = &zLine[2]; zPerm = next_token(&z); zUuid = next_token(&z); zName = rest_of_line(&z); dequote_git_filename(zName); i = 0; pFile = import_find_file(zName, &i, gg.nFile); if( pFile==0 ){ pFile = import_add_file(); pFile->zName = fossil_strdup(zName); } pFile->isExe = (fossil_strcmp(zPerm, "100755")==0); pFile->isLink = (fossil_strcmp(zPerm, "120000")==0); fossil_free(pFile->zUuid); pFile->zUuid = resolve_committish(zUuid); pFile->isFrom = 0; }else if( memcmp(zLine, "D ", 2)==0 ){ import_prior_files(); z = &zLine[2]; zName = rest_of_line(&z); dequote_git_filename(zName); i = 0; while( (pFile = import_find_file(zName, &i, gg.nFile))!=0 ){ if( pFile->isFrom==0 ) continue; fossil_free(pFile->zName); fossil_free(pFile->zPrior); fossil_free(pFile->zUuid); *pFile = gg.aFile[--gg.nFile]; i--; } }else if( memcmp(zLine, "C ", 2)==0 ){ int nFrom; import_prior_files(); z = &zLine[2]; zFrom = next_token(&z); zTo = rest_of_line(&z); i = 0; mx = gg.nFile; nFrom = strlen(zFrom); while( (pFile = import_find_file(zFrom, &i, mx))!=0 ){ if( pFile->isFrom==0 ) continue; pNew = import_add_file(); pFile = &gg.aFile[i-1]; if( strlen(pFile->zName)>nFrom ){ pNew->zName = mprintf("%s%s", zTo, pFile->zName[nFrom]); }else{ pNew->zName = fossil_strdup(pFile->zName); } pNew->isExe = pFile->isExe; pNew->isLink = pFile->isLink; pNew->zUuid = fossil_strdup(pFile->zUuid); pNew->isFrom = 0; } }else if( memcmp(zLine, "R ", 2)==0 ){ int nFrom; import_prior_files(); z = &zLine[2]; zFrom = next_token(&z); zTo = rest_of_line(&z); i = 0; nFrom = strlen(zFrom); while( (pFile = import_find_file(zFrom, &i, gg.nFile))!=0 ){ if( pFile->isFrom==0 ) continue; pNew = import_add_file(); pFile = &gg.aFile[i-1]; if( strlen(pFile->zName)>nFrom ){ pNew->zName = mprintf("%s%s", zTo, pFile->zName[nFrom]); }else{ pNew->zName = fossil_strdup(pFile->zName); } pNew->zPrior = pFile->zName; pNew->isExe = pFile->isExe; pNew->isLink = pFile->isLink; pNew->zUuid = pFile->zUuid; pNew->isFrom = 0; gg.nFile--; *pFile = *pNew; memset(pNew, 0, sizeof(*pNew)); } fossil_fatal("cannot handle R records, use --full-tree"); }else if( memcmp(zLine, "deleteall", 9)==0 ){ gg.fromLoaded = 1; }else if( memcmp(zLine, "N ", 2)==0 ){ /* No-op */ }else { goto malformed_line; } } gg.xFinish(); if( gg.hasLinks ){ db_set_int("allow-symlinks", 1, 0); } import_reset(1); return; malformed_line: trim_newline(zLine); fossil_fatal("bad fast-import line: [%s]", zLine); return; }